Conteúdo da trilha
8 minNarração em inglês, legenda em portuguêsPodcast (RSS)
Capítulos
  1. 0:00Abertura
  2. 1:01A ideia
  3. 1:42Como funciona
  4. 2:14Um caso real
  5. 3:26Um desafio
  6. 4:17Quando não usar
  7. 5:39Em produção
  8. 7:20Fechamento
Transcrição

Abertura

O Fábio cuida do assistente de back office de uma distribuidora. O agente concilia pagamentos, emite notas, consulta estoque, abre chamados com transportadoras e responde dúvidas de comissão.

Depois de fundir as ferramentas duplicadas, sobraram trinta e quatro. Todas legítimas, todas diferentes. E alguém usa cada uma delas.

Mas o agente ainda erra. Num pedido de conciliação, ele chama check stock em vez de find payment. As duas recebem um código de pedido, e as descrições começam igual. O trace mostra o modelo hesitando entre ferramentas que nem deviam estar na mesa.

E tem a conta. Toda chamada leva as trinta e quatro definições. Num loop de seis turnos, elas vão para o modelo seis vezes.

O Fábio não pode tirar ferramentas. O que ele pode mudar é quantas o modelo vê de cada vez. É esta aula.

A ideia

Organize as ferramentas em grupos por assunto. Conciliação, notas, estoque e logística, cada um no seu grupo. Antes de o loop do agente começar, uma etapa curta decide de quais grupos esta tarefa precisa. E o agente principal roda só com esses grupos.

O movimento central é tirar uma escolha do modelo grande e colocar numa etapa pequena, barata e testável. O agente principal para de responder qual destas trinta e quatro, e passa a responder qual destas oito. E sempre existe um caminho de volta. Se o agente descobre que precisa de outro grupo, ele pode pedir.

Como funciona

A tarefa chega, como texto de uma pessoa ou um evento do sistema.

Um modelo pequeno lê a tarefa e a lista de grupos, uma linha de descrição para cada.

O catálogo guarda os grupos e as ferramentas de cada grupo, versionado.

O roteador devolve os grupos escolhidos, e a confiança dele.

O agente principal roda com as ferramentas desses grupos, mais uma ferramenta extra, para pedir outro grupo.

As ferramentas rodam normalmente.

E a resposta sai, com o trace registrando quais grupos foram usados.

Um caso real

Chega uma tarefa. Concilie o pagamento do pedido 88231 com o extrato de ontem e, se bater, dê baixa no boleto. O roteador recebe a tarefa e quatro linhas, uma por grupo.

Financeiro: use para conciliar pagamentos com extratos e dar baixa em boletos.

Notas, estoque e logística, cada um com o seu uso.

Ele devolve: financeiro, com 92% de confiança. O agente principal roda com as sete ferramentas de financeiro, mais a de pedir grupo. A ferramenta de estoque que causava a confusão nem aparece. E uma ferramenta que não está na lista não tem como ser escolhida por engano.

Agora a conta, com números ilustrativos. Digamos que cada definição de ferramenta ocupa uns duzentos e cinquenta tokens. As trinta e quatro somam uns oito mil e quinhentos tokens por chamada.

Num loop de seis turnos, são uns cinquenta e um mil tokens só de definições.

Com oito ferramentas, a mesma tarefa leva uns doze mil. O roteador custa uma chamada curta num modelo pequeno. Ele paga uma vez. A economia acontece em todo turno.

Um desafio

Uma pergunta para você. Uma semana depois de colocar o roteador no ar, o painel mostra que em 40% das tarefas de cobrança, o agente pede o grupo de notas no meio da execução. Qual é a correção mais direta?

Incluir notas na seleção inicial das tarefas de cobrança, ajustando a descrição do roteador ou os exemplos dele. Um grupo pedido com frequência, no mesmo tipo de tarefa, quer dizer que a seleção inicial está estreita demais. Expansão é saída de emergência, não o caminho normal.

Tirar a ferramenta de pedir grupo, porque ela deixa o agente lento, deixaria essas tarefas sem a ferramenta certa. E juntar todos os grupos num só desfaz o padrão. Cobrança e notas aparecem juntas, então entram juntas.

