aunomo.tech aunomo.tech
← Zurück zur Übersicht

Wann ein einzelner Claude-Prompt reicht — und wann du einen Agenten brauchst

Single-Prompt oder Agentic Workflow? Ein technisches Entscheidungsframework mit konkreten Kriterien, Code-Beispielen und Kosten-Latenz-Abwägungen für Solopreneure und kleine Teams.

· von aunomo.tech · 5 Min. Lesezeit

Die Frage klingt einfach, ist es aber nicht: Reicht für meine Aufgabe ein einzelner API-Call an Claude — oder brauche ich einen Agenten mit mehreren Schritten, Werkzeugzugriff und Zustandsspeicher? Die falsche Antwort kostet entweder Zeit (zu viel Komplexität) oder Qualität (zu wenig Kapazität). Dieses Post liefert ein konkretes Entscheidungsframework.

Die Kernunterscheidung: Zustand, Werkzeuge, Verzweigung

Ein einzelner Prompt ist ein zustandsloser Funktionsaufruf: Eingabe rein, Text raus, fertig. Ein Agent dagegen ist eine Schleife: Das Modell entscheidet nach jedem Schritt, ob es weitere Werkzeuge aufruft, auf frühere Ergebnisse zurückgreift oder abbricht. Der Unterschied liegt nicht in der Modellgröße, sondern in der Architektur drumherum.

MerkmalEinzelner PromptAgent
Zustand zwischen SchrittenNeinJa (Memory / Context Window)
Werkzeugzugriff (APIs, DB, FS)Nein / optional per PostprocessingJa, dynamisch zur Laufzeit
Verzweigung / BedingungenNeinJa, vom Modell gesteuert
Latenz pro AufgabeNiedrig (1 API-Call)Hoch (n API-Calls)
Kosten pro AufgabeNiedrigProportional zu Schritten
FehlerfortpflanzungKeine KaskadeFehler in Schritt k beeinflusst k+1

Wann ein einzelner Prompt ausreicht

Ein Prompt ist die richtige Wahl, wenn die Aufgabe in einem einzigen, klar abgegrenzten Kontext vollständig beschreibbar ist und das Ergebnis keine externe Datenbeschaffung zur Laufzeit erfordert.

// Typischer Single-Prompt-Call mit dem Anthropic SDK
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

async function classifyEmail(emailBody: string): Promise<string> {
  const message = await client.messages.create({
    model: "claude-opus-4-5",
    max_tokens: 64,
    messages: [
      {
        role: "user",
        content: `Klassifiziere diese E-Mail als genau eines von: [SUPPORT, SALES, SPAM, INTERN].
Antworte nur mit dem Label, kein weiterer Text.

E-Mail:
${emailBody}`,
      },
    ],
  });

  const block = message.content[0];
  if (block.type !== "text") throw new Error("Unexpected response type");
  return block.text.trim();
}

// Aufruf: O(1) API-Calls, deterministisch, guenstig
const label = await classifyEmail("Mein Passwort funktioniert nicht mehr...");
console.log(label); // => "SUPPORT"

Wann du einen Agenten brauchst

Ein Agent ist notwendig, sobald mindestens eines dieser technischen Kriterien zutrifft:

  1. Externe Datenbeschaffung zur Laufzeit: Das Modell muss APIs aufrufen, Datenbanken abfragen oder Dateisystemoperationen ausführen, deren Ergebnisse erst den nächsten Prompt formen.
  2. Bedingte Verzweigung: Je nach Zwischenergebnis folgt ein anderer Pfad (z. B. 'Falls kein Ergebnis gefunden, suche mit anderen Keywords').
  3. Iterative Verfeinerung: Das Ergebnis eines Schritts wird als Input für den nächsten verwendet, über mehr als ein bis zwei feste Stufen hinaus.
  4. Zustandserhaltung über Anfragen: Der Agent muss sich an frühere Schritte erinnern, die nicht vollständig in einen einzelnen Context passen.
  5. Parallelisierung mit Koordination: Mehrere Teilaufgaben laufen parallel, deren Ergebnisse anschließend zusammengeführt werden.

Konkretes Beispiel: Recherche-Draft-Log-Pipeline

Aufgabe: 'Recherchiere aktuelle Preise für drei Wettbewerber, schreibe einen Vergleichsabschnitt und speichere ihn in unserer Notion-Datenbank.' Das ist kein Prompt — das ist eine Pipeline mit mindestens vier Schritten, externen Abhängigkeiten und Fehlerbehandlung pro Schritt.

