Use Cases (Aktualisiert: 3.6.2026)

Claude Code × Amazon Bedrock: Praxisleitfaden für Claude in Produktion auf AWS

Claude mit Claude Code und Amazon Bedrock produktiv betreiben: IAM, Converse API, Logs, Guardrails und Kostenkontrolle.

Claude Code × Amazon Bedrock: Praxisleitfaden für Claude in Produktion auf AWS

Für einen schnellen Claude-Prototyp ist der direkte Aufruf der Anthropic API oft am einfachsten. In Produktion auf AWS ändern sich die Anforderungen: API-Key-Verwaltung, IAM-Grenzen, Audit-Logs, Kostenstellen, Datenaufbewahrung, Retry-Verhalten und Quotas. Genau dafür ist Amazon Bedrock als Claude-Runtime interessant.

Amazon Bedrock ist der Managed Service von AWS für Foundation Models. Praktisch bedeutet das: Deine Anwendung ruft Claude über AWS-Identität, Berechtigungen, Logging, Abrechnung und Betriebsregeln auf. Claude Code bleibt hilfreich, sollte aber nicht nur ein Demo erzeugen. Die Aufgabe muss reviewbaren Code für IAM, Modellaufruf, Guardrails, Logging, Fehlerbehandlung und Kostenlimits enthalten.

Masas Erfahrung aus echten Projekten: Ein Bedrock-Demo läuft schnell, aber die Produktionsfreigabe fragt mehr. Welche Role ruft welches Modell auf? Welche Model IDs sind erlaubt? Was passiert bei Throttling? Werden Prompts gespeichert? Wie werden Kosten pro Team sichtbar? Dieser Guide übersetzt diese Fragen in Code und Claude-Code-Prompts.

Der Artikel basiert auf AWS-Dokumentation mit Stand 3. Juni 2026. Bedrock Model IDs, Regions, Quotas und Preise können sich ändern; prüfe vor dem Deployment immer die offiziellen Quellen.

Produktionsarchitektur

Bitte Claude Code nicht direkt um „einen Bedrock Chat“. Lege zuerst Caller, Runtime, Modell, Guardrails, Logs und Kostenzuordnung fest.

flowchart LR
  U["User / Admin UI"] --> A["API Gateway or ALB"]
  A --> R["Lambda or ECS task"]
  R --> G["Input validation and budget guard"]
  G --> B["Amazon Bedrock Runtime<br/>Converse / ConverseStream"]
  B --> C["Claude model"]
  R --> L["App logs<br/>CloudWatch Logs"]
  B --> M["Model invocation logs<br/>CloudWatch Logs or S3"]
  R --> K["Knowledge Bases<br/>optional RAG"]
  R --> Q["Cost Explorer / CUR<br/>IAM principal attribution"]

Converse API ist Bedrocks einheitliche Chat-Schnittstelle. Guardrails bewertet Nutzereingaben und Modellantworten anhand konfigurierter Sicherheitsrichtlinien. model invocation logging kann Aufrufdaten nach CloudWatch Logs oder S3 schreiben. IAM principal attribution hilft, Bedrock-Kosten nach IAM-Usern und Roles aufzuschlüsseln.

Geeignete Use Cases

Der erste Use Case ist internes Dokumenten-Q&A. Runbooks, Spezifikationen und Support-Prozesse liegen in S3 und Knowledge Bases; relevante Ausschnitte werden abgerufen und Claude erstellt eine Antwort mit Quellen. Das ist RAG, also retrieval augmented generation.

Der zweite Use Case sind Support-Antwortentwürfe. Claude kombiniert Kundenfrage, Tarifdaten und freigegebene Antwortvorlagen. Behalte vor Vollautomatisierung menschliche Freigabe, Guardrails, personenbezogene Datenregeln und Audit-Logs.

Der dritte Use Case ist ein Engineering-Operations-Assistent. Er kann CloudWatch-Logs zusammenfassen, Deployment-Checklisten erzeugen, Incident Notes vorbereiten oder Runbooks in Aufgaben zerlegen. Claude Code ist stark, weil API, Lambda, IAM, Tests und Dokumentation in einem reviewbaren Change entstehen können.