Quando não usar

Se o agente tem poucas ferramentas, consolide primeiro. Foi a última aula.

Se as tarefas cruzam todos os assuntos o tempo todo, o roteador sempre escolheria tudo.

Se o seu provedor oferece busca de ferramentas sob demanda, e o seu único problema é custo de token, esse mecanismo resolve, sem uma etapa extra sua.

E se o canal de entrada já diz o assunto, como uma fila ou um tipo de evento, use uma regra fixa no código. Sem modelo, custo zero, e zero erro de classificação.

Agora as armadilhas comuns. Agrupar por sistema, não por tarefa. Tudo que fala com o ERP vira um grupo de vinte e cinco ferramentas. Agrupe pelo que a pessoa quer fazer. Como conciliar, emitir ou despachar um pedido.

Descrever o conteúdo, não o uso. Ferramentas de financeiro não ajuda o roteador. Use para conciliar pagamentos com extratos ajuda, porque bate com o jeito que as tarefas chegam.

Um conjunto padrão com efeito colateral. Confiança baixa quer dizer que o roteador está em dúvida. O padrão seguro é só leitura. Não tudo, por via das dúvidas.

E esquecer a saída de emergência. Sem um jeito de pedir grupo, um erro do roteador vira um agente que responde sem a ferramenta certa. Ou inventa o dado.

Em produção

A falha mais cara aqui é a silenciosa. O grupo certo ficou de fora, e o agente não pediu. Ele responde não encontrei o pagamento, com toda a calma. Por isso a cobertura é o que mais importa. Em quantas tarefas os grupos escolhidos incluem toda ferramenta que a solução correta usa?

Mas cobertura e tamanho puxam para lados opostos. Um roteador que sempre escolhe tudo tem cobertura perfeita, e não serve para nada. Acompanhe os dois juntos.

E vigie a taxa de expansão por grupo. Um grupo pedido com frequência deve entrar na seleção inicial daquele tipo de tarefa.

Dá para montar o dataset do roteador com os traces que você já tem. Para cada tarefa resolvida com sucesso, os grupos esperados são os grupos das ferramentas que o agente chamou de fato. Inclua de propósito tarefas que cruzam assuntos, como emita a nota e agende a coleta. E vagas, como veja o que aconteceu com este pedido. E quando acrescentar uma ferramenta, rode de novo o eval do roteador. Uma descrição de grupo alterada pode desviar tarefas que antes iam para o lugar certo.

E um ponto de segurança. O roteador diminui a superfície. Ferramentas com efeito colateral só aparecem nas rotas que precisam delas. Uma pergunta sobre prazo de entrega não tem como disparar um estorno. Mas não trate isso como controle de acesso. Um texto malicioso dentro da tarefa consegue convencer o roteador a escolher outro grupo, e o agente pode pedir grupos sozinho. Permissão de verdade mora na ferramenta e no backend. Quem é o usuário, o que ele pode fazer e qual o limite de valor.

Fechamento

Então, a ideia para levar. Quando toda ferramenta é legítima, mas nenhuma tarefa precisa de todas, escolha a caixa de ferramentas antes de o trabalho começar. Uma etapa pequena escolhe os grupos, o agente trabalha com uma lista curta e um jeito de pedir mais, e você mede cobertura e tamanho juntos.

Na próxima aula, a gente sai das ferramentas e vai para a conversa em si, e o que acontece quando ela fica longa: context rot. Até lá.

PadrãoFerramentas e ação

Roteador de Ferramentas

Tool Router

Roteador de Ferramentas (Tool Router) é um padrão de projeto de IA para apps com LLM e agentes, do grupo Ferramentas e ação. Escolher um subconjunto pequeno de ferramentas antes de chamar o modelo principal.

