CodeGym /Kurse /ChatGPT Apps /Von Anweisungen zum Design von Tools und Metadaten: Disco...

Von Anweisungen zum Design von Tools und Metadaten: Discovery und Routing

ChatGPT Apps
Level 5 , Lektion 4
Verfügbar

1. Warum Anweisungen ohne gute Tools und Metadaten nicht ausreichen

Wichtig ist eine unbequeme Wahrheit festzuhalten: Das Modell sieht euren Code nicht. Es weiß nicht, welche Controller ihr in Next.js habt, welche Funktionen in TypeScript existieren und welche tollen Heuristiken ihr im Empfehlungssystem gesammelt habt.

Es sieht eure App über einige Schnittstellen:

  1. System‑prompt (rollenbasierter Vertrag).
  2. Tool‑Beschreibungen: Name, description, inputSchema, outputSchema, Annotationen usw.
  3. Metadaten der App selbst: Name, Icon, kurze und lange Beschreibung, Kategorien, Conversation Starters usw.

Bei der Verarbeitung einer Anfrage schaut das Modell auf den Dialogkontext und diese Metadaten, um zu entscheiden:

  • ob überhaupt irgendeine App vorgeschlagen werden soll;
  • wenn ja — welche genau von den verfügbaren;
  • und wenn die App gewählt ist — welches Tool dieser App zur aktuellen Anfrage passt.

Im letzten Teil von Modul 5 haben wir uns damit beschäftigt, was man dem Modell „in Worten erzählen“ kann — system‑prompt und UX‑Anweisungen. Jetzt gehen wir zu dem über, was es außer Text noch sieht: Tools und Metadaten.

Deshalb ist die Aufgabe in Modul 5 eigentlich zweigeteilt. Zuerst formuliert ihr im system‑prompt, „was diese App tun soll und wie sie sich verhalten soll“, und dann verpackt ihr es im Tool‑ und Metadaten‑Design in eine Form, die das Modell wirklich nutzen kann — unter anderem für Discovery und Routing.

Man kann es so formulieren: Der system‑prompt ist die Verfassung, und Tools und Metadaten sind die Gesetze und die ganze Bürokratie darum herum: Antragsformulare, Datenbankschemata usw. Wenn man sich nur auf die Verfassung beschränkt, kommt man nicht weit.

2. Dekomposition: „eine Aufgabe — ein Tool“, aber mit Augenmaß

Fangen wir mit dem Schmerzpunkt an: Wie viele Tools baut man überhaupt und wie schneidet man sie zu?

Intuitives Prinzip: Ein Tool — eine verständliche Aufgabe. Das erleichtert dem Modell die Wahl erheblich: Es hat nicht eine monströse Funktion do_everything, sondern mehrere saubere Aktionen mit guten Namen.

Für GiftGenius könnten wir solche Basistools haben:

  • profile_to_segments — eine freie Beschreibung des Empfängers (Alter, Interessen, Beziehung, Kontext) in normalisierte Segmente wie "tech", "fitness", "gamer" umwandeln.
  • recommend_gifts — eine Liste von Geschenk‑IDs anhand von Segmenten, Budget, Locale und Anlass zusammenstellen.
  • get_gift — die vollständige Karte eines gewählten Geschenks (Beschreibung, Medien, SKU/Varianten) per ID abrufen.
  • (optional) similar_gifts — zu einem gewählten Geschenk noch 3–5 ähnliche Varianten vorschlagen.

Theoretisch könnte man ein einziges gift_tool mit dem Parameter mode: "profile_to_segments" | "recommend" | "details" | "similar" machen, aber damit macht ihr es euch und dem Modell schwerer: Die Beschreibung wird zur Textwand, das inputSchema bläht sich auf und bei der Tool‑Wahl hat das Modell weniger klare Anker.

Anti‑Pattern: God Tool

Stellt euch folgendes Schema vor:

server.registerTool(
  "gift_tool",
  {
    description: "Verschiedene Operationen mit Geschenken.",
    inputSchema: { /* 50 Felder und Flags */ },
  },
  async ({ input }) => { /* riesiger switch über mode */ }
);

Im Kopf des Modells sieht das aus wie „es gibt irgendein abstraktes Tool für Geschenke, den Rest finden wir schon heraus“. Das verschlechtert die Auswahlgenauigkeit, behindert Discovery und erschwert euch die Wartung.

Aber in die andere Extreme zu verfallen — 50 mikroskopische Tools für jeden Kleinkram — ist auch schlecht. Jedes zusätzliche Tool landet im Kontext, belastet die Aufmerksamkeit des Modells und erhöht das Fehlerrisiko beim Routing. Die Dokumentation warnt ausdrücklich: Zu viele Kleintools bedeuten Qualitätsverlust, besonders wenn sich ihre Beschreibungen überschneiden.