Der vierte Use Case ist Content Operations für eine Seite wie ClaudeCodeLab. Artikel-QA, description-Länge, interne Links und Codeblock-Prüfung laufen unter AWS-IAM und Abrechnung. Wenn Content-Qualität Umsatz beeinflusst, lies zusätzlich den Claude Code Kostenleitfaden und den Verification Receipt Workflow.

Setup

Voraussetzungen sind Node.js 20+, AWS-CLI-Credentials, ein AWS-Konto mit Bedrock-Zugriff und ein Anthropic-Modell in der Ziel-Region. Je nach Konto können First-Time-Use-Angaben, AWS-Marketplace-Berechtigungen und eine gültige Zahlungsmethode erforderlich sein.

Fixiere keine Model ID aus einem Artikel. Liste die verfügbaren Modelle in deinem Konto und setze die ID als Umgebungsvariable.

export AWS_REGION=us-east-1

aws bedrock list-foundation-models \
  --region "$AWS_REGION" \
  --query "modelSummaries[?providerName=='Anthropic'].[modelId,modelName]" \
  --output table

export BEDROCK_MODEL_ID="anthropic.claude-sonnet-4-20250514-v1:0"
aws bedrock get-foundation-model \
  --region "$AWS_REGION" \
  --model-identifier "$BEDROCK_MODEL_ID" \
  --query "modelDetails.{input:inputModalities,output:outputModalities,streaming:responseStreamingSupported}"

Erstelle ein minimales TypeScript-Projekt.

mkdir bedrock-claude-lab
cd bedrock-claude-lab
npm init -y
npm install @aws-sdk/client-bedrock @aws-sdk/client-bedrock-runtime @aws-sdk/client-bedrock-agent-runtime
npm install --save-dev typescript tsx @types/node
npx tsc --init --module NodeNext --moduleResolution NodeNext --target ES2022
mkdir -p src/lambda

Füge Scripts zu package.json hinzu.

{
  "type": "module",
  "scripts": {
    "chat": "tsx src/chat.ts",
    "stream": "tsx src/stream.ts",
    "typecheck": "tsc --noEmit"
  }
}

IAM-Basis

Auch mit Converse API braucht IAM Modellaufrufrechte. Nicht-streaming benötigt bedrock:InvokeModel; Streaming benötigt bedrock:InvokeModelWithResponseStream. Trenne App-Logging-Rechte von Bedrocks model invocation logging.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListBedrockModelsForStartupCheck",
      "Effect": "Allow",
      "Action": ["bedrock:ListFoundationModels", "bedrock:GetFoundationModel"],
      "Resource": "*"
    },
    {
      "Sid": "InvokeOnlyApprovedClaudeModels",
      "Effect": "Allow",
      "Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
      "Resource": [
        "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-*",
        "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-*",
        "arn:aws:bedrock:us-east-1:123456789012:inference-profile/*"
      ]
    },
    {
      "Sid": "ApplyApprovedGuardrail",
      "Effect": "Allow",
      "Action": ["bedrock:ApplyGuardrail"],
      "Resource": "arn:aws:bedrock:us-east-1:123456789012:guardrail/your-guardrail-id"
    }
  ]
}

Ersetze Account ID, Regions, Guardrail und Model Scope. Bei cross-Region inference gehören auch Inference Profile und Zielmodell-ARNs in die Policy. Für Least-Privilege-Review siehe den Claude Code AWS IAM Guide.

Claude aufrufen

Der wichtige Produktionspunkt ist requestMetadata. AWS dokumentiert es als Filterhilfe für Invocation Logs; speichere also Request ID, Feature und Caller-Kategorie.

// src/bedrock-client.ts
import { randomUUID } from "node:crypto";
import {
  BedrockRuntimeClient,
  ConverseCommand,
  ConverseStreamCommand,
  type ConverseCommandInput,
} from "@aws-sdk/client-bedrock-runtime";

