Zurück zum Katalog
Season 6 18 Episoden 1h 10m 2026

OpenAI Agents SDK

v0.13 — 2026 Edition. Ein umfassender Leitfaden zur Entwicklung produktionsreifer Multi-Agent-Systeme mit dem OpenAI Agents SDK für Python (v0.13 - 2026). Lerne Core Primitives, Orchestration Patterns, Tools, Handoffs, Guardrails, State Management, MCP und Realtime Voice Integration kennen.

AI/ML-Frameworks Multi-Agenten-Systeme
OpenAI Agents SDK
Aktuelle Wiedergabe
Click play to start
0:00
0:00
1
Jenseits von Swarm: Die Core Primitives
Entdecke die grundlegenden Konzepte des OpenAI Agents SDK. Diese Episode behandelt, warum das SDK existiert, wie es Swarm verbessert und die zentralen Designprinzipien, die minimale Abstraktionen priorisieren.
3m 30s
2
Den Agent und den Run Loop definieren
Lerne, wie man das grundlegende Agent-Objekt konfiguriert. Wir untersuchen Instructions, Model Settings und wie man strukturierte Datenausgaben nahtlos erzwingt.
3m 28s
3
Agents mit Python Function Tools ausstatten
Befähige deine Agents zum Handeln, indem du Standard-Python-Funktionen in ausführbare Tools umwandelst. Verstehe die automatische Schema-Generierung und Type Inference.
3m 35s
4
Tool-Oberflächen skalieren mit Hosted Tool Search
Lerne, wie du riesige Tool-Bibliotheken verwaltest, ohne dein Token-Budget auszuschöpfen. Wir behandeln Deferred Loading, Namespaces und Hosted Tool Execution.
3m 25s
5
Dezentrale Delegation: Das Handoff Pattern
Meistere die Kunst der Multi-Agent-Orchestrierung mit dem Handoff Pattern. Entdecke, wie du Triage Agents erstellst, die die volle Kontrolle nahtlos an spezialisierte Sub-Agents delegieren.
3m 42s
6
Zentrale Orchestrierung: Agents as Tools
Behalte die Kontrolle über die Konversation an einem Ort mit dem Agents as Tools Pattern. Wir besprechen, wie ein Manager Agent Antworten von mehreren spezialisierten Sub-Agents synthetisieren kann.
3m 55s
7
Kontext formen mit Handoff Inputs und Filters
Optimiere die Token-Nutzung von Multi-Agent-Systemen, indem du Konversationsverläufe zwischen Handoffs anpasst. Lerne, wie du Metadaten injizierst und Transcript Filters anwendest.
4m 26s
8
State kontrollieren: to_input_list und Server IDs
Ein Deep Dive in das manuelle Konversationsmanagement. Verstehe die Low-Level-Methoden zur Erhaltung des Kontexts über Turns hinweg und die Nutzung serverseitiger Response IDs.
4m 19s
9
Memory automatisieren mit Built-in Sessions
Vereinfache deine Chat Loops mit dem integrierten Memory-System des SDKs. Wir untersuchen SQLiteSession, OpenAIConversationsSession und automatisierte Persistenz.
4m 02s
10
Workflows schützen: Input und Output Guardrails
Sichere deine AI Pipelines, indem du bösartige Inputs abfängst, bevor sie teure Modelle erreichen. Wir behandeln Agent-Level Guardrails sowie parallele vs. blockierende Ausführung.
4m 16s
11
Aktionen validieren: Tool-Level Guardrails
Verhindere kritische Datenlecks auf Funktionsebene. Lerne, wie du spezifische Tools mit präzisen Input und Output Guardrails umhüllst.
4m 27s
12
Ausführung pausieren: Human-in-the-Loop und RunState
Implementiere Schutzmaßnahmen für irreversible Aktionen, indem du Human-in-the-Loop-Freigaben erzwingst. Wir untersuchen die RunState-Serialisierungspipeline zum Pausieren und Fortsetzen von Workloads.
3m 54s
13
Lokale Abhängigkeiten injizieren mit RunContextWrapper
Meistere Dependency Injection in deinen Agent Flows. Lerne, wie du lokale States und Datenbankverbindungen sicher an Tools übergibst, ohne sie an das LLM durchsickern zu lassen.
4m 24s
14
Das USB-C für KI: Einführung in MCP
Eine Einführung in das Model Context Protocol (MCP). Entdecke, wie dieser Standard als universeller Anschluss fungiert, um AI Agents einfach mit SaaS-Plattformen zu verbinden.
3m 28s
15
Lokale MCP Server über Stdio und HTTP verbinden
Tauche tiefer in MCP ein, indem du standardmäßige lokale Server ausführst. Lerne, den Dateisystemzugriff und interne Tools mit MCPServerStdio sicher in einer Sandbox zu isolieren.
3m 57s
16
Workflows visualisieren mit Built-in Tracing
Eliminiere das Debuggen mit Print-Statements durch die integrierte SDK Observability. Entdecke, wie automatische Spans und Traces ganze komplexe Workflows verknüpfen.
3m 47s
17
Low-Latency Voice mit Realtime Agents
Brich das Standard-Request-Response-Paradigma. Sieh dir an, wie Realtime Agents Live-WebSocket-Verbindungen aufrechterhalten, um Unterbrechungen und multimodales Reasoning zu handhaben.
3m 47s
18
Reaktive UIs bauen mit Streaming Events
Gehe über das Streamen von Text-Tokens hinaus. Nutze Semantic Streaming Events, um extrem reaktionsschnelle Frontend-Interfaces zu bauen, die in Echtzeit auf Agent-Aktionen reagieren.
4m 20s

Episoden

1

Jenseits von Swarm: Die Core Primitives

3m 30s

Entdecke die grundlegenden Konzepte des OpenAI Agents SDK. Diese Episode behandelt, warum das SDK existiert, wie es Swarm verbessert und die zentralen Designprinzipien, die minimale Abstraktionen priorisieren.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 1 von 18. Die meisten AI Agent Frameworks zwingen dich, ein Dutzend neue Abstraktionen, Custom Syntax und komplexe Objekt-Hierarchien zu lernen. Du verbringst mehr Zeit damit, mit dem Framework zu kämpfen, als deine eigentliche Application Logic zu schreiben. Heute schauen wir uns Beyond Swarm an: Die Core Primitives. Wenn Entwickler von einem neuen Agent Framework hören, erwarten sie oft ein riesiges Ecosystem mit einer steilen Lernkurve. Das OpenAI Agents SDK ist genau das Gegenteil. Es ist eine Weiterentwicklung der experimentellen Swarm Library. Swarm hat bewiesen, dass du komplexe Interaktionen mit sehr einfachen Konzepten bauen kannst. Das Agents SDK nimmt diese Philosophie und macht sie fit für den Production-Einsatz. Es ist bewusst lightweight und komplett Python-first. Die Architektur basiert auf zwei fundamentalen Design-Prinzipien: sehr wenige Core Primitives bereitzustellen und die Execution extrem customizable zu halten. Du brauchst hier keinen komplexen Graph aus Nodes oder eine proprietäre deklarative Sprache, um einen Agent zu bauen. Das SDK gibt dir ein winziges Set an Building Blocks. Das Fundament ist das Agent Object. Du definierst einen Agent, indem du ihm einen Namen und ein Set an Instructions gibst. Wenn du einen einfachen History Tutor bauen willst, instanziierst du einen Agent, nennst ihn HistoryTutor und übergibst ihm einen Text String, der ihn anweist, historische Ereignisse klar und präzise zu vermitteln. Das ist deine komplette Agent Configuration. Es gibt keinen Hidden State und keine komplizierte Initialization. Aber ein Agent für sich allein ist nur eine statische Data Structure. Er macht nichts, bis er ausgeführt wird. Hier wird es interessant. Die Execution wird komplett von einer separaten Component namens Runner übernommen. Der Runner managt den kompletten Interaction Loop zwischen deinem lokalen Code und der remote OpenAI API. In einer typischen Application müsstest du eine custom while-Loop schreiben, um zu checken, ob das Model einen Tool Call machen will, die Response parsen, das Tool ausführen und das Ergebnis zurücksenden. Der Runner abstrahiert das alles weg. Um den Prozess zu starten, übergibst du deinen HistoryTutor Agent und den User Prompt an die run-Methode. Ab da übernimmt der Runner. Er sendet den Prompt an das Model. Wenn das Model entscheidet, dass es ein bestimmtes historisches Datum nachschlagen muss, fordert es einen Tool Call an. Der Runner pausiert, führt die lokale Python-Funktion aus, die du für dieses Tool bereitgestellt hast, fängt den Return Value ab und sendet ihn direkt an das Model zurück. Er wiederholt diesen Cycle automatisch. Er gibt die Kontrolle erst dann an deine Application zurück, wenn das Model entscheidet, dass der Task abgeschlossen ist, und eine finale Text Response generiert. Diese strikte Trennung zwischen der statischen Agent Definition und der aktiven Runner Execution macht das SDK so customizable. Weil Tools einfach nur Standard-Python-Funktionen mit regulären Type Hints sind und der Agent nur ein Plain Object ist, behältst du die volle Kontrolle über deinen Application Flow. Du kannst problemlos custom Logging, Metrics oder Error Handling um den Runner herum injecten, ohne tiefe Framework Classes zu überschreiben. Du schreibst einfach nur Python. Der wahre Wert dieses SDKs liegt nicht darin, was es hinzufügt, sondern was es weglässt – es steht dir nicht im Weg und lässt dich Language Models mit einfachem, lesbarem Code orchestrieren. Wenn du die Show unterstützen möchtest, kannst du auf Patreon nach DevStoriesEU suchen. Das war's für diese Folge. Bis zum nächsten Mal!
2

Den Agent und den Run Loop definieren

3m 28s