// Vereinfachter Agentic Loop mit Tool Use
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const tools: Anthropic.Tool[] = [
  {
    name: "fetch_competitor_price",
    description: "Ruft den aktuellen Preis eines Wettbewerbers per Slug ab.",
    input_schema: {
      type: "object",
      properties: {
        competitor_slug: { type: "string" },
      },
      required: ["competitor_slug"],
    },
  },
  {
    name: "save_to_notion",
    description: "Speichert einen Markdown-Text in der Notion-Datenbank.",
    input_schema: {
      type: "object",
      properties: {
        title: { type: "string" },
        content: { type: "string" },
      },
      required: ["title", "content"],
    },
  },
];

async function fetchCompetitorPrice(slug: string): Promise<string> {
  const prices: Record<string, string> = {
    acme: "49 EUR/Monat",
    globex: "39 EUR/Monat",
    initech: "59 EUR/Monat",
  };
  return prices[slug] ?? "Preis nicht verfuegbar";
}

async function saveToNotion(title: string, content: string): Promise<string> {
  console.log(`[Notion] Gespeichert: "${title}"`);
  return "ok";
}

async function runCompetitorResearchAgent() {
  const messages: Anthropic.MessageParam[] = [
    {
      role: "user",
      content:
        "Recherchiere die Preise von acme, globex und initech. " +
        "Schreibe dann einen kurzen Vergleichsabschnitt und speichere ihn in Notion.",
    },
  ];

  while (true) {
    const response = await client.messages.create({
      model: "claude-opus-4-5",
      max_tokens: 1024,
      tools,
      messages,
    });

    if (response.stop_reason === "end_turn") {
      console.log("Agent abgeschlossen.");
      break;
    }

    if (response.stop_reason === "tool_use") {
      messages.push({ role: "assistant", content: response.content });

      const toolResults: Anthropic.ToolResultBlockParam[] = [];

      for (const block of response.content) {
        if (block.type !== "tool_use") continue;

        let result: string;
        if (block.name === "fetch_competitor_price") {
          const input = block.input as { competitor_slug: string };
          result = await fetchCompetitorPrice(input.competitor_slug);
        } else if (block.name === "save_to_notion") {
          const input = block.input as { title: string; content: string };
          result = await saveToNotion(input.title, input.content);
        } else {
          result = "Unbekanntes Tool";
        }

        toolResults.push({
          type: "tool_result",
          tool_use_id: block.id,
          content: result,
        });
      }

      messages.push({ role: "user", content: toolResults });
    }
  }
}

await runCompetitorResearchAgent();

Dieser Loop läuft so lange, bis das Modell 'end_turn' zurückgibt. Die Anzahl der API-Calls ist zur Compile-Zeit unbekannt — das ist das definitorische Merkmal eines Agenten.

Kosten und Latenz: Die ehrliche Rechnung

Agenten sind nicht nur komplexer zu bauen — sie sind pro Aufgabe teurer und langsamer. Das ist kein Argument gegen Agenten, aber ein Argument für bewusste Entscheidungen.

SzenarioAPI-CallsApprox. LatenzApprox. Token-Kosten
E-Mail klassifizieren (Prompt)1~0,5 s~500 Tokens
Wettbewerber-Recherche (3 Tools + Draft + Speichern)5–8~15–30 s~8.000–15.000 Tokens
Autonome Bug-Triage (iterativ, Codebase-Zugriff)10–25~60–180 s~30.000–80.000 Tokens

Entscheidungsbaum: Prompt oder Agent?

Beantworte diese vier Fragen der Reihe nach. Die erste 'Ja'-Antwort zeigt die Richtung.

  1. Sind alle benötigten Informationen bereits im Input vorhanden, ohne externen Abruf? — Ja: Prompt reicht.
  2. Ist die Abfolge der Schritte zur Compile-Zeit vollständig bekannt und fest (keine Verzweigung)? — Ja: Feste Pipeline (mehrere Prompts in Sequenz, kein autonomer Agent).
  3. Muss das Modell selbst entscheiden, welche Werkzeuge es in welcher Reihenfolge aufruft? — Ja: Agent mit Tool Use.
  4. Muss der Agent über mehrere Nutzer-Sessions hinweg Zustand behalten? — Ja: Agent mit persistentem Memory-Layer (z. B. Datenbank-backed).

Häufige Muster und ihre Zuordnung

AufgabeTypBegründung
Betreffzeile für E-Mail generierenPromptVollständiger Kontext im Input
Support-Ticket kategorisieren und priorisierenPromptKlassifikation, kein externer Zugriff nötig
Rechnung aus PDF-Text strukturiert extrahierenPromptTransformation bekannter Eingabe
Wöchentlichen Bericht aus Jira, Slack und Git zusammenstellenAgentDrei externe Datenquellen, Koordination
Onboarding-E-Mail-Sequenz in 5 Schritten entwerfenFeste PipelineSequenz bekannt, keine Verzweigung
Autonomes Bug-Fixing mit Codebase-Zugriff und TestsAgentIterativ, verzweigt, externe Tools
Keyword-Recherche, Briefing und Outline erstellenAgentExterne Suche und mehrstufige Verfeinerung

