Function Calling
Talos Ihre Tools aufrufen lassen und strukturierte Tool-Argumente zurückgeben
Beide API-Oberflächen unterstützen Tool Calling: Sie beschreiben Funktionen, und das Modell entscheidet, wann es sie aufruft.
from openai import OpenAI
import json
client = OpenAI(
base_url="https://api.ablatic.ai/v1",
api_key="sk-ablatic-...",
)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"},
},
"required": ["city"],
},
},
}
]
messages = [{"role": "user", "content": "What is the weather in Linz?"}]
resp = client.chat.completions.create(
model="talos",
messages=messages,
tools=tools,
)
call = resp.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments) # arguments is a JSON-encoded STRING
weather = {"city": args["city"], "temp_c": 21}
messages.append(resp.choices[0].message)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(weather),
})
final = client.chat.completions.create(model="talos", messages=messages, tools=tools)
print(final.choices[0].message.content)OpenAI-Oberfläche
Bei /v1/chat/completions definieren Sie jedes Tool unter function mit einem parameters-JSON-Schema. Wenn das Modell ein Tool aufruft, enthält die Antwort tool_calls, und jeder function.arguments-Wert ist ein JSON-codierter STRING. Parsen Sie ihn vor der Verwendung mit json.loads. Sie geben das Ergebnis als Nachricht mit role: "tool" und dem passenden tool_call_id zurück.
Anthropic-Oberfläche
Bei /v1/messages definieren Sie jedes Tool mit einem input_schema. Das Modell gibt einen tool_use-Content-Block zurück, dessen input bereits ein geparstes OBJEKT ist, sodass kein JSON-Parsing nötig ist. Sie geben das Ergebnis als tool_result-Content-Block zurück.
Die Unterschiede
Die Strukturen unterscheiden sich an zwei Stellen. OpenAI-Tools verwenden function.parameters und geben function.arguments als JSON-STRING zurück. Anthropic-Tools verwenden input_schema und geben tool_use.input als geparstes OBJEKT zurück. Auch die tool_choice-Enums unterscheiden sich: OpenAI verwendet required, Anthropic verwendet any.
Auf der OpenAI-Oberfläche ist function.arguments ein String. Parsen Sie ihn vor der Verwendung. Auf der Anthropic-Oberfläche ist tool_use.input bereits ein Objekt.
Welches Tool laufen darf
tool_choice entscheidet, ob das Modell überhaupt ein Tool aufrufen darf.
| Wert | Wirkung |
|---|---|
weggelassen oder "auto" | Das Modell entscheidet selbst, ob es ein Tool aufruft |
"none" | Das Modell ruft nie ein Tool auf und antwortet in content |
"required" | Das Modell muss eines der übergebenen Tools aufrufen |
{"type": "function", "function": {"name": "get_weather"}} | Das Modell muss genau diese Funktion aufrufen |
Mehrere Tools in einem Turn
Das Modell kann mehr als einen Eintrag in tool_calls zurückgeben. Führen Sie alle aus und schicken Sie im nächsten Request pro tool_call_id je eine Nachricht mit role: "tool" zurück. Iterieren Sie über das Array, statt tool_calls[0] zu lesen, sonst verlieren Sie Aufrufe und das Modell wartet auf ein Ergebnis, das nie kommt.
Token-Abrechnung über die Schleife
usage beschreibt genau den einen Request, mit dem es kam. Bei uns summiert sich nichts auf, da wir keinen Konversations-State halten.
Beim Aufsummieren über die Turns sind zwei Dinge wichtig.
reasoning_tokens ist Teil von completion_tokens und kein eigener Posten. Summieren Sie prompt_tokens und completion_tokens und lassen Sie reasoning_tokens weg, sonst zählen Sie das Reasoning doppelt. Das Feld erscheint nur, wenn Reasoning lief.
prompt_tokens wächst mit jedem Turn, weil Sie die vollständige Historie samt aller Tool-Ergebnisse erneut mitschicken.
Beim Streamen kommt usage im letzten Chunk vor data: [DONE].
Reasoning innerhalb einer Tool-Schleife
Jeder Turn denkt auf einem eigenen Budget, die gewählte Tiefe kostet also pro Turn. Ohne reasoning_effort erhalten Sie medium, das erlaubt rund 16k Reasoning-Token pro Turn. Senden Sie none oder low für kurze mechanische Tool-Schritte und heben Sie sich die tiefere Einstellung für den Turn auf, der die finale Antwort schreibt.
Bemessen Sie max_tokens für Reasoning und Antwort zusammen. Verbraucht ein Turn sein ganzes Budget im Denken, ohne Output zu erzeugen, bekommen Sie finish_reason: "length" statt eines leeren "stop". Wiederholen Sie diesen Turn mit größerem max_tokens.
Schicken Sie reasoning_content aus einem früheren Turn nicht in der Historie zurück.