Lerne, wie man das grundlegende Agent-Objekt konfiguriert. Wir untersuchen Instructions, Model Settings und wie man strukturierte Datenausgaben nahtlos erzwingt.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 2 von 18. Was wäre, wenn du dein Language Model dazu bringen könntest, immer in einer perfekt geparsten Data Structure zu antworten, ohne eine einzige Zeile komplexen Regex schreiben zu müssen? Heute behandeln wir das Definieren des Agents und den Run Loop – genau so erreichst du diese strikte Kontrolle. Ein häufiger Irrtum beim Einstieg in dieses SDK ist die Annahme, ein Agent sei ein aktiver, laufender Prozess. Das ist er nicht. In dieser Architektur ist das Agent-Objekt strikt ein Configuration Container. Es wrappt ein spezifisches Language Model in einem vordefinierten Kontext. Es führt sich nicht selbst aus und hält selbst keinen State. Du baust im Grunde nur einen Blueprint. Um diesen Blueprint zu definieren, instanziierst du einen Agent. Du beginnst mit dem instructions-Parameter. Das ist dein zentraler System Prompt, in dem du die Persona, die Grenzen und die spezifischen Regeln definierst, die das Modell befolgen muss. Als Nächstes gibst du die Model Settings an. Das legt fest, welches zugrunde liegende Modell verwendet werden soll, und konfiguriert Standard-Inference-Details. In diesem Stadium ist dein Agent vollständig definiert, liegt aber noch komplett inaktiv im Memory. Hier wird es interessant. Du kannst die Struktur der Agent-Response über den output type-Parameter strikt einschränken. Stell dir vor, du baust ein Tool, um Calendar Events aus chaotischen E-Mail-Threads zu extrahieren. Anstatt Instructions zu schreiben, die das Modell anflehen, Datumsangaben korrekt zu formatieren, definierst du eine konkrete Data Structure in deinem Code. Du definierst eine Calendar Event Class mit strikten Fields für einen Titel, eine Startzeit und eine Location. Diese Class übergibst du an den output type-Parameter deines Agents. Wenn das so konfiguriert ist, erzwingt die API das Schema. Der Agent kann keine konversationelle Text-Reply zurückgeben. Er wird immer nur ein validiertes Calendar Event-Objekt zurückgeben, das dein Application Code sofort verarbeiten kann. Du hast jetzt einen strikten, gut konfigurierten Agent Blueprint. Damit er auch wirklich arbeitet, brauchst du den Run Loop. Weil der Agent nur eine statische Definition ist, wird die Execution komplett von einer separaten Runner-Komponente übernommen. Der Runner ist die Engine. Du übergibst deine Agent-Definition und den User Input an den Runner, und er übernimmt die Execution. Wenn du den Runner triggerst, geht er in einen Execution Loop. Er bündelt deine Agent Instructions, das strikte Output Schema und den User Prompt und sendet sie an das Modell. Der Run Loop ist dafür verantwortlich, die gesamte Back-and-Forth-Orchestrierung zu managen. Wenn das Modell entscheidet, dass es ein externes Tool aufrufen muss, um fehlende Daten abzurufen, fängt der Runner diesen Request ab, führt den lokalen Tool-Code aus und gibt das Ergebnis an das Modell zurück. Er übernimmt all diese Zwischenschritte automatisch. Der Loop terminiert erst, wenn das Modell den Prompt verarbeitet und den finalen Output erzeugt, der exakt deinem Calendar Output Type entspricht. Die statische Agent-Konfiguration komplett getrennt vom aktiven Run Loop zu halten, ist genau das, was es dir ermöglicht, denselben Calendar Extraction Agent sicher für Tausende gleichzeitige Executions wiederzuverwenden, ohne dass sich Daten vermischen. Danke fürs Zuhören und Happy Coding zusammen!
3

Agents mit Python Function Tools ausstatten

3m 35s

Befähige deine Agents zum Handeln, indem du Standard-Python-Funktionen in ausführbare Tools umwandelst. Verstehe die automatische Schema-Generierung und Type Inference.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 3 von 18. JSON Schemas für Language Model Tools von Hand zu schreiben, ist mühsam und fehleranfällig. Eine fehlende Klammer oder ein falscher Type, und das Modell versteht nicht mehr, wie es mit deinem System interagieren soll. Anstatt diese Definitionen von Hand zu schreiben, kannst du einfach Standard-Python schreiben und die Übersetzung dem Framework überlassen. Genau darum geht es heute: Agents mit Python Function Tools ausstatten. Ein weit verbreiteter Irrglaube ist, dass das Exposing von lokaler Logik an einen Agenten die Pflege von zwei Sources of Truth erfordert. Viele denken, sie brauchen ihren eigentlichen Python-Code plus ein separates, komplexes JSON-Config-File, das diesen Code für das Language Model beschreibt. Mit dem Agents SDK umgehst du das manuelle Schreiben von JSON komplett. Du schreibst einfach eine Standard-Python-Funktion und packst den Function Tool Decorator direkt darüber. Wenn du diesen Decorator anwendest, legt das SDK unter der Haube los und nutzt Pythons eingebautes inspect-Modul und Pydantic. Es scannt deine Function Signature. Es liest die Parameternamen, extrahiert die Type Hints und zieht sich den Docstring der Funktion. Aus diesen Elementen generiert es automatisch ein striktes JSON Schema und hängt es an den Agenten an. Schauen wir uns ein konkretes Szenario an. Du möchtest deinem Agenten eine Funktion namens fetch weather geben. Diese Funktion braucht präzise geografische Daten, um zu funktionieren. Anstatt das Modell raten zu lassen, welches String-Format es nutzen soll, definierst du eine spezifische Struktur. Du erstellst einen Custom Type, vielleicht ein Typed Dictionary namens Location, das separate String-Felder für city und country enthält. Diesen Location-Type nutzt du dann als strikten Type Hint für den Input-Parameter deiner fetch weather Funktion. Hier ist der entscheidende Punkt. Du musst dieser Funktion einen klaren Docstring hinzufügen. Du schreibst vielleicht einen einfachen Satz, der besagt, dass dieses Tool die aktuellen Wetterbedingungen für eine bestimmte Stadt und ein bestimmtes Land abruft. Das Framework extrahiert diesen Text und nutzt ihn als Kernbeschreibung des Tools im Prompt. Dein Docstring ist nicht mehr nur eine hilfreiche Notiz für deine Entwicklerkollegen. Er ist die buchstäbliche Bedienungsanleitung, die der Agent auswertet, um zu entscheiden, ob er das Tool triggern soll. Wenn ein User fragt, ob er in Tokio eine Jacke braucht, prüft der Agent die verfügbaren Tools. Er liest deinen Docstring, erkennt, dass die fetch weather Funktion die Antwort liefert, und strukturiert einen Request. Weil du den Input mit deinem Location-Dictionary type-hinted hast, garantiert Pydantic, dass der Output des Agenten exakt den erforderlichen Feldern entspricht, noch bevor deine Python-Logik überhaupt ausgeführt wird. Wenn das Modell versucht, einen einzelnen Text-String anstelle des Dictionarys zu übergeben, fängt das Framework den Error ab und zwingt den Agenten, es mit der korrekten Struktur nochmal zu versuchen. Das SDK führt die Funktion lokal aus, fängt den Return Value ab und speist das Ergebnis direkt wieder in den Reasoning Loop des Agenten ein. Deine Standard-Python Type Hints und Docstrings sind keine passive Dokumentation mehr; sie bilden den aktiven, verbindlichen API Contract, auf den sich dein Agent verlässt, um mit der echten Welt zu interagieren. Danke, dass du ein paar Minuten mit mir verbracht hast. Bis zum nächsten Mal, mach's gut.
4

Tool-Oberflächen skalieren mit Hosted Tool Search

3m 25s

Lerne, wie du riesige Tool-Bibliotheken verwaltest, ohne dein Token-Budget auszuschöpfen. Wir behandeln Deferred Loading, Namespaces und Hosted Tool Execution.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 4 von 18. Hundert Tools an ein Language Model zu übergeben, zerstört die Performance und verbrennt dein Token-Budget, bevor auch nur eine einzige Action ausgeführt wird. Du kannst nicht jedes Enterprise-API-Schema in das initiale Context Window stopfen und gutes Reasoning erwarten. Die Lösung dafür ist das Skalieren von Tool Surfaces mit Hosted Tool Search. Bevor wir uns das Skalieren ansehen, müssen wir Hosted Tools definieren. Hosted Tools werden nativ auf der OpenAI-Infrastruktur ausgeführt, anstatt auf deiner lokalen Maschine zu laufen. Built-in-Beispiele dafür sind das Web Search Tool und das File Search Tool. Du schreibst dafür weder die Execution Logic, noch verwaltest du den Web Crawler oder baust den File Chunking-Mechanismus. Du hängst sie einfach an deinen Agent, und das OpenAI-Backend übernimmt die eigentliche Arbeit. Aber das Konzept der Hosted Tools erstreckt sich auch darauf, wie das Modell deine eigenen Custom Tools entdeckt, wenn du zu viele davon hast. Stell dir einen CRM-Agent vor. Du hast vielleicht fünfzig verschiedene Tools, um den Bestellstatus zu checken, die Billing History abzurufen, Lieferadressen zu updaten und Support Logs zu ziehen. Wenn du alle fünfzig Schemas direkt am Anfang übergibst, überlastest du das Modell und verschwendest Input Tokens. Viele Entwickler denken, sie müssen das mit einem client-side Retrieval-Schritt lösen. Sie gehen davon aus, dass sie den User Prompt abfangen, eine lokale Vector Database nach relevanten Tool-Schemas durchsuchen und diese dynamisch in den Prompt injecten müssen, bevor sie das Language Model aufrufen. Das musst du nicht tun. Hosted Tool Search passiert nativ auf den OpenAI-Servern über die Responses API. Das Modell selbst ist in der Lage, die verfügbare Tool Surface zu durchsuchen, ohne dass dein Client Code als Middleman fungiert. Das erreichst du mit zwei Parametern: Tool Namespace und defer loading. Wenn du deine CRM-Tools registrierst, gruppierst du verwandte Funktionen, indem du sie einem gemeinsamen Namespace zuweist. Zum Beispiel könntest du alle deine Customer Profile Tools in einen Namespace namens customer account packen. Dann setzt du den defer loading Parameter für diese Tools auf true. Das ist der entscheidende Punkt. Wenn defer loading aktiv ist, sendet der Agent zu Beginn der Conversation nicht die einzelnen Tool-Schemas an das Language Model. Stattdessen sendet er ein einzelnes, schlankes Schema, das den customer account Namespace selbst repräsentiert. Das Modell wird darauf hingewiesen, dass dieser Namespace existiert, und weiß, wie es ihn bei Bedarf abfragen kann. Wenn der User nach einer bestimmten Customer ID fragt, erkennt das Modell, dass es mehr Informationen braucht. Es führt nativ eine Suche gegen den customer account Namespace aus. Die OpenAI-Server finden das relevante Billing- oder Support-Tool, laden nur dieses spezifische Tool-Schema in den Model Context, und dann führt das Modell den Tool Call aus. Das entkoppelt die Größe deiner Tool Library komplett von deinen Upfront Token-Kosten. Du könntest Hunderte von Tools an einen einzigen Agent hängen, und der initiale Prompt bleibt winzig. Das Modell verursacht die Token-Kosten nur für die spezifischen Tool-Schemas, die es zur Runtime aktiv lädt. Durch das Defer Loading tauschst du eine massive statische Context-Last gegen einen dynamischen, präzisen Retrieval-Mechanismus. Das war's für diese Folge. Bis zum nächsten Mal!
5

