Pular para o conteúdo
fernando.moretes.com
BlogEstudosCursosE-booksOpen SourcePodcasts
Loading…
Fernando Azevedo

Arquiteto de TI Especialista

Arquitetura, AWS, IA em produção, sistemas financeiros e FinOps, escritos a partir do que foi operado, com os números.

  • LinkedIn
  • GitHub
  • E-mail

Conteúdo

  • Blog
  • Estudos de arquitetura
  • Cursos
  • E-books
  • Open Source
  • Podcasts
  • Assuntos
  • Trilhas

Ferramentas

  • Well-Architected self-check
  • Arquitetura deste site
  • Números públicos
  • Histórico de estudo

Sobre

  • Comunidade
  • IA Builder
  • Perfil
  • Currículo (CV)
  • Trabalhe comigo
  • Media kit
  • RSS do blog
  • RSS dos estudos
  • Artigos narrados (podcast)
  • llms.txt
  • Termos, privacidade e uso de IA

(c) 2026 Fernando Francisco Azevedo

Open Source/bedrock-agent-starter
Python

bedrock-agent-starter

Starter de agente no Bedrock com tools, memória, Terraform e evals já ligados

MITAtualizado em 29 de set. de 2026000 visualizações00 reproduções
Compartilhar:LinkedInWhatsAppXBaixar em Markdown
#ai#ai-agents#aws#bedrock#github-actions#lambda#moretes#portfolio#solution-architecture#terraform
Ver no GitHub Site
git clone https://github.com/fernando-moretes/app-bedrock-agent-starter.git
Ouvir guia

cerca de 4 min · áudio gerado ao tocar

O bedrock-agent-starter é um template em Python para colocar um agente de IA no Amazon Bedrock com o que um agente de verdade precisa: loop de tool-use sobre a Converse API, memória plugável, logs estruturados, métricas EMF, Terraform e um harness de evals.

Por que este repositório existe

Chamar um modelo no Bedrock é uma linha de SDK. Entregar um agente é outra coisa. Entre o converse() e um endpoint que alguém opera em produção existe uma lista de peças que todo time acaba montando do zero: registro de tools, memória entre turnos, log com session_id, métrica de tokens por turno, tratamento de erro de tool, IaC e alguma forma de saber se a mudança de prompt de ontem quebrou o comportamento de hoje.

O problema não é o esforço de escrever cada peça uma vez, é manter as peças coerentes entre si quando o modelo muda, quando entra uma tool nova ou quando alguém troca o backend de memória. Montei este starter para que essas decisões estejam tomadas e visíveis no código, num formato que dá para ler numa tarde.

A proposta é ser opinativo onde a opinião economiza tempo (Converse API, Pydantic para schema de tool, JSON estruturado no log) e substituível onde o contexto de cada empresa manda (backend de estado do Terraform, tags, naming, limites de IAM). Faça fork, configure AWS_REGION e o modelo, e você tem um agente respondendo no terminal antes de pensar em infraestrutura.

O que vem no template

Loop do agente: Bedrock Converse API com tool-use nativo, a mesma interface para Claude, Nova, Llama e Mistral.
Registro de tools: três tools prontas (calculator, get_time e um stub de web_search) e um decorator @tool para adicionar as suas.
Memória plugável: em memória no desenvolvimento local, DynamoDB em produção.
Observabilidade: log JSON por turno com session_id, turn, model_id e métricas EMF no namespace BedrockAgent.
Deploy e qualidade: Terraform para Lambda (Python 3.12), API Gateway HTTP API e DynamoDB; CI com ruff, mypy e pytest; docs em MkDocs Material.

Como uma pergunta percorre o agente

O mesmo núcleo em src/agent/ atende o CLI local e o handler Lambda. Só a borda e o backend de memória mudam.

💻 Local
  • agent chat · CLI
  • Memória · in-memory
🟧 AWS: entrada
  • API Gateway · HTTP API
  • Lambda · Python 3.12
🤖 Núcleo do agente
  • Agent loop · Converse API
  • Tool registry · @tool
  • Amazon Bedrock · BEDROCK_MODEL_ID
🟧 AWS: estado e telemetria
  • DynamoDB · sessions
  • CloudWatch · logs + EMF

Instalar e usar

  1. 1

    Clone e crie o ambiente

    Requer Python 3.11 ou superior. Crie um virtualenv e instale com pip install -e ".[dev]", que traz ruff, mypy e pytest junto.

  2. 2

    Configure credenciais e modelo

    Exporte AWS_REGION (ou AWS_PROFILE) e BEDROCK_MODEL_ID. O padrão do README é um Claude Sonnet; o modelo precisa estar habilitado na sua conta e região, senão a primeira chamada volta AccessDeniedException.

  3. 3

    Converse no terminal

    Rode agent chat. Cada chamada de tool aparece como linha [tool] antes da resposta, o que torna visível quando o modelo escolheu a tool errada.

  4. 4

    Rode as evals antes de mudar prompt ou modelo

    pytest tests/evals/ reexecuta golden.jsonl e falha se a substring ou a chamada de tool esperada sumir.

  5. 5

    Faça o deploy com Terraform

    Em terraform/, rode terraform init e terraform apply -var="project=my-agent". Defina antes o backend de estado: o template não traz um.

Quickstart: do clone ao primeiro turno
bash
git clone https://github.com/fernando-moretes/app-bedrock-agent-starter.git
cd app-bedrock-agent-starter
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

