Aula 4: Tools e Function Calling
Video da aula
Video em breve. O conteudo completo em texto esta disponivel abaixo.
O que voce vai aprender
- O que sao Tools e por que sao o recurso mais poderoso de agentes
- Como criar tools customizadas com LangChain
- Function Calling nativo do GPT e Claude
- Criar um agente que decide sozinho quais ferramentas usar
- Exemplos praticos: calculadora, busca web, API de clima
O que sao Tools?
Tools transformam o LLM de um “gerador de texto” em um “executor de acoes”. Em vez de apenas responder, o agente pode:
- Buscar informacoes atualizadas na web
- Fazer calculos matematicos precisos
- Consultar APIs externas (clima, cotacoes, etc.)
- Ler e escrever arquivos
- Executar codigo
O LLM decide qual ferramenta usar e com quais parametros, baseado na pergunta do usuario.
1. Criando tools customizadas
import os
import json
from dotenv import load_dotenv
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
load_dotenv()
@tool
def calcular(expressao: str) -> str:
"""Calcula uma expressao matematica. Exemplo: '2 + 2', '15 * 3.14', 'pow(2, 10)'"""
try:
# Permite apenas operacoes matematicas seguras
allowed = set("0123456789+-*/.() ,powsqrtabsintfloatround")
if not all(c in allowed for c in expressao.replace(" ", "")):
return "Expressao invalida."
result = eval(expressao, {"__builtins__": {}}, {
"pow": pow, "sqrt": __import__("math").sqrt,
"abs": abs, "int": int, "float": float, "round": round
})
return str(result)
except Exception as e:
return f"Erro no calculo: {e}"
@tool
def buscar_clima(cidade: str) -> str:
"""Busca a temperatura atual de uma cidade usando a API wttr.in"""
import urllib.request
try:
url = f"https://wttr.in/{cidade}?format=%t+%C&lang=pt"
req = urllib.request.Request(url, headers={"User-Agent": "curl/7.0"})
with urllib.request.urlopen(req, timeout=5) as resp:
return f"Clima em {cidade}: {resp.read().decode('utf-8').strip()}"
except Exception:
return f"Nao consegui buscar o clima de {cidade}."
@tool
def hora_atual(fuso: str = "America/Sao_Paulo") -> str:
"""Retorna a data e hora atual no fuso horario especificado."""
from datetime import datetime
try:
from zoneinfo import ZoneInfo
now = datetime.now(ZoneInfo(fuso))
return now.strftime("%d/%m/%Y %H:%M:%S")
except Exception:
from datetime import datetime
return datetime.now().strftime("%d/%m/%Y %H:%M:%S")
# Lista de tools disponiveis
tools = [calcular, buscar_clima, hora_atual]
O decorator @tool transforma uma funcao Python em uma tool que o LLM pode chamar. A docstring e crucial: e ela que o LLM le para decidir quando usar a ferramenta.
2. Agente com ReAct (Reasoning + Acting)
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# Prompt que instrui o agente a usar tools
prompt = ChatPromptTemplate.from_messages([
("system", """Voce e um assistente inteligente com acesso a ferramentas.
Use as ferramentas quando precisar de informacoes em tempo real, calculos ou dados externos.
Sempre responda em portugues."""),
MessagesPlaceholder(variable_name="chat_history", optional=True),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
# Criar agente
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Testar
result = executor.invoke({"input": "Quanto e 15% de 2.350?"})
print(result["output"])
Com verbose=True, voce ve o raciocinio do agente:
> Entering new AgentExecutor chain...
Invoking: `calcular` with `2350 * 0.15`
352.5
O valor de 15% de 2.350 e R$ 352,50.
> Finished chain.
3. Agente que combina multiplas tools
# O agente decide sozinho quais tools usar
queries = [
"Qual a temperatura em Sao Paulo agora?",
"Quanto e 2 elevado a 32?",
"Que horas sao em Tokyo?",
"Se esta 28 graus em SP e eu quero converter pra Fahrenheit, quanto da?",
]
for q in queries:
print(f"\nPergunta: {q}")
result = executor.invoke({"input": q})
print(f"Resposta: {result['output']}")
O agente analisa a pergunta e decide:
- “temperatura” -> usa
buscar_clima - “2 elevado a 32” -> usa
calcular - “que horas” -> usa
hora_atual - “converter temperatura” -> usa
calcularcom a formula
4. Criando uma tool para API externa
@tool
def buscar_github(usuario: str) -> str:
"""Busca informacoes publicas de um usuario do GitHub."""
import urllib.request
try:
url = f"https://api.github.com/users/{usuario}"
req = urllib.request.Request(url, headers={"User-Agent": "python-agent"})
with urllib.request.urlopen(req, timeout=5) as resp:
data = json.loads(resp.read().decode("utf-8"))
return json.dumps({
"nome": data.get("name"),
"bio": data.get("bio"),
"repos_publicos": data.get("public_repos"),
"seguidores": data.get("followers"),
"localizacao": data.get("location"),
}, ensure_ascii=False)
except Exception as e:
return f"Erro ao buscar usuario: {e}"
# Adicionar ao executor
tools.append(buscar_github)
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Testar
result = executor.invoke({"input": "Me fale sobre o usuario DiegoNogueiraDev no GitHub"})
print(result["output"])
5. Tool com confirmacao (seguranca)
Para tools que executam acoes perigosas, adicione confirmacao:
@tool
def enviar_email(destinatario: str, assunto: str, corpo: str) -> str:
"""Prepara um email para envio. REQUER confirmacao do usuario."""
preview = f"""
Para: {destinatario}
Assunto: {assunto}
---
{corpo}
"""
print(f"\n[PREVIEW DO EMAIL]{preview}")
confirm = input("Enviar este email? (s/n): ").strip().lower()
if confirm == "s":
# Aqui voce integraria com um servico de email real
return "Email enviado com sucesso!"
return "Envio cancelado pelo usuario."
6. Pattern: Tool Router
Para muitas tools, organize por categoria:
# Em vez de uma lista gigante, agrupe por dominio
math_tools = [calcular]
web_tools = [buscar_clima, buscar_github]
time_tools = [hora_atual]
# O executor recebe todas, mas voce pode filtrar por contexto
all_tools = math_tools + web_tools + time_tools
Diagrama do fluxo
Usuario: "Qual a temperatura em SP e quanto e isso em Fahrenheit?"
|
v
[LLM analisa a pergunta]
|
+---------+---------+
| |
v v
[buscar_clima("SP")] [calcular("28 * 9/5 + 32")]
| |
v v
"28 graus" "82.4"
| |
+-------+-----------+
|
v
[LLM combina as respostas]
|
v
"Sao Paulo esta com 28°C, que equivale a 82.4°F"
Exercicio pratico
- Crie uma tool que busca cotacao de moedas (USD, EUR, BTC) usando uma API publica
- Crie uma tool que le um arquivo de texto local e retorna o conteudo
- Combine as tools da Aula 2 (RAG) com function calling: o agente decide se busca nos documentos ou na web
- Adicione um log de todas as tools chamadas (para auditoria)
Proximo passo
Na Aula 5, vamos colocar tudo em producao. Vamos criar uma API com FastAPI, um frontend simples, e fazer o deploy na cloud. Seu agente vai estar acessivel para qualquer pessoa via navegador.