Dezentrale Delegation: Das Handoff Pattern

3m 42s

Meistere die Kunst der Multi-Agent-Orchestrierung mit dem Handoff Pattern. Entdecke, wie du Triage Agents erstellst, die die volle Kontrolle nahtlos an spezialisierte Sub-Agents delegieren.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 5 von 18. Manchmal ist es für einen Manager am besten, sich bei einer komplexen Aufgabe komplett rauszuhalten. Wenn dein Haupt-Routing-Agent versucht, jede Interaktion zwischen einem User und deinen Backend-Systemen zu vermitteln, werden deine Prompts aufgebläht und deine Execution wird unzuverlässig. Genau dieses Problem soll Decentralized Delegation, insbesondere das Handoff Pattern, lösen. Ein Handoff ist ein Mechanismus, bei dem ein Agent die vollständige Kontrolle über die Konversation an einen anderen Agenten übergibt. Ein häufiger Fehler ist es, einen Handoff mit normalem Tool Calling zu verwechseln. Die beiden sind grundlegend verschieden. Wenn ein Agent eine normale Funktion aufruft, pausiert er, wartet auf die Daten und formuliert dann eine Antwort für den User. Wenn ein Agent einen Handoff triggert, gibt er den kompletten Conversation Turn ab. Die Kontrolle geht komplett an den neuen Agenten über. Der ursprüngliche Agent hält sich komplett raus. Das ist wichtig, weil es deine Architektur dezentral hält. Wenn ein zentraler Triage-Agent den Output jeder Spezialisten-Aktion verarbeiten muss, muss sein System Prompt riesig sein. Er braucht Instructions, wie er Refund Policies formulieren soll, für technisches Troubleshooting und für Account-Löschungen. Noch schlimmer: Der Triage-Agent wird unweigerlich versuchen, dem User die Arbeit des Spezialisten nachzuerzählen. Das verschwendet Tokens, erhöht die Latency und bringt ein hohes Risiko für Halluzinationen mit sich. Handoffs verhindern das, indem sie den Spezialisten direkt mit dem User sprechen lassen. Stell dir ein Customer Support System vor. Du deployst einen allgemeinen Triage-Agenten, der User begrüßt und Anfragen kategorisiert. Ein Kunde schreibt und bittet um eine Rückerstattung. Du hast außerdem einen dedizierten Refund-Agenten, der mit spezifischen Billing Tools und strengen Instructions zur Return Policy der Firma ausgestattet ist. Um sie über das SDK zu verbinden, schreibst du eine Standardfunktion namens transfer to refund. Aber anstatt einen String oder JSON-Daten zurückzugeben, gibt diese Funktion dein Refund-Agent-Objekt zurück. Du übergibst diese Transfer-Funktion dann deinem Triage-Agenten und listest sie genau wie jedes andere Tool auf. Wenn der Kunde nach einer Rückerstattung fragt, entscheidet der Triage-Agent, die Transfer-Funktion aufzurufen. Hier ist der entscheidende Punkt. Der zugrundeliegende SDK Runner Loop führt die Funktion aus und sieht, dass ein Agent-Objekt anstelle von Standarddaten zurückgegeben wurde. Der Runner tauscht sofort den aktiven Agenten in seinem Memory aus. Er nimmt die bestehende Conversation History und füttert sie direkt in den neu aktivierten Refund-Agenten. Der Refund-Agent übernimmt den aktiven Turn, verarbeitet den User Request, triggert seine eigenen Billing Tools und antwortet dem User direkt. Du kannst während dieser Transition auch Daten übergeben. Wenn der Triage-Agent den User bereits nach seiner Bestellnummer gefragt hat, kann er diese Bestellnummer als Argument in die Transfer-Funktion übergeben. Die Funktion kann diese Bestellnummer dann in die Context Variables des neuen Agenten injecten, bevor sie ihn zurückgibt. Der Refund-Agent wacht auf und weiß bereits genau, welche Transaktion er nachschlagen muss. Wenn du Handoffs nutzt, hältst du jeden Agenten klein, fokussiert und vorhersehbar, und lässt die Konversation ganz natürlich von einem spezialisierten Experten zum nächsten fließen. Das war's für diese Folge. Danke fürs Zuhören und keep building!
6

Zentrale Orchestrierung: Agents as Tools

3m 55s

Behalte die Kontrolle über die Konversation an einem Ort mit dem Agents as Tools Pattern. Wir besprechen, wie ein Manager Agent Antworten von mehreren spezialisierten Sub-Agents synthetisieren kann.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 6 von 18. Wenn dein AI-Assistent drei verschiedene Abteilungen konsultieren muss, bevor er einem User antwortet, willst du in der Regel nicht, dass der User direkt mit diesen Abteilungen spricht. Du willst eine einzige, einheitliche Stimme, die die Konversation steuert und Informationen still im Hintergrund abruft. Genau das ermöglicht dir Centralized Orchestration, bei der du Agents als Tools einsetzt. Du könntest das mit Handoffs verwechseln, bei denen ein Agent den User dauerhaft an einen anderen Agent übergibt. Bei Handoffs übernimmt der neue Agent die Konversation komplett. Bei der Centralized Orchestration wird die Kontrolle niemals abgegeben. Der Main Agent, der meistens als Manager fungiert, behält die absolute Kontrolle über die Konversation. Der Manager ist die einzige Stimme, die der User jemals hört. Das erreichst du, indem du einen fertig konfigurierten Agent nimmst und ihn in eine aufrufbare Function verwandelst. Jedes Agent-Objekt im SDK hat eine Method namens as_tool. Wenn du diese Method aufrufst, wrappt sie den kompletten Agent, inklusive seiner spezifischen Instructions und seiner eigenen Tools, in ein Standard-Tool-Format. Diesen gewrappten Agent übergibst du dann deinem Manager Agent, genau wie du es mit einer Standard-Python-Function machen würdest. Schauen wir uns ein praktisches Szenario an. Du baust ein Customer Support Portal. Du erstellst einen Booking Specialist Agent. Seine einzige Aufgabe ist es, interne Systeme abzufragen, Daten abzugleichen und die Verfügbarkeit zurückzugeben. Dieser Agent ist hochgradig technisch. Seine Instructions sind auf Database-Genauigkeit optimiert, nicht auf höfliche Konversation. Du willst nicht, dass der User mit diesem Specialist interagiert. Also rufst du die as_tool Method auf dem Booking Specialist auf. Als Nächstes erstellst du deinen Manager Agent. Du gibst dem Manager strikte Instructions, einen höflichen Corporate-Ton beizubehalten und die User-Beziehung zu managen. Dann fügst du den gewrappten Booking Specialist zur Tool-Liste des Managers hinzu. Wenn ein User den Manager bittet, die Verfügbarkeit für nächsten Dienstag zu checken, verarbeitet der Manager den Request. Er erkennt, dass ihm die eigentlichen Daten fehlen, aber er weiß, dass er ein Tool hat, das sie finden kann. Der Manager ruft das Booking Tool auf. Hier ist der entscheidende Punkt. Wenn dieses Tool aufgerufen wird, wacht der Booking Specialist Agent auf, führt seine eigenen isolierten internen Schritte aus und produziert eine Antwort. Aber er sendet diese Antwort nicht an den User. Er gibt ein rohes, faktisches Result direkt an den Manager zurück. Der Manager empfängt diese Daten, synthetisiert sie, wrappt sie in eine höfliche Corporate-Begrüßung und antwortet schließlich dem User. Dieses Hub-and-Spoke-Pattern löst ein großes Problem bei komplexen Applications: Context Bloat. Der Manager Agent muss weder das Database Schema noch die Regeln für den Datums-Check kennen. Er hält seinen System Prompt sauber und konzentriert sich komplett auf das Routing von Requests und das Formatieren von Responses. Währenddessen muss sich der Specialist Agent nicht um die Conversation History oder die Brand Voice kümmern. Er macht einfach seinen eng definierten Job und gibt ein Result zurück. Wenn du dich zwischen einem Handoff und einem Tool entscheidest, frag dich, wem die finale Response gehört. Wenn der Specialized Agent in einen längeren Hin-und-Her-Dialog mit dem User treten muss, willst du einen Handoff. Aber wenn der Specialized Agent nur ein hochentwickelter Data Processor ist, der eine Antwort liefert, die der Main Assistant nutzen soll, dann wrappe ihn als Tool und überlass dem Manager die Beziehung zum User. Danke, dass du ein paar Minuten mit mir verbracht hast. Bis zum nächsten Mal, mach's gut.
7

Kontext formen mit Handoff Inputs und Filters

4m 26s

