OpenAI · GPT-6 Astra

GPT-6 Astra Function Calling 2026: APIs, Datenbanken und eigene Tools aufrufen

2026.09.11 · ~15 Min. Lesezeit

Function Calling ist nicht schwer — die Tücken sind ein fehlerhafter Tool-Loop, fehlende Rechteisolierung und die Bindung an Chat Completions, die gehostete Tools sperrt. Hier: HTTP-API-Toolschema, vollständiger Tool-Loop, schreibgeschütztes DB-Muster, Vergleich Funktions- vs. gehostete Tools, Entscheidungsmatrix und 7 Schritte.

Entwickler debuggt einen GPT-6-Astra-Function-Calling-Tool-Loop am Monitor

GPT-6 Astra Function Calling ist der Motor von KI-Agenten: Das Modell entscheidet, welches Tool aufgerufen wird und welche Argumente übergeben werden; die Laufzeit führt den Seiteneffekt aus; das Ergebnis fließt zurück ins Modell, das weiter schlussfolgert. Wenn dieser Loop korrekt ist, kann Astra eigenständig APIs abfragen, Datenbanken lesen und benutzerdefinierte Logik ausführen. Wenn er fehlerhaft ist, hängt der Loop, oder Tool-Berechtigungen übersteigen das Gewollte. Was Function Calling ist, erklärt der Protokollvergleich; wie man einen API-Key holt, das API-Tutorial. Dieser Artikel deckt die drei Tool-Muster ab, die aus "es läuft" ein "es ist sicher deploybar" machen.

Responses
Einziger Pfad für Tools
function_call
Event-Typ im output
allowlist
Sicherheitslinie für DB-Tools
Responses API ist Pflicht
Funktions-Tools, gehostete Tools (Websuche, Code Interpreter, Computer Use) und asynchrone Tool-Loops benötigen zwingend die Responses API. Ein gehostetes Tool auf einem Chat-Completions-Request gibt HTTP 400 zurück. Alle Code-Beispiele dieses Artikels setzen einen funktionierenden Textpfad voraus und verwenden Responses.

Schritt 1: Ein Tool-Schema definieren

Ein Tool-Schema ist ein JSON-Objekt, das dem Modell sagt, wie das Tool heißt, was es tut und welche Parameter es erwartet. Beispiel: ein Tool, das eine Wetter-HTTP-API aufruft.

Tool-Schema (HTTP-API-Tool)
import json
from openai import OpenAI

client = OpenAI()

tools = [
    {
        "type": "function",
        "name": "get_weather",
        "description": "Get current weather for a city via HTTP API.",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "City name, e.g. Tokyo, London, Shanghai",
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "Temperature unit. Default celsius.",
                },
            },
            "required": ["city"],
            "additionalProperties": False,
        },
    }
]

Die description sollte beschreiben, was das Tool tut — nicht nur seinen Namen wiederholen. Das Modell liest dieses Feld, um zu entscheiden, ob es das Tool aufrufen soll. Pflichtfelder kommen in required; optionale Felder in properties, aber nicht in required. additionalProperties: false verringert die Wahrscheinlichkeit, dass das Modell unerwartete Schlüssel übergibt. Mehrere Tools kommen in dieselbe Liste; das Modell wählt eines oder mehrere basierend auf dem Gespräch. Wenn das Modell mehrere Tools parallel aufruft, muss der Loop alle Ergebnisse verarbeiten, bevor er weiterläuft.

Schritt 2: Der vollständige Tool-Loop

Das Muster lautet: Request senden → function_call-Einträge in output prüfen → ausführen → Ergebnisse an input anhängen → erneut senden, bis keine neuen function_call-Einträge mehr erscheinen. Der Loop muss ein while True sein. Ein if-Einmal-Loop lässt die Abschlussantwort des Modells nie ankommen.

Vollständiger Tool-Loop (Responses API)
import json
import requests
from openai import OpenAI

client = OpenAI()

def call_weather_api(city: str, unit: str = "celsius") -> dict:
    """Replace with your real HTTP endpoint."""
    url = "https://api.example.com/weather"
    r = requests.get(url, params={"city": city, "unit": unit}, timeout=5)
    r.raise_for_status()
    return r.json()  # e.g. {"city": "Tokyo", "temp": 22, "condition": "sunny"}

# Initial request — model may call tools
response = client.responses.create(
    model="gpt-6-astra",
    input="What is the weather in Tokyo right now?",
    tools=tools,
    reasoning={"effort": "low"},
)

# Tool loop: keep going until model stops calling tools
while True:
    tool_calls = [o for o in response.output if o.type == "function_call"]
    if not tool_calls:
        break  # model is done — final answer is in response.output_text

    tool_results = []
    for call in tool_calls:
        args = json.loads(call.arguments)
        if call.name == "get_weather":
            result = call_weather_api(**args)
        else:
            result = {"error": f"Unknown tool: {call.name}"}
        tool_results.append({
            "type": "function_call_output",
            "call_id": call.call_id,
            "output": json.dumps(result, ensure_ascii=False),
        })

    # Append history + results and continue
    response = client.responses.create(
        model="gpt-6-astra",
        input=response.output + tool_results,
        tools=tools,
        reasoning={"effort": "low"},
    )