Elemento
31/70
Nível
Intermediário
Leitura
9 min
Atualizado
Nesta página 18
  1. 01Intenção
  2. 02Problema
  3. 03Solução
  4. 04Estrutura
  5. 05Pseudocódigo
  6. 06Cenários reais
  7. 07Aplicabilidade
  8. 08Quando não usar
  9. 09Como implementar
  10. 10Variações
  11. 11Custo, latência e falhas
  12. 12Como avaliar
  13. 13Em produção
  14. 14Segurança
  15. 15Prós e contras
  16. 16Relações
  17. 17Código
  18. 18Teste seu entendimento
  19. ··Perguntas rápidas

Intenção

Escolher um subconjunto pequeno de ferramentas antes de chamar o modelo principal. Serve para agentes que cobrem muitos assuntos e precisam de muitas ferramentas no total, mas poucas em cada tarefa.

Em uma frase
Um mecânico que leva para o carro só a maleta do conserto da vez, não a oficina inteira.

Problema

Fábio cuida do assistente de back-office de uma distribuidora. O agente concilia pagamentos, emite notas fiscais, consulta estoque, abre chamados com transportadoras e responde dúvidas de comissão. Depois de consolidar as ferramentas duplicadas, sobraram 34, todas legítimas e diferentes entre si.

Mesmo assim o agente erra. Num pedido de conciliação, ele chama consultar_estoque em vez de buscar_pagamento, porque as duas recebem um código de pedido e as descrições começam parecidas. O trace mostra o modelo hesitando entre ferramentas que nem deveriam estar na mesa.

Tem também a conta. Cada chamada leva as 34 definições, e o contexto de toda tarefa começa com milhares de tokens de ferramentas que não têm nada a ver com ela. Num loop de seis voltas, essas definições vão seis vezes para o modelo.

Fábio não pode remover ferramentas: todas são usadas por alguém. O que ele pode mudar é quantas o modelo vê de cada vez.

A pergunta que este padrão responde: como manter muitas ferramentas no sistema sem obrigar o modelo a escolher entre todas em toda chamada?

Solução

Organize as ferramentas em grupos por assunto (conciliação, notas, estoque, logística). Antes do loop do agente, um passo curto decide quais grupos a tarefa precisa. O agente principal roda só com esses grupos.

O roteador pode ser um modelo pequeno com saída estruturada, uma busca por similaridade entre a tarefa e a descrição dos grupos, ou regras simples quando o canal já diz o assunto. Sempre exista um caminho de volta: se o agente perceber que precisa de outro grupo, ele pode pedir.

A escolha que importa é tirada do modelo grande e colocada num passo pequeno, testável e barato. O agente principal deixa de responder “qual destas 34?” e passa a responder “qual destas 8?”.

Exemplo trabalhado

Chega a tarefa: “Concilia o pagamento do pedido 88231 com o extrato de ontem e, se bater, dá baixa no título”. O roteador recebe a tarefa e quatro linhas de descrição, uma por grupo:

billing:   Use para conciliar pagamentos com extratos e dar baixa em títulos.
invoices:  Use para emitir, cancelar ou consultar notas fiscais (NF-e).
stock:     Use para saldo, reserva e movimentação de estoque.
logistics: Use para frete, coleta e chamados com transportadoras.

E devolve uma saída estruturada curta:

{ "groups": ["billing"], "confidence": 0.92 }

O agente principal roda com as 7 ferramentas de billing e mais request_group. A ferramenta de estoque, que causava a confusão, nem aparece.

Agora a conta, com números ilustrativos. Suponha que cada definição de ferramenta ocupe uns 250 tokens. As 34 somam cerca de 8.500 tokens por chamada; num loop de seis voltas, são uns 51 mil tokens só de definições. Com 8 ferramentas, a mesma tarefa carrega uns 12 mil. O roteador custa uma chamada curta num modelo pequeno, com o texto da tarefa e quatro linhas de grupo.

Os números exatos variam com o seu catálogo e o seu provedor. O formato da conta não varia: o roteador paga uma vez, a economia acontece em toda volta do loop.

Checagem +20 XP de primeiraO agente de Fábio confunde consultar_estoque com buscar_pagamento porque as duas recebem um código de pedido. Ele adota o Roteador de Ferramentas. Por que isso tende a reduzir esse erro específico?

Estrutura

