paint-brush
Inicie APIs LangChain sem esforço com integração LangServe e MinIOpor@minio
5,586 leituras
5,586 leituras

Inicie APIs LangChain sem esforço com integração LangServe e MinIO

por MinIO15m2024/06/21
Read on Terminal Reader

Muito longo; Para ler

Neste artigo, desenvolveremos os conceitos abordados em "Capacitando Agentes Langchain com MinIO". Expandiremos a funcionalidade de um agente MinIO para encapsular habilidades adicionais e implantar o agente personalizado via LangServe. Iremos nos aprofundar no processo de integração do MinIO com LangChain nas etapas a seguir.
featured image - Inicie APIs LangChain sem esforço com integração LangServe e MinIO
MinIO HackerNoon profile picture
0-item
1-item
2-item


Nossa jornada pelo mundo inovador do LangChain revelou suas capacidades substanciais na transformação do gerenciamento de dados e da funcionalidade de aplicativos.


Por meio de discussões anteriores, nos aprofundamos em vários tópicos enquanto exploramos os intrincados recursos do LangChain. Neste artigo, desenvolveremos os conceitos abordados em "Capacitando Agentes Langchain com MinIO" à medida que expandimos a funcionalidade de um agente MinIO para encapsular habilidades adicionais e implantar o agente personalizado via LangServe.


  • Inovando recuperação de bucket S3 com LangChain : Um passo a passo sobre como aproveitar os carregadores S3 da LangChain e a API OpenAI para criar agentes de IA conversacionais personalizados, estabelecendo uma abordagem simplificada para gerenciamento de dados.


  • Capacitando Agentes LangChain com MinIO : Um mergulho profundo no aproveitamento do MinIO, mostrando como o LangChain, juntamente com o GPT da OpenAI, abre novas fronteiras no processamento de dados de IA e ML.


Com base nesses insights, agora voltamos nosso foco para LangServe , uma ferramenta essencial na transição de aplicativos LangChain do desenvolvimento para a implantação, simplificando o processo de lançamento de APIs prontas para produção.

LangServe: simplificando a implantação de aplicativos LangChain

LangServe permanece como a base para os desenvolvedores, eliminando as complexidades tradicionalmente associadas à implantação de API. Ele permite uma transição suave de aplicativos LangChain integrados ao MinIO para APIs acessíveis e fáceis de usar. Veja como LangServe redefine o cenário de implantação:


  • Criação automática de endpoints de API: os recursos de automação do LangServe geram facilmente os endpoints de API necessários, simplificando os esforços de desenvolvimento e reduzindo significativamente o tempo de implantação.


  • Geração e validação de esquema: Com sua inferência de esquema inteligente, LangServe garante que as APIs ofereçam interfaces bem definidas, facilitando a integração e uma experiência de usuário perfeita.


  • Configuração personalizável de endpoints: LangServe oferece uma variedade de endpoints para atender às diversas necessidades de aplicativos, desde operações síncronas até atualizações em tempo real, proporcionando aos desenvolvedores uma flexibilidade incomparável.


  • Integração sem esforço: Talvez seu recurso mais atraente, a capacidade do LangServe de se integrar perfeitamente ao código LangChain existente, significa que os desenvolvedores podem aproveitar sua base de código e experiência atuais sem alterações significativas.


Documentação gerada automaticamente do aplicativo LangServe/FastAPI /docs

Mergulhando profundamente em LangChain e Langserve

Iremos nos aprofundar no processo de integração do MinIO com LangChain nas etapas a seguir.


  1. Crie um aplicativo LangChain com langchain-cli .
  2. Desenvolva um agente LangChain personalizado em um arquivo agent.py .
  3. Implemente nosso agente em server.py para rodar como uma API LangServe.

Usando a interface de linha de comando do LangChain para criar aplicativos

