ToolSimulator: AWS lança framework pra testar agentes de IA sem chamar API real
A AWS soltou o ToolSimulator, framework dentro do Strands Evals que usa LLM pra simular tool calls de agentes. Em vez de bater em API real (com risco de vazar PII, disparar ações indevidas ou lidar com rate limit), o simulator gera respostas adaptativas, mantém estado entre chamadas e valida schema Pydantic. Disponível hoje via `pip install strands-evals`.
Mock por LLM resolve o problema real de testar agente multi-turno sem quebrar mock estático toda semana. Só que adiciona latência e custo de inferência no CI — fica de olho no budget se você tem milhares de test cases rodando em pipeline.
A AWS lançou o ToolSimulator, framework de simulação de tools via LLM que vive dentro do Strands Evals. A ideia é testar agentes de IA que dependem de ferramentas externas sem bater em API real.
Roda localmente (não precisa de conta AWS pra começar) e já sai com pip install strands-evals.
O problema que ataca
Agente moderno não só raciocina. Ele chama API, consulta banco, invoca serviço MCP (Model Context Protocol) e mexe com sistema externo. O comportamento do agente depende do que essas tools retornam, e testar contra API real traz três dores:
- Rate limit e downtime te travam. Rodar centenas de test cases contra API viva vira inviável.
- Side effect é risco real. Teste pode mandar email de verdade, modificar banco de produção ou reservar voo.
- PII (dados pessoais) cria barreira de compliance. Rodar teste contra sistema real expõe dado sensível sem necessidade.
A alternativa óbvia, mock estático, quebra em workflow multi-turno. Agente de reserva de voo que busca voo numa chamada e checa status de booking na seguinte precisa que a segunda resposta reflita o que a primeira fez. Mock hardcoded não captura isso.
O que o ToolSimulator faz diferente
Três capacidades que trabalham juntas:
- Resposta adaptativa. Output da tool reflete o que o agente pediu de verdade. Busca voo SEA→JFK? Volta opções plausíveis com preço e horário realista, não placeholder genérico.
- Estado compartilhado entre chamadas. Write operation afeta read subsequente. Dá pra testar interação com banco e fluxo de booking sem tocar produção.
- Schema enforcement. Valida resposta contra modelo Pydantic que você define, pegando resposta malformada antes dela chegar no agente.
Como funciona na prática
O fluxo são três passos: decorar e registrar tool, opcionalmente guiar a simulação com contexto, e deixar o ToolSimulator mockar quando o agente rodar.
Passo 1, decora e registra:
from strands_evals.simulation.tool_simulator import ToolSimulator
tool_simulator = ToolSimulator()
@tool_simulator.tool()
def search_flights(origin: str, destination: str, date: str) -> dict:
"""Search for available flights between two airports on a given date."""
pass # implementação real nunca é chamada durante simulação
Passo 2, guia opcional via três parâmetros:
share_state_id: liga tools que compartilham o mesmo backend. Setter de uma vira visível pro getter da outra.initial_state_description: descrição em linguagem natural do estado pré-existente. Quanto mais rico o contexto, mais consistente a resposta.output_schema: modelo Pydantic definindo a estrutura esperada. ToolSimulator gera resposta que bate com o schema.
Passo 3, mock automático. Quando o agente chama a tool registrada, o wrapper intercepta, valida parâmetro contra schema, gera resposta conforme output_schema e atualiza o registry de estado.
Workflow multi-turno com estado
Exemplo clássico, sistema de booking de voo com duas tools no mesmo share_state_id:
@tool_simulator.tool(
share_state_id="flight_booking",
initial_state_description="Flight booking system: SEA->JFK flights at 8am, 12pm, and 6pm. No bookings currently active.",
)
def search_flights(origin: str, destination: str, date: str) -> dict:
pass
@tool_simulator.tool(share_state_id="flight_booking")
def get_booking_status(booking_id: str) -> dict:
pass
Dá pra inspecionar o estado antes e depois de rodar o agente com tool_simulator.get_state("flight_booking"), validando não só o output final, mas a sequência inteira de interações.
Dica boa do próprio post: como initial_state_description aceita linguagem natural, dá pra jogar o output de DataFrame.describe() como seed. O simulator gera resposta que reflete a distribuição estatística real, sem nunca acessar os dados originais.
Integração com Strands Evals
Encaixa direto no pipeline de avaliação do Strands. O post traz exemplo completo usando GoalSuccessRateEvaluator pra pontuar performance em tarefa de tool calling, com telemetria via StrandsEvalsTelemetry exportando pra memória e StrandsInMemorySessionMapper montando a trajetória da sessão.
O trajectory dá pros evaluators acesso à sequência completa de tool calls e invocações de modelo, não só a resposta final.
Boas práticas que o time recomenda
- Começa com config padrão. Só override quando precisar de controle preciso.
- Enche o
initial_state_descriptionde contexto. Inclui faixa de dados, contagem de entidades, relação entre eles. - Usa
share_state_idem tool que mexe com o mesmo backend. - Aplica
output_schemaem tool com spec estrita tipo OpenAPI ou MCP. - Valida a sequência de interações, não só output final.
- Começa pequeno e expande. Complementa simulação com teste direcionado contra API real em caminhos críticos de produção.
Na prática, pra quem já roda Strands Evals, isso entra como parte natural do pipeline de CI. Pra quem usa outro framework de agente (LangGraph, CrewAI, custom), vai precisar adaptar, mas a ideia de mock adaptativo por LLM é portável.
Disponibilidade
Instalação: pip install strands-evals. Backend de LLM pra geração de resposta pode ir via Amazon Bedrock. Conta AWS não é obrigatória pra rodar local.
☕ comentários · 0