flowchart LR
  IN(["1. Tarefa"]):::io --> R(["2. Roteador de ferramentas"]):::llm
  C[("3. Catálogo de grupos")]:::store --> R
  R --> S["4. Subconjunto escolhido"]:::tool
  S --> A(["5. Agente principal"]):::llm
  A --> T["6. Ferramentas do grupo"]:::tool
  T --> A
  A -->|"precisa de outro grupo"| R
  A --> OUT(["7. Resposta"]):::io
  1. A tarefa chega como texto do usuário ou evento do sistema.
  2. Um modelo pequeno lê a tarefa e a lista de grupos, com uma linha de descrição cada.
  3. O catálogo guarda os grupos e as ferramentas de cada um, versionados.
  4. O roteador devolve os grupos escolhidos e a confiança.
  5. O agente principal roda com as ferramentas desses grupos e mais uma ferramenta para pedir outro grupo.
  6. As ferramentas executam normalmente.
  7. A resposta sai e o trace registra quais grupos foram usados.

Pseudocódigo

schema Selection { groups: list["billing" | "invoices" | "stock" | "logistics"], confidence: float }

GROUPS = catalog.load("tool-groups@4")

function handle(task):
    # 2. escolher grupos com modelo pequeno
    sel = llm(ROUTER_PROMPT + GROUPS.summaries(), task) -> Selection
    trace.span("tool_route", sel)

    if sel.confidence < 0.6:
        sel.groups = GROUPS.default_set()           # 4. conjunto padrão seguro

    tools = GROUPS.tools_for(sel.groups) + [request_group]
    # 5 e 6. agente principal só com o subconjunto
    while budget.check():
        reply = llm_with_tools(AGENT_PROMPT, tools, state)
        if reply.is_final:
            return reply.text                        # 7
        for call in reply.tool_calls:
            if call.name == "request_group":
                tools += GROUPS.tools_for([call.args.group])
                trace.span("tool_route_expand", call.args)
            state.add(execute(call))

Cenários reais

  • Automação de back-office com execução durável. Conciliação, emissão de notas e cobrança têm ferramentas próprias. Cada processo começa com o grupo do seu assunto e pede outro grupo só quando precisa. O que muda: o processo de cobrança nunca vê a ferramenta que cancela NF-e.
  • Bot de suporte com escalonamento humano. O roteador de intenção já escolhe a rota; cada rota recebe só as ferramentas do seu assunto, e as de efeito ficam fora das rotas de dúvida. O que muda: uma pergunta sobre prazo de entrega não tem como disparar um estorno.

Aplicabilidade

  • O agente tem mais de 15 ou 20 ferramentas, todas necessárias, de assuntos diferentes.
  • Cada tarefa usa ferramentas de um ou dois assuntos.
  • As definições de ferramenta ocupam uma parte grande do contexto de cada chamada.
  • Você quer limitar quais ferramentas de efeito ficam ao alcance em cada tipo de tarefa.

Quando não usar

  • O agente tem poucas ferramentas. Consolide antes: veja Consolidar Ferramentas.
  • As tarefas cruzam todos os assuntos o tempo todo. O roteador sempre escolheria tudo.
  • O provedor oferece busca de ferramentas sob demanda e o seu problema é só o custo em tokens. Esse mecanismo resolve sem um passo extra; veja também Revelação Progressiva.
  • O canal de entrada já define o assunto. Use uma regra fixa em código, sem modelo.

Como implementar

  1. Agrupe as ferramentas por assunto, com no máximo 8 a 10 por grupo.
  2. Escreva uma descrição de uma linha por grupo, focada em quando usar.
  3. Defina um conjunto padrão para baixa confiança: o grupo mais comum ou só ferramentas de leitura.
  4. Implemente o roteador com saída estruturada e um modelo pequeno.
  5. Dê ao agente uma ferramenta request_group para pedir um grupo que ficou de fora.
  6. Monte um eval do roteador sozinho: tarefa e grupos esperados.
  7. Rode o eval completo do agente e compare com a versão sem roteador.