A implantação de aplicativos LangChain com LangServe traz uma jornada de integração perfeita, preenchendo a lacuna entre funcionalidades complexas de IA e a exposição à API RESTful, capacitando os desenvolvedores a aproveitar todo o espectro de recursos LangChain de forma eficiente, estabelecendo um novo padrão para a implantação de aplicativos inteligentes no cenário digital acelerado de hoje. .


LangChain oferece um método simples e conveniente de criar aplicativos usando seu langchain-cli biblioteca que pode ser instalado com pip . Este pacote fornece uma interface que permite aos usuários criar facilmente novos aplicativos utilizando Modelos de aplicativos LangChain ou criando o seu próprio.


Nota: Todos os arquivos necessários estão localizados no repositório “blog-assets” do MinIO no diretório denominado “minio-langserve-deployment ”.


Para criar um novo aplicativo LangChain podemos começar com os seguintes comandos para criar um ambiente virtual e instalar o pacote langchain-cli :


 mkdir minio-langserve-testing cd minio-Langserve-testing python -m venv .myenv source .myenv/bin/activate pip install langchain-cli 


Captura de tela de langchain-cli


Para criar um novo aplicativo usando langchain-cli podemos digitar langchain em nosso terminal, o seguinte comando é escrito para criar um novo diretório de aplicativo chamado my-app .


 langchain app new my-app


O aplicativo langchain criado com os comandos acima faz todo o trabalho pesado, criando um ambiente consistente para desenvolvimento. A estrutura de um novo aplicativo LangChain pronto para uso é assim:


 ./my-app ├── Dockerfile ├── README.md ├── app │ ├── __init__.py │ └── server.py ⇐ (This is where we will import our agent into) ├── packages ⇐ (This directory is where we will write our agent) │ └── README.md └── pyproject.toml


Nas etapas a seguir, faremos alterações no aplicativo LangChain recém-criado ( my-app ), escrevendo um novo arquivo chamado packages/agent.py e fazendo alterações em app/server.py .


Estes são os arquivos que discutiremos neste artigo:


  • my-app/packages/agent.py
  • my-app/app/server.py

Desenvolvendo um agente LangChain MinIO para implantação com LangServe

Para ilustrar a implantação de um agente LangChain integrado ao MinIO com LangServe, começaremos salvando o código da cadeia do agente em agent.py .


Primeiro, vamos inicializar um minio_client que se conecta ao servidor público "play.min.io:443". Este arquivo eventualmente chamará agent_executor do LangChain, permitindo-nos passá-lo para o wrapper add_route do LangServe.


Nota: Lendo a publicação anterior " Ferramenta MinIO Langchain " fornecerá informações valiosas sobre o desenvolvimento conjunto com LangChain e MinIO. Seguiremos uma abordagem conceitual semelhante, mas com lógica de ferramenta MinIO adicional.


Para começar, abra o arquivo agent.py usando um editor de texto:


 sudo nano packages/agent.py


No início do arquivo importe os pacotes necessários, como os , io , minio e ChatOpenAI :


 import os import io from minio import Minio from minio.error import S3Error from langchain_openai import ChatOpenAI os.environ["OPENAI_API_KEY"] = "<<Your API Key Here>>" # Initialize llm llm = ChatOpenAI(api_key=os.environ["OPENAI_API_KEY"]) # Initialize MinIO client minio_client = Minio('play.min.io:443', access_key='minioadmin', secret_key='minioadmin', secure=True)


Neste trecho de código, importamos os pacotes necessários e inicializamos o modelo de linguagem ChatOpenAI com a chave de API OpenAI armazenada na variável de ambiente OPENAI_API_KEY . Também inicializamos o minio_client fornecendo os detalhes de conexão necessários ao servidor público "play.min.io".


A seguir, vamos definir o bucket MinIO e criá-lo se ele não existir:


 # This variable will check if bucket exists bucket_name = "test" try: # Check if bucket exists if not minio_client.bucket_exists(bucket_name): # Create the bucket because it does not exist minio_client.make_bucket(bucket_name) print(f"Bucket '{bucket_name}' created successfully.") else: print(f"Bucket '{bucket_name}' already exists.") except S3Error as err: print(f"Error encountered: {err}")