export const AWS_REGION = process.env.AWS_REGION ?? "us-east-1";
export const BEDROCK_MODEL_ID =
  process.env.BEDROCK_MODEL_ID ?? "anthropic.claude-sonnet-4-20250514-v1:0";

export const bedrock = new BedrockRuntimeClient({
  region: AWS_REGION,
  maxAttempts: Number(process.env.BEDROCK_MAX_ATTEMPTS ?? "3"),
});

type AskClaudeInput = {
  prompt: string;
  system?: string;
  maxTokens?: number;
  temperature?: number;
  userId?: string;
  feature?: string;
};

function optionalGuardrail(): ConverseCommandInput["guardrailConfig"] | undefined {
  const guardrailIdentifier = process.env.BEDROCK_GUARDRAIL_ID;
  if (!guardrailIdentifier) return undefined;

  return {
    guardrailIdentifier,
    guardrailVersion: process.env.BEDROCK_GUARDRAIL_VERSION ?? "DRAFT",
    trace: "enabled",
  };
}

export async function askClaude(input: AskClaudeInput) {
  const requestId = randomUUID();
  const startedAt = Date.now();

  const response = await bedrock.send(
    new ConverseCommand({
      modelId: BEDROCK_MODEL_ID,
      system: input.system ? [{ text: input.system }] : undefined,
      messages: [{ role: "user", content: [{ text: input.prompt }] }],
      inferenceConfig: {
        maxTokens: input.maxTokens ?? 800,
        temperature: input.temperature ?? 0.2,
      },
      guardrailConfig: optionalGuardrail(),
      requestMetadata: {
        requestId,
        feature: input.feature ?? "local-cli",
        userId: input.userId ?? "anonymous",
      },
    })
  );

  const text =
    response.output?.message?.content
      ?.map((block: { text?: string }) => block.text ?? "")
      .join("") ?? "";

  console.log(
    JSON.stringify({
      level: "info",
      event: "bedrock_converse",
      requestId,
      modelId: BEDROCK_MODEL_ID,
      latencyMs: Date.now() - startedAt,
      stopReason: response.stopReason,
      usage: response.usage,
      metrics: response.metrics,
    })
  );

  return { text, usage: response.usage, stopReason: response.stopReason, requestId };
}

export async function streamClaude(prompt: string) {
  const response = await bedrock.send(
    new ConverseStreamCommand({
      modelId: BEDROCK_MODEL_ID,
      messages: [{ role: "user", content: [{ text: prompt }] }],
      inferenceConfig: { maxTokens: 1200, temperature: 0.2 },
      guardrailConfig: optionalGuardrail(),
      requestMetadata: { feature: "stream-cli", requestId: randomUUID() },
    })
  );

  if (!response.stream) throw new Error("Bedrock did not return a stream.");

  for await (const event of response.stream) {
    const text = event.contentBlockDelta?.delta?.text;
    if (text) process.stdout.write(text);

    if (event.metadata?.usage) {
      process.stderr.write(`\nusage=${JSON.stringify(event.metadata.usage)}\n`);
    }
  }
}
// src/chat.ts
import { askClaude } from "./bedrock-client.js";

const prompt = process.argv.slice(2).join(" ").trim();
if (!prompt) {
  console.error('Usage: npm run chat -- "Summarize Amazon Bedrock in three bullets"');
  process.exit(1);
}

const result = await askClaude({
  prompt,
  system: "You are a concise AWS assistant. If you are unsure, say what to verify.",
  maxTokens: 600,
  feature: "developer-chat",
});

console.log(result.text);
// src/stream.ts
import { streamClaude } from "./bedrock-client.js";

const prompt = process.argv.slice(2).join(" ").trim();
if (!prompt) {
  console.error('Usage: npm run stream -- "Write a deployment checklist"');
  process.exit(1);
}

await streamClaude(prompt);

Ausführen:

export AWS_REGION=us-east-1
export BEDROCK_MODEL_ID="anthropic.claude-sonnet-4-20250514-v1:0"

