CodeGym /Kurse /ChatGPT Apps /Einstieg in Agenten: Rollen, Run‑Zyklus, Determinismus, I...

Einstieg in Agenten: Rollen, Run‑Zyklus, Determinismus, Idempotenz

ChatGPT Apps
Level 12 , Lektion 0
Verfügbar

1. Was ist ein Agent überhaupt und wozu brauchen Sie ihn

Agenten sind kein Pflichtbestandteil der ChatGPT App: Man kann beliebig viele großartige Anwendungen erstellen, ohne LLM‑Agenten zu verwenden. Dennoch habe ich drei triftige Gründe, Ihnen davon zu erzählen.

Agenten sind eine hervorragende Möglichkeit, Intelligenz in das Backend Ihrer Anwendung zu bringen. Intelligente Geschenkeauswahl, Analyse textlicher Wünsche des Nutzers. Komplexe Szenarien der Suche, Analyse, Verarbeitung und Zusammenfassung – all das lässt sich mit LLM‑Agenten sehr leicht umsetzen.

ChatGPT hat seine Agents SDK für TS und Python veröffentlicht. Sie ist sehr gut. Die Orchestrierung von Agenten kommt out of the box. An einer komplexen Aufgabe arbeitet nicht ein einzelner Agent, sondern ein ganzes Team. Das ist ein sehr vielversprechender Ansatz.

Und es gibt auch ein Lernziel. ChatGPT ruft mcp-tools genau so auf, wie LLM‑Agenten ihre tools aufrufen. Sobald Sie verstanden haben, wie LLM‑Agenten funktionieren, wird klar, wie man z. B. eine Zustandsmaschine auf der Modellseite in der Anwendung baut. Ebenso vermittelt das Studium des Agents SDKs ein Gefühl dafür, wie das ChatGPT SDK künftig funktionieren wird.

Dann legen wir los.

Was ist ein LLM‑Agent

Wenn die ChatGPT App das hübsche und bequeme „Frontend“ Ihres Dienstes innerhalb von ChatGPT ist und der MCP‑Server der „Motor“ mit Tools und Business‑Logik, dann ist der Agent so etwas wie ein intelligenter Dispatcher, der Folgendes kann:

  • das Ziel lesen;
  • selbst entscheiden, welche Tools in welcher Reihenfolge aufzurufen sind;
  • bei Bedarf zusätzliche Daten erfragen;
  • Schritte wiederholen, falls Fehler auftraten;
  • zu einem klaren finalen Ergebnis gelangen.

In einer Formulierung, die der offiziellen Dokumentation des Agents SDK nahekommt, ist ein Agent ein Programm. Mit Zugriff auf eine LLM und einen Satz von Tools kann es eigenständig Schritte planen, um ein Ziel zu erreichen, und sie über Tool‑Calls ausführen.

Parallele zu dem, was Sie bereits haben:

  • In einer gewöhnlichen ChatGPT App orchestriert das ChatGPT‑Modell die Aufrufe Ihrer MCP‑Tools direkt.
  • Ein LLM‑Agent im Backend hat ebenso eine Aufgabenbeschreibung und einen Toolsatz und entscheidet selbst, welche tools er aufruft, wie viele Schritte er macht, wann er stoppt und welches Ergebnis er zurückgibt.

Im Kontext unseres GiftGenius kann das so aussehen:

  • App ohne Agent: Das Modell ruft direkt searchGifts auf, dann filterByBudget, dann getDetails – und denkt jedes Mal von vorn.
  • App mit Agent: ChatGPT ruft ein mcp‑tool auf, und das Backend stellt dem Agenten die Aufgabe: „Finde die Top‑5 Geschenke für ein bestimmtes Profil“. Der Agent macht mehrere Schritte: sammelt Zusatzinformationen, ruft verschiedene Search‑Tools auf, filtert, sortiert, baut finale Karten und gibt bereits eine fertig strukturierte Antwort zurück.