Praktische Faustregel:

  • alles, was der Nutzer als einen „Schritt“ im Szenario wahrnimmt (z. B. die erste Auswahl von Geschenken anhand eines Profils), ist ein guter Kandidat für ein eigenes Tool;
  • was strikt innerhalb dieses Schritts ausgeführt wird und keinen eigenständigen Sinn hat (z. B. Scoring berechnen oder das Betrachten von Karten protokollieren), bleibt besser innerhalb der Tool‑Implementierung.

Angenommen, ihr habt eure Szenarien nach diesem Prinzip bereits in 2–4 Tools geschnitten. Dann stellt sich die wichtige Frage — wie die Eingaben dieser Tools so zu beschreiben sind, dass das Modell sie ohne Rätselraten nutzen kann. Damit fangen wir an.

3. Use‑Cases auf das Input Schema projizieren

Nehmen wir nun einen konkreten Use‑Case und schauen ehrlich, welche Daten das Tool wirklich braucht.

Szenario: „Schenker unter Zeitdruck: 5–7 Ideen für einen 25‑jährigen Freund finden, liebt Fußball und Brettspiele, Budget bis 50 $“.

Aus Jobs‑to‑be‑Done ist klar, dass die Aufgabe des Empfehlungskerns von GiftGenius darin besteht, die Auswahl auf eine kleine Liste einzugrenzen und die Unsicherheit „was, wenn ich Mist auswähle“ zu reduzieren. Auf Chatebene braucht der Assistent:

  • Basisinfos über den Empfänger (Alter, Geschlecht, Beziehung zum Schenker);
  • Interessen/Hobbys;
  • Budget und Währung;
  • Anlass (Geburtstag, Jubiläum, Neujahr usw.);
  • optional — Land/Stadt zur Filterung nach Versand.

In der GiftGenius‑Architektur ist das in zwei Schritte zerlegt:

  1. profile_to_segments(input) nimmt „Rohdaten“ (Alter, Interessen, Textbeschreibung) und transformiert sie in normalisierte Segmente, mit denen man weiter bequem arbeitet.
  2. recommend_gifts(segments, budget, locale, occasion) wählt anhand der Segmente und des Budgets konkrete Geschenk‑IDs aus dem Katalog aus.

Aus Sicht des ChatGPT ↔ MCP‑Vertrags ist dabei der zweite Schritt — das Schema von recommend_gifts — wichtig, denn dieses Tool wird in den meisten Auswahl‑Szenarien verwendet.

Dabei muss man nicht sofort alles vom Nutzer verlangen: Das Modell kann Teile per Follow‑up nachfragen („und wie hoch ist ungefähr das Budget?“). Das heißt, einige Felder im Profil können optional sein; aber wenn wir bei recommend_gifts ankommen, sollte es bereits einen normalisierten Parametersatz haben.

Beispiel: TypeScript + JSON Schema für recommend_gifts

Im MCP‑Server auf TypeScript kann das so aussehen:

// apps/mcp/server.ts
import { McpServer } from "@openai/mcp-server";

const server = new McpServer();

server.registerTool(
  "recommend_gifts",
  {
    title: "Geschenkempfehlungen",
    description:
      "Verwende dieses Tool, wenn du Geschenke anhand von Empfängersegmenten, Budget, Locale und Anlass auswählen sollst.",
    inputSchema: {
      type: "object",
      properties: {
        segments: {
          type: "array",
          description:
            "Liste der Empfängersegmente, z. B. ['tech', 'football_fan']. Stammt gewöhnlich aus profile_to_segments.",
          items: { type: "string" },
          minItems: 1
        },
        budget: {
          type: "object",
          description:
            "Budgetspanne für das Geschenk in der Währung des Nutzers (Minimum/Maximum).",
          properties: {
            min: {
              type: "number",
              minimum: 0,
              description: "Mindestbetrag, den der Nutzer ausgeben möchte."
            },
            max: {
              type: "number",
              minimum: 0,
              description: "Höchstbetrag, den der Nutzer ausgeben möchte."
            },
            currency: {
              type: "string",
              minLength: 3,
              maxLength: 3,
              description: "Dreistelliger Währungscode (z. B. USD, EUR, RUB)."
            }
          },
          required: ["min", "max", "currency"]
        },
        locale: {
          type: "string",
          description:
            "Benutzerlokale im BCP‑47‑Format (z. B. 'ru-RU' oder 'en-US')."
        },
        occasion: {
          type: "string",
          description:
            "Anlass für das Geschenk, z. B. 'birthday', 'new_year', 'anniversary'."
        }
      },
      required: ["segments", "budget", "locale", "occasion"]
    }
  },
  async ({ input }) => {
    // Wir machen es hier noch nicht schlau, sondern liefern einen Stub zurück
    return {
      content: [
        {
          type: "text",
          text: `Ich wähle Geschenke nach Segmenten ${input.segments?.join(
            ", "
          )} im Budget ${input.budget?.min}–${input.budget?.max} ${input.budget?.currency} aus...`
        }
      ],
      structuredContent: {}
    };
  }
);