Optimiere die Token-Nutzung von Multi-Agent-Systemen, indem du Konversationsverläufe zwischen Handoffs anpasst. Lerne, wie du Metadaten injizierst und Transcript Filters anwendest.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 7 von 18. Wenn du einen Kunden an einen menschlichen Spezialisten weiterleitest, zwingst du ihn nicht, ein riesiges rohes Transcript aller gerade durchgeführten automatisierten System-Checks zu lesen. Du gibst ihm einen klaren Grund für den Transfer und eine saubere Zusammenfassung des Problems. Trotzdem kippen Entwickler, wenn sie AI Agents verbinden, oft das gesamte rohe Chat-Log in das Context Window des nächsten Agents. Heute fixen wir das, indem wir den Context mit Handoff Inputs und Filtern formen. Wenn ein Agent die Kontrolle an einen anderen übergibt, braucht er einen Weg, um zu kommunizieren, warum der Handoff passiert. Das machst du über den input type Parameter in deiner Handoff-Routine. Du definierst ein Schema, typischerweise ein Pydantic-Modell, das genau festlegt, welche Informationen der empfangende Agent braucht. Wenn der aktuelle Agent entscheidet, den Handoff auszuführen, generiert das zugrunde liegende Language Model einen Payload, der zu diesem Schema passt. Lass uns gleich mal ein häufiges Missverständnis ausräumen. Man verwechselt diesen input type leicht mit persistentem Application State, wie einer User Profile ID oder einer Backend-Datenbankverbindung, die über die gesamte Session hinweg existiert. Das ist er aber nicht. Der input type ist streng genommen nur für transiente, modellgenerierte Metadaten gedacht, die exakt im Moment des Handoffs erstellt werden. Wenn zum Beispiel ein Triage Agent einen User an einen Billing-Spezialisten übergibt, könnte der input type ein Feld namens escalation reason erfordern. Der Triage Agent generiert einen kurzen String, der den spezifischen Billing-Fehler erklärt, und der Billing Agent empfängt diese strukturierten Daten sofort beim Aufwachen. Damit wäre die explizite Handoff-Message abgedeckt. Jetzt müssen wir die Conversation History managen. Standardmäßig reist die gesamte Message History mit dem Handoff mit. Jeder User Prompt, jede Assistant Reply und jeder Background Tool Call wird weitergegeben. Das verbrennt schnell Tokens und füllt das Context Window mit irrelevantem Noise. Du kontrollierst das mit einem Input Filter. Ein Input Filter ist eine Standard-Python-Funktion, die die Conversation History abfängt, kurz bevor der empfangende Agent sie liest. Sie nimmt die komplette Liste der vorherigen Messages als Argument, verarbeitet sie und gibt eine neue, modifizierte Liste von Messages zurück. Stell dir ein Szenario vor, in dem dein initialer Agent zehn Turns damit verbracht hat, verschiedene Search Tools und Database APIs aufzurufen, um ein Problem zu lösen, bevor er schließlich aufgibt und den User an einen allgemeinen FAQ Agent weiterleitet. Der FAQ Agent braucht nur die eigentlichen Fragen des Users. Er braucht absolut nicht die rohen JSON-Outputs von zehn fehlgeschlagenen Tool Calls. Um das zu lösen, schreibst du eine Input Filter Funktion. Darin iterierst du durch die Liste der eingehenden Messages. Du checkst die Role von jeder Message. Wenn die Message eine Tool Execution oder ein rohes Tool Result ist, verwirfst du sie. Wenn es eine direkte User Message oder eine finale Assistant Reply ist, hängst du sie an deine neue Liste an. Dann gibst du diese saubere Liste zurück und hängst deine Filter-Funktion an die Handoff-Definition an. Der FAQ Agent erhält nun eine gestraffte History, die nur das menschenlesbare Hin und Her enthält. Hier ist die wichtigste Erkenntnis. Handoff Inputs fügen der Transition strukturierte Intelligenz hinzu, während Input Filter den Noise rigoros herausschneiden. Zusammen formen sie genau das, was der empfangende Agent weiß. Du sparst Tokens, reduzierst die Latency und verhinderst, dass der neue Agent basierend auf dem verworfenen Reasoning des vorherigen Agents halluziniert. Den Context an der Handoff Boundary zu kontrollieren, ist der mit Abstand effektivste Weg, um ein Multi-Agent-System schnell und präzise zu halten. Wenn du helfen willst, die Show am Laufen zu halten, kannst du auf Patreon nach DevStoriesEU suchen – deine Unterstützung bedeutet uns sehr viel. Das war's für diese Folge. Danke fürs Zuhören und keep building!
8

State kontrollieren: to_input_list und Server IDs

4m 19s

Ein Deep Dive in das manuelle Konversationsmanagement. Verstehe die Low-Level-Methoden zur Erhaltung des Kontexts über Turns hinweg und die Nutzung serverseitiger Response IDs.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 8 von 18. Ein KI-Agent mit Amnesie ist nutzlos. Aber wenn du sein Memory falsch speicherst, kann das unbemerkt die Conversation History duplizieren und deine API-Kosten verdoppeln. Das passiert, wenn du versehentlich verschiedene Methoden zum Tracking der Chat History vermischst. Heute schauen wir uns State-Kontrolle an: to_input_list und Server IDs. Standardmäßig ist ein einfacher Agent Run komplett stateless. Du sendest einen String und bekommst einen String zurück. Wenn du eine Follow-up-Frage stellst, hat der Agent keinen Kontext zu dem, was ihr gerade besprochen habt. Du musst die History selbst bereitstellen. Obwohl das SDK High-Level Session Wrappers bietet, brauchst du manchmal den transparentesten Lowest-Level-Weg, um die Chat History über mehrere Turns hinweg ohne magisch versteckten State zu verwalten. Dafür gibt es zwei explizite Wege. Die erste Methode behält die Source of Truth auf deiner Maschine, und zwar mit einer Methode namens to_input_list. Wenn ein Agent einen Run beendet, gibt er ein Result-Objekt zurück. Dieses Objekt enthält die finale Response, aber auch die versteckten Schritte, die der Agent gemacht hat, um dorthin zu gelangen. Wenn der Agent ein Database Tool aufgerufen, den Output gelesen und dann eine Antwort formuliert hat, sind all diese Zwischenschritte Teil des Conversation States. Der Aufruf von to_input_list auf dem Result-Objekt verpackt diese gesamte Sequenz. Er gibt ein flaches Array zurück, das den ursprünglichen User Prompt, die Agent Replies, die spezifischen Tool Calls und die Tool Outputs enthält. Das alles wird exakt so formatiert, wie die API es erwartet. Wenn du einen Command-Line Chat Loop baust, sieht die Logik so aus: Du definierst eine Variable, um das Conversation-Array zu speichern. Anfangs enthält sie nur den ersten User Prompt. Du übergibst dieses Array an den Agenten. Wenn der Agent fertig ist, nimmst du das Result und rufst to_input_list auf, was dir die komplette, aktualisierte History dieses Turns gibt. Wenn der User seine zweite Frage eintippt, hängst du seine neue Message manuell ans Ende dieser Liste an und übergibst das Ganze wieder dem Agenten. Du hast die volle Kontrolle über den Payload. Nun zum zweiten Teil. Ein massives Array aus vorherigen Messages und JSON Tool Outputs bei jedem einzelnen Turn über das Netzwerk hin und her zu schieben, verbraucht Bandbreite. Wenn du das vermeiden willst, kannst du Server-Side IDs verwenden. Jede Response, die du von der API bekommst, enthält einen Unique Identifier. Anstatt ein Array vergangener Messages in deinen nächsten Agent Run zu übergeben, übergibst du einen Parameter namens previous_response_id. Hier ist die entscheidende Erkenntnis: Wenn du eine previous_response_id angibst, sendet dein Client nur die brandneue User Message. Du sendest nicht das History-Array. Der OpenAI-Server sucht diese ID, ruft den bestehenden Context Thread auf seiner Seite ab, hängt deine neue Message daran an und generiert die nächste Reply. Das bringt uns zu einer kritischen Falle. Du könntest in Versuchung geraten, diese Ansätze zu mischen. Du könntest den User Input an die Client-Side-Liste anhängen, diese komplette Liste an den Agenten übergeben und sicherheitshalber auch noch die previous_response_id mitschicken. Mach das nicht. Du musst dich pro Conversation für genau eine Strategie entscheiden. Wenn du sowohl das komplette History-Array als auch eine previous_response_id übergibst, wird der Server sie konkatenieren. Dein Agent wird die gesamte Conversation zweimal lesen, durch die doppelten Tool Calls verwirrt werden, und du zahlst für diese Tokens doppelt. Die Wahl zwischen diesen beiden Methoden läuft auf Visibility versus Effizienz hinaus. Verwende Client-Side-Listen, wenn du die Conversation History zwischen den Turns auditieren, filtern oder modifizieren musst. Verwende Server-Side IDs, wenn du dem Raw Thread vertraust und deinen Network Payload minimieren willst. Das war's für diese Folge. Danke fürs Zuhören und keep building!
9

Memory automatisieren mit Built-in Sessions

4m 02s