ChatGPT und ein LLM‑Agent im Backend sind wie ein Geschäftsführer und ein Mitarbeiter. ChatGPT hat viel mehr Freiheit: Er spricht mit dem Nutzer und entscheidet, welche strategischen Aufgaben gestartet werden (mcp‑tools aufrufen). Der LLM‑Agent arbeitet nur im Backend, interagiert nicht mit dem Nutzer, „denkt“ aber ebenfalls und kann eigene tool‑Aufrufe tätigen. Sozusagen ChatGPT in klein.

2. Woraus ein Agent besteht: LLM, Instruktionen, Tools und Zustand

Es ist hilfreich, sich den Agenten als mehrere Ebenen vorzustellen.

Erstens werkelt unter der Haube dieselbe LLM. Das kann GPT‑5.1 oder ein anderes Modell sein, das das Agents SDK verwendet. Sie generiert Text, plant Schritte, wählt Tools – kurz: sie übernimmt das „Denken“, nun aber in Ihrem Orchestrierungs‑Kontext.

Zweitens kommen auf das Modell die Instruktionen. Das ist der System‑Prompt des Agenten, der seine Rolle, Grenzen, den Kommunikationsstil und die Nutzung der Tools festlegt. Ähnliches haben Sie bereits für die ChatGPT App gemacht, jetzt gilt es für einen separaten Agenten.

Drittens gibt es den Satz der Agenten‑Tools. Das können sein:

  • Funktionen in TypeScript (klassisches Function Calling);
  • HTTP/REST‑Tools;
  • Wrapper um Ihre MCP‑Tools, damit der Agent in dasselbe Backend gehen kann wie die ChatGPT App;
  • eingebaute „hosted“ Tools von OpenAI selbst (z. B. Web‑Search, falls Sie sie aktivieren).

Und schließlich gibt es Regeln für Zustand und Schritte: wie der Session‑Zustand (session state) gespeichert wird, wie Zwischenergebnisse persistiert werden, wie Schleifen begrenzt werden. Ausführlicher sprechen wir darüber in der nächsten Vorlesung zu Speicher und Zustand, aber es ist bereits jetzt hilfreich, im Kopf zu behalten, dass ein Agent kein „Einmal‑Request“ ist, sondern potenziell ein langer Prozess mit Fortschrittsspeicherung.

Schauen Sie mit den Augen eines TypeScript‑Entwicklers darauf, ergibt sich gedanklich ein Objekt ungefähr dieser Art (Pseudocode, nahe am Agents SDK für TS):

const giftAgent = new Agent({
  model: "gpt-5.1",
  systemPrompt: giftAgentPrompt,
  tools: { searchGifts, filterGifts, checkoutDraft },
  // hier — Einstellungen für Speicher, Schrittlimits usw.
});

Wir vertiefen uns jetzt nicht in exakte APIs; wichtig ist das Bild: Modell, Instruktionen, Tools und Verhaltens‑Settings an einem Ort.

3. Nachrichtenrollen: system / user / assistant / tool in der Agentenwelt

Sie kennen bereits die klassischen Rollen system, user, assistant und tool aus Chat Completions. Im Agents SDK bleiben sie erhalten, bekommen aber einen etwas praktischeren Sinn.

Die Rolle system definiert Persönlichkeit und Mission des Agenten. Für den GiftGenius‑Agenten könnte das z. B. sein: „Du bist ein Agent für die Geschenkauswahl. Deine Aufgabe ist es, mit möglichst wenigen Schritten 3–7 relevante Geschenkoptionen auf Basis des Empfängerprofils und Budgets auszuwählen und anschließend ein strukturiertes JSON für das Widget vorzubereiten.“ Hier legen Sie auch Einschränkungen fest: was er nicht tun darf (z. B. keine echten Käufe ohne separaten Schritt) und wie mit Tools zu arbeiten ist.

Die Rolle user ist im Agenten‑Kontext nicht zwingend ein „echter Mensch“. Meist ist es die „Aufgabe“ für den Agenten: ein Ziel, das von Ihrer App, einem Dienst oder einem anderen Agenten formuliert wurde. Beispielsweise kann die ChatGPT App den Agenten mit einer user‑Nachricht aufrufen: „Stelle 5 Geschenkideen für einen Entwickler‑Kollegen zusammen, Budget 50 Dollar, Anlass – Geburtstag.“

