Tools/KI-Agenten
OpenAI Agents SDK: eine schlanke Agent-Runtime mit scharfen Kanten
Eine Bewertung des OpenAI Agents SDK: Runner-Schleife, Tracing, Guardrails und Approvals, plus was Release-Tempo und die Responses-only-Funktionen kosten.
- Art
- Agent framework
- Preis
- MIT · API pay per token
Balázs Csorba··10 Min. Lesezeit
- Agent runtime
- Tracing
- Guardrails
- MCP
- Python

Das Wichtigste in Kürze
- Das Python-Paket steht unter MIT, braucht Python 3.10 oder neuer und war am 2. Oktober 2026 bei Version 0.23.1, nach 123 PyPI-Releases seit März 2025.
- Der Runner begrenzt standardmäßig auf max_turns=10 und wirft MaxTurnsExceeded, ein sinnvoller Default, den die meisten Teams behalten sollten.
- Tracing ist per Default aktiv und transportiert Modell- und Tool-Ein- sowie Ausgaben, Produktionsläufe sollten also trace_include_sensitive_data=False setzen.
- Guardrails laufen neben dem Agenten, beim Tripwire sind Tokens also schon verbraucht; run_in_parallel=False ist die Einstellung für kostenkritische Pfade.
- Computer Use, Hosted Tool Search und Programmatic Tool Calling werden auf Chat-Completions-Modellen und Nicht-Responses-Backends abgelehnt, das provider-agnostische Versprechen ist damit dünner als es klingt.
OpenAI Agents SDK ist die Agent-Runtime, die OpenAI für Python und TypeScript ausliefert: wenige Primitive, eine Turn-Schleife und Tracing, das aktiv ist, bevor jemand danach fragt. Es ist ein guter Default für Teams, die sich auf OpenAI-Modelle standardisieren und den Loop lieber in einer Bibliothek als in selbst geschriebenem asyncio sehen. Es ist das falsche Werkzeug, sobald der Workflow zum Zustandsautomaten wird.
Es sitzt zwischen der reinen Responses API und einem vollständigen Orchestrierungs-Framework. Die Responses API ist die Modellschnittstelle. Das SDK ergänzt einen Runner, der Turns, Tool-Dispatch, Guardrails, Handoffs und Sessions verwaltet. Graph-Runtimes wie LangGraph liegen darüber und kodieren den Workflow explizit. Die Dokumentation zieht die Grenze selbst: die Responses API direkt nutzen, wenn Loop, Tool-Dispatch und State-Handling selbst verantwortet werden sollen.
Was es ist
Das Design ist bewusst dünn. Ein Agent ist Instruktionen plus Modell plus Tools. Delegation hat genau zwei Formen: Agent.as_tool() für einen Manager, der das Gespräch behält, und handoff() für einen Spezialisten, der es übernimmt. Guardrails sind gewöhnliche Funktionen, die ein Tripwire-Flag zurückgeben. Alles Weitere, Sessions, MCP, Sandbox-Clients, Realtime und Voice, sind Module um diesen Kern und keine neue Abstraktion, die man zuerst lernen müsste.
- Paket:
openai-agentsauf PyPI, MIT-Lizenz, benötigt Python 3.10 oder neuer. - Version: 0.23.1 vom 2. Oktober 2026, die 123. Veröffentlichung seit 0.0.1 am 4. März 2025; allein 77 davon kamen 2026.
- Modelle: standardmäßig die OpenAI Responses API, Chat Completions als explizite Alternative, LiteLLM- und AnyLLM-Adapter für andere Anbieter.
- Tools: einfache Python-Funktionen hinter dem Dekorator @function_tool, dazu Hosted Tools, Computer Use, Shell und Apply Patch.
- MCP: stdio, Streamable HTTP, der veraltete SSE-Transport und gehostete MCP-Server, jeweils mit Tool-Filtern und Freigaberichtlinien.
- Speicher: Sessions über SQLite, SQLAlchemy, Redis, MongoDB, Dapr, verschlüsselt sowie über die OpenAI Conversations API.
- Dauerhafte Ausführung: nicht enthalten; die Dokumentation verweist für langlebige Läufe an Temporal, DBOS, Dapr oder Restate.
Wie die Schleife arbeitet
Runner.run() ist eine Schleife, kein Funktionsaufruf. Es schickt die aktuelle Eingabe an das Modell und tut mit der Antwort eines von drei Dingen: Es behandelt Text des erwarteten Ausgabetyps ohne Tool-Aufrufe als Endausgabe, es wechselt bei einem Handoff zu einem anderen Agenten, oder es führt die verlangten Tools aus, hängt deren Ergebnisse an und beginnt von vorn.
Diese Definition der Endausgabe sollte zweimal gelesen werden, denn sie macht die Schleife erst zur Schleife. Ein Lauf ist fertig, wenn das Modell Text des verlangten Typs liefert und nichts weiter anfordert. Alles andere hält ihn am Leben, weshalb max_turns die erste Einstellung ist, die man bewusst entscheidet statt erbt. max_turns=None hebt die Grenze vollständig auf.
Erste Schritte
pip install openai-agents ist die komplette Einrichtung, und das SDK liest OPENAI_API_KEY, wenn es den ersten Client anlegt. Ein minimaler Agent mit einem Tool und einer typisierten Antwort ist rund zwanzig Zeilen lang:
from pydantic import BaseModel
from agents import Agent, Runner, function_tool
@function_tool
def order_status(order_id: str) -> str:
"""Look up the fulfilment status of an order."""
return STATUS.get(order_id, "unknown")
class Reply(BaseModel):
answer: str
order_id: str
agent = Agent(
name="Order assistant",
instructions="Answer with the status of the order the customer names.",
tools=[order_status],
output_type=Reply,
)
result = Runner.run_sync(agent, "Where is order A-1024?", max_turns=6)
print(result.final_output)
print(result.context_wrapper.usage.total_tokens)Der Dekorator leitet das JSON-Schema aus Signatur und Docstring ab, das Modell sieht also genau so viel, wie der Docstring behauptet. output_type macht aus der letzten Nachricht ein validiertes Pydantic-Modell statt eines Strings. usage summiert über alle Modellaufrufe des Laufs, auch über die, die Tool-Aufrufe und Handoffs erzeugt haben.
Guardrails und Freigaben
Guardrails werden am häufigsten falsch verstanden, weil sie nicht alle an derselben Stelle greifen. Input-Guardrails laufen nur für den ersten Agenten einer Kette, Output-Guardrails nur für den Agenten, der die Endausgabe erzeugt, und keiner von beiden sieht die dazwischen delegierte Arbeit.
- run_in_parallel=False auf einem Input-Guardrail blockiert den Agenten, bevor er startet. Der Default lässt den Guardrail neben dem Agenten laufen, was die Latenz senkt, aber Tokens sind beim Tripwire schon verbraucht.
- Tool-Guardrails umschließen einzelne Function-Tools und lokale MCP-Tools und sind die einzige Sorte, die jeden Aufruf in einer Multi-Agenten-Kette sieht.
- Ein Tripwire wirft InputGuardrailTripwireTriggered oder OutputGuardrailTripwireTriggered. Wirft die Guardrail-Funktion selbst, gilt das Urteil als unbekannt und der Runner persistiert den abgeschlossenen Turn, bevor der Fehler sichtbar wird.
- needs_approval an einem Tool, an Agent.as_tool(), an ShellTool oder an ApplyPatchTool pausiert den Lauf stattdessen; die offenen Aufrufe erscheinen in result.interruptions.
- Aufrufbare Freigaberegeln verweigern standardmäßig. Fehlen die Argumente, sind sie fehlerhaft oder kein JSON-Objekt, verlangt der Aufruf eine manuelle Freigabe, statt durchgewinkt zu werden.
Freigabezustand ist über RunState serialisierbar, ein pausierter Lauf kann also in einer Queue liegen und in einem anderen Prozess fortgesetzt werden. Die Dokumentation sagt ausdrücklich, dass RunState.from_json() nichts authentifiziert: Ein Snapshot in nicht vertrauenswürdigen Händen ist eine Menge Anweisungen, die der Server ausführt, er gehört also in serverseitigen Speicher, und der Prüfer muss von der Anwendung authentifiziert werden. Das ist dasselbe Freigabemuster wie in der Bewertung zu Human-in-the-loop, nur mit einer State-Datei statt eines Sockets.
Tracing und Kostenkontrolle
Tracing ist der stärkste Grund für dieses SDK und zugleich der am wenigsten kontrollierte Teil. Spans erfassen Runner, Task und Turn, jeden Agenten, jede Generierung, jeden Funktionsaufruf, Guardrails, Handoffs und Audio. Der Standard-BatchTraceProcessor exportiert im Hintergrund alle paar Sekunden, ein Worker kann einen Job also beenden und beenden, bevor das Dashboard den Lauf zeigt.
- Standardmäßig erzeugte Spans: Runner, Task, Turn, Agent, Generierung, Function, Guardrail, Handoff, Transkription und Sprache.
- Global abschalten mit OPENAI_AGENTS_DISABLE_TRACING=1 oder set_tracing_disabled(True), für einen Lauf mit RunConfig(tracing_disabled=True).
- Für eine Zustellgarantie flush_traces() nach dem Verlassen des Trace-Kontexts aufrufen. Tracing abzuschalten verwirft keine Spans, die ein Processor bereits gepuffert hat.
- add_trace_processor() fügt ein Ziel hinzu und lässt den OpenAI-Exporter registriert. set_trace_processors() ersetzt den Standard und braucht einen eigenen BatchTraceProcessor mit Exporter.
- Die Dokumentation listet rund 27 externe Processor, darunter Langfuse, MLflow, Arize Phoenix, LangSmith, Braintrust, Datadog und Pydantic Logfire.
Kostenkontrolle ist Rechnen, nicht Konfiguration. result.context_wrapper.usage führt requests, input_tokens, output_tokens, total_tokens, Einträge pro Anfrage sowie Details zu Cache- und Reasoning-Tokens; die Kompaktierungsanfrage einer Responses-Session landet in denselben Summen. Die relevante Kennzahl sind Kosten pro erfolgreichem Lauf, und der wirksamste Hebel bleibt max_turns, denn eine Schleife, die zwölf Turns bis zum Scheitern braucht, braucht sie jedes Mal.
Wo es hakt
Beginnen wir mit den Schwächen. Dauerhafte Ausführung ist nicht Teil des Pakets: Ein Lauf, der einen Prozessneustart überstehen, Stunden auf eine Freigabe warten oder in einem neuen Container fortsetzen muss, braucht Temporal, DBOS, Dapr oder Restate daneben. Die Sandbox- und Harness-Arbeit für Python kam in 0.14.0 im April 2026, TypeScript-Unterstützung war zum Redaktionszeitpunkt noch als künftige Arbeit bezeichnet. Tracing sendet standardmäßig Nutzdaten an OpenAI und ist unter ZDR schlicht nicht verfügbar. Und das provider-agnostische Versprechen ist dünner, als es klingt: Computer Use, Hosted Tool Search und Programmatic Tool Calling werden auf Chat-Completions-Modellen und Nicht-Responses-Backends abgelehnt.
Dazu kommt das Release-Tempo. Das Projekt hat in den ersten neun Monaten 2026 siebenundsiebzig Versionen veröffentlicht, und 0.21.0 hob die Untergrenze auf openai>=3.0.0,<4, wodurch der Standardanbieter auf HTTPX2 wechselte und Anwendungen brachen, die einen alten httpx-Client übergaben. Eine weiterhin mit 0.x versionierte Bibliothek in diesem Takt ist ein Argument fürs Festnageln und fürs Lesen des Changelogs statt der Release-Überschrift.
| Option | Steuermodell | Dauerhafte Ausführung | Letzte Version, Oktober 2026 |
|---|---|---|---|
| OpenAI Agents SDK | Modelldirigierte Schleife, Handoffs, Agents als Tools | Extern: Temporal, DBOS, Dapr, Restate | 0.23.1 |
| LangGraph | Expliziter Graph mit Checkpoints | Eingebaut | 1.2.14 |
| Pydantic AI | Code-Orchestrierung, typisierte Agenten | Extern: Temporal, DBOS, Prefect, Restate | 2.54.0 |
| Google ADK | Modelldirigierte Agenten plus Workflow-Agenten | Eingebaut, ADK-2.0-Workflow-Runtime | 2.11.0 |
Liest die vierte Spalte vor der zweiten. LangGraph bei 1.x und ADK bei 2.x stehen unter einer Kompatibilitätszusage; 0.23.1 heißt, dass OpenAI eine Konstruktorsignatur auch in einem Patch-Release verschieben kann, was mit der openai-Client-Untergrenze bereits passiert ist. Die Steuermodell-Spalte ist weniger wichtig, als sie wirkt: Eine modelldirigierte Schleife ist schneller gebaut, und ein Graph ist nur so lange leicht nachvollziehbar, wie der Graph klein bleibt.
Urteil
Das SDK gewinnt dort, was sich später schwer nachrüsten lässt. Tracing, das existiert, bevor die Observability-Code geschrieben wird, sauber serialisierbare Freigabe-Interrupts und MCP über vier Transporte ohne selbstgebauten Client sind allesamt echte Entwicklungszeit. Es verliert dort, was sich später nicht ohne Neuschreiben nachrüsten lässt: dauerhafte Ausführung und ein expliziter Kontrollfluss, der einen Workflow prüfbar macht.
- Nimm es, wenn das Team sich auf OpenAI-Modelle standardisiert und der Workflow eine Tool-Schleife mit Guardrails und Freigaben ist. Dafür wurde es entworfen.
- Nimm es, wenn Tracing nicht verhandelbar ist, weil Spans und Dashboard bereits am Runtime hängen und nicht nachträglich angeflanscht werden.
- Nimm es für MCP-lastige Agenten, wo vier Transporte und Tool-Filter pro Server mehr Code sparen, als das Framework kostet.
- Nimm es nicht als einzige Runtime, wenn Läufe einen Neustart überstehen, stundenlang auf einen Menschen warten oder in einem frischen Container fortsetzen müssen. Pair es von Anfang an mit Temporal oder DBOS.
- Nimm es nicht für einen Workflow, dessen nächster Schritt eine Geschäftsregel ist. Ist die Abfolge bekannt, sagt ein Graph-Runtime oder schlicht Code es ehrlicher als ein Modell, das ihr vielleicht nicht folgt.
- Lass es ganz weg, wenn die ganze Aufgabe ein Modellaufruf mit einer Antwort ist. Responses API plus Pydantic ist kleiner und günstiger.
Nichts davon ist ein Makel des Pakets. Es ist eine kleine, lesbare, MIT-lizenzierte Bibliothek, die eine enge Aufgabe sauber erledigt und es in der eigenen Dokumentation zugibt. Das zu vermeidende Scheitern ist nicht die Wahl, sondern die Wahl wegen des gratis mitgelieferten Tracings und die Feststellung ein Jahr später, dass die Workflow-Logik in Prompts steckt, die niemand diffen kann. Dauerhafte Ausführung und Geschäftsregeln gehören außerhalb des Runners.
Genug Funktionen, um nützlich zu sein, aber wenige genug Primitive, um schnell erlernbar zu bleiben. — die beiden Designprinzipien aus der Dokumentation des OpenAI Agents SDK.
Quellen
Häufige Fragen
Ist das OpenAI Agents SDK kostenlos?
Das SDK selbst steht unter MIT und installiert sich mit pip install openai-agents. Kosten entstehen an der API: Die Modelle, die die Schleife aufruft, werden pro Token abgerechnet, und OpenAI schreibt, dass Harness- und Sandbox-Funktionen seit April 2026 die Standard-API-Preise nach Token und Tool-Nutzung nutzen.
Kann das OpenAI Agents SDK auch fremde Modelle fahren?
Ja. Das Paket bringt LiteLLM- und AnyLLM-Adapter mit, liest OPENAI_BASE_URL, und das Projekt-README nennt mehr als 100 unterstützte Modelle. Mehrere Funktionen sind jedoch Responses-only und werden auf Chat-Completions-Modellen und Nicht-Responses-Backends abgelehnt, daher sollte ein kompletter Agentenlauf getestet werden und nicht ein einzelner Modellaufruf.
Worin unterscheidet sich das Agents SDK von der Responses API?
Die Responses API ist die Modellschnittstelle; das SDK ergänzt eine Runtime darum, die Turns, Tool-Dispatch, Guardrails, Handoffs und Sessions verwaltet. Ist die Aufgabe ein einzelner Aufruf mit einer Antwort, nutzt das SDK Maschinerie, die niemand braucht, und die Responses API ist die kleinere Wahl.
Wie funktioniert die menschliche Freigabe von Tool-Aufrufen?
Setzt man needs_approval auf einem Function-Tool, auf Agent.as_tool(), auf ShellTool oder auf ApplyPatchTool, pausiert der Lauf mit ToolApprovalItem-Einträgen in result.interruptions. Das Ergebnis wird mit to_state() serialisiert, state.approve() oder state.reject() entscheidet, und Runner.run(agent, state) setzt fort. Aufrufbare Freigaberegeln verweigern standardmäßig, wenn die Argumente nicht parsebar sind.