Beachtet ein paar Punkte.

Erstens nutzen wir enum‑ähnliche Einschränkungen und verständliche Beschreibungen. Selbst wenn es formal nur Strings sind, deutet description dem Modell an, welche Werte erwartet werden — das erhöht deutlich die Chance, dass es die Argumente korrekt ausfüllt. Anstelle eines vagen Strings "anlass": "irgendetwas wie geburtstag" haben wir eine saubere occasion: "birthday".

Zweitens werden die Feldbeschreibungen nicht „für Teamkollegen“ geschrieben, sondern buchstäblich als Hinweise für das Modell: Was ist das Feld, welche typischen Werte, gibt es ein Beispiel. Die Autoren der Apps‑SDK‑Dokumentation empfehlen ausdrücklich, für jeden Parameter verständliche Beschreibungen und Beispiele hinzuzufügen.

Was im Input‑Schema nichts zu suchen hat

Typische „parasitär“ wirkende Felder, die man dort oft hineinzustopfen versucht:

  • interne IDs (tenantId, internalSegment), die ihr ohnehin auf dem Server hinzufügen könnt;
  • Dinge, die das Modell unmöglich wissen kann (z. B. deploymentRegion) — das ist eure Verantwortung;
  • Duplikate der Chat‑Historie (z. B. userPrompt): Das Modell sieht die Ursprungsnachricht ohnehin, zwingt es nicht zum Copy‑Paste.

Das Input Schema ist genau das, was das Modell ableiten und ausfüllen soll — kein Sammelbecken für alles.

4. Output Schema: nicht nur Daten, sondern auch Bedeutung

Im Apps SDK kommt das Tool‑Ergebnis als Nachricht mit role: tool zurück in den Dialog. Danach entscheidet das Modell, was damit zu tun ist: wie die Antwort zu formulieren ist, welche Follow‑ups zu stellen sind, ob ein Widget geöffnet werden soll usw. Daher ist das Design des Output‑Schemas nicht weniger wichtig als das des Inputs.

Es gibt zwei Ansätze.

Variante „Rohdaten“ sieht so aus:

{
  "items": [
    { "id": "GIFT_1" },
    { "id": "GIFT_2" }
  ]
}

Das Modell sieht nur eine Liste von IDs, ohne zu verstehen, warum diese Varianten überhaupt hier sind, wie viele Kandidaten es gab und welche die besten sind. Es kann sich etwas ausdenken, aber die Wahrscheinlichkeit für Seltsamkeiten ist höher.

Semantisch reichere Variante:

{
  "items": [
    {
      "id": "GIFT_1",
      "score": 0.92,
      "reason": "Hohe Übereinstimmung mit dem Segment 'football_fan' und liegt im Budget."
    },
    {
      "id": "GIFT_2",
      "score": 0.81,
      "reason": "Passt für Brettspiel-Fans, liegt nahe an der oberen Budgetgrenze."
    }
  ],
  "meta": {
    "totalCandidates": 27,
    "returned": 5,
    "segmentsUsed": ["football_fan", "board_games"],
    "budget": { "min": 20, "max": 50, "currency": "USD" },
    "advice": "Am besten mit Varianten mit dem höchsten Score und nachvollziehbarer Begründung starten."
  }
}

Jetzt kann das Modell ehrlich erklären, warum genau diese Geschenke vorgeschlagen werden, und Follow‑ups aufbauen: „Ich habe 27 Varianten gefunden, zeige 5 der besten, und das sind die Gründe.“

Beispiel: Output Schema für recommend_gifts beschreiben

Wir fügen in die Tool‑Beschreibung ein Ergebnisschema hinzu (selbst wenn es technisch nicht zwingend ist — es ist Teil des Vertrags mit dem Modell):