Die Rolle assistant ist das, was das Modell selbst innerhalb des Agenten „sagt“. Hier können sowohl Zwischengedanken und Pläne als auch die finale Antwort stehen. Ihre Aufgabe ist es, den System‑Prompt so einzustellen, dass diese Nachrichten nützlich sind und bei Bedarf geloggt werden.

Die Rolle tool (oder ihre Entsprechungen im jeweiligen SDK) beschreibt die Ergebnisse von Tool‑Aufrufen: „über MCP wurden 50 Produkte gefunden“, „API gab einen Timeout‑Fehler zurück“, „DB lieferte das Nutzerprofil“. Diese Nachrichten bilden zusammen mit den assistant‑Nachrichten die History des Run‑Zyklus des Agenten.

Praktisch lässt sich das in einer kleinen Tabelle zusammenfassen:

Rolle Wer spricht Beispiel im GiftGenius‑Kontext
system
Sie (als Agent‑Entwickler) „Du bist ein Agent für die Geschenkauswahl …“
user
Externer Aufruf (App, anderer Agent) „Wähle 5 Geschenke bis 50 $ …“
assistant
Modell innerhalb des Agenten „Plan: 1) Details erfragen …“
tool
Ergebnis des aufgerufenen Tools „searchGifts gab 20 Varianten zurück …“

Diese Struktur ist wichtig, denn genau auf ihrer Basis wird der Run‑Zyklus aufgebaut – der Hauptdarsteller der heutigen Vorlesung.

4. Wie die LLM Funktionen in Ihrem Backend aufruft

Wenn man an den Modus „Frage–Antwort“ gewöhnt ist, scheint es, als arbeite die LLM nach einem einfachen Schema: Text kommt → Modell antwortet mit Text. Tatsächlich ist es unter der Haube etwas komplizierter – und genau deshalb funktioniert Function Calling.

Das Modell erhält nicht eine einzelne Frage, sondern eine Liste von Nachrichten – die Dialoghistorie. Dort liegen bereits alle vorherigen Beiträge: System‑Instruktionen („wer du bist und was erlaubt ist“), Ihre Nachrichten, frühere Modellantworten, Tool‑Ergebnisse. In jedem Schritt betrachtet das Modell die gesamte Chronik wie ein Chat‑Log und entscheidet: „Welche nächste Nachricht muss ans Ende angehängt werden?“

Das ist der Kern: Eine LLM macht immer einen Schritt – sie hängt die nächste Nachricht ans Ende der Historie. Sie „ändert nicht die Vergangenheit“ und bearbeitet keine alten Nachrichten, sondern setzt die Liste fort. Sie schreiben eine Frage, das Modell antwortet. Sie fügen die zweite Frage hinzu, das Modell antwortet wieder – aber unter Berücksichtigung der gesamten Dialoghistorie (aller Nachrichten).

Function Calling funktioniert auf demselben Prinzip. Anstatt eine Funktion direkt „zu starten“, macht das Modell Folgendes:

  • es sieht die Liste der verfügbaren Tools/tools und deren Beschreibungen zusammen mit der Dialoghistorie;
  • es entscheidet: „Jetzt ist es sinnvoller, nicht nur textuell zu antworten, sondern zuerst ein bestimmtes Tool aufzurufen“;
  • und es schreibt als nächste Nachricht nicht eine normale Textantwort, sondern eine spezielle Nachricht vom Format „ich möchte dieses tool mit diesen Parametern aufrufen“.

Danach liest nicht das Modell, sondern Ihr Backend diese neue Nachricht am Ende der Historie, erkennt, dass es sich um einen Funktionsaufruf handelt, und ruft das gewünschte Tool auf. Anschließend fügt es der Historie eine weitere Nachricht – mit dem Tool‑Ergebnis – hinzu und sendet die vollständige Nachrichtenliste erneut an das Modell. Das Modell betrachtet die komplette Chronik erneut und hängt den nächsten Schritt an: entweder einen weiteren Aufruf oder bereits die finale, menschenlesbare Antwort.

Das heißt:

  • für normales Q&A: „nächste Nachricht“ = Textantwort;
  • für Function Calling: „nächste Nachricht“ = Anweisung, eine Funktion aufzurufen oder Antwort nach Nutzung der Funktion.