print(response.output_text)

Wichtige Implementierungsdetails. Erstens enthält response.output eine Liste mit gemischten Typen; nur type == "function_call" filtern. Zweitens beim Fortfahren response.output + tool_results als input übergeben; nur tool_results zu senden, verliert den Konversationsverlauf. Drittens muss die call_id im Ergebnis zur call_id des jeweiligen Tool-Calls passen. Viertens Tool-Rückgabewerte mit json.dumps serialisieren — kein rohes Python-Dict übergeben.

Sicherheit: Allowlist und Ausführungsisolierung
Was ein Tool darf, bestimmt die Laufzeit, nicht das Modell. Das name-Feld gegen eine Allowlist validieren. Argumenttypen prüfen. HTTP-Tools brauchen ein Timeout und eine Domain-Allowlist. DB-Tools führen nur vordefinierte SQL-Statements aus — niemals Modell-Output direkt in SQL konkatenieren. Tools, die auf Disk schreiben oder Shell-Befehle ausführen, gehören auf einen isolierten, wegwerfbaren Remote-Mac.

Schritt 3: Ein schreibgeschütztes Datenbank-Tool

Drei Anforderungen für ein sicheres DB-Tool: Nur-Lese-Verbindung (kein INSERT, UPDATE, DELETE), parametrisierte Queries (kein SQL-Injection), SQL-Allowlist (kein beliebiges SQL).

Schreibgeschütztes DB-Tool (Allowlist + Parametrisierung)
import sqlite3
from typing import Any

# Only these parameterized queries can be executed — no raw user SQL
ALLOWED_QUERIES: dict[str, str] = {
    "get_order":   "SELECT id, status, total, created_at FROM orders WHERE id = ?",
    "list_orders": "SELECT id, status, total FROM orders WHERE user_id = ? LIMIT 20",
}

def query_db(query_name: str, params: list[Any]) -> list[dict]:
    """Execute an allowlisted, parameterized read-only query.
    Never accepts raw SQL strings from the model.
    """
    sql = ALLOWED_QUERIES.get(query_name)
    if sql is None:
        raise ValueError(f"Query '{query_name}' not in allowlist")
    con = sqlite3.connect("orders.db", check_same_thread=False)
    con.row_factory = sqlite3.Row
    try:
        rows = con.execute(sql, params).fetchall()
        return [dict(r) for r in rows]
    finally:
        con.close()

# Schema exposed to the model
db_tool = {
    "type": "function",
    "name": "query_db",
    "description": "Query the orders DB. Only read-only allowlisted queries.",
    "parameters": {
        "type": "object",
        "properties": {
            "query_name": {
                "type": "string",
                "enum": list(ALLOWED_QUERIES.keys()),
                "description": "Name of the allowlisted query",
            },
            "params": {
                "type": "array",
                "items": {"type": ["string", "number"]},
                "description": "Positional parameters for the query",
            },
        },
        "required": ["query_name", "params"],
    },
}

In Produktion ergänzt man: Connection Pool (kein Connect/Close pro Tool-Call), Query-Timeout, Zeilenanzahl-Limit in jeder SQL (kein SELECT * ohne Limit), Maskierung sensibler Felder. Das Tool-Ergebnis soll eine Zusammenfassung sein, kein roher Tabellen-Dump — denn jede zurückgegebene Zeile kostet Input-Token im nächsten Request.

Funktions-Tools vs. gehostete Tools

DimensionFunktions-Tools (type: function)Gehostete Tools (OpenAI-betrieben)
AusführungsortEigene Laufzeit (lokal / Remote-Mac)OpenAI-Infrastruktur
Geeignet fürPrivate APIs, interne DBs, Custom-LogikWebsuche, Code Interpreter, Shell, Computer Use
EntwicklungsaufwandSchema + Ausführungsfunktion + Loop selbst schreibenToolnamen angeben, OpenAI erledigt den Rest
AbrechnungNur TokenToken + Tool-Gebühr pro Aufruf
IsolierungsanforderungSchreibende Tools brauchen isolierte UmgebungOpenAI verwaltet Sandbox; Datensicherheit obliegt Ihnen

Beide Typen können in einem Request kombiniert werden. Gehostete Tool-Ergebnisse fließen automatisch in den Konversationsverlauf ein; kein manuelles Einreichen notwendig. Funktions-Tool-Ergebnisse müssen manuell als function_call_output übermittelt werden.

Entscheidungsmatrix

Wenn Sie benötigenWählen SieBegründung
Internes REST-API aufrufenFunktions-ToolPrivates Netz von OpenAI-Infra nicht erreichbar
Interne DB lesen (nur lesen)Funktions-Tool + SQL-AllowlistPrivate Daten; Zugriffsrechte selbst verwalten
Öffentliche Web-Suche in EchtzeitGehostetes web_search_previewCrawling und Ranking übernimmt OpenAI
Modell soll Python ausführenGehostetes code_interpreterLäuft in OpenAI-Sandbox; kein lokaler Ressourcenverbrauch
Modell soll Desktop/Browser steuernGehostetes computer_use + isolierter MacSichtbarer Desktop nötig; Isolation verhindert Versehen
Shell-Befehle mit Disk-SchreibzugriffFunktions-Tool + Remote-Mac-IsolierungSchreibrechte nur auf wegwerfbarem Host