Aqui, definimos bucket_name como “test” e verificamos se ele já existe usando o método minio_client.bucket_exists() . Se o bucket não existir, nós o criamos usando minio_client.make_bucket() . Se o bucket já existir, imprimimos uma mensagem indicando isso. Também incluímos o tratamento de erros usando um bloco try-except para capturar e imprimir qualquer S3Error que possa ocorrer durante o processo.


Com a configuração básica definida, podemos agora definir as funções da ferramenta MinIO e criar o executor do agente, que abordaremos nas próximas etapas.

Usando o Function Decorator do LangChain para ferramentas de agente

Langchain e Langserve fornecem uma abordagem semelhante para encapsular lógica e funcionalidade, permitindo que sejam perfeitamente integrados à lógica do agente e da cadeia. Isso é conseguido através do uso do decorador @tool com uma documentação detalhada dentro da função definida, que marca as funções como componentes reutilizáveis que podem ser utilizados e interpretados pelo agente de IA.


Vamos dar uma olhada mais de perto nos exemplos de código fornecidos:


 from langchain.agents import tool @tool def upload_file_to_minio(bucket_name: str, object_name: str, data_bytes: bytes): """ Uploads a file to MinIO. Parameters: bucket_name (str): The name of the bucket. object_name (str): The name of the object to create in the bucket. data_bytes (bytes): The raw bytes of the file to upload. """ data_stream = io.BytesIO(data_bytes) minio_client.put_object(bucket_name, object_name, data_stream, length=len(data_bytes)) return f"File {object_name} uploaded successfully to bucket {bucket_name}."


A função upload_file_to_minio é decorada com @tool , indicando que é um componente reutilizável. Ele recebe os parâmetros necessários para fazer upload de um arquivo para um bucket MinIO, como o nome do bucket, o nome do objeto e os bytes brutos do arquivo. A função utiliza o minio_client para realizar a operação de upload do arquivo e retorna uma mensagem de sucesso após a conclusão.


 @tool def download_file_from_minio(file_info): """ Custom function to download a file from MinIO. Expects file_info dict with 'bucket_name', 'object_name', and 'save_path' keys. 'save_path' should be the local path where the file will be saved. """ bucket_name = file_info['bucket_name'] object_name = file_info['object_name'] save_path = file_info['save_path'] minio_client.get_object(bucket_name, object_name, save_path)


Da mesma forma, a função download_file_from_minio também está marcada com @tool . Ele espera um dicionário file_info contendo as informações necessárias para baixar um arquivo de um bucket MinIO, como o nome do bucket, o nome do objeto e o caminho local onde o arquivo deve ser salvo. A função usa minio_client para recuperar o objeto do bucket especificado e salvá-lo no caminho local designado.


 @tool def list_objects_in_minio_bucket(file_info): """ Custom function to list objects in a MinIO bucket. Expects file_info dict with 'bucket_name' key. Returns a list of dictionaries containing 'ObjectKey' and 'Size' keys. """ bucket_name = file_info['bucket_name'] response = minio_client.list_objects(bucket_name) return [{'ObjectKey': obj.object_name, 'Size': obj.size} for obj in response.items]


A função list_objects_in_minio_bucket , também decorada com @tool é responsável por listar os objetos presentes em um bucket MinIO. Ele espera um dicionário file_info com a chave bucket_name . A função usa minio_client para recuperar a lista de objetos no bucket especificado e retorna uma lista de dicionários contendo a chave e o tamanho do objeto para cada objeto.


Ao encapsular essas funcionalidades como ferramentas, Langchain e Langserve permitem que o agente de IA as incorpore perfeitamente em sua lógica e processo de tomada de decisão. O agente pode selecionar e executar de forma inteligente a ferramenta apropriada com base na tarefa em questão, aprimorando suas capacidades e permitindo interações mais complexas e dinâmicas com o sistema de armazenamento MinIO.