Vereinfache deine Chat Loops mit dem integrierten Memory-System des SDKs. Wir untersuchen SQLiteSession, OpenAIConversationsSession und automatisierte Persistenz.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 9 von 18. Du baust einen persistenten Chatbot. Du schreibst Code, um vorherige Messages aus einer Datenbank abzurufen, sie an deinen Agent zu übergeben, die neue Response zu extrahieren und die aktualisierte Liste zurück in die Datenbank zu schreiben. Das ist mühsamer Boilerplate, den du schon dutzende Male geschrieben hast. Heute schauen wir uns Automating Memory mit Built-in Sessions an, was diese ganze Datenbank-Lese- und Schreiblogik durch ein einziges Object ersetzt. Lass uns gleich mal mit einem häufigen Missverständnis aufräumen. Wenn Developer anfangen, Sessions in diesem SDK zu nutzen, denken sie oft, sie müssten die Message History weiterhin manuell fetchen und zusammen mit der Session an den Agent Runner übergeben. Müssen sie aber nicht. Wenn du dem Runner ein Session Object übergibst, ersetzt das das manuelle History Management komplett. Du übergibst quasi die Schlüssel. Der Runner holt sich automatisch vergangene Messages, kurz bevor der Conversation Turn beginnt, und hängt die neuen Messages automatisch an, sobald der Turn endet. Stell dir einen persistenten Slack-Bot vor, der sich User Preferences über mehrere Tage hinweg merken muss. Du willst diesen State auf der Festplatte speichern, ohne eine schwere externe Datenbank aufzusetzen. Das SDK bietet dafür ein Built-in Tool namens SQLite Session. Weil die Interaktion mit einem File System IO-Operationen erfordert, ist dieses Tool komplett async. Um es zu nutzen, instanziierst du zuerst eine SQLite Session und übergibst einen File Path für deine lokale Datenbank. Dann verbindest du dich über einen Async Context Manager damit. Stell dir das wie das Öffnen einer sicheren Connection vor, die garantiert, dass das Datenbank-File richtig gelockt und wieder freigegeben wird. Innerhalb dieses Connection Blocks rufst du deinen Agent Runner auf. Anstatt dem Runner ein Array aus vergangenen Messages zu übergeben, übergibst du einfach das Session Object und eine Session ID. Die Session ID ist einfach ein eindeutiger String. Für deinen Slack-Bot könnte diese ID die User ID oder die Channel ID sein. Der Runner nimmt diese ID, durchsucht das SQLite-File, lädt die existierende History, verarbeitet den User Prompt und persistiert den neuen State danach sicher zurück ins File. Das alles passiert im Hintergrund. Hier ist der entscheidende Punkt. Eine unbegrenzte Conversation History wird früher oder später deine Context Window Limits sprengen. Du willst nicht, dass ein unwichtiger Chat von vor drei Monaten deine Token Usage in die Höhe treibt oder heute deinen API Call crashen lässt. Um das zu kontrollieren, bietet das SDK Session Settings. Wenn du den Runner aufrufst, kannst du neben der Session selbst auch ein Session Settings Object übergeben. Dieses Settings Object akzeptiert einen Parameter für die maximale Anzahl vergangener Messages. Wenn du ihn auf zehn setzt, kürzt der Runner automatisch die geladene History. Er behält nur die zehn aktuellsten Messages im aktiven Context, der an das Model gesendet wird, aber dein komplettes historisches Log bleibt in der SQLite-Datenbank sicher und unangetastet. SQLite Session ist ideal für lokale Persistence oder Single-Server-Applications. Wenn dein Slack-Bot wächst und du über mehrere Server skalieren musst, übernimmt das SDK das nahtlos. Du behältst deinen Runner-Code exakt bei, tauschst aber die lokale SQLite Session gegen eine verteilte Option wie eine Redis Session oder eine Dapr Session aus. Das wichtigste Takeaway ist, dass Sessions eine strikte Separation of Concerns erzwingen. Indem du ein Session Object konfigurierst und es dem Runner übergibst, eliminierst du fragilen Datenbank-Boilerplate und garantierst, dass dein Agent Memory immer perfekt mit seinem Execution State synchronisiert ist. Das war’s für heute. Danke fürs Zuhören – geh los und bau was Cooles.
10

Workflows schützen: Input und Output Guardrails

4m 16s

Sichere deine AI Pipelines, indem du bösartige Inputs abfängst, bevor sie teure Modelle erreichen. Wir behandeln Agent-Level Guardrails sowie parallele vs. blockierende Ausführung.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 10 von 18. Dein leistungsstärkstes Reasoning Model ist gleichzeitig auch dein teuerstes. Wenn ein User versucht, es auszutricksen, um seine Mathehausaufgaben zu lösen oder Sicherheitsrichtlinien zu verletzen, willst du das nicht erst herausfinden, nachdem es gerade zwei Minuten und tausend Tokens damit verbracht hat, darüber nachzudenken. Genau das verhinderst du, indem du deine Workflows mit Input und Output Guardrails schützt. Agent-Level Guardrails fungieren als Türsteher für deine primären Modelle. Das sind separate Funktionen, oft angetrieben von kleineren, schnelleren und günstigeren Modellen, die Daten validieren, die in deinen Agent reingehen oder ihn verlassen. Indem sie Requests abfangen, sorgen sie dafür, dass sich deine teuren Modelle auf die eigentliche Arbeit konzentrieren und deine Applikation sicher und on-topic bleibt. Du wendest sie an zwei Stellen an: beim Input und beim Output. Input Guardrails evaluieren den Prompt des Users, bevor dein primärer Agent mit der Arbeit beginnt. Stell dir ein Szenario vor, in dem du ein großes, langsames Modell hast, das komplexe Finanzanalysen durchführt. Du kannst eine Input Guardrail mit einem schnellen, leichtgewichtigen Modell aufsetzen, um jede eingehende Message zu überprüfen. Wenn ein User eine Frage stellt, fängt dieses schnelle Modell sie ab. Es checkt, ob der User versucht, den Agent dazu zu bringen, eine Schulaufgabe zu machen, oder vielleicht eine Prompt Injection Attacke versucht. Wenn der Input geflaggt wird, weist die Guardrail ihn sofort zurück und gibt eine Standard-Ablehnungsnachricht zurück. Dein großes Reasoning Model wacht nicht einmal auf. Du sparst Zeit und du sparst Geld. Output Guardrails kümmern sich um das andere Ende der Transaktion. Sie bieten einen finalen Check, bevor der User die Response sieht. Der Main Agent hat seinen Task abgeschlossen, aber du musst sicherstellen, dass keine sensiblen Daten leaken oder dass der Tonfall mit deinen Unternehmensrichtlinien übereinstimmt. Die Output Guardrail reviewt den generierten Text. Wenn sie eine Halluzination oder eine Policy Violation erkennt, blockiert sie die Message, bevor sie den User erreicht. Hier ist die wichtigste Erkenntnis: Wie sich diese Guardrails auf deine Applikation auswirken, hängt komplett von ihrem Execution Mode ab. Du kannst sie im Blocking Mode oder im Parallel Mode ausführen. Der Blocking Mode ist eine strikte Sequenz. Eine Input Guardrail muss ihre Evaluierung abschließen und ein Pass zurückgeben, bevor der Main Agent starten darf. Eine Output Guardrail muss den Check der finalen Response abschließen, bevor der User auch nur ein einziges Wort empfängt. Das ist der sicherste Ansatz und garantiert, dass du kein Geld für Bad Requests verschwendest, aber es fügt der Interaktion Latency hinzu. Der Parallel Mode tauscht strikte Kostenkontrolle gegen Geschwindigkeit. Ein häufiges Missverständnis ist, dass die Parallel Execution den Main Agent irgendwie pausiert, während die Guardrail nebenher läuft. Das ist nicht der Fall. Im Parallel Mode starten die Input Guardrail und der Main Agent exakt zur gleichen Zeit. Der Agent generiert aktiv Text und verbraucht Tokens, während die Guardrail den Input Prompt noch evaluiert. Wenn die Guardrail entscheidet, den Request fehlschlagen zu lassen, bricht sie den Main Agent mitten in der Ausführung ab. Der User ist weiterhin davor geschützt, den Output zu sehen, aber du bezahlst trotzdem für die Tokens, die der primäre Agent verbraucht hat, bevor er abgebrochen wurde. Du konfigurierst das, indem du eine einfache Funktion definierst, die eine Pass- oder Fail-Entscheidung zurückgibt, sie an deinen Agent anhängst und ihren Mode deklarierst. Passe deinen Execution Mode immer deinen Prioritäten an: Nutze Blocking Guardrails, um dein Budget vor teuren Modellen zu schützen, und Parallel Guardrails, um deine User Experience vor Latency zu bewahren. Das war's für diese Folge. Danke fürs Zuhören und keep building!
11

Aktionen validieren: Tool-Level Guardrails

4m 27s

Verhindere kritische Datenlecks auf Funktionsebene. Lerne, wie du spezifische Tools mit präzisen Input und Output Guardrails umhüllst.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 11 von 18. Selbst die intelligenteste KI kann versehentlich ein Database Secret leaken, wenn sie Raw Data direkt in ihren Context zieht. Du denkst vielleicht, dass deine Top-Level Safety Checks alles abfangen, aber die laufen nur ganz am Anfang oder ganz am Ende einer Conversation. Wenn du sensible Daten mitten im Workflow abfangen willst, brauchst du Validating Actions, genauer gesagt Tool-Level Guardrails. Eine häufige Falle ist zu glauben, dass Agent-Level Guardrails deine zugrundeliegenden Systeme schützen. Das tun sie nicht. Agent Guardrails verarbeiten den initialen User Prompt oder die finale Response, die an den User zurückgeht. Sie sind blind für das interne Hin und Her, wenn ein Agent eine Datenbank oder eine Third-Party API aufruft. Wenn ein Rogue Prompt deinen Agenten dazu bringt, ein internes Tool aufzurufen, werden die Agent-Level Checks das nicht stoppen. Um die Tools selbst zu schützen, bietet das OpenAI Agents SDK Tool Guardrails. Diese sitzen direkt auf der Function und fungieren als obligatorischer Checkpoint, direkt bevor oder nachdem das Tool ausgeführt wird. Es gibt zwei Typen, die du kennen musst. Der erste ist der Tool Input Guardrail. Du wendest diesen Decorator an, um Arguments zu validieren, bevor das eigentliche Tool läuft. Angenommen, ein Agent versucht, ein Tool aufzurufen, das einen User Account löscht. Der Input Guardrail fängt die Arguments ab, die der Agent generiert hat. Er prüft, ob die übergebene User ID einem gültigen Format entspricht, oder ob die aktuelle Session das richtige Authorization Level hat. Wenn der Input diesen Check nicht besteht, stoppt der Guardrail die Ausführung des Tools komplett. Anstatt die Löschung auszuführen, gibt er eine Error Message direkt an den Agenten zurück. Der Agent liest diesen Error und kann es mit korrigierten Inputs nochmal versuchen, ohne jemals die eigentliche Datenbank zu berühren. Der zweite Teil davon ist der Tool Output Guardrail. Dieser greift, nachdem das Tool erfolgreich ausgeführt wurde, aber bevor das Result an den Agenten zurückgegeben wird. Hier filterst, schwärzt oder validierst du den Payload. Nehmen wir ein Database Lookup Tool als Beispiel. Der Agent fragt nach einem Developer Profile, und das Tool holt den Raw Record. Dieser Record enthält aber zufällig einen aktiven API Key, der mit den Buchstaben s-k-dash beginnt. Wenn dieser Raw Key zurück an den Agenten geht, landet er im Context Window des Language Models. Das ist ein massives Security-Risiko. Um das zu beheben, fügst du dieser speziellen Lookup Function einen Tool Output Guardrail hinzu. Der Guardrail nimmt das Raw Database Result, scannt den Text nach diesem s-k-dash Pattern und ersetzt den eigentlichen Key durch einen Placeholder String wie redacted. Erst nach diesem Scrubbing-Prozess werden die bereinigten Daten an den Agenten zurückgegeben. Der Agent bekommt immer noch die Profile Information, die er braucht, um dem User zu antworten, aber das Secret verlässt niemals die isolierte Execution Boundary des Tools. Das ist der entscheidende Punkt. In komplexen Multi-Agent Workflows können verschiedene spezialisierte Agenten Tools in unvorhersehbaren Sequenzen aufrufen. Du kannst dich nicht darauf verlassen, den Agenten so zu prompten, dass er sich sicher verhält. Du kannst auch nicht darauf hoffen, dass der finale Output Filter einen geleakten Key abfängt, kurz bevor er an den User geht, denn bis dahin wurde der Key bereits dem Language Model exposed. Du musst das Tool selbst absichern. Indem du den Guardrail direkt an die Function hängst, reist die Security-Logik mit dem Tool mit. Es spielt keine Rolle, welcher Agent es aufruft oder wann es im Workflow aufgerufen wird. Der Schutz ist absolut. Tool Guardrails behandeln deine Functions als Zero-Trust Boundaries und stellen so sicher, dass dein Agent, egal wie autonom er wird, niemals schlechte Daten hineingeben oder sensible Daten herausziehen kann. Das war’s für diese Folge. Danke fürs Zuhören und keep building!
12