const recommendGiftsOutputSchema = {
  type: "object",
  properties: {
    items: {
      type: "array",
      items: {
        type: "object",
        properties: {
          id: { type: "string", description: "Geschenk-ID im Katalog." },
          score: {
            type: "number",
            description: "Match-Score zum Profil (0..1)."
          },
          reason: {
            type: "string",
            description:
              "Kurze Begründung, warum das Geschenk passt (kann im Backend generiert werden)."
          }
        },
        required: ["id", "score"]
      },
      description: "Liste empfohlener Geschenke mit Relevanzbewertung."
    },
    meta: {
      type: "object",
      properties: {
        totalCandidates: {
          type: "integer",
          description: "Wie viele Kandidaten im Katalog gefunden wurden."
        },
        returned: {
          type: "integer",
          description: "Wie viele Geschenke dieser Aufruf zurückgab."
        },
        advice: {
          type: "string",
          description:
            "Allgemeine Empfehlung: z. B. mit welcher Art von Geschenken man beginnen sollte."
        }
      }
    }
  },
  required: ["items"]
};

Und wir verwenden dieses Schema in der Implementierung:

server.registerTool(
  "recommend_gifts",
  {
    title: "Geschenkempfehlungen",
    description:
      "Verwende dies, wenn du 3–7 Geschenke anhand von Segmenten und Budget auswählen sollst. Gibt Geschenk-IDs und Match-Scores zurück; detaillierte Karten erhältst du über get_gift.",
    inputSchema: /* wie oben */,
    // outputSchema wird nicht immer formal angegeben, ist aber für die Dokumentation hilfreich:
    // outputSchema: recommendGiftsOutputSchema
  },
  async ({ input }) => {
    const recommendations = await recommendFromCatalog(input); // unsere Business-Logik

    return {
      content: [
        {
          type: "text",
          text: `Ich habe ${recommendations.items.length} passende Ideen gefunden. Ich zeige jetzt die besten.`
        }
      ],
      structuredContent: {
        items: recommendations.items,
        meta: {
          totalCandidates: recommendations.meta.totalCandidates,
          returned: recommendations.items.length,
          advice: recommendations.meta.advice
        }
      }
    };
  }
);

Wir tun zwei Dinge: Wir geben dem Modell minimalen Text für den Nutzer und legen gleichzeitig semantisches JSON ab, anhand dessen es den Dialog und Follow‑ups weiterführen kann.

Dabei zieht get_gift die vollständigen Karten (Name, Medien, SKU usw.) per ID nach, und das GiftGenius‑Widget rendert sie als Geschenk‑Karten.

5. Benennung und Beschreibungen der Tools als Grundlage für Discovery

Jetzt zum spannendsten Teil: wie Namen und Beschreibungen von Tools beeinflussen, ob das Modell sie aufruft oder nicht.

Die Dokumentation und Best Practices für Metadaten empfehlen:

  • action‑orientierte Namen zu verwenden: profile_to_segments, recommend_gifts, get_gift, similar_gifts statt tool1, search, do_stuff;
  • die Beschreibung mit „Verwende dieses Tool, wenn …“ zu beginnen und Trigger‑Szenarien und Einschränkungen („verwende es nicht für …“) zu benennen.

Das hängt direkt mit eurem Golden Prompt Set zusammen. Die Formulierungen der Beschreibung sollten sich mit realen Nutzeranfragen überschneiden. Wenn in der Beschreibung steht „Verwende es, wenn der Nutzer um eine Geschenkauswahl nach Budget und Interessen des Empfängers bittet“ und ihr im Golden Prompt „Finde ein Geschenk für einen Gamer‑Freund bis 50 $“ habt, kann das Modell Anfrage und Tool viel leichter matchen.

Beispiel für eine gute Tool‑Beschreibung

Betrachten wir ein zusätzliches GiftGenius‑Tool — similar_gifts, das hilft, die Auswahl durch ähnliche Ideen auf Basis eines konkreten Geschenks zu erweitern:

server.registerTool(
  "similar_gifts",
  {
    title: "Ähnliche Geschenke",
    description:
      "Verwende dieses Tool, wenn der Nutzer ein konkretes Geschenk ausgewählt hat und noch einige ähnliche Varianten sehen möchte. Verwende es nicht für die erste Auswahl von Null — dafür gibt es recommend_gifts.",
    inputSchema: {
      type: "object",
      properties: {
        giftId: {
          type: "string",
          description:
            "Die Geschenk-ID aus der vorherigen Auswahl, zu der ähnliche Varianten gefunden werden sollen."
        },
        limit: {
          type: "integer",
          description:
            "Wie viele ähnliche Geschenke zurückgegeben werden sollen (standardmäßig 3–5).",
          minimum: 1,
          default: 5
        }
      },
      required: ["giftId"]
    }
  },
  async () => {
    /* ... */
  }
);

Wichtige Punkte:

  • Wir sagen explizit, wann das Tool genutzt werden soll und wann nicht.
  • In der Beschreibung kommen Wörter wie „ähnliche Varianten“, „konkretes Geschenk gewählt“ vor — genau die, die häufig in echten Nutzeranfragen vorkommen.
  • Wir vermeiden Überschneidungen mit dem Bereich von recommend_gifts — das verringert die Konkurrenz zwischen Tools bei der Auswahl.

