Agente com Tool Calling
Um agente e um modelo que decide quais ferramentas chamar para responder uma pergunta. O fluxo: o modelo recebe a pergunta e a lista de ferramentas disponiveis, decide qual chamar, voce executa a ferramenta, e devolve o resultado para o modelo gerar a resposta final.
Como funciona
- Voce define ferramentas com nome, descricao e schema de parametros
- O modelo analisa a pergunta e retorna
tool_calls(nao executa nada) - Seu codigo executa as funcoes e devolve o resultado como mensagem
tool - O modelo recebe o resultado e gera a resposta final em linguagem natural
1. Definir ferramentas
python
import json
from openai import OpenAI
client = OpenAI(
base_url="https://api.usetokia.com/v1",
api_key="sk-...",
)
tools = [
{
"type": "function",
"function": {
"name": "consultar_clima",
"description": "Consulta a previsao do tempo de uma cidade",
"parameters": {
"type": "object",
"properties": {
"cidade": {"type": "string", "description": "Nome da cidade"},
},
"required": ["cidade"],
},
},
},
{
"type": "function",
"function": {
"name": "consultar_cotacao",
"description": "Consulta a cotacao atual do dolar em BRL",
"parameters": {"type": "object", "properties": {}},
},
},
]2. Implementar as funcoes
python
def consultar_clima(cidade: str) -> str:
dados = {
"brasilia": "28C, ensolarado",
"sao paulo": "22C, nublado",
"rio de janeiro": "32C, sol com nuvens",
}
return dados.get(cidade.lower(), f"Dados nao disponiveis para {cidade}")
def consultar_cotacao() -> str:
return "USD 1 = BRL 5.60"
TOOL_REGISTRY = {
"consultar_clima": consultar_clima,
"consultar_cotacao": consultar_cotacao,
}3. Loop do agente
O loop continua enquanto o modelo pedir tool calls. Quando ele responde sem pedir ferramentas, a conversa termina:
python
def run_agent(question: str) -> str:
messages = [
{"role": "system", "content": "Voce e um assistente que usa ferramentas para responder."},
{"role": "user", "content": question},
]
while True:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools,
)
choice = response.choices[0]
if choice.finish_reason == "tool_calls" and choice.message.tool_calls:
messages.append(choice.message)
for tool_call in choice.message.tool_calls:
fn_name = tool_call.function.name
fn_args = json.loads(tool_call.function.arguments)
fn = TOOL_REGISTRY.get(fn_name)
if fn:
result = fn(**fn_args)
else:
result = f"Ferramenta {fn_name} nao encontrada"
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result),
})
else:
return choice.message.content or ""
print(run_agent("Como esta o tempo em Brasilia e qual a cotacao do dolar?"))Versao TypeScript
typescript
import OpenAI from "openai";
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
const client = new OpenAI({
baseURL: "https://api.usetokia.com/v1",
apiKey: process.env.TOKIA_API_KEY,
});
const toolRegistry: Record<string, (args: Record<string, string>) => string> = {
consultar_clima: ({ cidade }) => {
const dados: Record<string, string> = {
brasilia: "28C, ensolarado",
"sao paulo": "22C, nublado",
};
return dados[cidade.toLowerCase()] ?? "Dados indisponiveis";
},
};
async function runAgent(question: string): Promise<string> {
const messages: ChatCompletionMessageParam[] = [
{ role: "system", content: "Use ferramentas para responder." },
{ role: "user", content: question },
];
while (true) {
const response = await client.chat.completions.create({
model: "gpt-4o-mini",
messages,
tools: [
{
type: "function",
function: {
name: "consultar_clima",
description: "Previsao do tempo de uma cidade",
parameters: {
type: "object",
properties: { cidade: { type: "string" } },
required: ["cidade"],
},
},
},
],
});
const choice = response.choices[0];
if (!choice.message.tool_calls?.length) {
return choice.message.content ?? "";
}
messages.push(choice.message);
for (const tc of choice.message.tool_calls) {
const fn = toolRegistry[tc.function.name];
const args = JSON.parse(tc.function.arguments);
messages.push({
role: "tool",
tool_call_id: tc.id,
content: fn ? fn(args) : "Ferramenta nao encontrada",
});
}
}
}Boas praticas
- Limite de iteracoes: adicione um contador no loop (max 5-10 iteracoes) para evitar loops infinitos se o modelo ficar chamando tools sem parar.
- Descricoes claras: a qualidade das descricoes das ferramentas impacta diretamente a precisao do modelo em escolher a ferramenta certa.
- Modelo:
gpt-4o-minifunciona bem para 2-5 tools. Para cenarios com 10+ tools ou logica complexa de decisao, useclaude-sonnet-46. - Seguranca: valide os argumentos antes de executar. O modelo pode enviar valores inesperados.
Proximos passos
- Tool Calling — referencia completa do formato de ferramentas
- LangChain / LangGraph — framework com ReAct agent pronto
- Chatbot com Memoria — combine agente + historico de conversa