Ausführung pausieren: Human-in-the-Loop und RunState

3m 54s

Implementiere Schutzmaßnahmen für irreversible Aktionen, indem du Human-in-the-Loop-Freigaben erzwingst. Wir untersuchen die RunState-Serialisierungspipeline zum Pausieren und Fortsetzen von Workloads.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 12 von 18. Du würdest einen neuen Praktikanten ja auch nicht eine Production Database droppen lassen, ohne vorher um Erlaubnis zu fragen. Dein AI Agent sollte das auch nicht dürfen. Wenn ein Agent Zugriff auf hochgradig destruktive oder sensible Tools hat, brauchst du eine Möglichkeit, ihn zu stoppen, seine Arbeit zu checken und manuell grünes Licht zu geben. Das wird durch Pausing Execution gelöst: Human-in-the-Loop und RunState. Wenn du einen Menschen brauchst, um eine Aktion zu genehmigen, ist dein erster Instinkt vielleicht, das Python-Skript zu pausieren und auf Keyboard Input zu warten. Mach das nicht. Einen Prozess am Leben zu halten, während du auf eine E-Mail-Antwort oder einen Dashboard-Klick wartest, verschwendet Server-Ressourcen. Es bricht auch komplett zusammen, wenn der Server neu startet oder du neuen Code deployest. Das OpenAI Agents SDK löst das sauber, indem es dem Python-Prozess erlaubt, sich komplett zu beenden und später auf einem völlig anderen Server weiterzulaufen. Es fängt bei der Tool-Definition an. Wenn du eine Funktion für deinen Agenten schreibst, zum Beispiel ein Tool namens delete production database, setzt du ein Flag namens needs approval auf true. Wenn der Agent einen Prompt verarbeitet und entscheidet, dass er genau dieses Tool aufrufen muss, hält die Engine sofort an. Das Tool wird nicht ausgeführt. Stattdessen gibt der Runner die Kontrolle an deinen Application Code zurück. Hier ist der entscheidende Punkt. Wenn die Execution anhält, gibt dir der Runner ein RunState-Objekt. Dieses Objekt hält den gesamten Kontext des Runs bis auf die genaue Millisekunde. Es kennt die Conversation History, den internen Thought Process des Agenten und den spezifischen Tool Call, den er als Nächstes ausführen will. Du nimmst dieses RunState-Objekt und serialisierst es in einen Standard-JSON-String. Du speicherst diese JSON-Payload in deiner Datenbank, pushst sie in eine Queue oder schreibst sie auf die Disk. Sobald dieser State sicher gespeichert ist, beendet sich dein Python-Skript. Deine Application ist jetzt idle. Stunden oder sogar Tage können vergehen. Irgendwann loggt sich ein Engineering Manager in ein Web-Dashboard ein, sieht die ausstehende Database Deletion und klickt auf approve. Dieser Klick triggert einen brandneuen Web Request. Dein Backend wacht auf und liest die gespeicherte JSON-Payload aus der Datenbank. Es deserialisiert diesen String zurück in ein gültiges RunState-Objekt. Dann startest du eine neue Runner Execution. Du übergibst dieselbe Agent Instance, den wiederhergestellten RunState und die Entscheidung des Menschen. Wenn du ein Approval übergibst, führt der Runner das Database Deletion Tool aus und der Agent antwortet dem User weiter. Wenn der Manager auf reject geklickt hat, übergibst du stattdessen eine Rejection. Der Runner führt das Tool nicht aus. Er gibt die Rejection als Tool Error an den Agenten zurück und zwingt den Agenten so, seinen Plan anzupassen oder dem User zu sagen, dass die Aktion abgelehnt wurde. Indem du den RunState serialisierst, verwandelst du ein synchrones Skript in einen asynchronen Workflow. So können Menschen und Agenten sicher über jede Zeitlücke hinweg zusammenarbeiten, ohne einen einzigen Server-Prozess hängen zu lassen. Wenn du helfen willst, die Show am Laufen zu halten, kannst du uns unterstützen, indem du auf Patreon nach DevStoriesEU suchst. Danke, dass du dabei warst. Ich hoffe, du hast etwas Neues mitgenommen.
13

Lokale Abhängigkeiten injizieren mit RunContextWrapper

4m 24s

Meistere Dependency Injection in deinen Agent Flows. Lerne, wie du lokale States und Datenbankverbindungen sicher an Tools übergibst, ohne sie an das LLM durchsickern zu lassen.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 13 von 18. Wie teilst du einer Funktion mit, welcher User gerade chattet, ohne dem LLM versehentlich seine private Database ID beizubringen? Wenn du sie in den System Prompt packst, legst du interne Daten offen und verschwendest Tokens. Um sicheren, lokalen State an deine Tools zu übergeben, nutzt du Injecting Local Dependencies mit dem Run Context Wrapper. Ein häufiger Fehler beim Bauen von Agents ist, das Language Model als Middleman für alles zu behandeln. Developer versuchen oft, Database Connection Strings, interne API Keys oder private User Identifier direkt in die System Instructions einzubetten. Sie machen das in der Hoffnung, dass das Model diese sensiblen Credentials brav als Parameter in die Tool Calls zurückgibt. Das ist ein erhebliches Sicherheitsrisiko. Außerdem verbraucht es unnötig Tokens im Context Window und erhöht die Wahrscheinlichkeit, dass das Model falsche Parameter halluziniert. Der richtige Ansatz ist, das Language Model für deinen lokalen Execution State komplett zu umgehen. Der Run Context Wrapper bietet einen sicheren Transport Layer, um Dependencies direkt in deine Tools und Lifecycle Hooks zu injizieren. Das Context Attribute, das an diesen Wrapper angehängt ist, ist reiner lokaler Python State. Das Model sieht ihn nie, liest ihn nie und muss auch nie darüber nachdenken. Stell dir ein konkretes Szenario vor. Ein authentifizierter User chattet mit deinem Customer Support Agent und bittet darum, seine letzten Abrechnungsdaten einzusehen. Dein System muss diese Records abrufen, was bedeutet, dass dein Billing Tool die interne Database ID des Users benötigt, um die Database Query sicher auszuführen. Zuerst definierst du deine lokale Dependency in deinem Application Code. Du könntest eine strukturierte Data Class namens User Info erstellen, die die interne User ID hält. Als Nächstes schreibst du deine Tool Function, um die Billing History abzurufen. In der Signatur dieser Tool Function definierst du einen Parameter, der speziell dafür getypt ist, das Context Object zu akzeptieren. Das SDK versteht diesen Type Hint und weiß, dass es diesen Parameter nicht an das Language Model exposen darf. Innerhalb des Function Bodys greifst du auf den Context Parameter zu, ziehst deine User Info Dependency heraus und nutzt diese private User ID, um dein Backend sicher abzufragen. Hier ist der entscheidende Punkt. Wenn du den Agent Run vorbereitest, übergibst du nicht einfach die rohe User Message. Du erstellst eine Instance des Run Context Wrappers. Du hängst deine befüllte User Info Data Class direkt an den Wrapper an. Dann übergibst du diesen Wrapper an den Execution Runner. Der Logic Flow erledigt den Rest automatisch. Wenn der User nach seiner Billing History fragt, entscheidet das Language Model, dein Billing Tool zu triggern. Das Model liefert nur die Argumente, die es aus der öffentlichen Konversation kennt, vielleicht gefiltert nach einem bestimmten Monat oder einer Rechnungsnummer. Es hat absolut keine Ahnung, wer der User in deinem Backend ist. Bevor die Function tatsächlich läuft, fängt das SDK den Call ab. Es inspiziert die Tool Signatur, merkt, dass das Tool den lokalen Context benötigt, und injiziert automatisch den State, den du an den Run Context Wrapper angehängt hast. Das Tool wird mit der sicheren User ID ausgeführt, ruft die Records ab und gibt die Daten an das Model zurück, um eine Response zu formulieren. Genau derselbe Dependency Injection Mechanismus funktioniert auch für Execution Hooks, wodurch du aktive Database Connection Pools oder Tracing IDs nahtlos in dein Event Logging übergeben kannst. Indem du das externe Reasoning des Models von der internen Execution deines Codes trennst, bleibt deine Infrastruktur sicher und deine Prompts bleiben komplett auf das Verhalten fokussiert. Halte deine Execution Dependencies komplett lokal und zwinge deine Architektur, sich vollständig auf den sicheren State zu verlassen, der zur Runtime injiziert wird. Danke fürs Zuhören, habt alle noch einen schönen Tag!
14

Das USB-C für KI: Einführung in MCP

3m 28s