npm run chat -- "Erkläre Amazon Bedrock in drei Zeilen"
npm run stream -- "Erstelle eine Bedrock-Produktionscheckliste"
npm run typecheck

Lambda-Pattern

In Lambda initialisierst du den Client außerhalb des Handlers, validierst Eingaben und begrenzt maxTokens serverseitig.

// src/lambda/assistant-handler.ts
import { askClaude } from "../bedrock-client.js";

type ApiEvent = {
  body?: string | null;
  requestContext?: { requestId?: string };
};

const headers = { "content-type": "application/json; charset=utf-8" };

export const handler = async (event: ApiEvent) => {
  try {
    const body = JSON.parse(event.body ?? "{}") as {
      prompt?: string;
      maxTokens?: number;
      userId?: string;
    };

    if (!body.prompt || body.prompt.length > 8000) {
      return {
        statusCode: 400,
        headers,
        body: JSON.stringify({ error: "prompt is required and must be <= 8000 chars" }),
      };
    }

    const result = await askClaude({
      prompt: body.prompt,
      maxTokens: Math.min(body.maxTokens ?? 800, 1200),
      userId: body.userId ?? "anonymous",
      feature: "support-assistant",
    });

    return {
      statusCode: 200,
      headers,
      body: JSON.stringify({
        text: result.text,
        usage: result.usage,
        stopReason: result.stopReason,
        requestId: result.requestId,
      }),
    };
  } catch (error) {
    const name =
      typeof error === "object" && error && "name" in error ? String(error.name) : "UnknownError";
    const retryable = ["ThrottlingException", "ServiceUnavailableException", "InternalServerException"].includes(name);

    console.error(JSON.stringify({ level: "error", event: "assistant_failed", name, retryable }));

    return {
      statusCode: retryable ? 503 : 500,
      headers,
      body: JSON.stringify({ error: retryable ? "Please retry later" : "Generation failed" }),
    };
  }
};

ValidationException ist meist ein Eingabe- oder Parameterproblem und sollte nicht blind retried werden. ThrottlingException und ServiceUnavailableException eignen sich für exponential backoff mit jitter. Für den serverless Gesamtaufbau lies Claude Code × AWS Lambda.

RAG mit Knowledge Bases

Für Chat über interne Dokumente ist Bedrock Knowledge Bases oft der bessere Start als ein eigener Vector Store. Antworten können Quellen enthalten und sind dadurch prüfbar. Wichtig: Guardrails wirken auf Eingabe und generierte Antwort, nicht auf die abgerufenen Referenzen selbst. Sensible Dokumente müssen vorher über S3, KMS, IAM und Datenklassifizierung begrenzt werden.

// src/rag.ts
import {
  BedrockAgentRuntimeClient,
  RetrieveAndGenerateCommand,
} from "@aws-sdk/client-bedrock-agent-runtime";

const agentRuntime = new BedrockAgentRuntimeClient({
  region: process.env.AWS_REGION ?? "us-east-1",
});

export async function askKnowledgeBase(question: string) {
  const knowledgeBaseId = process.env.BEDROCK_KNOWLEDGE_BASE_ID;
  const modelArn = process.env.BEDROCK_GENERATION_MODEL_ARN;

  if (!knowledgeBaseId || !modelArn) {
    throw new Error("Set BEDROCK_KNOWLEDGE_BASE_ID and BEDROCK_GENERATION_MODEL_ARN");
  }

  const response = await agentRuntime.send(
    new RetrieveAndGenerateCommand({
      input: { text: question },
      retrieveAndGenerateConfiguration: {
        type: "KNOWLEDGE_BASE",
        knowledgeBaseConfiguration: {
          knowledgeBaseId,
          modelArn,
          retrievalConfiguration: {
            vectorSearchConfiguration: { numberOfResults: 5 },
          },
        },
      },
    })
  );

  const sources =
    response.citations
      ?.flatMap((citation) => citation.retrievedReferences ?? [])
      .map((reference) => reference.location?.s3Location?.uri)
      .filter(Boolean) ?? [];

  return { answer: response.output?.text ?? "", sources };
}

Logs und Kosten