Compreendendo o método executável do LangChain

LangChain oferece uma infinidade de métodos para construção com lógica customizada, uma dessas abordagens é a de “ executáveis ”. Quanto à lógica demonstrativa acima, RunnableLambda que é uma construção fornecida por LangChain que permite que funções sejam tratadas como unidades executáveis dentro da lógica do agente de IA.


 from langchain_core.runnables import RunnableLambda upload_file_runnable = RunnableLambda(upload_file_to_minio) download_file_runnable = RunnableLambda(download_file_from_minio) list_objects_runnable = RunnableLambda(list_objects_in_minio_bucket)


Ao envolver as funções da ferramenta com RunnableLambda, criamos instâncias executáveis ( upload_file_runnable , download_file_runnable e list_objects_runnable ) que podem ser invocadas pelo agente durante sua execução. Esses executáveis encapsulam as funções da ferramenta correspondentes e fornecem uma interface uniforme para o agente interagir com eles.


 tools = [upload_file_to_minio, download_file_from_minio, list_objects_in_minio_bucket] llm_with_tools = llm.bind_tools(tools)


A lista de ferramentas contém as funções originais da ferramenta ( upload_file_to_minio , download_file_from_minio e list_objects_in_minio_bucket ), que servem como blocos de construção para os recursos do agente. A linha llm.bind_tools(tools) vincula as ferramentas ao modelo de linguagem ( llm ), estabelecendo uma conexão entre as capacidades de raciocínio do modelo e as funcionalidades específicas fornecidas pelas ferramentas. O llm_with_tools resultante representa o modelo de linguagem aprimorado com o conhecimento e a capacidade de empregar as ferramentas vinculadas.


O uso de RunnableLambda e a ligação de ferramentas ao modelo de linguagem demonstram a flexibilidade e extensibilidade de LangChain e LangServe na criação de agentes de IA poderosos e personalizáveis. Ao combinar o poder do modelo de linguagem com as funcionalidades específicas encapsuladas nas ferramentas, o agente de IA ganha a capacidade de realizar tarefas complexas, como fazer upload de arquivos para o MinIO, baixar arquivos do MinIO e listar objetos em um bucket do MinIO.

Escrevendo um modelo de prompt para orientar nosso agente

Em seguida, mudamos nosso foco para o modelo de prompt que orienta o agente de IA na compreensão e resposta às entradas do usuário. Ele é definido usando o método ChatPromptTemplate.from_messages() , que recebe uma lista de mensagens representadas como tuplas contendo a função e o conteúdo da mensagem.


 from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.agents.format_scratchpad.openai_tools import format_to_openai_tool_messages from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser from langchain_core.messages import AIMessage, HumanMessage prompt_template = ChatPromptTemplate.from_messages([ ("system", "You are a powerful assistant equipped with file management capabilities."), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ])



O prompt consiste em três mensagens:


  1. Uma mensagem de “sistema” que define o contexto para o agente de IA como um assistente poderoso com recursos de gerenciamento de arquivos.


  2. Uma mensagem de "usuário" representando a entrada do usuário, usando o espaço reservado {input} .


  3. Um MessagesPlaceholder chamado "agent_scratchpad" para armazenar as etapas intermediárias e o processo de pensamento do agente.


A função format_to_openai_tool_messages formata o scratchpad do agente em um formato compatível com as ferramentas da OpenAI, enquanto a classe OpenAIToolsAgentOutputParser analisa a resposta do modelo em um formato estruturado interpretável pelo agente.


As classes AIMessage e HumanMessage representam as mensagens trocadas entre o agente e o usuário, fornecendo uma forma padronizada de lidar com a comunicação dentro da lógica do agente.


Ao definir o modelo de prompt, fornecemos ao agente de IA uma estrutura e contexto claros para compreender e responder às entradas do usuário, utilizando o espaço reservado "agent_scratchpad" para acompanhar suas etapas intermediárias e processo de pensamento enquanto resolve a tarefa.

Definindo o Agente com suas Ferramentas

Finalmente, para completar nosso agent.py definimos nosso agente e criamos um AgentExecutor que pode ser importado e chamado de um script server.py usando a função add_route da biblioteca LangServe.


Instanciamos os componentes necessários e os encadeamos para criar uma única variável de agente.


 agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai_tool_messages(x["intermediate_steps"]), } | prompt_template | llm_with_tools | OpenAIToolsAgentOutputParser() )


O agente é definido usando uma combinação de dicionários e operações encadeadas. A chave de entrada extrai a entrada do usuário dos dados recebidos, enquanto a chave agent_scratchpad formata as etapas intermediárias do processo de pensamento do agente usando a função format_to_openai_tool_messages . O agente também incorpora o modelo de prompt ( prompt_template ), o modelo de linguagem com ferramentas ( llm_with_tools ) e o analisador de saída ( OpenAIToolsAgentOutputParser() ).

Definindo um AgentExecutor para executar o agente

Para criar um AgentExecutor , fornecemos a ele o agente definido, as ferramentas disponíveis e definimos verbose=True para saída detalhada.


 from langchain.agents import tool, AgentExecutor agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)


O AgentExecutor usa o agente e as ferramentas fornecidas para compreender a tarefa e selecionar a ferramenta apropriada com base na entrada do usuário. Em vez de ter prompts separados para cada ferramenta, o agente utiliza um único modelo de prompt que o orienta sobre como usar as ferramentas com base na entrada fornecida. O agente seleciona dinamicamente a ferramenta apropriada durante o processo de execução.

Definindo a rota LangServe com nosso AgentExecutor

Configurar nosso aplicativo integrando-o ao LangServe fornece um caminho simplificado para implantar e gerenciar nossos aplicativos LangChain como APIs. FastAPI é escolhido por seu desempenho e facilidade de uso, suportando operações assíncronas e gerando automaticamente documentação de API.


O Biblioteca LangServe , desenvolvido com FastAPI, enriquece isso simplificando a implantação de objetos LangChain como APIs REST, oferecendo middleware integrado para configurações CORS para garantir que nossa API possa ser chamada com segurança de diferentes domínios.


Para demonstrações mais aprofundadas/de casos de uso, você pode explorar visitando o langchain-ai/langserve Repositório GitHub sob o diretório de exemplos .


 from fastapi import FastAPI app = FastAPI( title="MinIO Agent API", version="1.0", description="A conversational agent facilitating data storage and retrieval with MinIO", )


Para definir cabeçalhos CORS, podemos adicionar as seguintes linhas para aumentar nossa segurança:


 from fastapi.middleware.cors import CORSMiddleware # Set all CORS enabled origins app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], expose_headers=["*"], )

Implementando o Agente usando LangServe

Agora que terminamos com packages/agent.py podemos importá-lo e usar a função add_route da biblioteca LangServe em nosso script app/server.py .


 from packages.agent import agent_executor from langserve import add_routes add_routes( app, agent_executor.with_types(input_type=Input, output_type=Output).with_config( {"run_name": "agent"} ), path=”/invoke” )


Chamando add_route(app, agent_executor(…), path="/invoke") , adicionamos uma rota ao nosso aplicativo de servidor ( app ) que mapeia o caminho /invoke para a função agent_executor() . Isso permite que o executor do agente seja chamado quando uma solicitação é feita ao endpoint /invoke .


Com esta configuração, o servidor pode lidar com solicitações recebidas, passá-las ao executor do agente e retornar a resposta do agente ao cliente. O executor do agente utiliza o agente definido, que incorpora o modelo de prompt, o modelo de linguagem com ferramentas e o analisador de saída, para processar a entrada do usuário e gerar uma resposta apropriada com base nas ferramentas disponíveis.

Iniciando o aplicativo LangServe via Uvicorn

Para iniciar o aplicativo LangServe, empregamos Uvicorn como servidor ASGI, preparando o terreno para a execução de nosso aplicativo. Este trecho de código é fundamental porque ativa o servidor, especificando o host universal e a porta designada para os pontos de acesso do aplicativo.


 if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)