Beispiel für eine schlechte Beschreibung

description: "Arbeit mit Geschenken."

Aus so einer Beschreibung versteht das Modell praktisch nichts. Ein solches Tool kann höchstens funktionieren, wenn GPT bereits verzweifelt versucht, „irgendetwas auf gut Glück“ aufzurufen.

6. Annotationen und Hints: dem Modell die Tragweite einer Aktion signalisieren

Ein Tool ist nicht nur Name und Schema, sondern auch Annotationen, die ChatGPT signalisieren, wie gefährlich/wichtig eine Aktion ist und ob man das Nutzer‑Einverständnis einholen sollte. In der Apps‑SDK‑Spezifikation gibt es dafür verschiedene Hints, etwa readOnlyHint, destructiveHint, openWorldHint und andere.

  • readOnlyHint: true sagt, dass das Tool nur Daten liest und keinen Zustand ändert. Dann kann der Assistent überflüssige Bestätigungen überspringen und es freier aufrufen.
  • destructiveHint: true signalisiert, dass das Tool etwas löschen oder unwiderruflich ändern kann — dann sollte man dem Nutzer ein deutliches „Sind Sie sicher?“ anzeigen.
  • openWorldHint: true zeigt an, dass die Aktion die Außenwelt betrifft (Posting in sozialen Netzwerken, Erstellen eines Eintrags außerhalb des Accounts usw.) — auch das ist wichtig zu erwähnen.

Minimales Level — ohne Bestätigungen

Wenn ihr öffentliche Read‑only‑Tools habt, lohnt es sich, sie mit readOnlyHint: true zu markieren. Beispiel:

"annotations": {
  "readOnlyHint": true,
  "destructiveHint": false,
  "openWorldHint": false
}

Solche Tools kann GPT ohne zusätzliche dialogische Bestätigungen aufrufen.

Eine Bestätigung

Wenn es Tools gibt, die etwas auf dem Server ändern, ist es logisch, sie mit readOnlyHint: false zu markieren:

"annotations": {
  "readOnlyHint": false,
  "destructiveHint": false,
  "openWorldHint": false
}

Das Modell wird ein solches Tool wahrscheinlich einmal vom Nutzer bestätigen lassen (meist ist das ein modaler Dialog in der ChatGPT‑UI).

Gefährliche Aktion

Wenn ihr ein Tool habt, das etwas auf dem Server löscht, markiert es mit destructiveHint: true:

"annotations": {
  "readOnlyHint": false,
  "destructiveHint": true,
  "openWorldHint": false
}

Das Modell wird dieses Tool sehr vorsichtig aufrufen und zweimal nachfragen:

  • erstens im Text beim Nutzer um Bestätigung bitten,
  • zweitens zeigt die Plattform ein Standard‑Dialogfenster.

Für unser GiftGenius schreiben wir in diesem Modul noch keine Commerce‑Tools, aber wir können skizzieren, wie das zukünftige create_gift_order aussehen wird:

server.registerTool(
  "create_gift_order",
  {
    title: "Geschenkbestellung erstellen",
    description:
      "Verwende dieses Tool nur nach ausdrücklicher Zustimmung des Nutzers, das gewählte Geschenk zu kaufen. Erstellt eine Bestellung im System und gibt den Status zurück.",
    inputSchema: {
      type: "object",
      properties: {
        giftId: {
          type: "string",
          description: "ID des Geschenks, das der Nutzer gewählt hat."
        },
        deliveryEmail: {
          type: "string",
          description: "E-Mail, an die das digitale Geschenk gesendet werden soll."
        }
      },
      required: ["giftId", "deliveryEmail"]
    },
    annotations: {
      destructiveHint: true,
      openWorldHint: true
    }
  },
  async () => {
    /* ... */
  }
);

Annotationen ersetzen nicht eure Server‑Berechtigungsprüfungen, sie helfen ChatGPT lediglich beim UX: Bestätigung erfragen, Warnung anzeigen und solche Tools nicht „heimlich“ ausführen.

7. App‑Metadaten und zwei Ebenen der Discovery

Tools sind die halbe Geschichte. Die andere Hälfte: Wie findet und startet der Nutzer eure App überhaupt?

Im ChatGPT‑Ökosystem gibt es zwei zentrale Discovery‑Ebenen.

Erste — In‑Conversation‑Discovery. Wenn der Nutzer etwas im Chat schreibt (auch ohne die App ausdrücklich zu erwähnen), schaut das Modell:

  • auf den Text der Nachricht und die Dialoghistorie;
  • auf die Beschreibungen verfügbarer Apps und ihrer Tools;
  • auf Marken‑Nennungen, Themen und Schlüsselphrasen.