Es gibt keinen separaten magischen „Befehl zum Funktionsaufruf“ – es ist einfach eine besondere Art der nächsten Nachricht, die das Modell ans Ende der Kette anhängt.

Das Modell ruft die Funktionen Ihres Backends nicht über ein öffentliches API auf. Es „schreibt einfach in den Chat“, dass es eine Funktion mit Parametern aufrufen möchte. Und Ihr Backend ruft die lokale Funktion auf und hängt deren Antwort wieder in den Chat. Und alles beginnt von vorn.

5. Run‑Zyklus des Agenten: wie er Schritt für Schritt „denkt“

Ein LLM‑Agent ist faktisch ein Objekt/Algorithmus auf Ihrem Server, der den agentenspezifischen Run‑Zyklus startet – ein erweiterter Zyklus „Frage → nachdenken → ggf. eine Aktion ausführen → erneut nachdenken → … → finale Antwort“. In der OpenAI‑Dokumentation nennt man das teils agent loop oder ReAct‑Pattern (Reason + Act + Observe).

Konzeptionell sieht ein Run des Agenten so aus:

  1. Der Agent erhält Input: System‑Instruktionen, Aufgabe (user‑Nachricht), eventuell den aktuellen Zustand.
  2. Das Modell generiert einen Schritt: entweder eine Textantwort oder Pläne sowie die Entscheidung, ein oder mehrere Tools aufzurufen.
  3. Wenn das Modell einen Tool‑Call wählt, ruft der Agent das entsprechende Tool im Code auf (das kann eine lokale Funktion, ein MCP‑Tool, ein HTTP‑Request, ein DB‑Zugriff usw. sein).
  4. Die Tool‑Ergebnisse werden als tool‑Nachrichten in der Historie abgelegt.
  5. Der Zyklus kehrt mit neuem Kontext zum Modell zurück. Das Modell entscheidet, wie es weitergeht: weiter planen, ein anderes Tool aufrufen oder die Aufgabe mit einer finalen Antwort abschließen.
  6. Wenn das Modell den Run explizit oder gemäß Stop‑Bedingungen beendet, gibt der Agent das finale Ergebnis an die aufrufende Seite zurück.

Als kleine Diagramm‑Darstellung:

