Como utilizar os Agentes LangChain para tarefas automatizadas poderosas
Published on
No fascinante mundo dos modelos de linguagem e automação, os Agentes LangChain se destacam como um farol de inovação, permitindo que desenvolvedores e entusiastas de tecnologia criem tarefas automatizadas sofisticadas que parecem saídas de um romance de ficção científica. Se você está procurando mergulhar no reino dos Agentes LangChain, mas não sabe por onde começar, está no lugar certo. Este guia desvendará o processo, tornando-o acessível e direto. Então, pegue uma xícara de café e vamos embarcar nesta jornada emocionante juntos.
Como utilizar os Agentes LangChain: Comece rapidamente
Para entender melhor a estrutura do agente, vamos construir um agente que tenha duas ferramentas: uma para pesquisar coisas on-line e outra para pesquisar dados específicos que carregamos em um índice.
Pressupõe-se o conhecimento de LLMs e recuperação, então, se você ainda não explorou essas seções, é recomendável que o faça.
Configuração: LangSmith
Por definição, os agentes executam uma sequência de etapas determinadas por si mesmos, dependentes da entrada, antes de retornar uma saída visível para o usuário. Isso torna a depuração desses sistemas particularmente difícil e a capacidade de observação particularmente importante. O LangSmith é especialmente útil para esses casos.
Ao construir com o LangChain, todas as etapas serão automaticamente rastreadas no LangSmith. Para configurar o LangSmith, precisamos apenas definir as seguintes variáveis de ambiente:
export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="<sua-chave-de-api>"
Definir ferramentas
Primeiro, precisamos criar as ferramentas que queremos usar. Usaremos duas ferramentas: Tavily (para pesquisar online) e um recuperador em um índice local que criaremos.
- Tavily
Temos uma ferramenta integrada no LangChain para usar facilmente o mecanismo de pesquisa Tavily como ferramenta. Observe que isso requer uma chave de API - eles têm uma camada gratuita, mas se você não tiver uma ou não quiser criar uma, sempre poderá ignorar esta etapa.
Depois de criar sua chave de API, você precisará exportá-la como:
export TAVILY_API_KEY="..."
from langchain_community.tools.tavily_search import TavilySearchResults
search = TavilySearchResults()
search.invoke("qual é a previsão do tempo em SF")
- Recuperador
Também criaremos um recuperador com alguns dados próprios. Para uma explicação mais detalhada de cada etapa aqui, consulte esta seção.
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
loader = WebBaseLoader("https://docs.smith.langchain.com/overview")
docs = loader.load()
documents = RecursiveCharacterTextSplitter(
chunk_size=1000, chunk_overlap=200
).split_documents(docs)
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
retriever = vector.as_retriever()
retriever.get_relevant_documents("como fazer upload de um conjunto de dados")[0]
Agora que preenchemos nosso índice sobre o qual faremos a recuperação, podemos facilmente transformá-lo em uma ferramenta (o formato necessário para que um agente o utilize corretamente).
from langchain.tools.retriever import create_retriever_tool
retriever_tool = create_retriever_tool(
retriever,
"langsmith_search",
"Pesquisar informações sobre o LangSmith. Para qualquer pergunta sobre o LangSmith, você deve usar esta ferramenta!",
)
Ferramentas
Agora que criamos ambas, podemos criar uma lista de ferramentas que usaremos posteriormente.
tools = [search, retriever_tool]
Como criar um Agente LangChain
Agora que definimos as ferramentas, podemos criar o agente. Estaremos usando um agente de Funções OpenAI - para obter mais informações sobre este tipo de agente, bem como outras opções, consulte este guia.
Primeiro, escolhemos o LLM que queremos que oriente o agente.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
Em seguida, escolhemos o prompt que queremos usar para orientar o agente.
from langchain import hub
# Obtenha o prompt a ser usado - você pode modificá-lo!
prompt = hub.pull("hwchase17/openai-functions-agent")
prompt.messages
Agora, podemos inicializar o agente com o LLM, o prompt e as ferramentas. O agente é responsável por receber a entrada e decidir quais ações tomar. É crucial destacar que o Agente não executa essas ações - isso é feito pelo AgentExecutor (próxima etapa). Para obter mais informações sobre como pensar nesses componentes, consulte nosso guia conceitual.
from langchain.agents import create_openai_functions_agent
agent = create_openai_functions_agent(llm, tools, prompt)
Por fim, combinamos o agente (o cérebro) com as ferramentas dentro do AgentExecutor (que chamará repetidamente o agente e executará as ferramentas). Para obter mais informações sobre como pensar nesses componentes, consulte nosso guia conceitual.
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
Executar o agente
Agora podemos executar o agente em algumas consultas! Observe que, por enquanto, essas são consultas sem estado (não lembrará interações anteriores).
agent_executor.invoke({"input": "oi!"})
agent_executor.invoke({"input": "como o LangSmith pode ajudar nos testes?"})
agent_executor.invoke({"input": "qual é a previsão do tempo em SF?"})
Adicionar memória Como mencionado anteriormente, este agente é stateless. Isso significa que ele não se lembra de interações anteriores. Para dar a ele memória, precisamos passar o histórico de chat anterior. Note: ele precisa ser chamado de chat_history por causa do prompt que estamos usando. Se usarmos um prompt diferente, podemos alterar o nome da variável.
# Aqui passamos uma lista vazia de mensagens para chat_history porque é a primeira mensagem no chat
agent_executor.invoke({"input": "oi! meu nome é bob", "chat_history": []})
from langchain_core.messages import AIMessage, HumanMessage
agent_executor.invoke(
{
"chat_history": [
HumanMessage(content="oi! meu nome é bob"),
AIMessage(content="Olá Bob! Como posso ajudar você hoje?"),
],
"input": "qual é o meu nome?",
}
)
Se quisermos acompanhar essas mensagens automaticamente, podemos envolver isso em um RunnableWithMessageHistory. Para obter mais informações sobre como usar isso, consulte este guia.
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
message_history = ChatMessageHistory()
agent_with_chat_history = RunnableWithMessageHistory(
agent_executor,
# Isso é necessário porque na maioria dos cenários do mundo real, um session id é necessário
# Não é realmente usado aqui porque estamos usando um simple in memory ChatMessageHistory
lambda session_id: message_history,
input_messages_key="input",
history_messages_key="chat_history",
)
agent_with_chat_history.invoke(
{"input": "oi! Eu sou bob"},
# Isso é necessário porque na maioria dos cenários do mundo real, um session id é necessário
# Não é realmente usado aqui porque estamos usando um simple in memory ChatMessageHistory
config={"configurable": {"session_id": "<foo>"}},
)
Tipos de Agents LangChain
Tipos de Agentes
No mundo dos Agentes LangChain, a diversidade é a palavra-chave. Esses agentes vêm em várias versões, cada uma adaptada a tarefas e capacidades diferentes. Vamos explorar o mundo sutil dos Tipos de Agentes, desvendando seus modelos de tipo, suporte para histórico de chat, ferramentas com múltiplas entradas, chamadas de função paralelas e parâmetros de modelo necessários. Entender essas categorias ajudará você a selecionar o agente perfeito para suas necessidades.
-
OpenAI Tools: Um agente de ponta otimizado para modelos OpenAI recentes (a partir de 1106). É projetado para lidar com interações de chat, suportar ferramentas com múltiplas entradas e executar chamadas de função paralelas, exigindo os parâmetros de modelo 'tools'. Ideal para quem aproveita o que há de mais recente nas ofertas da OpenAI.
-
OpenAI Functions: Adaptado para modelos OpenAI ou modelos de origem aberta ajustados, que imitam as capacidades de chamada de função da OpenAI. Ele se destaca em ambientes de chat, lida com ferramentas de múltiplas entradas e requer parâmetros de modelo 'functions'. Uma escolha sólida para modelos especializados em chamadas de função.
-
XML: Este agente é adequado para modelos especializados em XML, como os da Anthropic. É construído para LLMs (não modelos de chat), suporta histórico de chat e é melhor usado com ferramentas não estruturadas que requerem uma única entrada de string. Escolha isso ao trabalhar com modelos proficientes em XML.
-
Structured Chat: Um agente versátil que brilha em aplicações baseadas em chat e suporta ferramentas com múltiplas entradas. Não precisa de parâmetros adicionais de modelo, sendo uma ótima opção para projetos que exigem interações complexas com ferramentas.
-
JSON Chat: Voltado para modelos excelentes em JSON, este agente é adequado para aplicações de chat. Simplifica o trabalho com modelos amigáveis ao JSON, agilizando o desenvolvimento de aplicativos baseados em chat.
-
ReAct: Simples, mas eficaz, este agente é adaptado para aplicativos LLM básicos. É um excelente ponto de partida para modelos simples que precisam de implementação direta.
-
Self Ask With Search: Ideal para modelos simples com uma única ferramenta de pesquisa, este agente é perfeito para projetos que exigem um conjunto de ferramentas conciso e focado.
Cada tipo de agente traz seu próprio conjunto de pontos fortes, tornando crucial combinar o agente com os requisitos específicos do seu projeto. Se você precisa de suporte para histórico de chat, ferramentas com várias entradas ou chamada de função paralela, existe um agente sob medida para atender a essas necessidades. Considere a complexidade de suas tarefas, as capacidades do modelo de linguagem escolhido e a natureza das interações que seu aplicativo irá lidar. Ao alinhar esses fatores com o tipo de agente correto, você pode desbloquear todo o potencial dos Agentes LangChain em seus projetos, abrindo caminho para soluções inovadoras e fluxos de trabalho simplificados.
Expandindo as complexidades dos Agentes LangChain, este guia tem o objetivo de proporcionar uma compreensão mais profunda e aplicativos práticos dos diferentes tipos de agentes. Ao explorar códigos de exemplo detalhados e cenários, você obterá insights para selecionar e implementar o agente mais adequado às necessidades do seu projeto. Vamos mergulhar no cerne dos Agentes LangChain, destacando suas características e capacidades únicas por meio de exemplos.
Agentes LangChain #1: Agente OpenAI Tools
O agente OpenAI Tools foi projetado para funcionar perfeitamente com os modelos OpenAI mais recentes, facilitando a execução de várias funções ou "tools" simultaneamente. Este agente é particularmente útil quando seu aplicativo requer a interação com várias APIs externas ou a execução de várias tarefas em paralelo, reduzindo assim o tempo de processamento total.
Código de Exemplo:
# Importar bibliotecas e ferramentas necessárias
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
# Inicializar a ferramenta Tavily Search
tools = [TavilySearchResults(max_results=1)]
# Recuperar o prompt e configurar o LLM
prompt = hub.pull("hwchase17/openai-tools-agent")
llm = ChatOpenAI(model="gpt-3.5-turbo-1106", temperature=0)
# Criar o agente OpenAI Tools
agent = create_openai_tools_agent(llm, tools, prompt)
# Executa o agente com uma entrada de exemplo
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({"input": "o que é LangChain?"})
print(response)
Neste exemplo, a função create_openai_tools_agent
constrói um agente que pode utilizar o modelo OpenAI para decidir de forma inteligente quando invocar uma ou mais ferramentas com base na entrada. A ferramenta Tavily Search é usada aqui para demonstrar as capacidades de busca na web.
Agentes do LangChain #2: Agente de Funções OpenAI
O agente Funções OpenAI é mais adequado para tarefas em que o modelo precisa decidir se e qual função chamar com base na entrada. Embora seja semelhante ao agente de ferramentas, ele foi especificamente projetado para cenários em que a chamada de função é central para a tarefa, com a OpenAI tendo deprecado essa abordagem em favor de ferramentas para modelos mais recentes.
Exemplo de Código:
# Configuração do agente de Funções OpenAI
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
# Inicializa as ferramentas e escolhe o LLM
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/openai-functions-agent")
llm = ChatOpenAI(model="gpt-3.5-turbo-1106")
# Constrói e executa o agente de Funções OpenAI
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({"input": "o que é LangChain?"})
print(response)
Este exemplo mostra como configurar e usar o agente de Funções OpenAI, utilizando a Tavily Search como uma ferramenta para demonstrar a capacidade do agente de invocar funções específicas com base em consultas do usuário.
Agentes do LangChain #3: Agente XML
O agente XML é otimizado para modelos que são proficientes em gerar e interpretar estruturas XML. Este tipo de agente é vantajoso quando se trabalha com dados estruturados ou quando a interação com o modelo se beneficia do formato estruturado do XML.
Exemplo de Código:
# Inicializa o agente XML
from langchain import hub
from langchain.agents import AgentExecutor, create_xml_agent
from langchain_community.chat_models import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/xml-agent-convo")
llm = ChatAnthropic(model="claude-2")
# Cria e executa o agente XML
agent = create_xml_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({"input": "o que é LangChain?"})
print(response)
Essa configuração demonstra o uso de um agente XML com o modelo Claude-2, um modelo Antropo conhecido por sua proficiência com XML. O formato XML fornece uma maneira estruturada de comunicar entre o agente e o modelo, facilitando o manuseio de dados complexos.
Agentes do LangChain #4: Agente JSON Chat
O agente JSON Chat aproveita a formatação JSON para suas saídas, tornando-o adequado para aplicativos que requerem dados de resposta estruturados. Este agente é ideal para modelos de chat que se destacam no processamento e geração de estruturas JSON.
Exemplo de Código:
# Configuração do agente JSON Chat
from langchain import hub
from langchain.agents import AgentExecutor, create_json_chat_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/react-chat-json")
llm = ChatOpenAI()
# Cria e executa o agente JSON Chat
agent = create_json_chat_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
response = agent_executor.invoke({"input": "o que é LangChain?"})
print(response)
Aqui, o agente JSON Chat é usado para processar uma entrada e gerar uma resposta estruturada em JSON, utilizando a ferramenta Tavily Search para capacidades de busca na web. Esse agente é especialmente útil em cenários em que a resposta estruturada é necessária para processamento adicional ou para uma interação mais estruturada com o usuário.
Agentes do LangChain #5: Agente Chat Estruturado
O agente de Chat Estruturado é excelente em cenários que envolvem ferramentas com várias entradas, possibilitando interações complexas que requerem mais do que uma simples entrada de texto. Este agente é projetado para facilitar fluxos de trabalho complexos em que vários parâmetros precisam ser considerados para cada invocação de ferramenta.
Exemplo de Código:
# Inicializa o agente de Chat Estruturado
from langchain import hub
from langchain.agents import AgentExecutor, create_structured_chat_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/structured-chat-agent")
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-1106")
# Constrói e executa o agente de Chat Estruturado
agent = create_structured_chat_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
response = agent_executor.invoke({"input": "o que é LangChain?"})
print(response)
Este exemplo ilustra o uso de um agente de Chat Estruturado para interagir com ferramentas de várias entradas de forma eficaz. Ao especificar um prompt detalhado e selecionar um modelo de linguagem apropriado, este agente pode navegar por consultas complexas e interações de ferramentas de forma transparente. Ao compreender as distinções e capacidades desses Agentes LangChain, os desenvolvedores podem adaptar melhor suas aplicações para aproveitar todo o potencial dos modelos de linguagem e das tarefas automatizadas. Seja qual for a necessidade da sua aplicação, seja chamadas de função simples, processamento de dados estruturados ou interações complexas com várias ferramentas, há um Agente LangChain que atende às suas necessidades. Com esses exemplos como base, você está bem preparado para embarcar em sua jornada de construção de aplicações mais inteligentes, eficientes e responsivas.
Conclusão
Em conclusão, os Agentes LangChain oferecem um conjunto de ferramentas versátil e poderoso para os desenvolvedores que desejam integrar as capacidades avançadas dos modelos de linguagem em suas aplicações. Ao compreender as nuances de cada tipo de agente - desde os Agentes OpenAI Tools e Functions até os Agentes de Chat XML, JSON e Chat Estruturado - você pode escolher a ferramenta certa para atender às necessidades específicas do seu projeto. Esses agentes são capazes de lidar com uma ampla gama de tarefas, desde chamadas de função simples até interações complexas envolvendo várias entradas e formatos de dados estruturados.