Darauf basierend entscheidet es, ob es eine App vorschlägt und wenn ja — welche und mit welchem Szenario. Hier sind die Beschreibungen der Tools und der App besonders wichtig. Wenn sie „Trigger“ wie „Geschenkauswahl“, „Geschenkidee“, „Geschenkbudget“ enthalten, steigt die Chance stark, dass das Modell eure App wählt.

Zweite Ebene — globale Discovery: Katalog und Launcher. Dort entscheidet schon der Mensch: Er wählt die App nach Name, Icon, Kurzbeschreibung und Tags. Hier ist wichtig, dass ihr ehrlich und verständlich erklärt, was eure App macht, für wen sie ist und worin ihr Hauptnutzen liegt.

Man kann das in einer kleinen Tabelle zusammenfassen:

Ebene Was Modell/Nutzer sieht Worauf es in Metadaten ankommt
In‑conversation Dialogtext, Beschreibungen von Tools und App Trigger‑Formulierungen, action‑orientierte Benennung, Einschränkungen
Katalog/Launcher Name, Icon, Short/Long Description, Tags Klares Positioning, verständlicher Value‑Prop

Für GiftGenius könnte man beispielsweise formulieren:

  • Name: GiftGenius — Geschenkideen in 60 Sekunden.
  • Kurzbeschreibung: Erfasst das Profil des Empfängers und schlägt 5–7 Geschenkideen vor — mit der Möglichkeit zum sofortigen Kauf direkt in ChatGPT.
  • Beschreibung für In‑Conversation: Verwende diese App, wenn der Nutzer um Hilfe bei der Geschenkauswahl bittet, nicht weiß, was er schenken soll, ein Budget, Interessen des Empfängers oder einen Anlass nennt.

Diese Formulierungen sollten unbedingt mit dem, was ihr bereits im system‑prompt und in den Beschreibungen des Tools recommend_gifts geschrieben habt, synchronisiert werden. Dann sieht das Modell ein stimmiges Gesamtbild statt widersprüchlicher Texte.

8. Wie Routing „im Kopf“ von ChatGPT funktioniert

Fassen wir alles zusammen und schauen uns einen typischen Weg einer Anfrage an — ohne in das MCP‑Protokoll einzutauchen, das kommt in den nächsten Modulen.

Angenommen, der Nutzer schreibt:

„Hilf mir, ein Geschenk für meinen Bruder zu finden, er liebt Fußball und Brettspiele, Budget bis 50 Dollar.“

Grob vereinfachter Algorithmus:

  1. Das Modell analysiert die Nachricht und die Historie. Es sieht Wörter wie „Geschenk“, „Bruder“, „Fußball“, „Brettspiele“, „Budget 50“.
  2. Es vergleicht das mit den Beschreibungen verfügbarer Apps und deren Tools. Für GiftGenius enthalten die Beschreibungen ausdrücklich „Geschenkauswahl nach Interessen und Budget“, daher ist die Wahrscheinlichkeit hoch, dass die App relevant ist.
  3. Wenn die App in dieser Session noch nicht aktiv ist, formuliert das Modell eine Ankündigungs‑Antwort: „Ich kann die App GiftGenius öffnen, die bei der Geschenkauswahl nach deinen Parametern hilft. Öffnen?“ — das haben wir in den UX‑Anweisungen vorab definiert.
  4. Nach der Zustimmung des Nutzers wählt das Modell innerhalb der App das Tool recommend_gifts, weil dessen Beschreibung dem aktuellen Vorhaben am besten entspricht. Hier wirken Name, description und die Struktur des inputSchema als Eingangssignale.
  5. Das Modell füllt die Tool‑Argumente auf Basis der Anfrage aus: Zuerst (falls nötig) ruft es profile_to_segments auf, um aus „Bruder, liebt Fußball und Brettspiele“ die Segmente ["football_fan", "board_games"] zu erhalten, dann ruft es recommend_gifts mit segments, budget: {min: 0, max: 50, currency: "USD"}, locale, occasion: "birthday" auf.
  6. Der MCP‑Server führt das Tool aus, formt ein strukturiertes Ergebnis mit items und meta und gibt es zurück.
  7. Das Modell liest das JSON, das ihr im outputSchema beschrieben habt, und baut die Antwort: erklärt, was es gefunden hat, warum genau diese Geschenke, und schlägt Follow‑ups vor („möchtest du nach Kategorie eingrenzen?“, „ähnliche zu diesem Geschenk zeigen?“ oder „diesen Artikel kaufen?“).

Hier ist ein einfaches Flussdiagramm dieses Prozesses:

flowchart TD
  A[User: Anfrage zum Geschenk] --> B[ChatGPT analysiert den Kontext]
  B --> C[Abgleich mit den Metadaten von App und Tools]
  C -->|relevant| D[GiftGenius ankündigen]
  D -->|Nutzer stimmt zu| E["Aufruf recommend_gifts (+ profile_to_segments)"]
  E --> F[MCP-Server GiftGenius]
  F --> G[JSON-Ergebnis mit items/meta]
  G --> H[Modell formuliert Antwort und Follow-up]

Je besser ihr Tools und Use‑Cases beschrieben habt, desto weniger Zufall steckt hier drin und desto stabiler ist das Routing.

Insight: Tool Call SEO

Im Apps‑Ökosystem werdet ihr bald nicht nur um die Aufmerksamkeit von Menschen im Katalog konkurrieren, sondern auch um die Aufmerksamkeit des Modells selbst. Auf dieselbe Nutzeranfrage kann ChatGPT ein Dutzend verschiedener Apps in Betracht ziehen — und die Auswahl findet nicht anhand der schönsten Präsentation statt, sondern in einer „Suchergebnisliste“ im Kopf des Modells. Diese unsichtbare Ebene erinnert immer mehr an SEO, nur dass ihr statt Seiten Tools und MCP‑Server habt.

Das Modell rankt Kandidaten im Grunde: erst auf App‑Ebene, dann auf Ebene einzelner Tools. Es schaut auf Namen, Beschreibungen, Schemata, Annotationen und gleicht sie mit der Formulierung der Anfrage ab. Wenn in der Beschreibung von recommend_gifts „Geschenkauswahl nach Budget und Interessen des Empfängers“ steht und in der Anfrage „Finde ein Geschenk für einen Gamer‑Freund für 50 $“ vorkommt, hat dieses Tool eine größere Chance, „oben zu landen“ als ein abstraktes search mit der Beschreibung „Arbeit mit Geschenken“.

Daraus entsteht die praktische Idee der Tool Call SEO: Behandelt Namen, Beschreibungen, Enum‑Werte und Metadaten wie Schlüsselwörter und Snippets. Ihr beschreibt nicht nur einen Vertrag für Entwickler — ihr optimiert ihn für den echten Anfrage‑Traffic aus eurem Golden Prompt Set. Zu allgemeine Formulierungen, sich überschneidende Bereiche mehrerer Tools, God‑Tools ohne klare Nische — all das senkt den „CTR“ eurer App im Kopf des Modells.

9. Eine kleine praktische Übung

Versucht gedanklich (oder in eurem Repository) Folgendes durchzuspielen.

Wählt zunächst eines der Schlüsselszenarien von GiftGenius — zum Beispiel „Ein Geschenk für eine Kollegin/einen Kollegen mit begrenztem Budget auswählen“.

Formuliert dazu:

  1. Welches eigene Tool für dieses Szenario nötig ist: reines recommend_gifts, oder braucht ihr noch ein spezialisiertes Tool für den B2B‑Case, oder reicht es, nach recommend_gifts similar_gifts für Variationen zu nutzen?
  2. Welche Felder im Eingabeschema von recommend_gifts wirklich notwendig sind. Welche Felder kann man den Nutzer separat (per Follow‑up) fragen, statt das Modell raten zu lassen.
  3. Wie das outputSchema aussehen sollte, damit das Modell die Auswahl ehrlich erklären und nächste Schritte vorschlagen kann (z. B. in den B2B‑Modus wechseln, nur digitale Geschenke zeigen, nach Preisspanne eingrenzen).

Und schaut danach auf euer Golden Prompt Set aus der letzten Vorlesung und prüft:

  • gibt es für jede Referenzanfrage ein offensichtliches Tool (recommend_gifts, get_gift, similar_gifts usw.);
  • ist es nicht so, dass zwei Tools gleichermaßen zu einer und derselben Anfrage „passen“ (overlapping tools);
  • muss man Beschreibungen schärfen oder ein Tool umbenennen, damit das Modell weniger verwechselt.

Das ist genau der Prozess, den ihr vor jeder ernsthaften Änderung am Prompt, an Schemata oder Logik wiederholen werdet — im Grunde ein Mini‑Eval der Discovery‑Qualität.

Wenn man alles oben zu einer Checkliste verdichtet, braucht ihr in diesem Schritt:

  • Szenarien ehrlich in 2–4 sinnvolle Tools zu schneiden;
  • inputSchema/outputSchema sauber mit Beispielen und enums zu beschreiben;
  • Namen, Beschreibungen und Annotationen aufzuräumen;
  • das mit dem system‑prompt und den App‑Metadaten zu synchronisieren.

