Ato 2: A Construção (Perspectiva Alternativa)
"Você dominou a complexidade da orquestração com LangChain. Agora, vamos explorar a elegância da simplicidade. Agno nos convida a pensar de forma diferente sobre a construção de agentes, focando em um design minimalista e em um fluxo de trabalho intuitivo. É a prova de que o poder não precisa vir da complexidade."
Depois de mergulhar na vastidão de opções do LangChain, Agno surge como um contraponto refrescante. Criado com a filosofia de ser "painfully simple" (dolorosamente simples), este framework open-source foca em fazer uma coisa e fazê-la excepcionalmente bem: criar agentes de IA autônomos.
Neste módulo, vamos aprender:
- A filosofia e princípios de design do Agno
- Como criar agentes com código minimalista
- Padrões avançados (RAG, Memory, Multi-Agent)
- Quando escolher Agno vs LangChain
- Best practices para produção
Capítulo 4.1: A Filosofia Agno
O Problema da Complexidade
Após trabalhar com LangChain, você pode ter experimentado:
Desafios Comuns:
- 🤯 Curva de aprendizado íngreme: Dezenas de classes e abstrações
- 🍝 "Spaghetti code": Chains aninhadas difíceis de debugar
- 🐛 Debugging complexo: Rastrear erros através de múltiplas camadas
- 📚 Documentação fragmentada: Muitas opções, pouca clareza
- ⏰ Time to hello world: Horas para entender o básico
A Solução Agno
Agno foi criado para resolver exatamente esses pontos de dor:
Mesmo agente em Agno:
from agno import Agent
@tool
def my_tool(input: str) -> str:
"""Descrição da ferramenta"""
return result
agent = Agent(tools=[my_tool])
agent.run("Pergunta") # Pronto!
Os 3 Pilares da Filosofia Agno
1. Simplicidade Extrema
Manifesto:
- Código linear e direto
- Zero abstrações desnecessárias
- API intuitiva e previsível
- Menos é mais
2. Foco no Agente
Foca em:
- ✅ Agentes que tomam decisões
- ✅ Agentes que usam ferramentas
- ✅ Agentes que colaboram
- ✅ Simplicidade de debugging
3. Transparência Total
Logging claro e automático:
[Agent] Thinking: Preciso buscar informações sobre Python
[Agent] Action: search_web
[Agent] Action Input: "Python programming language"
[Agent] Observation: Python is a high-level...
[Agent] Thinking: Agora tenho a informação
[Agent] Final Answer: Python is...
Comparação Direta: Agno vs LangChain
| Aspecto | LangChain | Agno |
|---|---|---|
| Filosofia | Framework abrangente | Framework focado |
| Curva de Aprendizado | Íngreme (dias/semanas) | Suave (horas) |
| Linhas de Código | Muitas (~50-100 para agente) | Poucas (~10-20) |
| Debugging | Complexo, múltiplas camadas | Simples, linear |
| Flexibilidade | Muito alta | Moderada |
| Performance | Boa | Excelente (menos overhead) |
Quando Usar Cada Um?
Use LangChain quando:
- Precisa de integrações com tudo
- Projeto complexo de processamento de dados
- Pipelines avançados de transformação
- Time grande com tempo para aprender
Use Agno quando:
- Foco principal é agentes autônomos
- Prototipagem rápida
- Clareza e manutenibilidade são prioridades
- Time pequeno ou solo developer
- Deadline apertado
Capítulo 4.2: Setup e Primeiros Passos
Instalação
# Instalação básica
pip install agno
# Com OpenAI
pip install "agno[openai]"
# Com Anthropic (Claude)
pip install "agno[anthropic]"
# Completo
pip install "agno[all]"
Configuração de API Keys
import os
# Opção 1: Variável de ambiente
os.environ["OPENAI_API_KEY"] = "sk-..."
# Opção 2: .env file (recomendado)
from dotenv import load_dotenv
load_dotenv()
Hello World: Seu Primeiro Agente
from agno import Agent, tool
@tool
def get_weather(city: str) -> str:
"""
Retorna informações sobre o clima de uma cidade.
Args:
city: Nome da cidade
"""
# Simulação (na prática, chamar API de clima)
return f"O clima em {city} está ensolarado, 25°C"
# Criar agente
agent = Agent(
name="Assistente de Clima",
tools=[get_weather],
model="gpt-4"
)
# Executar
result = agent.run("Como está o tempo em São Paulo?")
print(result)
[Agent] Thinking: Preciso verificar o clima em São Paulo [Agent] Action: get_weather [Agent] Action Input: São Paulo [Agent] Observation: O clima em São Paulo está ensolarado, 25°C [Agent] Thinking: Tenho a informação necessária [Agent] Final Answer: O clima em São Paulo está ensolarado com 25°C.
Anatomia de um Tool
@tool # Decorator obrigatório
def nome_da_funcao(parametro: tipo) -> tipo: # Type hints são importantes!
"""
Descrição clara e concisa do que a ferramenta faz.
O LLM usa esta descrição para decidir quando usar a tool.
Seja específico e objetivo.
Args:
parametro: Descrição do parâmetro
Returns:
Descrição do retorno
"""
# Implementação
return resultado
Regras de Ouro:
- ✅ Sempre use type hints - Agno valida tipos
- ✅ Docstring detalhada - É a "interface" para o LLM
- ✅ Nome descritivo -
get_weather>tool1 - ✅ Uma responsabilidade - Cada tool faz UMA coisa
- ✅ Retorno sempre string - LLMs entendem texto
Capítulo 4.3: Tools - O Poder das Ferramentas
Tools Básicas
1. Tool de Cálculo
@tool
def calculator(expression: str) -> str:
"""
Calcula expressões matemáticas.
Args:
expression: Expressão matemática (ex: "2 + 2", "10 * 5")
"""
try:
result = eval(expression)
return f"Resultado: {result}"
except Exception as e:
return f"Erro ao calcular: {str(e)}"
2. Tool com API Externa
import requests
@tool
def get_exchange_rate(from_currency: str, to_currency: str) -> str:
"""
Retorna taxa de câmbio entre duas moedas.
Args:
from_currency: Moeda de origem (ex: USD, BRL, EUR)
to_currency: Moeda de destino
"""
try:
url = f"https://api.exchangerate-api.com/v4/latest/{from_currency}"
response = requests.get(url)
data = response.json()
rate = data['rates'][to_currency]
return f"1 {from_currency} = {rate} {to_currency}"
except Exception as e:
return f"Erro ao buscar taxa: {str(e)}"
3. Tool com Estado (Database)
# Simular banco de dados em memória
TASKS_DB = []
@tool
def add_task(task: str) -> str:
"""
Adiciona uma nova tarefa à lista.
Args:
task: Descrição da tarefa a adicionar
"""
TASKS_DB.append(task)
return f"✓ Tarefa adicionada: '{task}'. Total: {len(TASKS_DB)} tarefas."
@tool
def list_tasks() -> str:
"""
Lista todas as tarefas pendentes.
"""
if not TASKS_DB:
return "Nenhuma tarefa pendente."
tasks_list = "\n".join([f"{i+1}. {task}" for i, task in enumerate(TASKS_DB)])
return f"Tarefas pendentes:\n{tasks_list}"
Agente com Múltiplas Tools
from agno import Agent
# Criar agente assistente completo
assistant = Agent(
name="Assistente Pessoal",
description="Ajuda com cálculos, buscas, tarefas e arquivos",
tools=[
calculator,
get_exchange_rate,
add_task,
list_tasks,
],
model="gpt-4",
show_tool_calls=True # Mostrar raciocínio
)
# Testar capacidades
responses = [
assistant.run("Qual é 25 * 17?"),
assistant.run("Adicione 'Comprar leite' às minhas tarefas"),
assistant.run("Quanto vale 1 dólar em reais?"),
]
Capítulo 4.4: Memory e Contexto Conversacional
Memory Simples
from agno import Agent
# Ativar memória com uma linha
agent = Agent(
tools=[...],
memory=True # Isso é tudo!
)
# Conversa com contexto
agent.run("Meu nome é João")
agent.run("Qual é meu nome?") # Lembra: "Seu nome é João"
Memory Configurada
from agno import Agent
from agno.memory import ConversationMemory
# Memória customizada
memory = ConversationMemory(
max_messages=10, # Últimas 10 mensagens
summary_threshold=20 # Resume após 20 mensagens
)
agent = Agent(
tools=[...],
memory=memory
)
Memory Persistente (Storage)
from agno import Agent
from agno.storage import FileStorage
# Salvar histórico em arquivo
storage = FileStorage(path="./agent_history.json")
agent = Agent(
tools=[...],
memory=True,
storage=storage
)
# Histórico persiste entre execuções
Memory com Database (SQLite)
from agno import Agent
from agno.storage import SQLStorage
# Usar SQLite para persistência
storage = SQLStorage(
connection_string="sqlite:///agent_memory.db",
session_id="user_123" # ID único por usuário
)
agent = Agent(
tools=[...],
memory=True,
storage=storage
)
Capítulo 4.5: RAG (Retrieval-Augmented Generation) com Agno
Abordagem 1: RAG como Tool
A forma mais simples de fazer RAG em Agno é criar uma tool que consulta seu conhecimento base:
from agno import Agent, tool
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
# Setup do vector store
model = SentenceTransformer('all-MiniLM-L6-v2')
documents = [
"Python é uma linguagem de programação de alto nível.",
"JavaScript é usado para desenvolvimento web.",
"SQL é usado para consultar bancos de dados.",
]
# Criar embeddings e índice
embeddings = model.encode(documents)
index = faiss.IndexFlatL2(embeddings.shape[1])
index.add(embeddings.astype('float32'))
@tool
def search_knowledge_base(query: str) -> str:
"""
Busca informações na base de conhecimento.
Args:
query: Pergunta ou termo de busca
"""
query_embedding = model.encode([query]).astype('float32')
k = 2
distances, indices = index.search(query_embedding, k)
results = [documents[i] for i in indices[0]]
return "\n".join(results)
# Agente com RAG
rag_agent = Agent(
name="Assistente Técnico",
tools=[search_knowledge_base],
model="gpt-4"
)
Abordagem 2: RAG com Documentos Reais
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
# Carregar e processar PDFs
loader = PyPDFLoader("manual_produto.pdf")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = text_splitter.split_documents(documents)
# Criar vector store
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(chunks, embeddings)
vectorstore.save_local("vectorstore_agno")
# Tool para consultar
@tool
def query_product_manual(question: str) -> str:
"""
Consulta o manual do produto.
Args:
question: Pergunta sobre o produto
"""
vs = FAISS.load_local(
"vectorstore_agno",
OpenAIEmbeddings(),
allow_dangerous_deserialization=True
)
docs = vs.similarity_search(question, k=3)
context = "\n\n".join([doc.page_content for doc in docs])
return context
Capítulo 4.6: Sistemas Multi-Agentes
Padrão 1: Agente como Tool
A abordagem mais simples: um agente pode usar outro agente como tool.
from agno import Agent, tool
# Agentes Especialistas
researcher = Agent(
name="Pesquisador",
tools=[search_web, search_knowledge_base],
model="gpt-4"
)
writer = Agent(
name="Escritor",
tools=[save_to_file],
model="gpt-4"
)
# Transformar agentes em tools
@tool
def research(topic: str) -> str:
"""
Pesquisa informações detalhadas sobre um tópico.
"""
return researcher.run(f"Pesquise sobre: {topic}")
@tool
def write_article(topic: str, research_data: str) -> str:
"""
Escreve um artigo baseado em dados de pesquisa.
"""
prompt = f"Escreva sobre '{topic}' usando:\n{research_data}"
return writer.run(prompt)
# Agente Gerente
manager = Agent(
name="Gerente de Conteúdo",
tools=[research, write_article],
model="gpt-4"
)
Padrão 2: Pipeline de Agentes
class AgentPipeline:
"""Pipeline sequencial de agentes"""
def __init__(self, agents: list):
self.agents = agents
def run(self, initial_input: str) -> str:
current_input = initial_input
for i, agent in enumerate(self.agents):
print(f"\nEtapa {i+1}: {agent.name}")
current_input = agent.run(current_input)
return current_input
# Criar pipeline
pipeline = AgentPipeline([
Agent(name="Planejador", ...),
Agent(name="Executor", ...),
Agent(name="Revisor", ...)
])
final_result = pipeline.run("Pesquise sobre IA")
Padrão 3: Collaborative Agents
class CollaborativeAgents:
"""Múltiplos agentes colaborando em paralelo"""
def __init__(self, agents: dict):
self.agents = agents
def run(self, task: str) -> dict:
results = {}
for name, agent in self.agents.items():
print(f"\n{name} trabalhando...")
results[name] = agent.run(task)
return results
# Criar time
team = CollaborativeAgents({
"Analista Técnico": Agent(...),
"Analista de Mercado": Agent(...),
"Analista Financeiro": Agent(...)
})
results = team.run("Avalie lançar produto de IA no Brasil")
Capítulo 4.7: Configurações e Customização
Configurando o Agente
from agno import Agent
agent = Agent(
# Identidade
name="Assistente Executivo",
description="Especialista em produtividade e gestão",
# Comportamento
instructions="""
Você é um assistente executivo altamente organizado.
Suas prioridades:
1. Precisão sobre velocidade
2. Proatividade
3. Comunicação clara e profissional
""",
# Modelo e parâmetros
model="gpt-4",
temperature=0.3, # Mais determinístico
# Tools
tools=[...],
# Memory
memory=True,
max_memory_messages=20,
# Debugging
show_tool_calls=True,
# Limites de segurança
max_iterations=10,
timeout=60, # segundos
)
System Prompts Avançados
agent = Agent(
instructions="""
# IDENTIDADE
Você é Alex, um assistente de pesquisa acadêmica.
# CAPACIDADES
- Buscar papers científicos
- Resumir artigos técnicos
- Explicar conceitos complexos
# PROCESSO DE TRABALHO
1. Entenda completamente a pergunta
2. Use ferramentas para buscar informações
3. Sintetize findings de múltiplas fontes
4. Forneça resposta estruturada com citações
# RESTRIÇÕES
- NUNCA invente citações
- SEMPRE indique quando informação é incerta
- Admita limitações quando apropriado
""",
tools=[...],
model="gpt-4"
)
Capítulo 4.8: Best Practices e Padrões
1. Estrutura de Projeto
2. Factory Pattern para Agentes
from agno import Agent
from tools import web_tools, database_tools
from config.settings import settings
def create_researcher_agent():
"""Factory para criar agente pesquisador"""
return Agent(
name="Researcher",
tools=[
web_tools.search_web,
database_tools.query_knowledge_base
],
model=settings.default_model,
memory=True
)
3. Error Handling
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10)
)
def run_agent_with_retry(agent, input_text):
"""Executa agente com retry automático"""
try:
return agent.run(input_text)
except Exception as e:
print(f"❌ Erro: {e}")
raise
4. Testing
import pytest
from agents import create_researcher_agent
@pytest.fixture
def researcher():
return create_researcher_agent()
def test_researcher_basic_query(researcher):
result = researcher.run("O que é Python?")
assert "Python" in result
assert len(result) > 100
def test_researcher_memory(researcher):
researcher.run("Meu nome é João")
result = researcher.run("Qual é meu nome?")
assert "João" in result
📝 Resumo Gráfico do Módulo 4
Conceitos-Chave
Filosofia Agno:
- Simplicidade > Complexidade
- Foco > Generalização
- Transparência > Caixa-preta
Componentes:
Patterns:
- Single Agent (1 agente, N tools)
- Agent as Tool (agente usando agente)
- Pipeline (sequência de agentes)
- Collaborative (agentes em paralelo)
Quando Usar:
- ✅ Protótipos rápidos
- ✅ Agentes autônomos
- ✅ Código limpo e manutenível
- ✅ Time pequeno
🚀 Projeto Prático do Módulo 4
Desafio: Assistente Pessoal Completo
Objetivo: Criar um assistente pessoal com múltiplas capacidades usando Agno.
Funcionalidades:
- Gerenciamento de tarefas (CRUD)
- Lembretes e agenda
- Notas e anotações
- Busca de informações
- Cálculos e conversões
- Memory persistente
Veja o arquivo completo do Assistente Pessoal (300+ linhas) no conteúdo markdown do módulo, incluindo:
• Sistema completo de tarefas, notas e lembretes
• Tools customizadas para cada funcionalidade
• Storage persistente em JSON
• Interface interativa via CLI
• Memory conversacional
Como Executar
# 1. Instalar dependências
pip install agno python-dotenv
# 2. Configurar .env
echo "OPENAI_API_KEY=sk-..." > .env
# 3. Executar
python personal_assistant.py
Exemplos de Uso
Você: Adicione "estudar Python" às minhas tarefas com alta prioridade
🤖 Assistente: ✓ Tarefa #1 adicionada: 'estudar Python' (prioridade: high)
Você: Liste minhas tarefas pendentes
🤖 Assistente: Tarefas (pending):
○ #1 [high] estudar Python
Você: Quanto é 25 * 17?
🤖 Assistente: Resultado: 425
💡 Conclusões e Próximos Passos
O que você aprendeu:
- ✓ Filosofia de simplicidade do Agno
- ✓ Criar agentes com código minimalista
- ✓ Desenvolver tools customizadas
- ✓ Implementar memory e storage
- ✓ RAG simplificado
- ✓ Sistemas multi-agentes
- ✓ Best practices e patterns
- ✓ Projeto completo production-ready
Agno vs LangChain: Veredito
Use Agno quando:
- Velocidade de desenvolvimento é crítica
- Foco em agentes autônomos
- Clareza > Flexibilidade
- Equipe pequena
Use LangChain quando:
- Necessita ecossistema completo
- Pipelines complexos de dados
- Múltiplas integrações especializadas