Sistema de agentes do zero|INEMA.CLUB-PRO

Aula 3 · 15 min

Ferramentas: o agente para de só falar e age

Sozinho, o modelo só escreve texto. Com ferramentas, ele pede "leia este arquivo", o seu programa lê e devolve o conteúdo, e ele continua dali. Esse vai e volta é o loop, o coração de todo agente. Nesta aula ele cabe em menos de 20 linhas.

Começar a aula
Mão robótica pegando uma ferramenta de uma parede de ferramentas organizada.

Nesta aula você vai

  1. 1Descrever uma ferramenta para o modelo
  2. 2O loop: pedir, executar, devolver, repetir
  3. 3Por que o loop tem um número máximo de voltas

Objetivo: dar ao agente a ferramenta ler_arquivo e ver o loop pedir, executar e responder em duas rodadas.

01O loop do agente

Clique em cada etapa. Ele repete até o modelo responder sem pedir ferramenta, ou até 5 voltas.

Clique em cada bloco do diagrama para ver o que ele faz.

02O agente.py da aula 3

Rode dentro de agente-do-zero/. O cp troca o agente.py pelo da aula 3.

Arquivo · kit/aula3/agente.py
#!/usr/bin/env python3
"""Agente do zero (aula 3): o loop com ferramenta. O modelo pede, o código executa, o resultado volta."""
import json, os, sys, urllib.request

MODELO = os.environ.get("MODELO", "llama3.2")
URL = os.environ.get("OLLAMA_URL", "http://localhost:11434") + "/api/chat"
PASTA = os.path.realpath("trabalho")
MAX_RODADAS = 5


def cerebro(mensagens, ferramentas):
    corpo = {"model": MODELO, "messages": mensagens, "tools": ferramentas, "stream": False, "think": False,
             "options": {"temperature": 0, "seed": 1}}
    pedido = urllib.request.Request(URL, json.dumps(corpo).encode(), {"Content-Type": "application/json"})
    with urllib.request.urlopen(pedido, timeout=600) as r:
        return json.loads(r.read())["message"]


def ler_arquivo(nome):
    with open(os.path.join(PASTA, nome)) as f:      # ainda sem trava: ela entra na aula 5
        return f.read()


FERRAMENTAS = {"ler_arquivo": ler_arquivo}
DESCRICOES = [
    {"type": "function", "function": {"name": "ler_arquivo", "description": "Lê um arquivo da pasta de trabalho.",
     "parameters": {"type": "object", "properties": {"nome": {"type": "string"}}, "required": ["nome"]}}},
]


def responder(pedido, mostrar=print):
    mensagens = [{"role": "user", "content": pedido}]
    for rodada in range(MAX_RODADAS):
        msg = cerebro(mensagens, DESCRICOES)
        mensagens.append(msg)
        if not msg.get("tool_calls"):
            return msg.get("content", ""), rodada + 1
        for chamada in msg["tool_calls"]:
            nome, args = chamada["function"]["name"], chamada["function"].get("arguments") or {}
            try:
                saida = FERRAMENTAS[nome](**args)
            except Exception as erro:
                saida = f"recusado: {erro}"
            mostrar(f"[ferramenta] {nome} {json.dumps(args, ensure_ascii=False)} -> {saida[:80]}")
            mensagens.append({"role": "tool", "content": saida})
    return "Parei: cheguei ao limite de rodadas.", MAX_RODADAS


if __name__ == "__main__":
    os.makedirs(PASTA, exist_ok=True)
    resposta, rodadas = responder(" ".join(sys.argv[1:]))
    print(f"{resposta}\n({rodadas} rodada(s))")
Terminal · a primeira ferramenta
cd ~/agente-do-zero
cp ~/agentes-do-zero-v72/kit/aula3/agente.py .
echo "Reunião com o fornecedor às 15h." > trabalho/notas.txt
python3 agente.py "leia notas.txt e diga a hora da reunião"
Exemplo do repositório
[ferramenta] ler_arquivo {"nome": "notas.txt"} -> Reunião com o fornecedor às 15h.

Parece que o arquivo "notas.txt" foi lido com sucesso!

Aqui está o conteúdo do arquivo:

Reunião com o fornecedor às 15h.
O que você gostaria de saber mais sobre a reunião?
(2 rodada(s))

Rodada 1: o modelo pediu ler_arquivo. Rodada 2: com o conteúdo na mão, respondeu. A resposta é falante, mas a hora está certa.

03As três partes novas

Clique em cada uma.

1. A função

Uma função Python comum, que abre o arquivo dentro de trabalho/ e devolve o texto.

Ainda sem trava: um pedido esperto consegue sair da pasta. Você vai ver isso acontecer e fechar o furo na aula 5.

04Prática: ver o loop rodar

Faça na ordem.

E1 · A ferramenta em ação

10 min

Rode o bloco do terminal com o agente.py da aula 3.

Pronto quando: a saída tem a linha [ferramenta] ler_arquivo {"nome": "notas.txt"} e termina com (2 rodada(s)).

E2 · Um arquivo seu

10 min

Crie um arquivo seu em trabalho/ (uma lista, um lembrete) e faça uma pergunta que só dá para responder lendo ele.

Pronto quando: a linha [ferramenta] mostra o nome do seu arquivo e a resposta usa o que está nele.

05Teste o que aprendeu

A explicação aparece depois da sua resposta.

Pergunta 1 de 3

Como o modelo sabe que existe a ferramenta ler_arquivo?

06Resumo da aula

FerramentaFunção Python + descrição que o modelo lê.
LoopPedir, executar, devolver, repetir, até 5 vezes.
RodadasCada volta é uma chamada ao modelo: custo e tempo.
Aula anteriorPróxima aula