Construindo um simples agente RAG com Agno v2 e LLaMA
Introdução
Falando de forma superficial, RAG (Retrieval-Augmented Generation) é uma técnica utilizada para permitir que um LLM tenha acesso a conhecimentos específicos nos quais ele não foi treinado originalmente. Alguns exemplos incluem os documentos de onboarding da empresa A, o cardápio do restaurante B ou o FAQ da academia XYZ do seu bairro. Nesse contexto, utilizamos um modelo de linguagem (LLM) como o “cérebro” do sistema, enquanto PDFs, CSVs, vídeos e outros formatos de arquivos servem como fontes de dados externas. Sendo sincero, para compreender RAG de forma completa, é necessário entender diversos conceitos: carregamento de documentos, fragmentação (chunking) dos textos, modelos de embeddings, bancos de dados vetoriais, entre outros. Acreditem em mim, é um pouquinho mais complicado do que a tabuada. Neste artigo não entraremos nos detalhes, o objetivo é mostrar como é fácil fazer isso com Agno.
Pô, legal, mas o que é esse Agno exatamente?
Resumindo a ópera, o Agno é um framework Python voltado para a construção de aplicações baseadas em LLMs. Existem outros frameworks com propostas semelhantes, como o LangChain, que tende a ser um pouco mais complexo, mas oferece um leque maior de possibilidades, e o CrewAI, que é focado na construção de sistemas multiagentes. No geral, há uma grande variedade de frameworks nesse ecossistema, cada um com suas próprias características e pontos fortes. Para o desenvolvimento, estarei utilizando o PyCharm, mas fique à vontade para usar a ferramenta que preferir, como VS Code, Cursor ou o próprio PyCharm. Crie um novo projeto e, a partir dele, vamos inicializar o ambiente e instalar as dependências necessárias. Um detalhe importante: estarei usando o gerenciador de pacotes uv. Eu já o tenho instalado globalmente, mas você também pode instalá-lo no seu ambiente utilizando o pip.
Gerenciador de pacotes
Comando para instalar o uv:
1pip install uvIniciando o projeto
Comando para iniciar o projeto:
1uv initDependências
Comando para iniciar o projeto:
1uv add agno openai groq chromadb chonkie pdfreader pypdf python-dotenv sqlalchemy sentence-transformersGroq api key
Ok, guys. Normalmente eu utilizo os modelos da OpenAI, que são pagos. Existem modelos muito bons e relativamente baratos, com cerca de R$ 30 dá para fazer bastante coisa mesmo. No entanto, para manter este artigo livre de custos financeiros, vamos utilizar o LLaMA, da Meta, que para nossa brincadeira aqui, sai “de grátis”. Para isso acesse https://groq.com/groqcloud, crie uma api key, crie um arquivo chamado .env e cole sua api key nele.
"Vale destacar que existe uma enorme variedade de provedores de LLMs(OpenAI, Anthropic, Google, Mistral, etc), e cada provedor disponibiliza diversos modelos, com características, custos e níveis de desempenho diferentes. A escolha do modelo ideal depende do caso de uso, do orçamento e dos requisitos da aplicação."
1GROQ_API_KEY=sua-groq-api-keyConhecimento do agente
Continuando, crie um arquivo chamado agent_knowledge.py, com o projeto já inicializado, as dependências instaladas e a API key em mãos, o primeiro passo será trabalhar no processo de ingestão de arquivos externos. Para manter o artigo enxuto e facilitar a didática, utilizaremos apenas um único PDF como fonte de dados. Esse arquivo será disponibilizado junto com o projeto, na pasta assets. Trata-se de um PDF contendo o FAQ de uma academia fictícia, criado no ChatGPT, mas você é totalmente livre para utilizar outro documento de sua preferência. Como este é um código com fins didáticos, todo ele contém comentários explicativos detalhando cada etapa. Em termos práticos, o que fazemos a seguir é: criamos um banco de dados vetorial, instanciamos a classe de conhecimento do agente e a vinculamos a esse banco. Por fim, adicionamos o conteúdo do PDF ao conhecimento do agente, permitindo que ele seja consultado posteriormente por meio de buscas semânticas.
1from agno.knowledge import Knowledge
2from agno.knowledge.embedder.sentence_transformer import SentenceTransformerEmbedder
3from agno.knowledge.reader.pdf_reader import PDFReader
4from agno.knowledge.chunking.semantic import SemanticChunking
5from agno.vectordb.chroma import ChromaDb
6
7# Criação do banco de dados vetorial usando ChromaDB.
8# Esse banco será responsável por armazenar os embeddings
9# gerados a partir dos documentos, permitindo buscas semânticas.
10vector_db = ChromaDb(
11 collection="agno_fit_collection", # Nome da coleção de vetores
12 path="../local_data/chromadb", # Caminho onde os dados serão persistidos localmente
13 embedder=SentenceTransformerEmbedder(
14 id="sentence-transformers/all-MiniLM-L6-v2"
15 ), # Modelo de embeddings open-source
16 persistent_client=True # Indica que o banco será persistente em disco
17)
18
19# Criação do objeto Knowledge.
20# Ele atua como a camada de conhecimento do agente,
21# conectando o banco vetorial aos dados que serão consultados via RAG.
22knowledge = Knowledge(
23 vector_db=vector_db,
24)
25
26# Adiciona o conteúdo de um PDF ao conhecimento do agente.
27# O documento será:
28# 1. Lido
29# 2. Quebrado em pedaços (chunks)
30# 3. Convertido em embeddings
31# 4. Armazenado no banco vetorial
32knowledge.add_content(
33 path="../assets/agno_fit_faq.pdf", # Caminho do PDF a ser indexado
34 reader=PDFReader(
35 chunck_strategy=SemanticChunking() # Estratégia de chunking semântico,
36 # que tenta dividir o texto respeitando o significado
37 ),
38 skip_if_exists=True # Evita reprocessar o documento caso ele já exista no banco
39)Usando llama com Groq
Primeira parte concluída, agora vamos criar o cérebro do nosso agente, agent_model.py. Essa etapa é bastante simples. Recapitulando: utilizaremos um modelo da Meta, disponibilizado por meio da Groq, e é neste ponto que entra a API key que criamos previamente, responsável por autenticar o acesso ao modelo de linguagem.
1import os
2from dotenv import load_dotenv
3from agno.models.groq import Groq
4
5
6# Carrega as variáveis de ambiente definidas no arquivo .env
7# Isso permite acessar a chave da API da Groq de forma segura,
8# sem deixá-la exposta diretamente no código.
9load_dotenv()
10
11# Cria a instância do modelo de linguagem utilizando o provedor Groq.
12# Embora o modelo LLaMA seja desenvolvido pela Meta,
13# ele é acessado por meio da Groq, que hospeda e disponibiliza o modelo via API.
14model = Groq(
15 id="llama-3.3-70b-versatile", # Identificador do modelo LLaMA a ser utilizado
16 api_key=os.getenv("GROQ_API_KEY"), # Chave de API carregada do ambiente
17)O Agente
Finalmente, vamos juntar todas as peças no arquivo agent.py e criar o nosso agente propriamente dito. Ele será o componente responsável por receber um “cérebro”, o modelo de linguagem (LLM) e também o conhecimento que esse cérebro poderá acessar. A partir disso, o agente será capaz de raciocinar e responder perguntas com base em tudo o que sabe, combinando modelo, histórico e dados externos. Lembre-se de ajustar o prompt do agente, pois essa é uma etapa extremamente importante. O prompt que estou utilizando está disponível na pasta assets, mas você pode modificá-lo ou criar um novo. Caso tenha usado um PDF com outro tema, certamente será necessário adaptar o prompt para que o agente se comporte corretamente dentro do novo contexto.
1from agno.agent import Agent
2from agno.db.sqlite import SqliteDb
3from agent_knowledge import knowledge
4from agent_model import model
5
6# Cria o banco de dados local que armazenará o histórico do agente.
7# Esse banco permite que o agente tenha memória entre execuções.
8db = SqliteDb(db_file="../local_data/agent.db")
9
10# Cria a instância do agente.
11agent = Agent(
12 name="agno-bot", # Nome do agente
13 model=model, # Modelo de linguagem (LLM)
14 instructions=open(
15 "../assets/agno_bot_prompt.md"
16 ).read(), # Prompt base que define o comportamento do agente
17 add_history_to_context=True, # Inclui histórico de conversas no contexto
18 num_history_runs=10, # Quantidade de interações passadas consideradas
19 db=db, # Banco de dados para persistência do histórico
20 search_knowledge=True, # Ativa busca semântica no conhecimento (RAG)
21 knowledge=knowledge, # Fonte de conhecimento do agente
22 add_knowledge_to_context=True # Injeta o conteúdo recuperado no contexto do LLM
23)
24
25# Executa uma consulta ao agente.
26# O agente irá:
27# 1. Buscar informações relevantes no banco vetorial
28# 2. Inserir os trechos encontrados no contexto
29# 3. Gerar a resposta usando o LLM
30response = agent.run("quais os planos da academia?", session_id="usuario-001")
31
32# Exibe apenas o conteúdo textual da resposta do agente.
33print(response.content)Links Relacionados
Gostou do artigo? Compartilhe com outros desenvolvedores!