In den nächsten Modulen schauen wir uns an, wie das alles über MCP funktioniert und wie man seltsames Discovery/Routing‑Verhalten diagnostiziert.

10. Typische Fehler beim Design von Tools und Metadaten

Fehler Nr. 1: „Wir haben alles im System‑Prompt beschrieben, die Tools kriegen das schon hin.“
Wenn ihr Rolle, Verantwortungsgrenzen und UX‑Verhalten eurer App hervorragend beschrieben habt, aber eure Tools tool1, search, do_stuff heißen und Schemata ohne Beschreibungen haben, kann das Modell euren schönen Text nicht mit echten Aufrufen verknüpfen. Für ChatGPT sind Tools die Hauptschnittstelle; ohne gutes Metadaten‑Design rettet euch kein system‑prompt.

Fehler Nr. 2: God‑Tool, das alles auf einmal macht.
Der Wunsch zu „optimieren“ und eine einzige Funktion mit mode zu bauen ist verständlich, führt aber zu monströsen JSON‑Schemata, Verwirrung in Beschreibungen und schlechterem Routing. Das Modell fängt an zu raten, welchen Modus es nutzen soll, und ihr pflegt einen riesigen switch auf dem Server. Lieber ein paar klare Tools für konkrete Schritte als ein „mach‑alles“‑Tool.

Fehler Nr. 3: Eingabeschéma, überladen mit „für alle Fälle“‑Feldern.
Entwickler versuchen oft, durch das inputSchema sofort alle Parameter zu schleusen, die irgendwann nützlich sein könnten, plus noch ein paar interne Felder. Am Ende versucht das Modell Dinge zu raten, die es nicht wissen kann (z. B. tenantId), und ihr wundert euch über seltsame Werte. Das Input Schema darf nur das enthalten, was das Modell aus dem Dialog wirklich ableiten oder nachfragen kann. Interne Details fügt auf dem Server hinzu.

Fehler Nr. 4: „Stumme“ Output‑Daten ohne Metainformationen.
Nur ein Array von Objekten aus dem Tool zurückzugeben, ist verführerisch. Aber so nehmt ihr dem Modell das Verständnis, warum diese Ergebnisse erscheinen. Ohne Felder wie score, reason, searchCriteria, totalCandidates ist es schwerer, ehrliche Erklärungen und Follow‑ups aufzubauen. Eine kleine meta‑Hülle mit Suchkriterien und Ratschlägen verbessert die Antwortqualität oft drastisch.

Fehler Nr. 5: Holzschnittartige Beschreibungen: „Arbeit mit Geschenken“, „Kurssuche“, „Datenverarbeitung“.
Solche Beschreibungen sind schlecht, weil sie dem Modell weder Trigger noch Einschränkungen liefern. Es weiß nicht, wann genau es das Tool aufrufen soll und wofür es gilt. Eine gute Beschreibung beginnt mit „Verwende dieses Tool, wenn …“ und enthält konkrete Szenarien sowie Verbote wie „Verwende es nicht für …“. Ideal ist, wenn diese Formulierungen sich mit den Goldanfragen aus eurem Golden Prompt Set überschneiden.

Fehler Nr. 6: Ignorieren von Annotationen und Vermischen von Read‑only‑ und verändernden Aktionen.
Wenn ihr Tools, die nur lesen (readOnlyHint), und solche, die Aktionen ausführen (destructiveHint, openWorldHint), nicht markiert, kann das Modell die richtige UX für Bestätigungen nicht aufbauen. Ergebnis: entweder überflüssige „Sind Sie sicher?“ bei jedem Schritt oder umgekehrt stille Käufe und Änderungen ohne Zustimmung. Annotationen sind ein einfacher und effektiver Weg, dem Modell die Wichtigkeit einer Operation zu signalisieren.

Fehler Nr. 7: App‑Metadaten für Katalog und In‑Conversation leben in verschiedenen Welten.
Manchmal ist die Kurzbeschreibung im Katalog vom Marketing geschrieben („Revolutionärer AI‑Assistent, der Ihr Leben verändert“), während Tool‑Beschreibungen und system‑prompt vom Entwickler stammen („Geschenkauswahl nach Budget“). Ergebnis: Im Katalog ist unklar, worum es bei der App geht, und das Modell kann im Chat Anfragen wie „Was ist das für ein Service?“ nicht mit den realen Möglichkeiten der App abgleichen. Schreibt Metadaten als eine einheitliche Spezifikation, nicht als zwei unabhängige Marketingtexte.

1
Umfrage/Quiz
Verhalten der ChatGPT App, Level 5, Lektion 4
Nicht verfügbar
Verhalten der ChatGPT App
Anweisungen für das Modell und das Verhalten der ChatGPT App
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION