DEV Community

Cover image for Criando multi-agents AI de forma simples
Airton Lira junior
Airton Lira junior

Posted on

Criando multi-agents AI de forma simples

Opa, pessoal! Espero que todos estejam bem.

Estou iniciando aqui uma série de artigos que vou escrever desde o mais básico até o mais avançado sobre o mundo da Inteligência Artificial (AI). Atualmente, no momento em que escrevo este artigo, não atuo mais diretamente com AI, mas é o meu PDI (Plano de Desenvolvimento Individual), ou seja, algo que estudo porque sei que será o futuro.

Portanto, neste artigo, vou te ensinar a desenvolver não apenas um chatbot simples (pois isso já não vale mais nada no mercado), mas sim três agentes de AI utilizando o framework LangChain e Python.

A ideia é que eu possa perguntar para a AI qualquer coisa sobre um determinado link da internet que eu passar para ela. O agente fará o scraping dessa URL, levará o contexto da página + sua pergunta para a AI e, então, ela te devolverá a resposta, evitando que você precise ler o site inteiro ou resumi-lo manualmente. O terceiro agente de AI será responsável por invocar uma função que formata código Python sob demanda. Agora, você pode se perguntar: como a AI consegue diferenciar essas funções através de perguntas? Continua comigo! 👇


Fluxo do projeto

Esse desenho (mega artístico) explica como funciona. O LangChain possui o que chamamos de tools, que são literalmente ferramentas que podem ser tanto uma função Python simples, sem AI, quanto uma função que envolve AI. Com nossas tools, podemos criar uma espécie de kit de ferramentas (toolkit). Ao utilizar algumas funções do LangChain, passamos uma lista dessas tools e, por baixo dos panos, a AI compreende sua pergunta e decide qual a melhor tool (agente) para responder. Legal, não?

Agora que explicamos a ideia e o funcionamento geral, vamos para o código! No final do artigo, já publiquei no meu GitHub o repositório com o código completo. Mas antes, vamos por partes para entender melhor.


📂 Estrutura de Arquivos do Projeto

📁 projeto-langchain
│── .env                # Armazena a chave da OpenAI (ainda não tenho poder computacional para rodar um LLaMA 3.3 70B 😅)
│── .gitignore          # Evita subir o .env e expor minha chave.
│── agents.py          # Concentra as funções dos agentes (tools) e a função main.
│── scrapper.py        # Função que utiliza BeautifulSoup para raspagem de dados da URL, caso seja fornecida na pergunta.
│── README.md          # Explicação do projeto, requisitos e como utilizá-lo.
Enter fullscreen mode Exit fullscreen mode

Começando pelo mais fácil, o scrapper.py:

import requests
from bs4 import BeautifulSoup

def get_text_from_url(url: str) -> str:
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')
        for script in soup(['script', 'style']):
            script.extract()
        text = soup.get_text()
        return "\n".join(line.strip() for line in text.splitlines() if line.strip())
    return f"Erro ao acessar a URL. Status Code: {response.status_code}"
Enter fullscreen mode Exit fullscreen mode

Este código define uma função chamada get_text_from_url que:

  1. Faz uma requisição HTTP GET para obter o conteúdo da página.
  2. Verifica se a requisição foi bem-sucedida (status_code 200).
  3. Usa BeautifulSoup para fazer parsing do HTML.
  4. Remove as tags <script> e <style>, eliminando conteúdo desnecessário.
  5. Extrai e formata o texto da página, removendo espaços extras.
  6. Se a requisição falhar, retorna um erro com o código de status.

O objetivo desse código é extrair apenas o texto relevante da página, para que nosso agente (tool) possa utilizá-lo.


🤖 Construindo os Agentes em agents.py

Importamos as bibliotecas necessárias:

import os
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
from scrapper import get_text_from_url
from langchain_core.messages import HumanMessage, SystemMessage
from langchain.tools import tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.agents import AgentExecutor, create_openai_tools_agent
Enter fullscreen mode Exit fullscreen mode