Eine Einführung in das Model Context Protocol (MCP). Entdecke, wie dieser Standard als universeller Anschluss fungiert, um AI Agents einfach mit SaaS-Plattformen zu verbinden.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 14 von 18. Hör auf, jedes Mal eigene API-Wrapper zu schreiben, wenn dein Agent mit einem neuen Service reden muss. Wenn du es satt hast, REST Endpoints manuell auf JSON-Schemas zu mappen, nur damit dein Language Model versteht, was ein Service macht, gibt es jetzt endlich einen universellen Standard. Wir schauen uns das Model Context Protocol, oder MCP, an und wie man es benutzt. Stell dir MCP wie den USB-C-Anschluss für AI vor. Vor USB-C brauchte jedes Gerät ein spezielles, proprietäres Ladekabel. In der AI-Welt braucht jedes externe System eigenen Glue Code. Wenn du willst, dass ein Agent eine Datenbank liest oder ein Support-Ticket erstellt, schreibst du einen REST-Client. Dann schreibst du ein komplexes Schema, das dem Model diesen Client beschreibt. Zum Schluss schreibst du die Logik, um die Model Response abzufangen und den eigentlichen HTTP Request zu triggern. MCP ersetzt diese Handarbeit. Es ist ein offener Standard, der genau vorgibt, wie Tools sich selbst, ihre Inputs und ihre Outputs direkt gegenüber einem AI Model beschreiben. Leute verwechseln MCP oft mit normalen REST APIs. Eine REST API sendet Daten zwischen Maschinen, aber sie erwartet, dass du vorher genau weißt, wie du den Request strukturieren musst. MCP standardisiert den Discovery Layer. Ein MCP Server sagt dem Agenten ganz genau, welche Tools er hat und welche Parameter nötig sind, und zwar exakt in dem Format, das das Model braucht. Im OpenAI Agents SDK konsumierst du diese externen MCP Server über eine Klasse namens Hosted MCP Tool. Hier ist der entscheidende Punkt. Du definierst das Tool Schema in deinem Python Code überhaupt nicht neu. Stattdessen initialisierst du das Hosted MCP Tool, indem du ihm die URL eines Remote MCP Servers gibst. Diese Connection läuft über Server-Sent Events, wodurch der Server Updates sicher an deinen Agenten pushen kann. Wenn du dieses Hosted MCP Tool an dein Agent Setup anhängst, passiert ein Handshake. Der Agent verbindet sich mit dem Remote Server, fragt, welche Tools verfügbar sind, zieht sich die fertigen Descriptions und registriert sie automatisch. Machen wir das an einem konkreten Szenario fest. Du willst deinem Agenten die Fähigkeit geben, Meetings zu planen. Ohne MCP würdest du die Google Calendar API studieren. Du würdest eine Python-Funktion schreiben, um dich zu authentifizieren und Events zu erstellen. Dann würdest du das Tool Schema ausschreiben, damit der Agent weiß, wie ein Event Title oder ein Timestamp aussieht. Mit MCP deployst du einen fertigen Google Calendar MCP Server remote. In deinem Application Code erstellst du eine neue Hosted MCP Tool Instanz und lässt sie auf diese Remote URL zeigen. Du übergibst diese einzige Instanz an deinen Agenten. Der Remote Server sagt dem Agenten sofort, dass er ein Tool namens schedule meeting hat. Wenn das Language Model entscheidet, dieses Meeting zu planen, proxyt das SDK den Call. Es routet den Request sicher über das Netzwerk zum Remote Server, führt die Action aus und gibt das Ergebnis zurück. Du hast null Zeilen Kalender-Integrations-Logik geschrieben. Die wahre Stärke von MCP ist das Entkoppeln deiner Core Agent Logik von externen Integrationen, sodass du Backend Services einfach austauschen oder upgraden kannst, indem du nur eine URL änderst. Danke fürs Zuhören, happy coding zusammen!
15

Lokale MCP Server über Stdio und HTTP verbinden

3m 57s

Tauche tiefer in MCP ein, indem du standardmäßige lokale Server ausführst. Lerne, den Dateisystemzugriff und interne Tools mit MCPServerStdio sicher in einer Sandbox zu isolieren.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 15 von 18. Einem Sprachmodell direkten Zugriff auf dein lokales Filesystem zu geben, klingt nach einem absoluten Security-Albtraum. Aber wenn du diesen Zugriff durch ein standardisiertes Protokoll strikt in einer Sandbox isolierst, wird er zu einem sicheren und mächtigen Weg, lokale Daten zu verarbeiten. Heute schauen wir uns an, wie man lokale MCP-Server über stdio und HTTP verbindet. Das Model Context Protocol definiert, wie deine Agents mit externen Tools und Datenquellen kommunizieren. Wenn du diese Server in deiner eigenen Infrastruktur laufen lassen willst, bietet das OpenAI Agents SDK zwei lokale Transportmethoden. Die erste ist Standard Input und Output, über die Klasse namens MCPServerStdio. Leute denken manchmal, das erfordert ein komplexes lokales Networking-Setup. Tut es aber nicht. Wenn du den stdio-Transport nutzt, spawnt das SDK den MCP-Server einfach als lokalen Child Process. Der Agent sendet Requests, indem er in den Standard Input dieses Prozesses schreibt, und liest Responses aus dessen Standard Output. Stell dir ein Szenario vor, in dem dein Agent Dateien lesen soll, aber nur aus einem ganz bestimmten lokalen Verzeichnis. Du instanziierst MCPServerStdio und übergibst ihm den Command, der ausgeführt werden soll. Zum Beispiel könntest du den Node Package Manager Command npx übergeben, gefolgt von den Argumenten, um den offiziellen MCP Filesystem Server zu starten, und dem absoluten Pfad zu deinem Zielverzeichnis. Weil dieser Server als Subprocess läuft, musst du seinen Lifecycle managen. Wenn dein Python-Script durchläuft oder crasht, willst du keinen verwaisten Node-Prozess im Hintergrund weiterlaufen haben. Das SDK erzwingt ein sauberes Lifecycle Management, indem es einen asynchronen Context Manager verlangt. Du definierst einen async with Block, um den stdio-Server zu initialisieren. Wenn die Ausführung in den Block eintritt, fährt das SDK den Child Process hoch. Wenn die Ausführung den Block verlässt, fährt es den Prozess sauber wieder runter. Innerhalb dieses Blocks verbindest du den laufenden Server mit deinem Agent. Du erstellst einen MCP Client, übergibst ihm deine stdio-Server-Instanz und gibst diesen Client dann an deinen Agent weiter. Der Agent hat jetzt gescopten, temporären Zugriff auf dein lokales Verzeichnis. Was aber, wenn du eine private interne API exposen oder dich mit einem Service verbinden willst, der bereits läuft? Dafür willst du keinen neuen Subprocess spawnen. Das bringt uns zur zweiten Transport-Option, nämlich MCPServerStreamableHttp. Anstatt einen ausführbaren Command zu übergeben, gibst du dieser Klasse die URL deines bestehenden Services. Das ist perfekt, um deinen Agent sicher mit einem internen Microservice zu verbinden, der auf localhost läuft. Der Agent kommuniziert, indem er Daten über HTTP streamt. Hier ist der entscheidende Punkt. Der Agent selbst hat keine Ahnung, welchen Transport du gewählt hast. Der Connection-Code in deiner Anwendung sieht exakt gleich aus. Du benutzt immer noch einen Context Manager, du erstellst immer noch einen MCP Client, und du übergibst ihn immer noch an den Agent. Das SDK abstrahiert den Transport Layer komplett. Das absolut Nützlichste, was du hier mitnehmen kannst, ist, dass du ein Custom Tool als lokales stdio-Script fürs Testing entwickeln und es später als eigenständigen HTTP-Service in Production deployen kannst, ohne eine einzige Zeile deiner Agent-Logik zu ändern. Das war's für diese Folge. Danke fürs Zuhören, und keep building!
16

Workflows visualisieren mit Built-in Tracing

3m 47s

Eliminiere das Debuggen mit Print-Statements durch die integrierte SDK Observability. Entdecke, wie automatische Spans und Traces ganze komplexe Workflows verknüpfen.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 16 von 18. Ein Multi-Agent-System mit Print-Statements zu debuggen, ist ein Albtraum. Du siehst die Logs vorbeiziehen und versuchst manuell, eine Tool Execution in Zeile 50 mit einer Model Generation in Zeile 200 abzugleichen. Zum Glück musst du das nie wieder tun. In dieser Folge geht es um die Visualisierung von Workflows mit Built-in Tracing. Wenn Entwickler anfangen, komplexe Agent Workflows zu bauen, ist ihr erster Instinkt oft, eigene Logging Wrapper zu schreiben. Sie schreiben Boilerplate-Code, um genau zu tracken, wann ein Agent startet, welche Argumente ein Tool empfängt und wie lange das Model für eine Antwort braucht. Bau das nicht selbst. Das Agents SDK übernimmt das für dich, komplett out of the box. Jedes Mal, wenn du einen Agent ausführst, eine Generation anforderst oder einen Tool Call triggerst, wrappt das SDK diese Aktion automatisch in einen Span. Ein Span ist einfach ein zeitlich erfasster, strukturierter Datensatz einer einzelnen Operation. Diese Spans erfassen die Inputs, die Outputs und die Dauer der Task. Sie werden automatisch an das OpenAI Dashboard gesendet. Das bedeutet, du bekommst eine komplette visuelle Timeline deiner Workflow Execution, ohne eine einzige Zeile Telemetry-Code zu schreiben. Hier ist der entscheidende Punkt. Während das SDK die granularen Details übernimmt, steuerst du das High-Level Grouping. Nehmen wir an, du hast ein Multi-Turn-Szenario, in dem ein Agent einen Witz generiert, ein zweiter Agent ihn evaluiert und der erste Agent ihn basierend auf dem Feedback verfeinert. By default trackt das SDK jede dieser Model Generations und Tool Calls als separate Spans. Aber für einen Menschen, der auf ein Dashboard schaut, ist dieses ganze Hin und Her einfach eine einzige logische Unit of Work. Du kannst diese Aktionen mit einem Custom Trace Block gruppieren. Du öffnest einen Context Block mit der Trace-Funktion und gibst ihm einen beschreibenden Namen, wie Joke Generation Loop. Innerhalb dieses Blocks führst du deine Multi-Turn Agent Logic aus. Das SDK respektiert diese Hierarchie. Es verschachtelt alle automatisch generierten Spans für die einzelnen Runs, Evaluations und Refinements unter deinem Custom Parent Trace. Wenn du das OpenAI Dashboard öffnest, siehst du zuerst den Top-Level Joke Generation Loop. Du kannst ihn dann aufklappen, um die genaue Sequenz der Model Calls und Tool Executions zu untersuchen, die darin passiert sind. Das deckt die Visibility ab, aber was ist mit Privacy? Es gibt Zeiten, in denen du absolut keine Telemetry senden darfst. Wenn dein Agent sensible medizinische Akten oder Finanzdaten verarbeitet oder strikte Zero Data Retention Compliance erfordert, ist das Senden von Input- und Output-Logs an ein Dashboard eine Security Violation. Für diese Situationen bietet das SDK einen Tracing Disabled Context Block. Wenn du deine Agent Execution in diesen Block wrappst, stoppt das SDK komplett das Generieren und Senden von Spans. Die Execution läuft lokal, das Ergebnis wird an deine Application zurückgegeben, aber kein Record des Prompts, der Tool Calls oder der Response wird auf dem OpenAI Dashboard erscheinen. Sobald der Code diesen Disabled Block verlässt, wird das normale automatische Tracing für den Rest deiner Application fortgesetzt. Tracing im SDK bedeutet, dass du aufhörst, Boilerplate Logging zu schreiben, sofortiges visuelles Debugging bekommst und trotzdem die volle Kontrolle darüber behältst, wann deine Daten komplett lokal bleiben. Das war's für diese Folge. Danke fürs Zuhören und keep building!
17

