Use Cases (Atualizado: 03/06/2026)

Claude Code × Amazon Bedrock: guia prático para rodar Claude em produção na AWS

Use Claude Code e Amazon Bedrock em produção: IAM, Converse API, logs, Guardrails e controle de custos.

Claude Code × Amazon Bedrock: guia prático para rodar Claude em produção na AWS

Chamar a API da Anthropic diretamente é o caminho mais rápido para um protótipo com Claude. Em produção na AWS, a conversa muda: gestão de API keys, limites de IAM, logs de auditoria, atribuição de custos, retenção de dados, retries e quotas. É aí que Amazon Bedrock como runtime para Claude se torna uma opção prática.

Amazon Bedrock é o serviço gerenciado de foundation models da AWS. Na prática, ele permite invocar Claude usando identidade, permissões, logs, cobrança e controles operacionais da AWS. Claude Code continua útil, mas não peça apenas um demo. Peça código revisável: IAM, chamada de modelo, Guardrails, logging, tratamento de erros e limites de custo.

A lição de Masa em projetos reais foi simples: um demo de Bedrock funciona rápido, mas a revisão de produção pergunta coisas difíceis. Qual role invoca o modelo? Quais modelos são permitidos? O que acontece em throttling? Prompts são armazenados? Como atribuir custo por equipe? Este guia transforma essas perguntas em implementação.

Este artigo segue a documentação oficial da AWS consultada em 3 de junho de 2026. Model IDs, Regions, quotas e preços do Bedrock podem mudar; confirme nas fontes oficiais antes de publicar ou implantar.

Arquitetura de produção

Não comece pedindo ao Claude Code “adicione um chat com Bedrock”. Primeiro defina chamador, runtime, modelo, Guardrails, logs e atribuição de custos.

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 é a interface de chat unificada do Bedrock. Guardrails avalia entradas e respostas do modelo com políticas de segurança configuradas. model invocation logging pode enviar dados de chamada para CloudWatch Logs ou S3. IAM principal attribution ajuda a acompanhar custos por usuário ou role IAM.

Casos de uso

O primeiro caso é Q&A sobre documentação interna. Runbooks, especificações e processos ficam em S3 e Knowledge Bases; trechos relevantes são recuperados e Claude responde com citações. Isso é RAG, ou retrieval augmented generation.

O segundo caso é rascunho de respostas de suporte. Claude combina pergunta do cliente, plano contratado e templates aprovados para criar uma resposta que um operador revisa. Antes da automação total, mantenha revisão humana, Guardrails, tratamento de dados pessoais e logs de auditoria.

O terceiro caso é um assistente de operações para engenharia. Ele resume logs do CloudWatch, cria checklists de deploy, prepara notas de incidente e transforma runbooks em tarefas. Claude Code ajuda porque consegue alterar API, Lambda, IAM, testes e documentação em uma mudança revisável.

O quarto caso é operação de conteúdo em sites como ClaudeCodeLab. QA de artigos, tamanho de description, links internos e revisão de blocos de código podem rodar dentro do IAM e da cobrança AWS. Se conteúdo afeta receita, combine com o guia de custos do Claude Code e o workflow de verificação.

Configuração

Você precisa de Node.js 20 ou superior, credenciais AWS CLI, uma conta com Bedrock e um modelo Anthropic disponível na Region escolhida. Dependendo da conta, modelos Anthropic podem exigir informações de primeiro uso, permissões AWS Marketplace e método de pagamento válido.

Não fixe um model ID copiado de um artigo. Liste os modelos disponíveis na sua conta e use variável de ambiente.

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}"

Crie um projeto TypeScript mínimo.

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

Adicione scripts ao package.json.

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

IAM mínimo

Mesmo com Converse API, IAM precisa permitir invocação de modelo. Chamadas sem streaming usam bedrock:InvokeModel; streaming usa bedrock:InvokeModelWithResponseStream. Separe permissões de logs da aplicação da configuração de model invocation logging do Bedrock.

{
  "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"
    }
  ]
}

Troque conta, Regions, Guardrail e escopo de modelos. Se usar cross-Region inference, inclua o inference profile e os ARNs dos modelos de destino. Para revisão de privilégio mínimo, veja o guia AWS IAM com Claude Code.

Invocar Claude

O detalhe de produção é requestMetadata. A AWS documenta esse campo como útil para filtrar logs de invocação, então inclua request ID, feature e categoria do usuário.