Ao incorporar este bloco na entrada principal do aplicativo, garantimos que o Uvicorn assuma o comando quando o script for executado diretamente, ativando assim nosso aplicativo FastAPI em um host e porta predefinidos. Essa abordagem não apenas simplifica o processo de implantação, mas também marca uma entrada clara para a execução do aplicativo em um ambiente de desenvolvimento ou produção.

Iniciando o aplicativo de servidor

O código acima foi demonstrado em uma abordagem modular que inclui o uso da biblioteca “langchain-cli”, a criação de um novo aplicativo langchain e o salvamento da lógica da cadeia em agent.py enquanto a implementação FastAPI e LangServe é salva em server.py .


Sendo esta a nossa etapa final, salvaremos o código do nosso aplicativo em server.py para o propósito demonstrativo de construção de nosso aplicativo.


A maneira mais simples de executar nosso serviço é com:


 python server.py


Este comando executará o aplicativo, retornando quaisquer logs ou mensagens de erro que ainda precisam ser depurados.


Captura de tela da saída do terminal executando LangServe


Parque LangServe

Na saída do python, os logs do LangServe identificam /invoke/playground como o endpoint do aplicativo. Agora podemos visitar o playground WebUI, bem como a documentação automatizada de nossa API que está disponível visitando o caminho /docs de nossa API; dando-nos uma abordagem simplificada para testar e configurar, incluindo o botão Experimente para cada um dos recursos de nossos aplicativos, bem como solicitações cURL predefinidas que podemos executar a partir da WebUI.


Captura de tela do LangServe Playground implantado


Consequentemente, nosso agente LangChain integrado ao MinIO agora está habilmente transformado em uma API implantável, pronta para ser desenvolvida e estendida para usuários com funcionalidades que vão desde processamento em lote até interações em tempo real.

Uso adicional da API LangServe

Com o aplicativo LangServe instalado e funcionando, podemos usá-lo fora de nosso server.py , direcionando nosso endpoint e agrupando-o no módulo RemoteRunnable do Langserve:


 from langserve import RemoteRunnable remote_runnable = RemoteRunnable("http://localhost:8000/<path>/")


Adicionar


LangChain possui uma vasta gama de módulos em suas bibliotecas, apresentando um kit de ferramentas diversificado projetado para capacitar os desenvolvedores na construção de aplicativos sofisticados baseados em IA. Desde construções de cadeias complexas até a integração perfeita com vários modelos de IA, a arquitetura modular do LangChain facilita uma ampla gama de funcionalidades, permitindo a criação de soluções altamente personalizáveis e avançadas no domínio da IA e do aprendizado de máquina.

Desenvolvendo pipelines de IA com LangServe

LangServe não apenas desmistifica, mas simplifica significativamente o processo de implantação de aplicativos LangChain. Ao preencher a lacuna entre o desenvolvimento e a implantação, garante que aplicações inovadoras que aproveitam o MinIO e o LangChain possam passar rapidamente do conceito à realidade, prontas para serem integradas ao ecossistema mais amplo e aprimorarem as experiências do usuário.


Através do desenvolvimento abordado em nossas explorações, vimos a integração perfeita do MinIO com LangChain é absolutamente possível, e como LangServe desempenha um papel fundamental na implantação dessas soluções avançadas. À medida que continuamos a navegar no cenário em evolução da IA e do ML, ferramentas como o LangServe continuarão a ser fundamentais para trazer tecnologias de ponta para a vanguarda do desenvolvimento de aplicações.


Na MinIO, somos energizados pela criatividade e pelo potencial da comunidade de desenvolvedores durante esta era rica em tecnologia. Não há melhor momento para colaboração e troca de conhecimento. Estamos ansiosos para nos conectar com você! Junte-se a nós em nosso Folga MinIO canal para continuar a conversa e alcançar novos patamares juntos.