Agora que você já sabe montar um grafo com LangGraph e LangChain podemos dar um passo a mais e adicionar tools (ferramentas) para os nossos LLMs. Com isso a IA poderá executar tarefas além do que está em seu treinamento.
Ferramentas (tools) são funções Python, scripts ou serviços externos que expomos para que a IA execute em nosso nome. Cada tool descreve quais argumentos aceita e o que devolve, permitindo que o modelo peça ações determinísticas, como calcular algo, consultar uma API, ler um arquivo e várias outras coisas. Por isso, a documentação da sua ferramenta é extremamente importante.
Outro ponto que muitas pessoas confundem é que a IA não executa diretamente a ferramenta, ela apenas sabe da sua existência. Quando alguma conversa do usuário é direcionada para algo que uma das ferramentas disponíveis resolve, a IA enviará um pedido para executar a ferramenta com os argumentos que o usuário solicitou.
Suponha que você tem uma ferramenta chamada multiply que recebe a e b. Sua
ferramenta está bem documentada, de forma que a IA não terá dificuldades em
saber quando chamá-la:
@tool
def multiply(a: float, b: float) -> float:
"""Multiply a * b and returns the result
Args:
a: float multiplicand
b: float multiplier
Returns:
the resulting float of the equation a * b
"""
return a * bQuando uma conversa direciona a IA para usar a ferramenta, acontece algo semelhante a isso:
Usuário: Oi, sou Otávio Miranda.
IA: Olá Otávio, como posso te ajudar hoje?
Usuário: Poderia me dizer quanto é 5.2 vezes 10?
Nesse momento o fluxo muda um pouco. Acontece algo semelhante a isso:
IA: (SOLICITA A CHAMADA DA FERRAMENTA: multiply com 5.2 e 10)
Dev: Chama a Ferramenta
Dev: Injeta o resultado de volta na IA (52.0)
Depois disso, a IA retoma a conversa:
IA: Otávio, o resultado entre 5.2 * 10 é 52.0.
LLMs trabalham apenas com o que está na janela de contexto e no treinamento.
Ferramentas nos permitem ultrapassar essas barreiras:
- Executar cálculos ou transformações determinísticas sem depender da "imaginação" do modelo.
- Buscar informações atualizadas em APIs, bancos de dados ou arquivos locais.
- Aplicar regras de negócio específicas do produto sem expô-las ao modelo.
- Integrar a conversa com outros sistemas (e-mails, automações, tickets, etc) mantendo rastreabilidade do que foi feito.
O LangChain padroniza todo esse processo. Com o decorator @tool ou classes que
herdam de BaseTool, definimos o schema de entrada e a execução da função. O
próprio LangChain usa Pydantic para validar os argumentos antes da chamada,
então sabemos que a tool receberá dados coerentes (ou que uma exceção será
lançada caso algo esteja errado).
Quando chamamos llm.bind_tools(tools), o modelo passa a responder com objetos
AIMessage contendo tool_calls. Cada chamada informa o nome da tool, os
argumentos serializados e um id único. O nosso código então decide se a
chamada faz sentido, executa a ferramenta com tool.invoke, trata eventuais
erros (ValidationError, ToolException etc.) e finalmente devolve o resultado
para a LLM usando um ToolMessage. Esse ToolMessage carrega o tool_call_id
para que o modelo saiba qual requisição foi atendida e possa produzir a resposta
final para o usuário.
Esse mecanismo manual que você verá na aula (multiplicar dois números, por exemplo) é o mesmo que utilizaremos para qualquer automação com tools.
- Mensagem do usuário: iniciamos uma lista de
messagese adicionamos umHumanMessagecom a pergunta. - Decisão da LLM: com as tools vinculadas, a resposta vem como
AIMessageindicando qual ferramenta deve ser executada e com quais argumentos. - Execução segura: procuramos a tool pelo nome, chamamos
invokee tratamos erros comuns. Nada impede que a LLM peça algo inválido, então essa etapa é nossa responsabilidade. - Retorno para o modelo: construímos um
ToolMessagecom o resultado (ou com o erro) e repassamos tudo parallm_with_tools.invoke. A LLM usa essa nova mensagem para formular a resposta final. - Histórico: armazenamos as mensagens para continuar a conversa ou repetir o ciclo com novas requisições.
Esse passo a passo sem grafo deixa claro o que está acontecendo por trás das cortinas antes de delegarmos parte da orquestração para o LangGraph.
Nas próximas aulas vamos conectar esse mesmo raciocínio ao LangGraph. Cada nó do grafo poderá chamar uma LLM com tools ou até uma tool específica. O LangGraph vai cuidar do estado, do histórico e dos checkpointers enquanto continuamos usando o LangChain para definir como cada tool funciona. Dessa forma conseguimos descrever rotas condicionais, paralelizar passos e reutilizar tools em diferentes partes do fluxo sem duplicar código.
Quando juntarmos tudo, o LangGraph fornecerá a orquestração (quem chama quem e quando), enquanto o LangChain continua sendo a base para falar com modelos e ferramentas. É por isso que entender bem o fluxo manual agora vai facilitar muito a transição para o grafo nas próximas aulas.
Fiz toda a explicação do código em vídeo. O código comentado está no arquivo a seguir:
- Link do arquivo - ex005 - code02.py
Agora que já sabemos como fazer todo o que vimos nas aulas anteriores, podemos
unir tudo isso no grafo com o LangGraph. Explico tudo em vídeo e deixo o código
completo na pasta src/examples/ex006 (link abaixo):
- Link da pasta ex006 - ex006 (pasta)