Pular para o conteúdo principal

RAG autêntico: Tutorial passo a passo com projeto de demonstração

Saiba como criar um pipeline Agentic RAG a partir do zero, integrando fontes de dados locais e raspagem da Web para gerar respostas com reconhecimento de contexto às consultas do usuário.
Actualizado 27 de fev. de 2025  · 12 min de leitura

Com que frequência você deseja que sua IA possa fazer mais do que apenas repetir o que ela já sabe? Como alguém que passou inúmeras horas refinando e ajustando sistemas de IA, posso dizer a você que os modelos tradicionais, embora impressionantes, muitas vezes parecem estar presos em uma bolha limitada ao que foi treinado. É aqui queo Agentic RAG entra em cena.

No RAG autêntico, as habilidades de tomada de decisão da IA autêntica encontram a adaptabilidade da geração aumentada por recuperação (RAG). Juntos, eles formam um sistema que pode acessar, raciocinar e gerar informações relevantes de forma independente.

Escrevi anteriormente um artigo sobre RAG autêntico que ajudará você a entender tudo sobre ele do ponto de vista teórico. Este artigo será mais prático, portanto, vamos nos concentrar nisso.

Visão geral do projeto Agentic RAG

Deixe-me mostrar a você o que estamos construindo, passo a passo. Trata-se de criar um pipeline RAG com base na arquitetura mostrada aqui:

Visão geral do projeto de demonstração do agentic rag

Etapa 1: Consulta do usuário

Quer seja uma consulta simples ou um problema complexo, tudo começa com uma pergunta do usuário. Essa é a faísca que coloca nosso pipeline em movimento.

Etapa 2: Roteamento da consulta

Em seguida, o sistema verifica: Posso responder a isso?

Sim? Ele extrai o conhecimento existente e fornece a resposta imediatamente.

Não? É hora de ir mais fundo! A consulta é encaminhada para a próxima etapa.

Etapa 3: Recuperação de dados

Se a resposta não estiver prontamente disponível, o pipeline se aprofunda em duas fontes possíveis:

  1. Documentos locais: Usaremos um PDF pré-processado como nossa base de conhecimento, na qual o sistema procura por partes relevantes de informações.
  2. Pesquisa na Internet: Se você precisar de mais contexto, o pipeline poderá entrar em contato com fontes externas para obter informações atualizadas.

Etapa 4: Criando o contexto

Os dados recuperados, seja do PDF ou da Web, são compilados em um contexto coerente e recuperado. Pense nisso como se você reunisse todas as peças do quebra-cabeça antes de montá-las.

Etapa 5: Geração da resposta final

Por fim, esse contexto é passado para um modelo de linguagem ampla (LLM) para criar uma resposta clara e precisa. Não se trata apenas de recuperar dados, mas de entendê-los e apresentá-los da melhor maneira possível.

Ao final, teremos um pipeline RAG inteligente e eficiente que poderá responder dinamicamente a consultas com contexto do mundo real.

Fonte de dados local

Para começar, vou usar um documento do mundo real como nossa fonte de dados local. O documento com o qual trabalharemos é nada menos que Princípios de IA generativa. Ele está repleto de insights valiosos, portanto, será o caso de teste perfeito para nosso pipeline. Você também precisaria de um resumo do arquivo que estou usando para fins de roteamento. Você pode obter o arquivo de resumo em aqui.

Aqui está tudo o que você precisa para começar, passo a passo.

Pré-requisitos

Antes de começarmos, há alguns aspectos que você precisa ter em mente:

  1. Chave de API do Groq: Você precisará de uma chave de API do Groq, que pode ser obtida aqui: Console da API do Groq
  2. Chave de API da Gemini: O Gemini ajudará você na orquestração com agentes, o Groq fornece respostas super rápidas, mas pode ficar preso aos limites de taxa atuais que eles têm: Console da API Gemini
  3. Chave de API do Serper.dev: Para qualquer funcionalidade de pesquisa na Internet, usaremos o Serper.dev. Obtenha sua chave de API aqui: Serper.dev API Key

Instalação de pacotes

Vamos nos certificar de que você tem as ferramentas certas instaladas. Abra o terminal e execute os seguintes comandos para instalar os pacotes Python necessários:

pip install langchain-groq faiss-cpu crewai serper pypdf2 python-dotenv setuptools sentence-transformers huggingface distutils`

Configuração do ambiente

Depois de ter as chaves e os pacotes prontos, você está pronto para ir! Recomendo que você salve suas chaves de API em um arquivo.env ou de forma segura em sua base de código. Aqui está um exemplo de como o arquivo .env pode parecer:

import os from dotenv 
import load_dotenv from langchain.vectorstores 
import FAISS from langchain.document_loaders 
import PyPDFLoader 
from langchain.text_splitter import RecursiveCharacterTextSplitter 
from langchain_huggingface.embeddings import HuggingFaceEmbeddings 
from langchain_groq import ChatGroq 
from crewai_tools import SerperDevTool 
from crewai import Agent, Task, Crew, LLM

load_dotenv() 
GROQ_API_KEY = os.getenv("GROQ_API_KEY") 
SERPER_API_KEY = os.getenv("SERPER_API_KEY")
GEMINI=os.getenv("GEMINI")

Carreguei variáveis de ambiente para poder gerenciar com segurança as chaves de API e os dados confidenciais sem codificá-los. Isso garante que o script permaneça seguro e que eu possa alterar as chaves em um só lugar ( arquivo.env ), se necessário.

Em poucas palavras, você verá o que esses pacotes e funções importados farão:

  • os: Fornece utilitários de interface do sistema operacional.
  • dotenv: Carrega variáveis de ambiente dos arquivos .env.
  • FAISS: Armazenamento de vetores para pesquisa e recuperação de similaridade.
  • PyPDFLoader: Extrai conteúdo de texto de documentos PDF.
  • RecursiveCharacterTextSplitter: Divide o texto em partes gerenciáveis de forma recursiva.
  • HuggingFaceEmbeddings: Gera embeddings de texto usando modelos HuggingFace.
  • ChatGroq: Interface de bate-papo com a aceleração de hardware do Groq.
  • SerperDevTool: Ferramenta para realizar pesquisas na Web.
  • ScrapeWebsiteTool: Extrai dados de páginas da Web.
  • Agente: Define uma entidade de IA com funções e objetivos.
  • Tarefa: Representa um objetivo ou uma ação específica para um agente.
  • Tripulação: Orquestra agentes e tarefas para fluxos de trabalho coordenados.
  • LLM: Interface de modelo de linguagem grande para gerar respostas de texto.

Inicialização dos LLMs

Começamos com a inicialização de dois modelos de linguagem:

  • llm: Para tarefas gerais, como roteamento e geração de respostas. Usaremos o modelo llama-3.3-70b-specdec.
  • crew_llm: Especificamente para o agente de raspagem da Web, pois ele precisa de uma configuração ligeiramente diferente (como temperatura para resultados mais criativos). Usaremos o modelo gemini/gemini-1.5-flash.
# Initialize LLM
llm = ChatGroq(
    model="llama-3.3-70b-specdec",
    temperature=0,
    max_tokens=500,
    timeout=None,
    max_retries=2,
)

crew_llm = LLM(
    model="gemini/gemini-1.5-flash",
    api_key=GEMINI,
    max_tokens=500,
    temperature=0.7
)

Adicionando o tomador de decisões

A função check_local_knowledge() abaixo atua como um tomador de decisões. Criei um prompt no qual passei a consulta do usuário e algum contexto local (do PDF). O modelo responde com "Yes" (Sim) ou "No" (Não), informando se ele tem informações suficientes localmente para responder à consulta. Caso contrário, recorreremos à coleta de dados da Web.

def check_local_knowledge(query, context):
    """Router function to determine if we can answer from local knowledge"""
    prompt = '''Role: Question-Answering Assistant
Task: Determine whether the system can answer the user's question based on the provided text.
Instructions:
    - Analyze the text and identify if it contains the necessary information to answer the user's question.
    - Provide a clear and concise response indicating whether the system can answer the question or not.
    - Your response should include only a single word. Nothing else, no other text, information, header/footer. 
Output Format:
    - Answer: Yes/No
Study the below examples and based on that, respond to the last question. 
Examples:
    Input: 
        Text: The capital of France is Paris.
        User Question: What is the capital of France?
    Expected Output:
        Answer: Yes
    Input: 
        Text: The population of the United States is over 330 million.
        User Question: What is the population of China?
    Expected Output:
        Answer: No
    Input:
        User Question: {query}
        Text: {text}
'''
    formatted_prompt = prompt.format(text=context, query=query)
    response = llm.invoke(formatted_prompt)
    return response.content.strip().lower() == "yes"

Agente de pesquisa e raspagem da Web

Em seguida, configuramos um agente de pesquisa e raspagem da Web usando a crewai biblioteca. Esse agente usa uma ferramenta de pesquisa (SerperDevTool) para encontrar artigos relacionados à consulta do usuário. A descrição da tarefa garante que o agente saiba o que recuperar e resume o conteúdo relevante da Web. É como enviar um trabalhador especializado para buscar dados na Internet.

Em seguida, a função get_web_content() executa o agente de raspagem da Web. Ele envia a consulta como entrada e recupera um resumo conciso do artigo mais relevante. Ele retorna o resultado bruto, que se torna nosso contexto se o roteador decidir que não temos informações locais suficientes.

def setup_web_scraping_agent():
    """Setup the web scraping agent and related components"""
    search_tool = SerperDevTool()  # Tool for performing web searches
    scrape_website = ScrapeWebsiteTool()  # Tool for extracting data from websites
    
    # Define the web search agent
    web_search_agent = Agent(
        role="Expert Web Search Agent",
        goal="Identify and retrieve relevant web data for user queries",
        backstory="An expert in identifying valuable web sources for the user's needs",
        allow_delegation=False,
        verbose=True,
        llm=crew_llm
    )
    
    # Define the web scraping agent
    web_scraper_agent = Agent(
        role="Expert Web Scraper Agent",
        goal="Extract and analyze content from specific web pages identified by the search agent",
        backstory="A highly skilled web scraper, capable of analyzing and summarizing website content accurately",
        allow_delegation=False,
        verbose=True,
        llm=crew_llm
    )
    
    # Define the web search task
    search_task = Task(
        description=(
            "Identify the most relevant web page or article for the topic: '{topic}'. "
            "Use all available tools to search for and provide a link to a web page "
            "that contains valuable information about the topic. Keep your response concise."
        ),
        expected_output=(
            "A concise summary of the most relevant web page or article for '{topic}', "
            "including the link to the source and key points from the content."
        ),
        tools=[search_tool],
        agent=web_search_agent,
    )
    
    # Define the web scraping task
    scraping_task = Task(
        description=(
            "Extract and analyze data from the given web page or website. Focus on the key sections "
            "that provide insights into the topic: '{topic}'. Use all available tools to retrieve the content, "
            "and summarize the key findings in a concise manner."
        ),
        expected_output=(
            "A detailed summary of the content from the given web page or website, highlighting the key insights "
            "and explaining their relevance to the topic: '{topic}'. Ensure clarity and conciseness."
        ),
        tools=[scrape_website],
        agent=web_scraper_agent,
    )
    
    # Define the crew to manage agents and tasks
    crew = Crew(
        agents=[web_search_agent, web_scraper_agent],
        tasks=[search_task, scraping_task],
        verbose=1,
        memory=False,
    )
    return crew

def get_web_content(query):
    """Get content from web scraping"""
    crew = setup_web_scraping_agent()
    result = crew.kickoff(inputs={"topic": query})
    return result.raw

Criando o banco de dados de vetores

A função setup_vector_db() configura o banco de dados vetorial a partir de um arquivo PDF. Veja como eu fiz isso passo a passo:

  1. Carregue o PDF: Usei o site PyPDFLoader para extrair o conteúdo.
  2. Separe o texto em partes: Dividi o conteúdo do PDF em partes menores (1000 caracteres com 50 caracteres sobrepostos) usando RecursiveCharacterTextSplitter. Isso torna os dados gerenciáveis e pesquisáveis.
  3. Criar o Vector DB: Incorporei os blocos usando um modelo de transformador de frases e os armazenei em um arquivo FAISS e os armazenei em um banco de dados de vetores FAISS. Isso me permite pesquisar textos relevantes com eficiência.

Depois disso, a função get_local_content() consulta o banco de dados de vetores para obter os 5 blocos mais relevantes relacionados à consulta do usuário. Ele combina esses blocos em uma única cadeia de contexto. 

def setup_vector_db(pdf_path):
    """Setup vector database from PDF"""
    # Load and chunk PDF
    loader = PyPDFLoader(pdf_path)
    documents = loader.load()
    
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=50
    )
    chunks = text_splitter.split_documents(documents)
    
    # Create vector database
    embeddings = HuggingFaceEmbeddings(
        model_name="sentence-transformers/all-mpnet-base-v2"
    )
    vector_db = FAISS.from_documents(chunks, embeddings)
    
    return vector_db

def get_local_content(vector_db, query):
    """Get content from vector database"""
    docs = vector_db.similarity_search(query, k=5)
    return " ".join([doc.page_content for doc in docs])

Gerando a resposta final

Quando tenho o contexto (de documentos locais ou de raspagem da Web), eu o passo para o modelo de linguagem junto com a consulta do usuário. O LLM gera a resposta final combinando o contexto e a consulta em um formato de conversação.

Aqui está o fluxo do processamento da consulta principal:

  1. Roteamento: Utilizo o site check_local_knowledge() para decidir se o conteúdo do PDF local tem dados suficientes para responder à consulta.
    • Se você "Sim"eu busco os pedaços relevantes no banco de dados de vetores.
    • Se "Não", eu busco artigos relevantes na Web.
  2. Resposta final: Depois de obter o contexto, eu o passo para o LLM para gerar a resposta final.
def generate_final_answer(context, query):
    """Generate final answer using LLM"""
    messages = [
        (
            "system",
            "You are a helpful assistant. Use the provided context to answer the query accurately.",
        ),
        ("system", f"Context: {context}"),
        ("human", query),
    ]
    response = llm.invoke(messages)
    return response.content

def process_query(query, vector_db, local_context):
    """Main function to process user query"""
    print(f"Processing query: {query}")
    
    # Step 1: Check if we can answer from local knowledge
    can_answer_locally = check_local_knowledge(query, local_context)
    print(f"Can answer locally: {can_answer_locally}")
    
    # Step 2: Get context either from local DB or web
    if can_answer_locally:
        context = get_local_content(vector_db, query)
        print("Retrieved context from local documents")
    else:
        context = get_web_content(query)
        print("Retrieved context from web scraping")
    
    # Step 3: Generate final answer
    answer = generate_final_answer(context, query)
    return answer

Por fim, unimos tudo com a função main():

def main():
    # Setup
    pdf_path = "genai-principles.pdf" 
    
    # Initialize vector database
    print("Setting up vector database...")
    vector_db = setup_vector_db(pdf_path)
    
    # Get initial context from PDF for routing
    local_context = get_local_content(vector_db, "")
    
    # Example usage
    query = "What is Agentic RAG?"
    result = process_query(query, vector_db, local_context)
    print("\nFinal Answer:")
    print(result)
if __name__ == "__main__":
    main()

Acima, nós:

  1. Configure o banco de dados de vetores: Carregar e processar o PDF.
  2. Inicializou o contexto local: Obtivemos algum conteúdo geral do PDF para passar como contexto para o roteador.
  3. Executou uma consulta de exemplo: Executamos uma consulta de amostra ("What is Agentic RAG?" ) e imprimimos a resposta final.

Este é o resultado do programa:

Agentic RAG is a technique for building Large Language Model (LLM) powered applications that incorporates AI agents. It is an extension of the traditional Retrieval-Augmented Generation (RAG) approach, which uses an external knowledge source to provide the LLM with relevant context and reduce hallucinations.
In traditional RAG pipelines, the retrieval component is typically composed of an embedding model and a vector database, and the generative component is an LLM. At inference time, the user query is used to run a similarity search over the indexed documents to retrieve the most similar documents to the query and provide the LLM with additional context.
Agentic RAG, on the other hand, introduces AI agents that are designed to interact with the user query and provide additional context to the LLM. These agents can be thought of as "virtual assistants" that help the LLM to better understand the user's intent and retrieve relevant documents.

The key components of Agentic RAG include:
1. AI agents: These are the virtual assistants that interact with the user query and provide additional context to the LLM.
2. Retrieval component: This is the component that retrieves the most similar documents to the user query.
3. Generative component: This is the component that uses the retrieved documents to generate the final output.

Agentic RAG has several benefits, including:
1. Improved accuracy: By providing additional context to the LLM, Agentic RAG can improve the accuracy of the generated output.
2. Enhanced user experience: Agentic RAG can help to reduce the complexity of the user interface and provide a more natural and intuitive experience.
3. Increased flexibility: Agentic RAG can be easily extended to support new use cases and applications.

However, Agentic RAG also has some limitations, including:
1. Increased complexity: Agentic RAG requires additional components and infrastructure, which can increase the complexity of the system.
2. Higher computational requirements: Agentic RAG requires more computational resources to handle the additional complexity of the AI agents and the retrieval component.
3. Training requirements: Agentic RAG requires more data and training to learn the behaviour of the AI agents and the retrieval component.

Explicação da saída

Quando fiz a pergunta "O que é Agentic RAG?" que não estava explicitamente disponível no documento fornecido, o sistema demonstrou sua flexibilidade e inteligência. Os agentes da crewAI encaminharam a consulta corretamente, usando o entendimento do roteador de que o contexto externo era necessário. Os agentes colaboraram para extrair o artigo mais relevante da Web, analisar seu conteúdo e gerar uma resposta bem informada.

O sistema forneceu uma explicação clara do RAG autêntico, seus componentes (agentes de IA, recuperação e elementos geradores), benefícios (precisão, experiência do usuário e flexibilidade) e limitações (complexidade, necessidades computacionais e requisitos de treinamento).

Isso destaca a capacidade do pipeline de buscar contexto dinamicamente e fornecer insights precisos, concisos e valiosos, mesmo quando confrontado com consultas que vão além do conjunto de dados inicial.

Conclusão

O pipeline que criamos é um processo dinâmico e de várias etapas que lida com eficiência com as consultas dos usuários combinando conhecimentos existentes e externos.

O sistema pode se adaptar dinamicamente a diversas consultas e fornecer respostas precisas e fáceis de usar. Com a integração de dados locais, pesquisas ao vivo na Internet e uma interface de usuário perfeita, o pipeline RAG prova ser uma solução robusta e prática para aplicações do mundo real. Como próxima etapa, tente criar algo próprio usando o fluxo de trabalho que abordamos.


Bhavishya Pandit's photo
Author
Bhavishya Pandit
LinkedIn
Twitter

Engenheiro sênior de GenAI e criador de conteúdo que obteve 20 milhões de visualizações ao compartilhar conhecimento sobre GenAI e ciência de dados.

Temas

Aprenda IA com estes cursos!

programa

Developing AI Applications

23hrs hr
Learn to create AI-powered applications with the latest AI developer tools, including the OpenAI API, Hugging Face, and LangChain.
Ver DetalhesRight Arrow
Iniciar curso
Ver maisRight Arrow
Relacionado

tutorial

RAG With Llama 3.1 8B, Ollama e Langchain: Tutorial

Aprenda a criar um aplicativo RAG com o Llama 3.1 8B usando Ollama e Langchain, configurando o ambiente, processando documentos, criando embeddings e integrando um retriever.
Ryan Ong's photo

Ryan Ong

12 min

tutorial

Tutorial do DeepChecks: Automatizando os testes de machine learning

Saiba como realizar a validação de dados e modelos para garantir um desempenho robusto de machine learning usando nosso guia passo a passo para automatizar testes com o DeepChecks.
Abid Ali Awan's photo

Abid Ali Awan

12 min

tutorial

Tutorial da API de assistentes da OpenAI

Uma visão geral abrangente da API Assistants com nosso artigo, que oferece uma análise aprofundada de seus recursos, usos no setor, orientação de configuração e práticas recomendadas para maximizar seu potencial em vários aplicativos de negócios.
Zoumana Keita 's photo

Zoumana Keita

14 min

tutorial

Dominando a retropropagação: Um guia abrangente para redes neurais

Mergulhe nos fundamentos da retropropagação em redes neurais com um guia prático para treinar e avaliar um modelo para um cenário de uso de classificação de imagens.
Zoumana Keita 's photo

Zoumana Keita

14 min

tutorial

Criação de modelos de redes neurais (NN) em R

Neste tutorial, você aprenderá a criar um modelo de rede neural no R.
Abid Ali Awan's photo

Abid Ali Awan

16 min

Ver maisVer mais