🔍 Explicação das bibliotecas:

  • load_dotenv(): Carrega as variáveis de ambiente do arquivo .env.
  • ChatOpenAI: Permite interagir com os modelos de chat da OpenAI.
  • tool: Decorador que define funções como ferramentas do agente.
  • AgentExecutor: Gerencia a execução dos agentes.

Agora, a função que envia mensagens para a OpenAI:

def get_response_from_openai(message: str):
    llm = ChatOpenAI(model_name="gpt-3.5-turbo")
    response = llm.invoke(message)
    return response
Enter fullscreen mode Exit fullscreen mode

📄 Agente de Documentação (documentation_tool)

@tool
def documentation_tool(url: str, question: str) -> str:
    """Recebe uma URL de documentação e uma pergunta sobre ela."""
    context = get_text_from_url(url)
    message = [
        SystemMessage(content="Explique documentações técnicas de forma simples."),
        HumanMessage(content=f"Documentação: {context}\n\n Pergunta: {question}")
    ]
    response = get_response_from_openai(message)
    return response
Enter fullscreen mode Exit fullscreen mode

🖥️ Agente de Formatação de Código (black_formatter_tool)

@tool
def black_formatter_tool(code: str) -> str:
    """Recebe um caminho de arquivo Python e formata seu código usando Black."""
    try:
        os.system(f"poetry run black {code}")
        return "Done!"
    except:
        return "Error! formatter"
Enter fullscreen mode Exit fullscreen mode

🔗 Conectando os Agentes

toolkit = [documentation_tool, black_formatter_tool]
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
Enter fullscreen mode Exit fullscreen mode

Criamos o agente:

prompt = ChatPromptTemplate.from_messages([
    ("system", "Use suas ferramentas para responder perguntas."),
    MessagesPlaceholder("chat_history", optional=True),
    ("human", "{input}"),
    MessagesPlaceholder("agent_scratchpad")
])

agent = create_openai_tools_agent(llm, toolkit, prompt=prompt)
agent_executor = AgentExecutor(agent=agent, tools=toolkit, verbose=True)
Enter fullscreen mode Exit fullscreen mode

🏁 Rodando o Script

def main():
    while True:
        try:
            pergunta = input("\nDigite sua pergunta (ou 'sair' para encerrar): ")
            if pergunta.lower() == 'sair':
                print("Até logo!")
                break
            resposta = agent_executor.invoke({"input": pergunta})
            print("\nResposta:", resposta["output"])
        except KeyboardInterrupt:
            print("\nPrograma encerrado pelo usuário.")
            break
Enter fullscreen mode Exit fullscreen mode

Agora, basta rodar:

python agents.py
Enter fullscreen mode Exit fullscreen mode

Vamos ver um exemplo prático com um tecnologia que sou fã o Duckdb?
Fazendo a perguntando e passando a URL de documentação do Duckdb:

Image description

Resultado:

Image description

Reparem que:

  • Ele "melhorou" minha pergunta.
  • Como habilitamos para ver todo tracking, podemos ver o que ele pegou de relevante da pagina.
  • Por eu estar utilizando o modelo mais barato da openAI GPT 3.5 talvez ele não compreendeu que gostaria que fosse em português (olha o prompt engineer ai rsrsrs), talvez teria que passar na pergunta.

Pronto! Simples como disse que seria né? no próximo artigo vamos usar a tecnica RAG (Retrieval-Augmented Generation) para conhecer mais esta técnica de aprendizado para a AI e também começar a se envolver com banco de dados vetoriais.

Queria deixar aqui o incentivo a escrever esse artigo o canal do youtube @datawaybr

Meu Linkedln para você me seguir, sempre posto temas relacionados a engenharia de dados e AI: https://www.linkedin.com/in/airton-lira-junior-6b81a661/

Obrigado, se cuidem, bebam agua e pratiquem atividade física

Top comments (0)