// 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);

Execute:

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

npm run chat -- "Explique Amazon Bedrock em três linhas"
npm run stream -- "Crie uma checklist de produção para Bedrock"
npm run typecheck

Padrão Lambda

No Lambda, inicialize o cliente fora do handler, valide entrada e limite maxTokens no servidor.

// 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" }),
    };
  }
};

Não faça retry cego de ValidationException; normalmente é entrada ou parâmetro inválido. ThrottlingException e ServiceUnavailableException aceitam backoff exponencial com jitter. Para serverless completo, leia Claude Code × AWS Lambda.

RAG com Knowledge Bases

Para chat com documentos internos, Bedrock Knowledge Bases é um bom começo antes de criar um vector store próprio. Ele retorna respostas com citações, facilitando validação. Atenção: Guardrails se aplica à entrada e à resposta gerada, não às referências recuperadas. Restrinja documentos sensíveis com S3, KMS, IAM e classificação de dados.

// 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 e custos

Use duas camadas de logs. Logs da aplicação devem incluir requestId, feature, tipo de usuário, modelo, usage, latência e stop reason. Evite guardar prompts brutos se a política de privacidade e retenção não permitir.

O model invocation logging do Bedrock pode escrever no CloudWatch Logs ou S3. Ele ajuda em auditoria, mas também pode armazenar entradas e saídas sensíveis. Defina retenção, criptografia, lifecycle de S3 e acesso antes de ativar amplamente.

Para custos, limite maxTokens na API, escolha modelo por complexidade, registre usage e use IAM principal attribution para agrupar gastos por role. Prompt caching ajuda com contextos longos e repetidos, não com prompts curtos ou totalmente dinâmicos.

Prompt para Claude Code

claude -p "
Adicione invocação de Claude via Amazon Bedrock a este repositório.

Requisitos:
- Usar AWS SDK v3 Converse API
- Ler o modelo de BEDROCK_MODEL_ID
- Usar us-east-1 se AWS_REGION não existir
- Limitar maxTokens a 1200 no servidor
- Adicionar requestMetadata com requestId, feature e userId
- Adicionar guardrailConfig somente se BEDROCK_GUARDRAIL_ID existir
- Logar usage, latencyMs e stopReason em JSON
- Não fazer retry de ValidationException
- Tratar ThrottlingException e ServiceUnavailableException como retryable
- Documentar política IAM de menor privilégio no README
- Mockar o cliente Bedrock nos testes; não chamar a API real

Mostre o plano antes de editar e reporte typecheck e testes no final.
"

Armadilhas comuns

A primeira é não verificar acesso ao modelo. Teste list-foundation-models e uma chamada Converse pequena.

A segunda é congelar um model ID de um artigo. Use configuração e validação no startup.

A terceira é tratar Guardrails como garantia de verdade. Ele ajuda em segurança, mas não substitui revisão humana, validação de domínio ou autorização.

A quarta é logar demais. Prompts completos ajudam no debug, mas podem vazar dados pessoais ou internos.

A quinta é repetir erros errados. Validation exige correção; throttling e falhas temporárias podem ter retry.

A sexta é controlar custos só no frontend. Limites reais pertencem à API.

Caminho de monetização

O valor de Bedrock não está no snippet do SDK, mas em sair do demo para produção: IAM, logs, custos, Guardrails, reviews e adoção em equipe. Para templates reutilizáveis, comece pelos produtos ClaudeCodeLab. Para rollout em um repositório real com CLAUDE.md, revisão IAM, verification receipts e CI gates, use treinamento e consultoria Claude Code.

Leituras relacionadas: Claude Code AWS Lambda, Claude Code AWS IAM, custos de Claude Code e workflow de verificação.

Resultado prático

Ao testar este padrão, o maior ganho não veio de mais abstrações, mas de um prompt mais claro para Claude Code: model ID por variável de ambiente, log de usage, não repetir ValidationException, Guardrails opcional por ambiente e política IAM no README. O diff ficou menor e a revisão mais objetiva. Sucesso com Bedrock depende menos de decorar o SDK e mais de declarar as restrições de produção antes de gerar código.

#claude-code #aws #bedrock #anthropic #typescript #generative-ai
Grátis

PDF grátis: cheatsheet do Claude Code

Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.

Cuidamos dos seus dados e não enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.