A — Solo-Entwickler/Prototyp: lokale Maschine, Funktions-Tools für HTTP-APIs (kein Disk-Write). Schema schreiben, Loop stabilisieren, call_id loggen. Erst nach stabilen Einzel-Tool-Aufrufen auf Mehrfach-Tools erweitern.

B — Kleines Team/Produkt: Funktions-Tools hinter internen Services mit Token-Auth. DB-Tool: read-only, Connection Pool, Query-Timeout. Gehostete Tools je nach Aufgabe aktivieren. Tool-Logik mit Unit-Tests abdecken; Rückgabewerte schema-validieren.

C — Enterprise: Alle Tool-Aufrufe über API-Gateway mit Audit-Log. DB: read-only Replica + Row-Level Security. Computer Use auf wegwerfbaren isolierten Mac-Nodes. Account und Liefergrenzen im Hilfecenter; Monatspreis für Nodes auf Mac-mini-Preise.

Häufige Fehler

  1. Loop nur einmal ausführen (if statt while): Die abschließende Textantwort des Modells kommt nie an.
  2. Ergebnisse ohne Verlauf einreichen: Nur tool_results als input übergeben — das Modell verliert den Kontext.
  3. Modell-Output direkt in SQL/Shell konkatenieren: Allowlist + parametrisierte Queries eliminieren die Angriffsfläche.
  4. Kein Timeout für HTTP-Tools: Ein hängender Downstream-Service friert die gesamte Agentensitzung ein.
  5. Große Daten-Dumps aus Tools zurückgeben: Zeilen verbrauchen Prompt-Token und können den 272K-Uplift auslösen.

Aktionsplan: 7 Schritte

  1. Zuerst den reinen Textpfad bestätigen (siehe API-Tutorial). Tools bauen darauf auf.
  2. Erstes Funktions-Tool-Schema schreiben. description als Verb-Phrase, required befüllen, additionalProperties: false.
  3. Ausführungsfunktion implementieren. HTTP-Tools: Timeout. DB-Tools: Allowlist + parametrisierte Queries.
  4. Responses-Request mit tools-Parameter senden; response.output ausgeben und function_call-Eintrag bestätigen.
  5. while-True-Loop implementieren. call_id korrekt abbilden, function_call_output einreichen, Verlauf mitgeben.
  6. Gehostete Tools (web_search, code_interpreter) hinzufügen, falls nötig. Deren Ergebnisse nicht manuell einreichen.
  7. Disk-schreibende, Shell-ausführende oder Browser-steuernde Tools auf einen isolierten Remote-Mac auslagern und Workspace am Sitzungsende vernichten.

FAQ

Ist die Responses API für Function Calling Pflicht?

Ja. Tool-Aufrufe, gehostete Tools und asynchrone Loops erfordern Responses. Chat Completions gibt bei gehosteten Tools HTTP 400 zurück.

Wie viele Tools pro Request?

Keine strenge kleine Obergrenze, aber mehr Tools = mehr Prompt-Token. Nur aufgabenrelevante Tools übergeben.

SQL-Injection verhindern?

Parametrisierte Queries mit ?-Platzhaltern kombiniert mit einer SQL-Allowlist. Modell-Output niemals direkt in SQL einfügen.

Funktions-Tool oder gehostetes Tool?

Private API, interne DB, Custom-Logik → Funktions-Tool. Websuche, Code-Interpreter, Computer Use → gehostetes Tool.

Finale Antwort nach Tool-Aufrufen streamen?

Ja. Erst den nicht-streamenden Loop stabilisieren, dann stream=True hinzufügen.

Fazit

Die drei Grundlagen von GPT-6 Astra Function Calling: ein Schema mit klarer description und vollständigen Parametern, ein while-Loop mit vollständigem Verlauf beim Einreichen, und DB-Tools mit Allowlist und parametrisierten Queries — write-fähige Tools auf einem isolierten Mac. Remote-Mac-Nodes finden Sie auf der Miet- und Preisseite; Kontodetails im Hilfecenter.

Weiterlesen

Tools, die echte APIs aufrufen? Auf einem isolierten Cloud-Mac ausführen

Einen öffentlichen HTTP-Endpunkt lokal aufzurufen ist in Ordnung. Sobald ein Tool Dateien schreibt, Repos bearbeitet oder einen Browser steuert, darf es den Alltags-Laptop nicht teilen. Remote-Macs isolieren einen Workspace pro Sitzung.

Jetzt bestellen · Preise ansehen

GPT-6 Astra Function Calling

Tools, die echte APIs aufrufen? Auf einem isolierten Cloud-Mac ausführen

Cloud Mac · isolated agent runtime

Jetzt bestellen
Mac Jetzt bestellen