Nutze zwei Log-Ebenen. App-Logs enthalten requestId, Feature, Caller-Typ, Model ID, usage, Latenz und Stop Reason. Rohe Prompts sollten nur gespeichert werden, wenn Datenschutz- und Retention-Regeln das erlauben.

Bedrock model invocation logging kann nach CloudWatch Logs oder S3 schreiben. Das hilft bei Audit und Debugging, kann aber sensible Ein- und Ausgaben speichern. Definiere Retention, Verschlüsselung, S3 Lifecycle und Zugriffsrechte vor der breiten Aktivierung.

Kostenkontrolle beginnt mit serverseitigem maxTokens, taskabhängiger Modellauswahl, usage-Logging und IAM principal attribution. Prompt caching hilft bei langen, wiederholten Kontexten, aber kaum bei kurzen oder stark dynamischen Prompts.

Prompt für Claude Code

claude -p "
Füge diesem Repository Claude-Aufrufe über Amazon Bedrock hinzu.

Anforderungen:
- AWS SDK v3 Converse API verwenden
- Model ID aus BEDROCK_MODEL_ID lesen
- AWS_REGION default auf us-east-1 setzen
- maxTokens serverseitig auf 1200 begrenzen
- requestMetadata mit requestId, feature und userId hinzufügen
- guardrailConfig nur setzen, wenn BEDROCK_GUARDRAIL_ID vorhanden ist
- usage, latencyMs und stopReason als JSON loggen
- ValidationException nicht retryen
- ThrottlingException und ServiceUnavailableException als retryable behandeln
- Least-Privilege-IAM-Policy in README dokumentieren
- Bedrock Client in Tests mocken; keine echte API aufrufen

Vor Änderungen Plan zeigen, danach typecheck und Testergebnis berichten.
"

Häufige Fehler

Erstens: Modellzugriff nicht prüfen. Teste list-foundation-models und einen kleinen Converse-Aufruf.

Zweitens: Model ID aus einem Artikel fest einbauen. Nutze Konfiguration und Startup-Validierung.

Drittens: Guardrails als Wahrheitsgarantie verstehen. Sie helfen bei Sicherheitsrichtlinien, ersetzen aber keine Fachprüfung, Autorisierung oder menschliche Freigabe.

Viertens: Zu viel loggen. Vollständige Prompts sind hilfreich beim Debugging, können aber personenbezogene oder interne Daten langfristig speichern.

Fünftens: Falsche Fehler retryen. Validation braucht Korrektur; Throttling und temporäre Servicefehler können retried werden.

Sechstens: Kosten nur im Frontend begrenzen. Wirkliche Limits gehören in die API.

Monetarisierung

Der Wert eines Bedrock-Artikels liegt nicht im SDK-Snippet, sondern im Weg vom Demo zur Produktion: IAM, Logs, Kosten, Guardrails, Reviews und Team-Rollout. Für wiederverwendbare Vorlagen nutze ClaudeCodeLab Produkte. Für repository-spezifische Einführung mit CLAUDE.md, IAM-Review, Verification Receipts und CI-Gates nutze Claude Code Training und Beratung.

Weitere Artikel: Claude Code AWS Lambda, Claude Code AWS IAM, Claude Code API-Kosten und Verification Receipt Workflow.

Praktisches Ergebnis

Im Test kam der größte Gewinn nicht durch mehr Code, sondern durch klarere Vorgaben an Claude Code: Model ID aus Environment, usage loggen, ValidationException nicht retryen, Guardrails optional über Environment und IAM-Policy in README. Die Diffs wurden kleiner und Reviews einfacher. Bedrock gelingt weniger durch SDK-Auswendiglernen, sondern durch klare Produktionsbedingungen vor der Codegenerierung.

#claude-code #aws #bedrock #anthropic #typescript #generative-ai
Kostenlos

Kostenloses PDF: Claude-Code-Cheatsheet

E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.

Wir schützen Ihre Daten und senden keinen Spam.

Masa

Über den Autor

Masa

Engineer für praktische Claude-Code-Workflows und Team-Einführung.