flowchart TD
    A[Start des Runs: Ziel + system] --> B[Modellaufruf]
    B --> C{Will das Modell
textuell antworten
oder ein Tool aufrufen?} C --> D["Textantwort
(assistant)"] D --> E{Aufgabe abgeschlossen?} E -->|Ja| F[Endergebnis] E -->|Nein| B C --> G["Tool‑Call
(Aufrufbeschreibung)"] G --> H[Funktions-/MCP-/HTTP‑Aufruf] H --> I["Tool‑Ergebnis
(tool message)"] I --> B

Übersetzt in vereinfachten TypeScript‑Pseudocode (weit vom echten API entfernt, aber logisch korrekt) ergibt sich in etwa:

async function runAgent(goal: string) {
  let context = buildInitialContext(goal);

  while (!isFinished(context)) {
    const decision = await callLLM(context); // Agentenschritt

    if (decision.type === "tool_call") {		// Funktion aufrufen?
      const toolResult = await callTool(decision.tool, decision.args);	// lokale Funktion aufrufen
      context = appendToolResult(context, toolResult);		// Ergebnis ans Ende der Liste anhängen
    } else {
      context = appendAssistantMessage(context, decision.message); 
    }

    enforceLimits(context); // Limits für Schritte/Zeit/Schleifen
  }

  return extractFinalResult(context);
}

Das Agents SDK nimmt Ihnen den Großteil dieser Routine ab: Speicherung der Historie, Marshalling der Tool‑Calls, Logik für Wiederholungen usw. Sie konfigurieren und implementieren die Tools.

Run vs. Step

Wichtig ist die Unterscheidung zweier Begriffe:

  • run – ein Agenten‑Start für ein bestimmtes Ziel: „Wähle Geschenke für diesen Anlass aus“;
  • step – ein Schritt des Run‑Zyklus: konkreter Modellaufruf, der zu einer Textantwort oder zu einem Tool‑Call führen kann.

Im Monitoring sehen Sie viele Steps innerhalb eines Runs; Sicherheits‑ und Kostenlimits werden häufig entweder „pro Run“ oder „pro Step“ gesetzt.

Jetzt, da klar ist, wie ein Agent innerhalb eines Runs lebt und im Run‑Zyklus Schritt für Schritt vorgeht, schauen wir, wo das Ganze wirklich sinnvoll ist – und wo einfache Tools genügen.

5. Wo in GiftGenius ein Agent sinnvoll ist und wo er überflüssig ist

Bevor Sie anfangen, überall Agenten zu schreiben, stellen Sie sich ehrlich die Frage: „Wird hier überhaupt ein Agent benötigt?“

Ein guter Anwendungsfall für einen Agenten ist eine mehrstufige Aufgabe mit Verzweigungen, Wiederholungen und Logik, die man ungern nur in Prompts kapselt.

In GiftGenius könnte dies ein „Assistent/Wizard für die intelligente Geschenkeauswahl“ sein, der:

  • wichtige Details nachfragt (Geschlecht des Empfängers, Hobbys, Beziehungsgrad);
  • mehrere Quellen für Produkte nutzt (verschiedene Vendoren über MCP‑Tools);
  • Ergebnisse filtert und rangiert;
  • bei Fehlern der Quellen erneut versucht oder einen Fallback‑Pfad nimmt;
  • nicht nur eine Textliste, sondern eine strukturierte Kandidatenliste mit Erklärungen und Links zu SKUs aus dem Product Feed zurückgibt.

Hier ist der Agent als „Orchestrator“ wirklich hilfreich – insbesondere, wenn Sie später Voice/Realtime‑Szenarien oder komplexe Commerce‑Fälle (ACP) ergänzen möchten.

Für einen einfachen Aufruf getGiftDetails(giftId) brauchen Sie hingegen keinen Agenten: Ein normales MCP‑Tool, direkt aus ChatGPT aufgerufen, deckt den Use Case vollständig ab. Gleiches gilt für banale „einstufige“ Szenarien wie „beschreibe dieses Geschenk anhand des Textes der Produktkarte“.

Die generelle Faustregel: Wenn sich das Szenario als „ein normales Tool“ beschreiben lässt – ist ein Agent wahrscheinlich nicht nötig. Beginnen Sie jedoch, einen explizit mehrstufigen Workflow mit Prüfungen und Wiederholungen zu skizzieren, wird ein Agent mit hoher Wahrscheinlichkeit Freude bereiten.

6. Determinismus: wie Sie das Verhalten des Agenten vorhersagbarer machen

Determinismus in der Welt der LLM‑Agenten ist tricky. Theoretisch möchten Sie bei gleichem Input und gleichen Einstellungen denselben Aktionsplan und dieselbe Sequenz von Tool‑Calls erhalten. In der Praxis bleibt das Modell stochastisch, aber Sie haben mehrere Stellschrauben für Vorhersagbarkeit.

Erstens die Klassiker: Temperatur und weitere Generierungsparameter. Je niedriger die Temperatur, desto weniger Kreativität und desto mehr „Gehorsam“. Für einen Agenten zur Geschenkeauswahl möchten Sie vermutlich kein Null‑Niveau, aber auch nicht zu viel Freiheit – sonst erfindet das Modell jeden Morgen eine neue Art, dasselbe Tool aufzurufen.

Zweitens klare System‑Instruktionen. Wenn Sie das Verhalten vage beschreiben wie „du kannst unterschiedliche Tools aufrufen und tun, was du willst“, wundern Sie sich nicht, wenn der Agent mal quer durchs API springt und mal „aus der Luft“ antworten will. Besser ist es, explizit festzulegen, wann genau welches Tool aufzurufen ist, welche Parameter zulässig sind, wie Fehler zu interpretieren sind und in welchen Fällen die Aufgabe zu beenden ist.

Beispielsweise kann der System‑Prompt für den GiftGenius‑Agenten folgenden Abschnitt enthalten:

Wenn dir das vollständige Profil des Empfängers (Alter, Geschlecht, Anlass, grobes Budget) fehlt,
stelle zuerst Rückfragen über den User-Facing-Kanal und warte auf Antworten.
Erst danach rufe das Tool search_gifts mit ausgefülltem Profil auf.
Erfinde keine Produkte aus der Luft, stütze dich stets auf die Ergebnisse der Tools.

Solche Vorgaben reduzieren die Varianz der Entscheidungen und machen das Verhalten deterministischer.

Drittens das Design der Tools. Wenn Sie drei Tools haben, die „so ungefähr dasselbe“ Geschenke suchen, wird das Modell unvermeidlich mal dieses, mal jenes wählen. Besser sind Tools mit klar abgegrenzten Zuständigkeiten – und entsprechende Beschreibungen.

Schließlich können Sie Guardrails verwenden – Regeln und Schemata, die die Aktionen des Agenten und die Modell‑Ergebnisse prüfen. Im Agents SDK gibt es eingebaute Unterstützung für Checks und Constraints, auch für die Struktur der Ausgabedaten. Wenn das Modell versucht, etwas nicht Schema‑konformes zu erzeugen, können Sie es sanft korrigieren oder den Schritt sogar wiederholen lassen.

Mini‑Beispiel: Ausgabeformat festzurren

Angenommen, der Agent soll immer JSON mit dem Feld gifts zurückgeben, und darin Objekte mit id, title und score. Sie können:

  • dieses Schema auf Agentenebene beschreiben;
  • angeben, dass der finale Output dem Schema entsprechen muss;
  • bei Verstößen – den Schritt wiederholen oder einen sicheren Fehler zurückgeben.

Pseudocode:

const giftResultSchema = z.object({
  gifts: z.array(z.object({
    id: z.string(),
    title: z.string(),
    score: z.number().min(0).max(1),
  }))
});

// In der Agenten-Konfiguration
const agent = new Agent({
  /* ... */
  outputSchema: giftResultSchema,
});

Wenn das Modell versucht, etwas Merkwürdiges zurückzugeben, meldet der Runner einen Validierungsfehler, und Sie können das Modell entweder neu fragen oder den Vorfall loggen.

7. Idempotenz: warum Ihr Agent Ihre API zweimal aufrufen kann

Wenn Determinismus „derselbe Plan bei denselben Eingaben“ bedeutet, dann steht Idempotenz für Sicherheit bei Wiederholungen. Im Agenten‑Kontext ist sie aus zwei Gründen kritisch.

Erstens kommt eine weitere Retry‑Ebene hinzu: nicht nur HTTP‑Clients und Load‑Balancer, sondern auch der Agent selbst kann entscheiden, einen Tool‑Aufruf zu wiederholen, falls er einen Fehler oder ein unvollständiges Ergebnis erhalten hat. Zweitens kommen in realen Produktionsszenarien Webhooks, Queues, Streaming‑Kanäle hinzu – und Sie können versehentlich denselben logischen Schritt mehrfach verarbeiten.

Über Idempotenz auf Ebene der MCP‑Tools haben Sie bereits gesprochen: keine doppelten Zahlungen, keine doppelte Auftragserstellung, Idempotenz‑Schlüssel in Requests. Jetzt gilt dasselbe – potenziert durch die Mehrschritt‑Natur des Agenten.

Stellen wir uns vor, in GiftGenius gibt es ein Tool create_checkout_session, das aus einer Liste gewählter Geschenke einen Draft‑Checkout in ACP/Stripe anlegt. Wenn der Agent diesen Aufruf wegen eines Netzwerkfehlers wiederholt, möchten Sie auf gar keinen Fall zwei getrennte Bestellungen und zwei Abbuchungen.

Also sollten Sie:

  • für jede logische Aktion einen externen idempotency key definieren (z. B. runId + stepIndex oder explizit generierte checkoutDraftId);
  • ihn an Ihr Backend/ACP‑Endpoint übergeben;
  • auf der Backend‑Seite prüfen, ob Sie diesen Schlüssel bereits verarbeitet haben, und statt einer erneuten Ausführung das gespeicherte Ergebnis zurückgeben.

Pseudobeispiel in TypeScript:

async function createCheckoutDraft(runId: string, payload: DraftPayload) {
  const key = `gift-checkout-${runId}`;

  const existing = await findDraftByKey(key);
  if (existing) return existing;

  const draft = await stripe.checkout.sessions.create({
    /* ... */,
    idempotencyKey: key, // oder eine eigene Schicht darüber
  });

  await saveDraftWithKey(key, draft);
  return draft;
}

Selbst wenn der Agent dieses Tool aus irgendeinem Grund zweimal mit derselben runId aufruft, bleibt Ihr Code idempotent: derselbe logische Schritt → dasselbe faktische Ergebnis.

„Erst prüfen, dann handeln“

Ein weiteres verbreitetes Idempotenz‑Muster: erst den Zustand prüfen, dann handeln. Bevor Sie beispielsweise einen Auftrag anlegen, prüfen Sie, ob es bereits einen Auftrag mit derselben clientReferenceId oder demselben Parametersatz gibt. Das ist besonders praktisch in langen Workflows, in denen der Agent „vergessen“ kann, was er im vorherigen Schritt bereits getan hat.

Safe‑Mode/Fake‑Mode

In der Entwicklungsphase ist ein „Sicherheitsmodus“ für gefährliche Tools hilfreich: Statt echter Aktionen loggen sie nur, was getan worden wäre, und liefern ein Pseudoergebnis zurück. Für Agenten ist das ein bequemer Weg, den Run‑Zyklus in produktionsnaher Umgebung durchzuspielen, ohne Geld oder Daten zu riskieren.

8. Mini‑Praxis: den GiftGenius‑Agenten in natürlicher Sprache beschreiben

Wir haben bereits über den Run‑Zyklus, Determinismus und Idempotenz der Tools gesprochen. Lassen Sie uns kurz vom Code lösen und prüfen, wie sich das in einem realen Szenario zusammensetzt.

Jetzt ist eine kleine Übung auf Papier (oder im Kopf) nützlich – ganz ohne Code.

Stellen Sie sich vor, Sie beschreiben einen einfachen Agenten:

  • system
    : Du bist ein Assistent für die Geschenkauswahl; du fragst wichtige Details immer nach, erfindest keine Produkte aus der Luft und nutzt ausschließlich die Ergebnisse der Tools.
  • user
    : Ich möchte ein Geschenk für einen Kollegen bis 50 $.

Beschreiben Sie in Worten, welche Schritte ein solcher Agent machen sollte.

Ein typisches Szenario könnte so aussehen.

  1. Zuerst prüft der Agent, ob die Informationen ausreichen. Falls nicht, stellt er Rückfragen: Womit beschäftigt sich der Kollege ungefähr (Designer, Entwickler, Manager)? Gibt es Tabus (Alkohol, scherzhafte Geschenke)? Gibt es Lieferbeschränkungen? Die Antworten landen entweder im Session‑State oder in den Parametern des Tool‑Aufrufs.
  2. Dann ruft der Agent das Tool search_gifts mit ausgefülltem Profil auf: „Kollege‑Entwickler, Budget 50 $, Kategorie – Gadgets und Office“. Das Tool liefert eine Kandidatenliste mit Preisen, Kategorien und Produkt‑IDs.
  3. Anschließend kann der Agent ein zusätzliches Tool filter_gifts_by_constraints aufrufen, wenn sich herausstellt, dass ein Teil der Produkte nicht in die gewünschte Region geliefert werden kann, oder er filtert in seinem Prompt. Danach sortiert er die Varianten nach Relevanz und Preis und ergänzt ggf. eigene Hinweise („geeignet, wenn der Kollege Kaffee liebt“, „gute Option für Remote‑Work“).
  4. Schließlich bereitet der Agent die finale strukturierte Antwort für die ChatGPT App vor: eine Liste von 5–7 Geschenken mit kurzen Beschreibungen, Nutzungshinweisen und Links zum Checkout (oder zum nächsten Schritt – dem Erstellen eines Draft‑Checkouts).

Wo sind hier Tool‑Calls nötig? Offensichtlich bei der Suche und Filterung von Produkten, bei der Verfügbarkeitsprüfung und beim Erstellen des Draft‑Checkouts. Welche Schritte müssen idempotent sein? In erster Linie alle Vorgänge rund um Bestellungen und Geld – das Erstellen eines Draft‑Checkouts, ggf. das Schreiben der Historie in die DB.

9. Typische Fehler bei den ersten Schritten mit Agenten

Fehler Nr. 1: den Agenten als „zweites ChatGPT ohne Grenzen“ verwenden.
Manchmal möchte man dem Modell einfach noch einen Prompt geben und es „Agent“ nennen. Heraus kommt etwas, das viel Text generiert, Tools chaotisch aufruft und schwer zu kontrollieren ist. Um das zu vermeiden, beschreiben Sie die Rolle des Agenten im system klar, begrenzen Sie die Tool‑Liste und denken Sie von vornherein an einen Orchestrator mit konkreter Mission – nicht an ein „zweites Text‑Universum“.

Fehler Nr. 2: fehlende Idempotenz in den Tools.
Entwickler portieren ihre alten HTTP‑Handler oft „as is“ unter einen Agenten, ohne zu berücksichtigen, dass der Runner nun Aufrufe automatisch wiederholen kann. Bei Zahlungen und Bestellungen kann das sehr unangenehme Folgen haben. Der richtige Ansatz: Tools sofort so entwerfen, dass ein erneuter Aufruf mit demselben logischen Schlüssel nicht zu einer erneuten Aktion führt.

Fehler Nr. 3: zu kreative Modell‑Settings.
Hohe Temperatur eignet sich großartig für Trinksprüche und Gedichte, aber für einen Agenten, der mehrstufige Prozesse zuverlässig orchestrieren soll, führt das zu unvorhersehbarem Verhalten: Das Modell wählt jedes Mal andere Tools, erzeugt abweichende Pläne und vergisst gelegentlich sogar, dass es Tools gibt. Behandeln Sie Agenten als „dienstliche“ Entitäten und halten Sie sie strenger.

Fehler Nr. 4: ein Tool „für alle Fälle“.
Manchmal möchte man ein universelles Tool wie execute_any_sql oder do_anything_with_orders bauen und es dem Agenten in die Hand geben. In Kombination mit LLM‑Kreativität ist das nahezu garantiert ein Sicherheitsrisiko. Besser mehrere spezialisierte Tools mit klaren Verträgen und Rechten als ein „göttliches“ mit Vollzugriff auf alles.

Fehler Nr. 5: keine expliziten Kriterien für das Ende eines Runs.
Wenn Sie dem Agenten nicht erklären, wann er stoppen soll, kann er in (halb‑)endlose Schleifen verfallen: Ergebnisse nochmal prüfen, den Nutzer nochmal nachfragen, bei demselben Fehler das Tool nochmal aufrufen. Oft zeigt sich das erst unter Last, wenn eine Abhängigkeit instabil ist. Setzen Sie Limits für die Anzahl der Schritte, die Run‑Zeit und die Anzahl der Wiederholungen bei identischem Fehler und beschreiben Sie im system, dass der Agent „ehrlich aufgeben“ soll, wenn vernünftige Optionen ausgeschöpft sind.

Fehler Nr. 6: alles und sofort im Agenten‑Zustand speichern.
Da das Agents SDK den Umgang mit dem Session‑State vereinfacht, ist die Versuchung groß, dort alles zu sammeln: große Dokumente, Roh‑Logs, sensible Daten. Das bläht den Kontext auf, erhöht die Kosten und schafft Sicherheitsrisiken. Der Zustand des Agenten sollte nur enthalten, was wirklich für die Fortsetzung nötig ist; alles andere gehört in DB, Logs und weitere Schichten – jeweils mit Blick auf Privatsphäre.

Fehler Nr. 7: den Agenten dort einsetzen, wo ein einfaches MCP‑Tool genügt.
Manchmal starten Entwickler mit einem Agenten, obwohl die Aufgabe nur darin besteht, eine Funktion aufzurufen und das Ergebnis zurückzugeben. Das fügt unnötige Komplexität hinzu: Run‑Zyklus, Zustand, zusätzliche Logs und mögliche Fehlerpunkte. Wenn das Szenario in einen einzigen Tool‑Call ohne komplexen Workflow passt, lassen Sie es so – und schalten Sie einen Agenten erst dazu, wenn echte Mehrschrittigkeit entsteht.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION