Dominando o Tool Use em AI Agents: Da Chamada de Funções à Automação de Tarefas

A Evolução dos LLMs: Do Texto à Ação

Modelos de linguagme de grande escala (LLMs) como o GPT-4 e o Claude são excepcionais em processar e gerar texto, mas, por padrão, eles operam em um "vácuo digital". Eles não têm acesso direto à internet em tempo real (além de ferramentas de navegação integradas), não podem manipular arquivos em seu sistema local nem interagir com APIs de terceiros de forma autônoma.

O Tool Use (ou uso de ferramentas) é a capacidade que transforma um LLM de um simples chatbot em um AI Agent funcional. Com essa habilidade, o modelo deixa de apenas sugerir como fazer algo e passa a efetivamente executar ações no mundo real através de interfaces de programação.

O Conceito de AI Agent e o Papel das Ferramentas

Um AI Agent pode ser definido como um sistema que utiliza um LLM como motor de raciocínio para interagir com o ambiente. O ciclo básico de operação de um Agent segue esta lógica:

  • Percepção: Receber a entrada do usuário ou dados do ambiente.
  • Raciocínio: Analisar se a solicitação exige informações externas ou ações específicas.
  • Ação (Tool Use): Selecionar a ferramenta adequada, gerar os parâmetros necessários e executá-la.
  • Observação: Analisar o resultado retornado pela ferramenta.
  • Resposta: Sintetizar a solução final para o usuário ou decidir pelo próximo passo.

Function Calling: A Base Técnica do Tool Use

A forma mais comum de implementar o Tool Use é através do Function Calling. Embora o LLM não execute o código Python ou a requisição API diretamente dentro de seus neurônios, ele é treinado para interromper a geração de texto e produzir um objeto estruturado (geralmente JSON) contendo o nome de uma função e os argumentos necessários.

Exemplo Prático: Sistema de Consulta de Câmbio

Imagine que queremos criar um assistente que consulta taxas de conversão de moedas em tempo real. Primeiro, definimos a função local que será nossa "ferramenta":

def consultar_taxa_cambio(moeda_base: str, moeda_destino: str) -> str:
    """
    Retorna a taxa de câmbio atual entre duas moedas.
    """
    # Simulação de uma chamada de API real
    base_dados_fake = {
        "USD_BRL": 5.10,
        "EUR_BRL": 5.50,
        "BTC_USD": 65000.00
    }
    chave = f"{moeda_base}_{moeda_destino}"
    taxa = base_dados_fake.get(chave, "Taxa não encontrada")
    return f"A taxa atual de {moeda_base} para {moeda_destino} é {taxa}."

Para que o LLM saiba que essa função existe, precisamos descrevê-la para o modelo em um formato que ele compreenda (Schema):

ferramentas_disponiveis = [
    {
        "type": "function",
        "function": {
            "name": "consultar_taxa_cambio",
            "description": "Obtém a cotação atual entre duas moedas específicas.",
            "parameters": {
                "type": "object",
                "properties": {
                    "moeda_base": {"type": "string", "description": "Código da moeda de origem (ex: USD)"},
                    "moeda_destino": {"type": "string", "description": "Código da moeda de destino (ex: BRL)"}
                },
                "required": ["moeda_base", "moeda_destino"]
            }
        }
    }
]

Implementando o Fluxo de Execução

O processo de execução envolve uma "conversa" de múltiplas etapas entre o seu código e o modelo. Abaixo, uma implementação simplificada utilizando a API da OpenAI:

import json
from openai import OpenAI

cliente = OpenAI(api_key="SUA_CHAVE_AQUI")

def executar_agente(pergunta_usuario):
    mensagens = [{"role": "user", "content": pergunta_usuario}]
    
    # Primeira chamada: O modelo decide se usa a ferramenta
    resposta = cliente.chat.completions.create(
        model="gpt-4-turbo",
        messages=mensagens,
        tools=ferramentas_disponiveis
    )
    
    msg_modelo = resposta.choices[0].message
    
    if msg_modelo.tool_calls:
        mensagens.append(msg_modelo)
        
        for acao in msg_modelo.tool_calls:
            nome_funcao = acao.function.name
            argumentos = json.loads(acao.function.arguments)
            
            if nome_funcao == "consultar_taxa_cambio":
                resultado = consultar_taxa_cambio(
                    moeda_base=argumentos.get("moeda_base"),
                    moeda_destino=argumentos.get("moeda_destino")
                )
                
                mensagens.append({
                    "tool_call_id": acao.id,
                    "role": "tool",
                    "name": nome_funcao,
                    "content": resultado
                })
        
        # Segunda chamada: O modelo recebe o resultado e responde ao usuário
        resposta_final = cliente.chat.completions.create(
            model="gpt-4-turbo",
            messages=mensagens
        )
        return resposta_final.choices[0].message.content
    
    return msg_modelo.content

# Teste
print(executar_agente("Quanto está custando o dólar em reais hoje?"))

Automação Complexa com ReAct e LangChain

Para tarefas que exigem múltiplos passos — como "verificar o preço do Bitcoin, calcular quanto vale em Reais e salvar em um arquivo" — a lógica manual se torna complexa. É aqui que entram frameworks como o LangChain e o padrão ReAct (Reasoning and Acting).

O padrão ReAct força o modelo a gerar um "Pensamento" (Thought) antes de cada "Ação" (Action). Isso permite que o agente corrija sua rota caso uma ferramenta retorne um erro ou uma informação inesperada.

Exemplo com LangChain

Utilizando o LangChain, podemos abstrair a gestão de histórico e a lógica de loop:

from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType

llm = ChatOpenAI(model="gpt-4", temperature=0)

# Definindo ferramentas para o framework
tools = [
    Tool(
        name="ConversorMoeda",
        func=consultar_taxa_cambio,
        description="Útil para saber valores de câmbio entre moedas."
    )
]

agente = initialize_agent(
    tools, 
    llm, 
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# O agente agora pode encadear pensamentos e ações automaticamente
agente.run("Se eu tiver 2 Bitcoins, quantos Reais eu teria aproximadamente? Use o dólar como ponte.")

Boas Práticas e Segurança no Tool Use

Ao dar "mãos" a um LLM, surgem desafios críticos de engenharia:

1. Descrições Precisas

A descrição da função é o "manual de instruções" para o LLM. Se a descrição for ambígua, o modelo pode passar parâmetros errados. Seja específico sobre formatos de data, unidades de medida e limites de valores.

2. Tratamento de Erros e Feedback

Se uma ferramenta falha (ex: erro 404 de API), o erro deve ser retornado ao LLM de forma descritiva. Em vez de apenas "Erro", retorne "Erro: O servidor de câmbio está fora do ar, tente novamente em 5 minutos". Isso permite que o agente explique o problema ao usuário ou tente uma ferramenta alternativa.

3. Segurança (Sandboxing)

Nunca dê a um agente acesso direto a comandos de sistema ou exclusão de banco de dados sem uma camada de validação humana (Human-in-the-loop). O fenômeno de Prompt Injection pode enganar o agente e fazê-lo executar comandos maliciosos se ele tiver permissões excessivas.

4. Esquemas de Validação

Utilize bibliotecas como o Pydantic para garantir que os dados gerados pelo LLM correspondam exatamente ao que sua função espera antes de executá-la. Isso evita erros de tipo (TypeErrors) durante a execução do código.

O Futuro: Agentes Multi-Ferramentas e Multi-Agentes

A fronteira atual do Tool Use envolve a colaboração entre diferentes agentes, onde cada um possui um conjunto de ferramentas especializado. Por exemplo, um agente pesquisador usa ferramentas de busca web, enquanto um agente analista usa ferramentas de processamento de dados SQL, e ambos trocam informações para resolver um problema complexo de negócio. O Tool Use deixa de ser uma funcionalidade isolada e passa a ser o protocolo de comunicação fundamental entre a inteligência artificial e a infraestrutura de software existente.

Tags: AI Agents Function Calling LLM Python LangChain

Publicado em 7-26 21:12