Low-Latency Voice mit Realtime Agents

3m 47s

Brich das Standard-Request-Response-Paradigma. Sieh dir an, wie Realtime Agents Live-WebSocket-Verbindungen aufrechterhalten, um Unterbrechungen und multimodales Reasoning zu handhaben.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 17 von 18. Die größte Herausforderung bei der Entwicklung von Voice AI ist nicht die Sprachgenerierung. Sondern zu wissen, wann man sofort abbrechen muss, weil der menschliche Anrufer mitten im Satz unterbricht. Wenn du dich auf den traditionellen Request-Response-Cycle verlässt, wird die Network Latency den Bot immer entlarven. Genau dieses Problem löst Low-Latency Voice mit Realtime Agents. Viele Developer verwechseln diese Architektur mit einer Standard-Voice-Pipeline. In einem traditionellen Setup nimmst du Audio auf, jagst es durch ein Speech-to-Text-Modell, schickst diesen Text an ein Language Model und pushst den Text-Output schließlich durch einen Text-to-Speech-Synthesizer. Diese Pipeline bringt bei jedem Schritt Latenz rein. Realtime Agents werfen diese Pipeline komplett über Bord. Sie nutzen ein einziges, multimodales Model, das Audio nativ verarbeitet. Audio geht direkt rein, und Audio streamt direkt wieder raus. Das System braucht keine Textübersetzung dazwischen, um den User zu verstehen. Um das zu erreichen, musst du das Standard-HTTP-Request-Response-Paradigma aufbrechen. Anstatt einen Payload zu senden und auf eine komplette Response zu warten, hält das System eine persistente Connection offen. Im SDK managst du das über zwei Hauptkomponenten. Die erste ist der RealtimeAgent. Dieses Object enthält deine System Instructions und alle Functions oder Tools, auf die das Model Zugriff braucht. Es definiert die Logik, die Capabilities und die Persönlichkeit deines Assistenten. Die zweite Komponente ist der RealtimeRunner. Der Runner ist die Execution Engine. Er managt den asynchronen Event Loop und kümmert sich um den persistenten Network Stream, typischerweise über eine WebSocket- oder WebRTC-Connection. Stell dir einen Telefonie-Kundenservice-Bot vor, der einen eingehenden Anruf annimmt. Du verbindest deinen Voice Provider, integrierst ihn vielleicht über SIP oder WebSockets, und routest das kontinuierliche Audio an deine Python-Application. Du erstellst deinen RealtimeAgent und stattest ihn mit einem Tool aus, um User Accounts abzurufen. Dann übergibst du diesen Agent und deinen Network Connection Client an den RealtimeRunner. Wenn du die Run-Methode auf dem Runner aufrufst, übernimmt er. Er hält die Connection alive, hört permanent auf den Audio Stream und verarbeitet gleichzeitig alle Function Calls, die der Agent machen muss. Er pusht und pullt Events gleichzeitig in beide Richtungen. Der User ruft an und fragt nach seinem Kontostand. Der Agent triggert das Account-Fetch-Tool, holt die Daten und fängt sofort an, seine gesprochene Response an den Anrufer zurückzustreamen. Mitten im Satz spricht der User plötzlich über den Bot hinweg und sagt, dass er eigentlich eine verlorene Karte melden will. Hier ist der entscheidende Punkt. Weil die WebSocket-Connection persistent offen ist und das Model den eingehenden Audio Stream nativ in Realtime verarbeitet, erkennt der Server die menschliche Stimme sofort. Er feuert ein Event, das seinen eigenen Audio-Output stoppt und die Truncation registriert. Du musst keine Custom Logic schreiben, um genau zu berechnen, welcher Audio Chunk gerade lief, als der User gesprochen hat. Die Streaming-Architektur verarbeitet die Unterbrechung nahtlos. Das Model absorbiert den neuen Audio Context aus der Unterbrechung und fängt sofort an, die aktualisierte Response zum Sperren der verlorenen Karte zu streamen. Du bekommst natürliche Conversational Dynamics, und zwar nur, weil der Network Layer und der Model Layer für Continuous Streaming gebaut sind. Die wahre Power der Realtime API im Agents SDK ist es, Voice als First-Class Continuous Stream zu behandeln, anstatt als verkleideten Batch von übersetztem Text. Das war's für diese Folge. Danke fürs Zuhören und keep building!
18

Reaktive UIs bauen mit Streaming Events

4m 20s

Gehe über das Streamen von Text-Tokens hinaus. Nutze Semantic Streaming Events, um extrem reaktionsschnelle Frontend-Interfaces zu bauen, die in Echtzeit auf Agent-Aktionen reagieren.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. OpenAI Agents SDK, Folge 18 von 18. Eure User wollen nicht einfach nur Text lesen, während er auf dem Bildschirm abgetippt wird. Sie wollen genau sehen, was die KI im Hintergrund macht. Wenn ihr versucht, einen Loading Spinner zu bauen, indem ihr rohe Token Chunks parst, um zu erraten, wann ein Search Tool läuft, macht ihr es euch unnötig schwer. Reactive UIs mit Streaming Events zu bauen, löst genau dieses Problem. Developer behandeln KI-Outputs oft wie eine einfache Schreibmaschine. Sie lauschen auf einen rohen Text Stream und schreiben fehleranfällige Parsing-Logik, um herauszufinden, ob der Agent gleich eine Function aufruft. Dieser Ansatz ist fragil. Er bricht, wenn das Model sein Phrasing auch nur leicht ändert, und euer Frontend hinkt dem tatsächlichen Execution State hinterher. Das OpenAI Agents SDK bietet eine strukturelle Alternative. Anstatt auf Strings zu warten, triggert ihr euren Agent über eine Methode namens run streamed auf eurem Runner. Diese Methode liefert keinen Plain Text. Stattdessen liefert sie eine asynchrone Sequenz von semantischen Events, jedes verpackt als ein Run Item Stream Event Object. Stellt euch ein Run Item Stream Event wie eine präzise Notification über den internen Lifecycle des Agents vor. Während der Agent einen Request verarbeitet, emittiert er eindeutige, vorhersehbare Signale. Er sagt euch genau, wann eine neue Message zum Thread hinzugefügt wird. Er sagt euch, wann die Kontrolle von einem Triage Agent an einen spezialisierten Agent übergeben wird. Ganz entscheidend für die Frontend-Entwicklung: Er verrät euch auf die Millisekunde genau, wann ein Tool Call beginnt und endet. Wenden wir das mal auf ein konkretes Szenario an. Euer Frontend soll einen Spinner anzeigen, der sagt Searching database, während der Agent einen Customer Record nachschlägt. Ihr ruft run streamed auf und loopt über die Results. Innerhalb dieser asynchronen Loop inspiziert ihr jedes Event, sobald es ankommt. Wenn ein Event reinkommt, checkt ihr seine Properties, um zu sehen, welche Art von Update es darstellt. Wenn ein Event anzeigt, dass ein Tool Call gestartet wurde, könnt ihr den tatsächlichen Namen des Tools direkt aus dem Event Payload auslesen. Ihr müsst keine Natural Language parsen. Wenn der Tool-Name mit eurer Database Search Function übereinstimmt, pusht ihr sofort ein State Update an euer Frontend, um den Spinner zu rendern. Wenn ein darauffolgendes Event signalisiert, dass die Tool Execution abgeschlossen ist, dispatcht ihr ein weiteres Update, um den Spinner auszublenden. Diese Stream Events enthalten auch standardmäßige Message Deltas. Wenn der Agent eine lange Text Response generiert, emittiert der Stream Chunk Events, die ihr an das User Interface anhängt. Die Architektur trennt den rohen Conversational Output von den semantischen Actions. Ihr routet die Text Chunks an das Chat Window, und ihr routet die Tool und Agent Lifecycle Events an euren UI State Manager. Diese Separation of Concerns erlaubt es euch, Interfaces zu bauen, die sich sofort responsive anfühlen und tief mit der Agent Logic verbunden sind. Ihr reagiert auf den tatsächlichen Execution Path des Systems, anstatt seine Intentions basierend auf Wörtern zu erraten. Hier ist die entscheidende Erkenntnis. Hört auf, euren Agent Output nur als Conversation Stream zu behandeln. Behandelt ihn als Event-driven State Machine, bei der jede interne Action eine Gelegenheit ist, euren User visuell auf dem Laufenden zu halten. Da dies die letzte Folge der Serie ist, ermutige ich euch, die offizielle Documentation durchzulesen und selbst zu versuchen, diese Streams zu orchestrieren. Wenn ihr Ideen habt, was wir in einer zukünftigen Serie behandeln sollten, besucht devstories dot eu und lasst es uns wissen. Das war's für diese Folge. Bis zum nächsten Mal!