Наше путешествие по инновационному миру LangChain раскрыло его существенные возможности в преобразовании управления данными и функциональности приложений.
В ходе предыдущих обсуждений мы углубились в несколько тем, изучая сложные возможности LangChain. В этой статье мы будем опираться на концепции, изложенные в разделе «Расширение возможностей агентов Langchain с помощью MinIO», расширяя функциональность агента MinIO для инкапсуляции дополнительных возможностей и развертывания специального агента через LangServe.
Опираясь на эти идеи, мы теперь обращаем наше внимание на
Автоматическое создание конечных точек API: возможности автоматизации LangServe легко генерируют необходимые конечные точки API, оптимизируя усилия по разработке и значительно сокращая время развертывания.
Генерация и проверка схемы. Благодаря интеллектуальному выводу схемы LangServe гарантирует, что API предлагают четко определенные интерфейсы, что упрощает интеграцию и обеспечивает удобство работы с пользователем.
Настраиваемая конфигурация конечных точек: LangServe предлагает множество конечных точек для удовлетворения разнообразных потребностей приложений, от синхронных операций до обновлений в реальном времени, предоставляя разработчикам беспрецедентную гибкость.
Легкая интеграция. Возможно, самая привлекательная особенность LangServe — способность легко интегрироваться с существующим кодом LangChain, что означает, что разработчики могут использовать свою текущую кодовую базу и опыт без существенных изменений.
Мы углубимся в процесс интеграции MinIO с LangChain на следующих шагах.
langchain-cli
.agent.py
.server.py
, чтобы он работал как API LangServe.Развертывание приложений LangChain с помощью LangServe обеспечивает плавную интеграцию, устраняя разрыв между сложными функциями искусственного интеллекта и использованием RESTful API, давая разработчикам возможность эффективно использовать весь спектр возможностей LangChain, устанавливая новый стандарт для развертывания интеллектуальных приложений в современном быстро меняющемся цифровом мире. .
LangChain предлагает удобный и простой метод создания приложений с помощью langchain-cli
pip
. Этот пакет предоставляет интерфейс, который позволяет пользователям легко создавать новые приложения, используя существующие
Примечание. Все необходимые файлы расположены в репозитории «blog-assets» MinIO в каталоге с именем «minio-langserve-deployment ».
Чтобы создать новое приложение LangChain, мы можем начать со следующих команд, чтобы создать виртуальную среду и установить пакет langchain-cli
:
mkdir minio-langserve-testing cd minio-Langserve-testing python -m venv .myenv source .myenv/bin/activate pip install langchain-cli
Чтобы создать новое приложение с помощью langchain-cli
мы можем ввести langchain
в нашем терминале, следующая команда пишется для создания нового каталога приложения с именем my-app
.
langchain app new my-app
Приложение langchain, созданное с помощью приведенных выше команд, выполняет всю тяжелую работу, создавая согласованную среду для разработки. Структура нового приложения LangChain прямо из коробки выглядит так:
./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
На следующих шагах мы внесем изменения во вновь созданное приложение LangChain ( my-app
), написав новый файл с именем packages/agent.py и внеся изменения в app/server.py
.
Вот файлы, которые мы будем обсуждать в этой статье:
my-app/packages/agent.py
my-app/app/server.py
Чтобы проиллюстрировать развертывание агента LangChain, интегрированного с MinIO, с помощью LangServe, мы начнем с сохранения кода цепочки агентов в agent.py
.
Сначала давайте инициализируем minio_client
, который подключается к общедоступному серверу play.min.io:443. Этот файл в конечном итоге вызовет agent_executor
LangChain, что позволит нам передать его оболочке add_route
LangServe.
Примечание: Читая предыдущую публикацию»
Для начала откройте файл Agent.py с помощью текстового редактора:
sudo nano packages/agent.py
В начале файла импортируйте необходимые пакеты, такие как os
, io
, minio
и 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)
В этом фрагменте кода мы импортируем необходимые пакеты и инициализируем языковую модель ChatOpenAI с помощью ключа API OpenAI, хранящегося в переменной среды OPENAI_API_KEY
. Мы также инициализируем minio_client, предоставляя необходимые данные подключения к общедоступному серверу play.min.io.
Далее давайте определим корзину MinIO и создадим ее, если она не существует:
# 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}")
Здесь мы определяем bucket_name
как «test» и проверяем, существует ли оно уже с помощью метода minio_client.bucket_exists()
. Если сегмент не существует, мы создаем его с помощью minio_client.make_bucket()
. Если сегмент уже существует, мы печатаем сообщение, указывающее на это. Мы также включили обработку ошибок с помощью блока try-кроме, чтобы перехватывать и печатать любые S3Error
, которые могут возникнуть во время процесса.
Имея базовую настройку, мы можем приступить к определению функций инструмента MinIO и созданию исполнителя агента, который мы рассмотрим на следующих шагах.
Langchain и Langserve предоставляют схожий подход к инкапсуляции логики и функциональности, что позволяет легко интегрировать его в логику агента и цепочки. Это достигается за счет использования декоратора @tool
с подробной строкой документации внутри определенной функции, которая помечает функции как повторно используемые компоненты, которые могут использоваться и интерпретироваться агентом ИИ.
Давайте подробнее рассмотрим предоставленные примеры кода:
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}."
Функция upload_file_to_minio
украшена @tool
, указывающим, что это компонент многократного использования. Для загрузки файла в корзину MinIO требуются необходимые параметры, такие как имя корзины, имя объекта и необработанные байты файла. Функция использует minio_client
для выполнения операции загрузки файла и возвращает сообщение об успешном завершении.
@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)
Аналогично, функция download_file_from_minio
также отмечена @tool
. Он ожидает, что словарь file_info
будет содержать необходимую информацию для загрузки файла из корзины MinIO, например имя корзины, имя объекта и локальный путь, по которому следует сохранить файл. Функция использует minio_client
для извлечения объекта из указанного сегмента и сохранения его по назначенному локальному пути.
@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]
Функция list_objects_in_minio_bucket
, также украшенная @tool
, отвечает за список объектов, присутствующих в корзине MinIO. Он ожидает словарь file_info
с ключом bucket_name
. Функция использует minio_client
для получения списка объектов в указанном сегменте и возвращает список словарей, содержащий ключ объекта и размер для каждого объекта.
Инкапсулируя эти функции в виде инструментов, Langchain и Langserve позволяют агенту ИИ беспрепятственно включать их в свою логику и процесс принятия решений. Агент может разумно выбирать и запускать соответствующий инструмент в зависимости от поставленной задачи, расширяя его возможности и обеспечивая более сложное и динамичное взаимодействие с системой хранения MinIO.
LangChain предлагает множество методов построения с использованием пользовательской логики, одним из таких подходов является «RunnableLambda
представляет собой конструкцию, предоставляемую LangChain, которая позволяет рассматривать функции как исполняемые единицы в логике агента ИИ.
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)
Обертывая функции инструмента RunnableLambda, мы создаем исполняемые экземпляры ( upload_file_runnable
, download_file_runnable
и list_objects_runnable
), которые могут быть вызваны агентом во время его выполнения. Эти исполняемые файлы инкапсулируют соответствующие функции инструмента и предоставляют агенту единый интерфейс для взаимодействия с ними.
tools = [upload_file_to_minio, download_file_from_minio, list_objects_in_minio_bucket] llm_with_tools = llm.bind_tools(tools)
Список инструментов содержит исходные функции инструмента ( upload_file_to_minio
, download_file_from_minio
и list_objects_in_minio_bucket
), которые служат строительными блоками для возможностей агента. Строка llm.bind_tools(tools)
привязывает инструменты к языковой модели ( llm
), устанавливая связь между возможностями рассуждения модели и конкретными функциями, предоставляемыми инструментами. Полученный результат llm_with_tools
представляет собой языковую модель, дополненную знаниями и возможностями использования связанных инструментов.
Использование RunnableLambda
и привязка инструментов к языковой модели демонстрируют гибкость и расширяемость LangChain и LangServe при создании мощных и настраиваемых агентов ИИ. Объединив мощь языковой модели с конкретными функциями, инкапсулированными в инструменты, агент ИИ получает возможность выполнять сложные задачи, такие как загрузка файлов в MinIO, загрузка файлов из MinIO и составление списка объектов в корзине MinIO.
Затем мы переключаем внимание на шаблон подсказки, который помогает агенту ИИ понимать и реагировать на вводимые пользователем данные. Он определяется с помощью метода ChatPromptTemplate.from_messages()
, который принимает список сообщений, представленных в виде кортежей, содержащих роль и содержимое сообщения.
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"), ])
Подсказка состоит из трёх сообщений:
«Системное» сообщение, устанавливающее контекст для ИИ-агента как мощного помощника с возможностями управления файлами.
«Пользовательское» сообщение, представляющее вводимые пользователем данные, с использованием заполнителя {input}
.
MessagesPlaceholder
с именем «agent_scratchpad» для хранения промежуточных шагов и мыслительного процесса агента.
Функция format_to_openai_tool_messages
форматирует блокнот агента в формат, совместимый с инструментами OpenAI, а класс OpenAIToolsAgentOutputParser анализирует ответ модели в структурированный формат, интерпретируемый агентом.
Классы AIMessage
и HumanMessage
представляют сообщения, которыми обмениваются агент и пользователь, обеспечивая стандартизированный способ обработки связи в рамках логики агента.
Определив шаблон подсказки, мы предоставляем ИИ-агенту четкую структуру и контекст для понимания и реагирования на вводимые пользователем данные, используя заполнитель «agent_scratchpad», чтобы отслеживать его промежуточные шаги и мыслительный процесс при решении задачи.
Наконец, чтобы завершить наш agent.py
, мы определяем нашего агента и создаем AgentExecutor, который можно импортировать и вызывать из сценария server.py
с помощью функции add_route
из библиотеки LangServe.
Мы создаем экземпляры необходимых компонентов и связываем их вместе, чтобы создать единую переменную агента.
agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai_tool_messages(x["intermediate_steps"]), } | prompt_template | llm_with_tools | OpenAIToolsAgentOutputParser() )
Агент определяется с использованием комбинации словарей и цепочек операций. Клавиша ввода извлекает вводимые пользователем данные из входящих данных, а клавиша agent_scratchpad
форматирует промежуточные этапы мыслительного процесса агента с помощью функции format_to_openai_tool_messages
. Агент также включает в себя шаблон приглашения ( prompt_template
), языковую модель с инструментами ( llm_with_tools
) и синтаксический анализатор вывода ( OpenAIToolsAgentOutputParser()
).
Чтобы создать AgentExecutor
, мы предоставляем ему определенный агент, доступные инструменты и устанавливаем verbose=True
для подробного вывода.
from langchain.agents import tool, AgentExecutor agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
AgentExecutor
использует предоставленный агент и инструменты для понимания задачи и выбора подходящего инструмента на основе данных пользователя. Вместо отдельных подсказок для каждого инструмента агент использует единый шаблон подсказок, который помогает ему использовать инструменты на основе заданных входных данных. Агент динамически выбирает подходящий инструмент в процессе выполнения.
Настройка нашего приложения путем его интеграции с LangServe обеспечивает упрощенный путь к развертыванию и управлению нашими приложениями LangChain в виде API. FastAPI выбран из-за его производительности и простоты использования, поддержки асинхронных операций и автоматического создания документации API.
Более подробную информацию о демонстрациях вариантов использования можно найти, посетив
langchain-ai/langserve Репозиторий GitHub под никомкаталог примеров .
from fastapi import FastAPI app = FastAPI( title="MinIO Agent API", version="1.0", description="A conversational agent facilitating data storage and retrieval with MinIO", )
Для настройки заголовков CORS мы можем добавить следующие строки для повышения безопасности:
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=["*"], )
Теперь, когда мы закончили с packages/agent.py
мы можем импортировать его и использовать функцию add_route
из библиотеки LangServe в нашем скрипте 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” )
Вызывая add_route(app, agent_executor(…), path="/invoke")
, мы добавляем маршрут к нашему серверному приложению ( app
), который сопоставляет путь /invoke
с функцией agent_executor()
. Это позволяет вызывать исполнителя агента при запросе к конечной точке /invoke
.
При такой настройке сервер может обрабатывать входящие запросы, передавать их исполнителю агента и возвращать ответ агента обратно клиенту. Исполнитель агента использует определенный агент, который включает в себя шаблон подсказки, языковую модель с инструментами и анализатор выходных данных для обработки ввода пользователя и генерации соответствующего ответа на основе доступных инструментов.
Чтобы запустить приложение LangServe, мы используем Uvicorn в качестве сервера ASGI, создавая основу для запуска нашего приложения. Этот фрагмент кода имеет решающее значение, поскольку он активирует сервер, определяя универсальный хост и назначенный порт для точек доступа приложения.
if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
Встраивая этот блок в основную запись приложения, мы гарантируем, что Uvicorn возьмет на себя управление при непосредственном выполнении сценария, тем самым активируя наше приложение FastAPI на заранее определенном хосте и порту. Такой подход не только упрощает процесс развертывания, но и дает четкую возможность запуска приложения в среде разработки или производственной среде.
В приведенном выше коде продемонстрирован модульный подход, который включает использование библиотеки «langchain-cli», создание нового приложения langchain и сохранение логики цепочки в agent.py
, в то время как реализация FastAPI и LangServe сохраняется в server.py
.
Это наш последний шаг: мы сохраним код нашего приложения на server.py
для наглядной цели создания нашего приложения.
Самый простой способ запустить наш сервис:
python server.py
Эта команда запустит приложение, вернув при этом все журналы или сообщения об ошибках, которые еще необходимо отладить.
В выводе Python журналы LangServe идентифицируют /invoke/playground
как конечную точку приложения. Теперь мы можем посетить веб-интерфейс игровой площадки, а также автоматизированную документацию для нашего API, доступную по пути /docs
нашего API; предоставляя нам упрощенный подход к тестированию и настройке, включая кнопку «Попробовать» для каждой функции нашего приложения, а также предопределенные запросы cURL, которые мы можем выполнять из веб-интерфейса.
Следовательно, наш агент LangChain, интегрированный с MinIO, теперь успешно трансформируется в развертываемый API, готовый к разработке и расширению для пользователей с различными функциональными возможностями — от пакетной обработки до взаимодействия в реальном времени.
Когда приложение LangServe запущено и работает, мы можем использовать его за пределами нашего server.py
, нацелив нашу конечную точку и обернув ее в модуль RemoteRunnable
Langserve:
from langserve import RemoteRunnable remote_runnable = RemoteRunnable("http://localhost:8000/<path>/")
Добавлять
LangChain может похвастаться огромным набором модулей в своих библиотеках, демонстрируя разнообразный набор инструментов, предназначенный для того, чтобы дать разработчикам возможность создавать сложные приложения на основе искусственного интеллекта. Модульная архитектура LangChain, от сложных цепных конструкций до бесшовной интеграции с различными моделями искусственного интеллекта, обеспечивает широкий спектр функциональных возможностей, позволяя создавать настраиваемые и передовые решения в области искусственного интеллекта и машинного обучения.
LangServe не только демистифицирует, но и значительно упрощает процесс развертывания приложений LangChain. Преодолевая разрыв между разработкой и развертыванием, он гарантирует, что инновационные приложения, использующие MinIO и LangChain, смогут быстро перейти от концепции к реальности, готовые к интеграции в более широкую экосистему и улучшению пользовательского опыта.
Благодаря разработке, описанной в наших исследованиях, мы увидели плавную интеграцию MinIO с
В MinIO нас вдохновляет креативность и потенциал сообщества разработчиков в эту богатую технологиями эпоху. Нет лучшего времени для сотрудничества и обмена знаниями. Мы хотим связаться с вами! Присоединяйтесь к нам на нашем