Armadilhas comuns

  • Agrupar por sistema, não por tarefa. “Tudo que fala com o ERP” vira um grupo de 25 ferramentas. Agrupe pelo que a pessoa quer fazer: conciliar, emitir, despachar.
  • Descrever o conteúdo, não o uso. “Ferramentas de faturamento” não ajuda o roteador. “Use para conciliar pagamentos com extratos” ajuda, porque bate com o jeito como as tarefas chegam.
  • Conjunto padrão com efeito. Se a confiança é baixa, o roteador está em dúvida. O padrão seguro é leitura, não “tudo, por garantia”.
  • Esquecer a saída de emergência. Sem request_group, um erro do roteador vira um agente que responde sem a ferramenta certa, ou que inventa o dado.

Variações

  • Roteamento por embedding. Compare a tarefa com exemplos ou descrições de cada grupo. Sem chamada de modelo, mais fraco em tarefas ambíguas.
  • Roteamento por regra. Fila, canal ou tipo de evento define o grupo. Zero custo, zero erro de classificação, só funciona quando o assunto vem na entrada.
  • Busca de ferramentas pelo provedor. O modelo vê um índice e carrega a definição completa quando precisa. Resolve o custo de tokens e parte da confusão.
  • Roteador por agente. Em vez de grupos de ferramentas, cada rota leva a um agente especializado. Aí o padrão vira Roteamento ou uma passagem entre agentes.
Variação Custo extra Lida com ambiguidade Quando escolher
Regra nenhum não o canal já diz o assunto
Embedding uma busca pouco muitos grupos, tarefas curtas e claras
Modelo pequeno uma chamada bem tarefas em texto livre que misturam assuntos
Busca do provedor nenhum passo seu depende do provedor o problema principal é token

Custo, latência e falhas

Aspecto O que acontece Como aparece no trace
Chamadas Uma extra por tarefa, no modelo pequeno span tool_route antes do loop
Latência O tempo do roteador soma ao início duração de tool_route
Custo Menos tokens de ferramenta em toda volta do loop compensa o roteador tokens de entrada menores em cada step
Falha: grupo faltando O agente não tem a ferramenta e responde sem ela request_group frequente para o mesmo grupo
Falha: grupos demais O roteador escolhe tudo por segurança média de grupos por tarefa perto do total

A falha mais cara é a silenciosa: o grupo certo ficou de fora e o agente não pediu. Ele responde “não encontrei o pagamento” com toda a calma do mundo. Por isso o eval de cobertura, abaixo, importa mais que o de tamanho.

Checagem +20 XP de primeiraDepois de uma semana com o roteador, o painel mostra que em 40% das tarefas de cobrança o agente chama request_group pedindo invoices. Qual é o ajuste mais direto?

Como avaliar

  • Cobertura: em quantas tarefas os grupos escolhidos incluem todas as ferramentas que a solução certa usa.
  • Tamanho médio do subconjunto escolhido.
  • Taxa de expansão: quantas vezes o agente precisou pedir um grupo.
  • Eval completo: taxa de conclusão e escolha correta de ferramenta, antes e depois.
{ "task": "Concilia o pagamento do pedido 88231 com o extrato de ontem", "expected_groups": ["billing"] }

Monte o dataset a partir dos traces que você já tem. Para cada tarefa resolvida com sucesso, os grupos esperados são os grupos das ferramentas que o agente de fato chamou. Inclua de propósito tarefas que cruzam assuntos (“emite a nota e agenda a coleta”) e tarefas vagas (“vê o que aconteceu com o pedido 88231”).

Cobertura e tamanho puxam para lados opostos. Um roteador que sempre escolhe tudo tem cobertura perfeita e não serve para nada. Acompanhe os dois juntos.

Em produção

  • Span tool_route com grupos, confiança e versão do catálogo.
  • Painel com a frequência de request_group por grupo. Um grupo pedido com frequência deve entrar na seleção inicial daquele tipo de tarefa.
  • Alerta quando a média de grupos por tarefa sobe, sinal de roteador inseguro.
  • Ao adicionar uma ferramenta nova, rode o eval do roteador de novo. Uma descrição de grupo que mudou pode desviar tarefas que antes iam certo.

Segurança