export AWS_REGION=us-east-1
export BEDROCK_MODEL_ID=anthropic.claude-3-5-sonnet-20241022-v2:0

agent chat
# > what time is it in Tokyo, and what is (123 * 456) - 789?
# [tool] get_time(tz="Asia/Tokyo")
# [tool] calculator(expression="(123 * 456) - 789") -> 55299

Como o loop funciona

A escolha central foi a Converse API em vez de InvokeModel. Com InvokeModel, cada família de modelo tem seu próprio formato de payload, e trocar Claude por Nova vira refatoração. A Converse normaliza mensagens, toolConfig e blocos toolUse/toolResult, então BEDROCK_MODEL_ID passa a ser configuração, não código.

O turno segue o ciclo clássico: o agente envia o histórico e a lista de tools, o modelo responde com texto ou com um ou mais toolUse, o registro executa a função Python correspondente, o resultado volta como toolResult e o ciclo repete até o modelo devolver texto final. Na pergunta do exemplo, get_time e calculator entram no mesmo turno.

O histórico mora atrás de uma interface de memória. Local, fica num dicionário e some quando o processo termina. Na Lambda, vai para a tabela DynamoDB de sessões, chaveada por session_id, que é o que permite conversa de vários turnos sobre uma função sem estado.

O CLI e o handler Lambda chamam o mesmo núcleo em src/agent/. Isso importa mais do que parece: o comportamento que você valida no terminal é o que vai para produção, e as evals exercitam o mesmo código.

Uma tool nova é um decorator e uma função; o schema JSON sai das anotações via Pydantic
python
# src/agent/tools.py
from agent.tools import tool

@tool(description="Translate text between languages using a deterministic table.")
def translate(text: str, source_lang: str, target_lang: str) -> str:
    ...
    return translated

Observabilidade e evals: o que separa demo de serviço

Cada turno emite uma linha JSON com session_id, turn, model_id, input_tokens, output_tokens, tool_calls e duration_ms. Com isso, uma busca no CloudWatch Logs Insights por session_id reconstrói a conversa inteira de um usuário que reclamou, sem guardar prompt em texto livre em outro lugar.

As métricas vão em formato EMF para o namespace BedrockAgent: Turns, InputTokens, OutputTokens, Duration e ToolErrors. EMF evita chamar PutMetricData no caminho da requisição; a métrica sai do próprio log. InputTokens é a que vira alarme de custo, porque histórico longo cresce o input a cada turno sem ninguém perceber. ToolErrors é a que avisa de falha silenciosa: o modelo costuma contornar uma tool quebrada e responder algo plausível, e sem essa métrica o erro só aparece na reclamação.

O harness de evals é deliberadamente simples: um golden.jsonl com prompt, substring esperada e tool esperada, executado pelo pytest. Não mede qualidade semântica. Mede regressão, que é o defeito mais comum quando alguém troca o modelo ou reescreve o system prompt numa sexta-feira.

O que o Terraform deixa para você, de propósito

O módulo provisiona Lambda, API Gateway HTTP API, tabela DynamoDB, roles IAM e log group. Backend de estado, tags, naming e permission boundaries ficam de fora porque cada organização já tem os seus. Rodar terraform apply sem backend remoto grava o estado local na sua máquina: o próximo colega que aplicar vai tentar recriar tudo. Configure o backend e revise a policy da role da Lambda (escopo de bedrock:InvokeModel por ARN de modelo) antes do primeiro deploy.

Perguntas frequentes

Preciso usar Claude?

Não. Como o loop usa a Converse API, basta trocar BEDROCK_MODEL_ID por um modelo Nova, Llama ou Mistral habilitado na sua conta. Confira se o modelo escolhido suporta tool-use na Converse; nem todos suportam.

A tool web_search funciona?

Não, é um stub. Ela existe para mostrar o formato de uma tool que chama serviço externo. Ligar a um provedor real é trabalho seu, inclusive timeout e tratamento de erro.

Por que não Bedrock Agents gerenciado?

Use o serviço gerenciado quando quiser que a AWS opere o loop e aceitar a configuração dele. Este starter serve quando você quer o loop em código Python, testável com pytest e com log e métrica sob seu controle.

Para quem é

Use quando você precisa de um agente com poucas tools, conversa de vários turnos e um endpoint HTTP, e quer começar com observabilidade e evals já no lugar em vez de adicioná-las depois do primeiro incidente. Não use como está se o seu caso exige orquestração de vários agentes, RAG com base vetorial ou guardrails de conteúdo: nada disso vem no template, e o esforço de adaptação passa a ser maior que o de partir de outra base. Trate-o como esqueleto a ser lido e cortado, não como framework a ser seguido.

Referências

GitHub: fernando-moretes/app-bedrock-agent-starterDocumentação do projeto / Project docsAmazon Bedrock: Converse API
Curte open source e arquitetura? Receba mais.

Deep dives de arquitetura, AWS, IA e mercado: direto no seu email. Grátis.

Sem spam · cancele quando quiser

Guia gerado com IA a partir do repositório e do README. · Fonte

Continue lendo

Pythonmcp-aws-solution-architectServidor MCP bilíngue com 5 ferramentas determinísticas para arquitetura AWSLer HCLaws-ai-reference-architecturesSeis arquiteturas de IA na AWS com decisões, custo S/M/L e TerraformLer HTMLaws-agentic-ai-reference-architectureArquitetura de referência para IA agêntica na AWS que aguenta produção, não só demoLer