Der oft übersehene Mittelweg: Feste Pipelines

Zwischen einem einzelnen Prompt und einem vollautonomen Agenten liegt die feste Pipeline: mehrere Prompts in deterministischer Reihenfolge, ohne dass das Modell die Ablaufsteuerung übernimmt. Der Code entscheidet, welcher Prompt wann aufgerufen wird. Das Modell liefert nur Text.

// Feste Pipeline: Kein Agent, aber mehr als ein Prompt
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

async function singlePrompt(userContent: string): Promise<string> {
  const message = await client.messages.create({
    model: "claude-opus-4-5",
    max_tokens: 512,
    messages: [{ role: "user", content: userContent }],
  });
  const block = message.content[0];
  if (block.type !== "text") throw new Error("Unexpected response type");
  return block.text.trim();
}

async function generateBlogOutline(topic: string, audience: string) {
  // Schritt 1: Kernaussagen extrahieren
  const keyPoints = await singlePrompt(
    `Nenne 5 technische Kernaussagen zum Thema "${topic}" fuer ${audience}. Nur Stichpunkte.`
  );

  // Schritt 2: Gliederung bauen
  const outline = await singlePrompt(
    `Erstelle eine Blog-Gliederung mit H2 und H3 auf Basis dieser Punkte:
${keyPoints}`
  );

  // Schritt 3: SEO-Titel vorschlagen
  const titles = await singlePrompt(
    `Schreibe 3 SEO-Titel-Varianten (max. 60 Zeichen) fuer diese Gliederung:
${outline}`
  );

  return { keyPoints, outline, titles };
}

// Der Code kontrolliert den Ablauf - das Modell nicht.
// Kein Loop, keine Tool-Calls, keine autonome Entscheidung.

Dieses Muster ist für viele Aufgaben in kleinen Teams die praktischste Option: geringere Komplexität als ein Agent, mehr Kapazität als ein einzelner Prompt. Typische Kandidaten sind mehrstufige Content-Workflows, Datenbereinigungspipelines oder Formular-zu-Dokument-Konvertierungen mit bekannter Struktur.

Häufige Fragen

Kann ich einen Agenten durch einen sehr langen System-Prompt ersetzen?

Für Aufgaben ohne externen Werkzeugzugriff oft ja. Wenn das Modell aber zur Laufzeit Daten aus APIs oder Datenbanken braucht, kommt kein Prompt daran vorbei — der Kontext muss irgendwie befüllt werden, und das erfordert Code-seitige Orchestrierung.

Ab wie vielen Schritten lohnt sich ein echter Agentic Loop?

Kein fixer Schwellenwert. Die entscheidende Frage ist, ob die Anzahl der Schritte oder ihre Reihenfolge zur Laufzeit variiert. Sind beide zur Compile-Zeit bekannt, ist eine feste Pipeline einfacher. Variiert beides je nach Eingabe, ist ein Agent die sauberere Architektur.

Wie gehe ich mit Fehlern in Agenten-Pipelines um?

Jeder Tool-Call ist ein Fehlerpunkt. Standardmuster: Tool-Ergebnis immer mit Fehler-Flag zurückgeben statt Exception zu werfen, dem Modell explizit erlauben, mit einem Fehler-Ergebnis fortzufahren oder abzubrechen, und maximale Schrittzahl als harter Guard implementieren, um Endlosschleifen zu verhindern.

Welches Modell ist für Agenten am besten geeignet?

Für Tool Use mit mehreren Werkzeugen und Verzweigungslogik empfehlen sich die stärkeren Modelle (z. B. Claude Opus), da schwächere Modelle bei komplexen Tool-Call-Entscheidungen häufiger Fehler machen. Bei einfachen, bekannten Tool-Schemas reichen auch kleinere Modelle wie Claude Haiku — zu deutlich geringeren Kosten.

Ist ein Agentic Workflow dasselbe wie ein RAG-System?

Nein. RAG (Retrieval-Augmented Generation) ist eine spezifische Technik, bei der vor dem Prompt relevante Dokumente abgerufen und in den Kontext eingebettet werden — das ist oft ein einzelner Prompt mit vorgelagertem Retrieval-Schritt. Ein Agent kann RAG als ein Werkzeug unter mehreren nutzen, ist aber eine breitere Architektur.

Wann ist weder Prompt noch Agent die richtige Antwort?

Wenn die Aufgabe deterministisch und regelbasiert lösbar ist, ohne LLM-Verständnis zu benötigen. Datenformatierung, String-Transformationen oder regelbasierte Klassifikation mit festem Mapping gehören in normalen Code — nicht in einen LLM-Aufruf.

Zusammenfassung

Verwandte Beiträge