Zum Hauptinhalt springen

Mehrsprachiger Tool-Calling-Agent

Das Tool-Calling-Agenten-Muster in diesem Guide funktioniert mit jedem Chat-Modell, das Funktionsaufrufe unterstützt. Das Beispiel verwendet Mistral-Medium-3.5-128B, aber es kann je nach Kosten- und Qualitätsanforderungen ein beliebiges der folgenden Modelle eingesetzt werden:

ModellSprachenHinweise
Mistral-Medium-3.5-128B40+Beste mehrsprachige Qualität
Qwen3.5-122B-A10B-FP8100+Thinking-Modus verfügbar; Vision
Qwen3.6-35B-A3B-FP8100+Kosteneffizienter; Reasoning + Vision
gpt-oss-120bEnglisch-zentriertAm besten für rein englische Workloads

Alle Modelle nutzen dieselbe OpenAI-kompatible Tool-Calling-API – ein Modellwechsel erfordert nur eine einzige Codezeile. Nutzer können auf Deutsch, Französisch, Spanisch oder einer anderen unterstützten Sprache fragen – das Modell versteht die Anfrage, ruft die richtigen Tools auf (die auf Englisch definiert sind) und antwortet in der Sprache des Nutzers ohne jeglichen Übersetzungsschritt.

Dieser Guide zeigt eine vollständige Agenten-Schleife: Das Modell entscheidet, welche Tools aufgerufen werden sollen, du führst sie aus und gibst die Ergebnisse zurück, bis das Modell alles hat, was es benötigt.

Einrichtung

user@local $ pip install openai
user@local $ export OPENAI_API_KEY="sk-…"

Tools definieren

Tool-Namen und -Beschreibungen werden immer auf Englisch verfasst. Das Modell ordnet jede Nutzersprache automatisch dem richtigen Tool zu.

import os
import json
from openai import OpenAI

client = OpenAI(base_url="https://llm.aihosting.mittwald.de/v1")

tools = [
{
"type": "function",
"function": {
"name": "get_exchange_rate",
"description": "Get the current exchange rate between two currencies.",
"parameters": {
"type": "object",
"properties": {
"from_currency": {
"type": "string",
"description": "ISO 4217 source currency code, e.g. EUR",
},
"to_currency": {
"type": "string",
"description": "ISO 4217 target currency code, e.g. USD",
},
},
"required": ["from_currency", "to_currency"],
},
},
},
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Return the status and estimated delivery date for a customer order.",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order identifier, e.g. ORD-12345",
},
},
"required": ["order_id"],
},
},
},
]

Tool-Funktionen implementieren

Diese Stubs durch echte Datenbankabfragen oder API-Aufrufe ersetzen:

def get_exchange_rate(from_currency: str, to_currency: str) -> dict:
# Stub — durch echten FX-API-Aufruf ersetzen
rates = {
("EUR", "USD"): 1.08,
("USD", "EUR"): 0.93,
("GBP", "EUR"): 1.17,
("EUR", "GBP"): 0.85,
}
rate = rates.get((from_currency.upper(), to_currency.upper()))
if rate is None:
return {"error": f"Kein Kurs verfügbar für {from_currency}/{to_currency}"}
return {"from": from_currency, "to": to_currency, "rate": rate}


def get_order_status(order_id: str) -> dict:
# Stub — durch echte Datenbankabfrage ersetzen
orders = {
"ORD-12345": {"status": "versandt", "lieferung": "2026-06-04"},
"ORD-99999": {"status": "in Bearbeitung", "lieferung": "2026-06-07"},
}
order = orders.get(order_id.upper())
if order is None:
return {"error": f"Bestellung {order_id} nicht gefunden"}
return {"order_id": order_id, **order}


FUNCTIONS = {
"get_exchange_rate": get_exchange_rate,
"get_order_status": get_order_status,
}

Die Agenten-Schleife

Die Schleife läuft, bis das Modell keine weiteren Tool-Aufrufe mehr anfordert (finish_reason != "tool_calls"):

def run_agent(user_message: str, system: str | None = None) -> str:
messages = []
if system:
messages.append({"role": "system", "content": system})
messages.append({"role": "user", "content": user_message})

while True:
response = client.chat.completions.create(
model="Mistral-Medium-3.5-128B",
messages=messages,
tools=tools,
tool_choice="auto",
temperature=0.2,
)
msg = response.choices[0].message
messages.append(msg)

if response.choices[0].finish_reason != "tool_calls":
return msg.content

# Jedes angeforderte Tool ausführen und Ergebnis zurückgeben
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = FUNCTIONS[call.function.name](**args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result),
})

Test in mehreren Sprachen

queries = [
"Was ist der aktuelle EUR/USD-Wechselkurs?", # Deutsch
"Quel est le taux de change EUR vers GBP?", # Französisch
"¿Cuál es el estado de mi pedido ORD-12345?", # Spanisch
"What is the status of order ORD-99999?", # Englisch
"Wie is de status van mijn bestelling ORD-12345?", # Niederländisch
]

for q in queries:
print(f"F: {q}")
print(f"A: {run_agent(q)}\n")

Das Modell antwortet in der Sprache, in der der Nutzer geschrieben hat – ohne explizite Spracherkennung oder Übersetzung im Code.

Persona über System-Prompt

SYSTEM = (
"Du bist ein freundlicher Kundensupport-Agent für mittwald. "
"Antworte immer in der Sprache, in der der Nutzer schreibt. "
"Sei knapp und professionell."
)

answer = run_agent("Mein Paket ORD-12345 — wann kommt es an?", system=SYSTEM)
print(answer)
# "Ihr Paket ORD-12345 ist bereits versandt und wird voraussichtlich am 4. Juni 2026 geliefert."

Parallele Tool-Aufrufe

Wenn eine Frage mehrere Tools gleichzeitig erfordert, kann das Modell mehrere tool_calls in einer einzigen Antwort zurückgeben. Die obige Schleife verarbeitet das bereits korrekt – sie iteriert über alle Aufrufe, bevor die nächste Modellanfrage gestellt wird.

# Diese Anfrage löst beide Tools in einem Durchgang aus
answer = run_agent(
"Wie ist der EUR/USD-Kurs und was ist der Status von Bestellung ORD-12345?"
)
print(answer)