O roteador reduz a superfície: ferramentas de efeito só aparecem nas rotas que precisam delas. Não trate isso como controle de acesso. Um texto malicioso dentro da tarefa pode convencer o roteador a escolher outro grupo, e o agente também pode pedir grupos via request_group.

A permissão de verdade fica na ferramenta e no backend: quem é o usuário, o que ele pode fazer, qual é o limite de valor. Veja Reduzir Permissões da Ferramenta.

Prós e contras

Prós Contras
Menos confusão na escolha de ferramenta Uma chamada extra no começo de cada tarefa
Menos tokens em toda volta do loop Um grupo errado deixa o agente sem a ferramenta certa
Ferramentas de efeito ficam fora das tarefas que não precisam O catálogo de grupos vira mais uma coisa para manter
Grupos novos entram sem mexer nos outros Tarefas que cruzam assuntos ficam mais lentas

Relações

Código

As abas fazem a seleção com um modelo pequeno e rodam o agente só com os grupos escolhidos. Python e TypeScript montam a lista e chamam o modelo. LangGraph separa as duas peças: um nó escolhe os grupos, o nó seguinte cria o agente só com as ferramentas desses grupos.

Python. Use quando o agente roda em Python e você monta a lista de ferramentas a cada tarefa.

from typing import Literal

import anthropic
from pydantic import BaseModel

client = anthropic.Anthropic()

GROUPS = {  # 3. catálogo: grupo -> (descrição, ferramentas)
    "billing": ("Use para conciliar pagamentos com extratos e dar baixa em títulos.", BILLING_TOOLS),
    "invoices": ("Use para emitir, cancelar ou consultar notas fiscais.", INVOICE_TOOLS),
    "stock": ("Use para saldo, reserva e movimentação de estoque.", STOCK_TOOLS),
    "logistics": ("Use para frete, coleta e chamados com transportadoras.", LOGISTICS_TOOLS),
}

Group = Literal["billing", "invoices", "stock", "logistics"]


class Selection(BaseModel):
    groups: list[Group]
    confidence: float


def select_tools(task: str) -> list[dict]:
    summary = "\n".join(f"{name}: {desc}" for name, (desc, _) in GROUPS.items())
    sel = client.messages.parse(  # 2. roteador com modelo pequeno
        model="claude-haiku-4-5",
        max_tokens=200,
        system=f"Escolha os grupos de ferramentas que a tarefa precisa.\n{summary}",
        messages=[{"role": "user", "content": task}],
        output_format=Selection,
    ).parsed_output
    groups = sel.groups if sel.confidence >= 0.6 else ["billing"]  # 4. padrão seguro
    return [tool for g in groups for tool in GROUPS[g][1]]


def handle(task: str) -> str:
    tools = select_tools(task)
    return run_agent(task, tools)  # 5. o mesmo loop de antes, com menos ferramentas

O que você ganhou: a lista de ferramentas de cada tarefa fica explícita e testável. O que você perdeu: a expansão via request_group precisa ser tratada no loop.

TypeScript. Use quando o agente roda em Node e você quer os grupos tipados.

import Anthropic from "@anthropic-ai/sdk";
import { zodOutputFormat } from "@anthropic-ai/sdk/helpers/zod";
import { z } from "zod";

const client = new Anthropic();

const GROUPS = {
  billing: { desc: "Use para conciliar pagamentos com extratos e dar baixa em títulos.", tools: BILLING_TOOLS },
  invoices: { desc: "Use para emitir, cancelar ou consultar notas fiscais.", tools: INVOICE_TOOLS },
  stock: { desc: "Use para saldo, reserva e movimentação de estoque.", tools: STOCK_TOOLS },
  logistics: { desc: "Use para frete, coleta e chamados com transportadoras.", tools: LOGISTICS_TOOLS },
} as const;

type Group = keyof typeof GROUPS;

const Selection = z.object({
  groups: z.array(z.enum(["billing", "invoices", "stock", "logistics"])),
  confidence: z.number(),
});

export async function selectTools(task: string): Promise<Anthropic.Tool[]> {
  const summary = Object.entries(GROUPS).map(([k, g]) => `${k}: ${g.desc}`).join("\n");
  const { parsed_output: sel } = await client.messages.parse({
    model: "claude-haiku-4-5",
    max_tokens: 200,
    system: `Escolha os grupos de ferramentas que a tarefa precisa.\n${summary}`,
    messages: [{ role: "user", content: task }],
    output_config: { format: zodOutputFormat(Selection) },
  });
  const groups: Group[] = sel && sel.confidence >= 0.6 ? sel.groups : ["billing"];
  return groups.flatMap((g) => [...GROUPS[g].tools]);
}

O que você ganhou: o compilador garante que só existem grupos conhecidos. O que você perdeu: o mesmo que em Python; o loop do agente continua por sua conta.

Python + LangGraph. Use quando a escolha dos grupos é um nó e o agente nasce no nó seguinte, só com essas ferramentas.

from typing import Literal

from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langgraph.graph import END, START, StateGraph
from pydantic import BaseModel
from typing_extensions import TypedDict

Group = Literal["billing", "invoices", "stock", "logistics"]


class Selection(BaseModel):
    groups: list[Group]
    confidence: float


class State(TypedDict):
    task: str
    groups: list[str]
    answer: str


router = init_chat_model("anthropic:claude-haiku-4-5", temperature=0)


def select(state: State) -> dict:
    # 2. o mesmo GROUPS da aba Python: nome -> (descrição, ferramentas)
    summary = "\n".join(f"{name}: {desc}" for name, (desc, _) in GROUPS.items())
    sel = router.with_structured_output(Selection).invoke(
        [("system", f"Escolha os grupos de ferramentas que a tarefa precisa.\n{summary}"),
         ("human", state["task"])]
    )
    groups = sel.groups if sel.confidence >= 0.6 else ["billing"]  # 4
    return {"groups": list(groups)}


def run(state: State) -> dict:
    tools = [tool for g in state["groups"] for tool in GROUPS[g][1]]  # 5
    agent = create_agent("anthropic:claude-opus-5-5", tools=tools,
                         system_prompt="Você é o assistente de back-office.")
    result = agent.invoke({"messages": [("human", state["task"])]}, {"recursion_limit": 16})
    return {"answer": result["messages"][-1].text}


graph = StateGraph(State)
graph.add_node("select", select)
graph.add_node("run", run)
graph.add_edge(START, "select")
graph.add_edge("select", "run")
graph.add_edge("run", END)
app = graph.compile()

O loop de create_agent tem as outras formas em Loop ReAct. request_group continua uma ferramenta sua, dentro de tools.

O que você ganhou: o agente é criado depois da escolha, então a ferramenta de estoque nem existe no segundo nó. O que você perdeu: recursion_limit conta passos do grafo, não reais.

Teste seu entendimento

Checagem +20 XP de primeiraSeu agente de atendimento tem 9 ferramentas e erra a escolha em 1 de cada 10 chamadas. Duas delas fazem quase a mesma coisa. Qual é o primeiro passo?

Checagem +20 XP de primeiraO roteador devolve confiança 0,4 para a tarefa ‘vê o que deu errado com o cliente 5512’. Qual conjunto padrão faz mais sentido?

Checagem +20 XP de primeiraUm colega propõe: ‘Com o roteador, o agente de dúvidas nunca recebe a ferramenta de estorno, então podemos tirar a checagem de permissão do backend de estorno’. O que você responde?

Perguntas rápidas

O que é Roteador de Ferramentas?

Roteador de Ferramentas (Tool Router) é um padrão de projeto de IA para apps com LLM e agentes, do grupo Ferramentas e ação. Escolher um subconjunto pequeno de ferramentas antes de chamar o modelo principal.

Quais smells o padrão Roteador de Ferramentas ajuda a curar?

Ferramentas Demais, System Prompt Roteador, Mega-Agente e Ferramentas Fantasma.

Onde Roteador de Ferramentas aparece na prática?

Nos cenários reais Automação de back-office com execução durável e Bot de suporte com escalonamento humano.

Para ir além

Relações

Refatorações que chegam aqui 2
Aparece nas trilhas 1
Buscar