Hành trình của chúng tôi xuyên qua thế giới đổi mới của LangChain đã tiết lộ những khả năng đáng kể của nó trong việc chuyển đổi chức năng ứng dụng và quản lý dữ liệu.
Thông qua các cuộc thảo luận trước đó, chúng tôi đã đào sâu vào một số chủ đề đồng thời khám phá các khả năng phức tạp của LangChain. Trong bài viết này, chúng tôi sẽ xây dựng dựa trên các khái niệm được đề cập trong "Trao quyền cho tác nhân Langchain với MinIO" khi chúng tôi mở rộng chức năng của tác nhân MinIO để gói gọn các khả năng bổ sung và triển khai tác nhân tùy chỉnh thông qua LangServe.
Dựa trên những hiểu biết sâu sắc này, giờ đây chúng tôi chuyển trọng tâm sang
Tạo điểm cuối API tự động: Khả năng tự động hóa của LangServe dễ dàng tạo ra các điểm cuối API cần thiết, hợp lý hóa các nỗ lực phát triển và giảm đáng kể thời gian triển khai.
Tạo và xác thực lược đồ: Với suy luận lược đồ thông minh, LangServe đảm bảo rằng các API cung cấp các giao diện được xác định rõ ràng, tạo điều kiện tích hợp dễ dàng hơn và trải nghiệm người dùng liền mạch.
Cấu hình điểm cuối có thể tùy chỉnh: LangServe cung cấp nhiều điểm cuối phù hợp với nhu cầu ứng dụng đa dạng, từ hoạt động đồng bộ đến cập nhật theo thời gian thực, mang đến cho các nhà phát triển sự linh hoạt tuyệt vời.
Tích hợp dễ dàng: Có lẽ tính năng hấp dẫn nhất của LangServe là khả năng tích hợp liền mạch với mã LangChain hiện có, nghĩa là các nhà phát triển có thể tận dụng cơ sở mã và kiến thức chuyên môn hiện tại của họ mà không cần thay đổi đáng kể.
Chúng tôi sẽ đi sâu hơn vào quá trình tích hợp MinIO với LangChain theo các bước sau.
langchain-cli
.agent.py
.server.py
để chạy dưới dạng API LangServe.Triển khai các ứng dụng LangChain với LangServe mang đến một hành trình tích hợp liền mạch, thu hẹp khoảng cách giữa các chức năng AI phức tạp và khả năng hiển thị API RESTful, trao quyền cho các nhà phát triển tận dụng toàn bộ khả năng của LangChain một cách hiệu quả, thiết lập tiêu chuẩn mới để triển khai các ứng dụng thông minh trong bối cảnh kỹ thuật số phát triển nhanh ngày nay .
LangChain cung cấp một phương pháp tạo ứng dụng thuận tiện và đơn giản bằng cách sử dụng langchain-cli
của họpip
. Gói này cung cấp giao diện cho phép người dùng dễ dàng tạo các ứng dụng mới bằng cách sử dụng
Lưu ý: Tất cả các tệp cần thiết đều nằm trong kho lưu trữ “tài sản blog” MinIO trong thư mục có tên “minio-langserve-deployment ”.
Để tạo một ứng dụng LangChain mới, chúng ta có thể bắt đầu bằng các lệnh sau để tạo môi trường ảo và cài đặt gói langchain-cli
:
mkdir minio-langserve-testing cd minio-Langserve-testing python -m venv .myenv source .myenv/bin/activate pip install langchain-cli
Để tạo một ứng dụng mới bằng langchain-cli
chúng ta có thể nhập langchain
vào terminal của mình, lệnh sau được viết để tạo một thư mục ứng dụng mới có tên my-app
.
langchain app new my-app
Ứng dụng langchain được tạo bằng các lệnh trên, thực hiện tất cả các công việc nặng nhọc bằng cách tạo ra một môi trường nhất quán để phát triển. Cấu trúc của một ứng dụng LangChain mới ngay lập tức trông như thế này:
./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
Trong các bước sau, chúng tôi sẽ thực hiện các thay đổi đối với ứng dụng LangChain mới tạo ( my-app
) bằng cách viết một tệp mới có tên packages/agent.py và thực hiện các thay đổi đối với app/server.py
.
Đây là những tập tin chúng ta sẽ thảo luận trong bài viết này:
my-app/packages/agent.py
my-app/app/server.py
Để minh họa việc triển khai tác nhân LangChain tích hợp MinIO với LangServe, chúng ta sẽ bắt đầu bằng cách lưu mã chuỗi tác nhân trong agent.py
.
Trước tiên, hãy khởi tạo minio_client
kết nối với máy chủ công cộng "play.min.io:443". Cuối cùng, tệp này sẽ gọi tới agent_executor
của LangChain, cho phép chúng tôi chuyển nó tới trình bao bọc add_route
của LangServe.
Lưu ý: Đọc ấn phẩm trước "
Để bắt đầu, hãy mở tệp Agent.py bằng trình soạn thảo văn bản:
sudo nano packages/agent.py
Ở đầu tệp, nhập các gói cần thiết, chẳng hạn như os
, io
, minio
và 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)
Trong đoạn mã này, chúng tôi nhập các gói cần thiết và khởi tạo mô hình ngôn ngữ ChatOpenAI bằng khóa API OpenAI được lưu trữ trong biến môi trường OPENAI_API_KEY
. Chúng tôi cũng khởi tạo minio_client bằng cách cung cấp chi tiết kết nối cần thiết cho máy chủ công cộng "play.min.io".
Tiếp theo, hãy xác định nhóm MinIO và tạo nó nếu nó không tồn tại:
# 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}")
Ở đây, chúng tôi xác định bucket_name
là "kiểm tra" và kiểm tra xem nó đã tồn tại hay chưa bằng phương thức minio_client.bucket_exists()
. Nếu nhóm không tồn tại, chúng tôi sẽ tạo nó bằng cách sử dụng minio_client.make_bucket()
. Nếu nhóm đã tồn tại, chúng tôi sẽ in một thông báo cho biết như vậy. Chúng tôi cũng bao gồm việc xử lý lỗi bằng cách sử dụng khối thử ngoại trừ để bắt và in bất kỳ S3Error
nào có thể xảy ra trong quá trình.
Với thiết lập cơ bản đã sẵn sàng, giờ đây chúng ta có thể tiến hành xác định các chức năng của công cụ MinIO và tạo trình thực thi tác nhân mà chúng ta sẽ đề cập đến trong các bước tiếp theo.
Langchain và Langserve đều cung cấp một cách tiếp cận tương tự để đóng gói logic và chức năng, cho phép nó được tích hợp liền mạch vào logic tác nhân và chuỗi. Điều này đạt được thông qua việc sử dụng trình trang trí @tool
với một chuỗi tài liệu chi tiết bên trong hàm được xác định, chuỗi này đánh dấu các hàm là các thành phần có thể tái sử dụng mà tác nhân AI có thể sử dụng và diễn giải.
Chúng ta hãy xem xét kỹ hơn các ví dụ mã được cung cấp:
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}."
Hàm upload_file_to_minio
được trang trí bằng @tool
, cho biết rằng đây là thành phần có thể tái sử dụng. Nó lấy các tham số cần thiết để tải tệp lên vùng lưu trữ MinIO, chẳng hạn như tên vùng lưu trữ, tên đối tượng và byte thô của tệp. Hàm sử dụng minio_client
để thực hiện thao tác tải tệp lên và trả về thông báo thành công sau khi hoàn thành.
@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)
Tương tự, hàm download_file_from_minio
cũng được đánh dấu bằng @tool
. Nó yêu cầu một từ điển file_info
chứa thông tin cần thiết để tải xuống tệp từ nhóm MinIO, chẳng hạn như tên nhóm, tên đối tượng và đường dẫn cục bộ nơi tệp sẽ được lưu. Hàm sử dụng minio_client
để truy xuất đối tượng từ nhóm được chỉ định và lưu nó vào đường dẫn cục bộ được chỉ định.
@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]
Hàm list_objects_in_minio_bucket
, cũng được trang trí bằng @tool
, chịu trách nhiệm liệt kê các đối tượng có trong nhóm MinIO. Nó mong đợi một từ điển file_info
có khóa bucket_name
. Hàm sử dụng minio_client
để truy xuất danh sách các đối tượng trong nhóm được chỉ định và trả về danh sách từ điển chứa khóa và kích thước đối tượng cho từng đối tượng.
Bằng cách gói gọn các chức năng này dưới dạng công cụ, Langchain và Langserve cho phép tác nhân AI kết hợp liền mạch chúng vào logic và quy trình ra quyết định của nó. Tác nhân có thể lựa chọn và thực thi công cụ thích hợp một cách thông minh dựa trên nhiệm vụ hiện tại, nâng cao khả năng của nó và cho phép thực hiện các tương tác phức tạp và năng động hơn với hệ thống lưu trữ MinIO.
LangChain cung cấp vô số phương pháp để xây dựng bằng logic tùy chỉnh, một trong những cách tiếp cận đó là “RunnableLambda
là một cấu trúc do LangChain cung cấp, cho phép các hàm được coi là đơn vị thực thi trong logic của tác nhân AI.
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)
Bằng cách gói các chức năng công cụ bằng RunnableLambda, chúng tôi tạo ra các phiên bản có thể chạy được ( upload_file_runnable
, download_file_runnable
và list_objects_runnable
) mà tác nhân có thể gọi ra trong quá trình thực thi. Các runnable này đóng gói các chức năng công cụ tương ứng và cung cấp giao diện thống nhất để tác nhân tương tác với chúng.
tools = [upload_file_to_minio, download_file_from_minio, list_objects_in_minio_bucket] llm_with_tools = llm.bind_tools(tools)
Danh sách công cụ chứa các hàm công cụ gốc ( upload_file_to_minio
, download_file_from_minio
và list_objects_in_minio_bucket
), đóng vai trò là khối xây dựng cho khả năng của tác nhân. Dòng llm.bind_tools(tools)
liên kết các công cụ với mô hình ngôn ngữ ( llm
), thiết lập kết nối giữa khả năng suy luận của mô hình và các chức năng cụ thể do các công cụ cung cấp. Kết quả llm_with_tools
thể hiện mô hình ngôn ngữ được nâng cao với kiến thức và khả năng sử dụng các công cụ bị ràng buộc.
Việc sử dụng RunnableLambda
và liên kết các công cụ với mô hình ngôn ngữ thể hiện tính linh hoạt và khả năng mở rộng của LangChain và LangServe trong việc tạo ra các tác nhân AI mạnh mẽ và có thể tùy chỉnh. Bằng cách kết hợp sức mạnh của mô hình ngôn ngữ với các chức năng cụ thể được gói gọn trong các công cụ, tác nhân AI có được khả năng thực hiện các tác vụ phức tạp, chẳng hạn như tải tệp lên MinIO, tải tệp xuống từ MinIO và liệt kê các đối tượng trong nhóm MinIO.
Tiếp theo, chúng tôi chuyển trọng tâm sang mẫu lời nhắc hướng dẫn tác nhân AI hiểu và phản hồi thông tin đầu vào của người dùng. Nó được xác định bằng phương thức ChatPromptTemplate.from_messages()
, phương thức này nhận danh sách các thông báo được biểu diễn dưới dạng bộ dữ liệu chứa vai trò và nội dung thông báo.
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"), ])
Lời nhắc bao gồm ba thông báo:
Thông báo "hệ thống" đặt bối cảnh cho tác nhân AI như một trợ lý đắc lực với khả năng quản lý tệp.
Thông báo "người dùng" thể hiện thông tin đầu vào của người dùng, sử dụng phần giữ chỗ {input}
.
MessagesPlaceholder
có tên là "agent_scratchpad" để lưu trữ các bước trung gian và quy trình suy nghĩ của tác nhân.
Hàm format_to_openai_tool_messages
định dạng bảng ghi nhớ của tác nhân thành định dạng tương thích cho các công cụ của OpenAI, trong khi lớp OpenAIToolsAgentOutputParser phân tích phản hồi của mô hình thành định dạng có cấu trúc mà tác nhân có thể hiểu được.
Các lớp AIMessage
và HumanMessage
đại diện cho các tin nhắn được trao đổi giữa tác nhân và người dùng, cung cấp một cách tiêu chuẩn hóa để xử lý giao tiếp trong logic của tác nhân.
Bằng cách xác định mẫu lời nhắc, chúng tôi cung cấp cho tác nhân AI cấu trúc và ngữ cảnh rõ ràng để hiểu và phản hồi thông tin đầu vào của người dùng, sử dụng phần giữ chỗ "agent_scratchpad" để theo dõi các bước trung gian và quy trình suy nghĩ trong khi giải quyết nhiệm vụ.
Cuối cùng, để hoàn thành agent.py
chúng ta xác định tác nhân của mình và tạo một AgentExecutor có thể được nhập và gọi từ tập lệnh server.py
bằng cách sử dụng hàm add_route
từ thư viện LangServe.
Chúng tôi khởi tạo các thành phần cần thiết và xâu chuỗi chúng lại với nhau để tạo ra một biến tác nhân duy nhất.
agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai_tool_messages(x["intermediate_steps"]), } | prompt_template | llm_with_tools | OpenAIToolsAgentOutputParser() )
Tác nhân được xác định bằng cách sử dụng kết hợp các từ điển và các hoạt động theo chuỗi. Khóa đầu vào trích xuất thông tin đầu vào của người dùng từ dữ liệu đến, trong khi khóa agent_scratchpad
định dạng các bước trung gian trong quá trình suy nghĩ của tác nhân bằng cách sử dụng hàm format_to_openai_tool_messages
. Tác nhân cũng kết hợp mẫu lời nhắc ( prompt_template
), mô hình ngôn ngữ với các công cụ ( llm_with_tools
) và trình phân tích cú pháp đầu ra ( OpenAIToolsAgentOutputParser()
).
Để tạo một AgentExecutor
, chúng tôi cung cấp cho nó tác nhân được xác định, các công cụ có sẵn và đặt verbose=True
cho đầu ra chi tiết.
from langchain.agents import tool, AgentExecutor agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
AgentExecutor
sử dụng tác nhân và công cụ được cung cấp để hiểu nhiệm vụ và chọn công cụ thích hợp dựa trên thông tin đầu vào của người dùng. Thay vì có các lời nhắc riêng cho từng công cụ, nhân viên sử dụng một mẫu lời nhắc duy nhất để hướng dẫn cách sử dụng các công cụ dựa trên thông tin đầu vào đã cho. Tác nhân tự động chọn công cụ thích hợp trong quá trình thực thi.
Việc thiết lập ứng dụng của chúng tôi bằng cách tích hợp nó với LangServe sẽ cung cấp một lộ trình hợp lý để triển khai và quản lý các ứng dụng LangChain của chúng tôi dưới dạng API. FastAPI được chọn vì hiệu suất và tính dễ sử dụng, hỗ trợ các hoạt động không đồng bộ và tự động tạo tài liệu API.
Các
Để biết thêm các minh họa sâu hơn/trường hợp sử dụng, có thể khám phá bằng cách truy cập
langchain-ai/langserve Kho lưu trữ GitHub dướithư mục ví dụ .
from fastapi import FastAPI app = FastAPI( title="MinIO Agent API", version="1.0", description="A conversational agent facilitating data storage and retrieval with MinIO", )
Để đặt tiêu đề CORS, chúng tôi có thể thêm các dòng sau để tăng cường bảo mật:
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=["*"], )
Bây giờ chúng ta đã hoàn thành với packages/agent.py
chúng ta có thể nhập nó và sử dụng hàm add_route
từ thư viện LangServe trong tập lệnh app/server.py
của chúng ta.
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” )
Bằng cách gọi add_route(app, agent_executor(…), path="/invoke")
, chúng ta thêm một tuyến đến ứng dụng máy chủ của mình ( app
) để ánh xạ đường dẫn /invoke
tới hàm agent_executor()
. Điều này cho phép người thực thi tác nhân được gọi khi có yêu cầu được gửi tới điểm cuối /invoke
.
Với thiết lập này, máy chủ có thể xử lý các yêu cầu đến, chuyển chúng cho người thực thi tác nhân và trả lại phản hồi của tác nhân cho máy khách. Trình thực thi tác nhân sử dụng tác nhân đã xác định, kết hợp với mẫu lời nhắc, mô hình ngôn ngữ với các công cụ và trình phân tích cú pháp đầu ra, để xử lý thông tin đầu vào của người dùng và tạo ra phản hồi thích hợp dựa trên các công cụ có sẵn.
Để khởi động ứng dụng LangServe, chúng tôi sử dụng Uvicorn làm máy chủ ASGI, tạo tiền đề cho ứng dụng của chúng tôi chạy. Đoạn mã này rất quan trọng vì nó kích hoạt máy chủ, chỉ định máy chủ chung và cổng được chỉ định cho các điểm truy cập của ứng dụng.
if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
Bằng cách nhúng khối này vào mục nhập chính của ứng dụng, chúng tôi đảm bảo rằng Uvicorn sẽ nắm quyền kiểm soát khi tập lệnh được thực thi trực tiếp, từ đó kích hoạt ứng dụng FastAPI của chúng tôi trên máy chủ và cổng được xác định trước. Cách tiếp cận này không chỉ đơn giản hóa quá trình triển khai mà còn đánh dấu bước khởi đầu rõ ràng để chạy ứng dụng trong môi trường phát triển hoặc sản xuất.
Đoạn mã trên đã được chứng minh là một cách tiếp cận mô-đun bao gồm việc sử dụng thư viện “langchain-cli”, tạo một ứng dụng langchain mới và lưu logic chuỗi vào agent.py
trong khi việc triển khai FastAPI và LangServe được lưu vào server.py
.
Đây là bước cuối cùng của chúng tôi, chúng tôi sẽ lưu mã ứng dụng của mình vào server.py
cho mục đích minh họa là xây dựng ứng dụng của chúng tôi.
Cách đơn giản nhất để chạy dịch vụ của chúng tôi là:
python server.py
Lệnh này sẽ chạy ứng dụng, đồng thời trả về mọi nhật ký hoặc thông báo lỗi cần được gỡ lỗi.
Trong đầu ra python, nhật ký LangServe xác định /invoke/playground
là điểm cuối của ứng dụng. Giờ đây, chúng tôi có thể truy cập WebUI của sân chơi cũng như tài liệu tự động có sẵn cho API của chúng tôi bằng cách truy cập đường dẫn /docs
trong API của chúng tôi; cung cấp cho chúng tôi cách tiếp cận đơn giản hóa để kiểm tra và định cấu hình bằng cách bao gồm nút Dùng thử cho từng tính năng ứng dụng của chúng tôi, cũng như các yêu cầu cURL được xác định trước mà chúng tôi có thể thực thi từ WebUI.
Do đó, tác nhân LangChain tích hợp MinIO của chúng tôi hiện đã được chuyển đổi một cách thành thạo thành một API có thể triển khai, sẵn sàng phát triển và mở rộng cho người dùng với các chức năng từ xử lý hàng loạt đến tương tác thời gian thực.
Với ứng dụng LangServe đang chạy, chúng ta có thể sử dụng nó từ bên ngoài server.py
bằng cách nhắm mục tiêu điểm cuối của chúng ta và gói nó trong mô-đun RemoteRunnable
của Langserve:
from langserve import RemoteRunnable remote_runnable = RemoteRunnable("http://localhost:8000/<path>/")
Thêm vào
LangChain tự hào có một loạt mô-đun trên các thư viện của mình, giới thiệu một bộ công cụ đa dạng được thiết kế để trao quyền cho các nhà phát triển trong việc xây dựng các ứng dụng phức tạp dựa trên AI. Từ các cấu trúc chuỗi phức tạp đến tích hợp liền mạch với nhiều mô hình AI khác nhau, kiến trúc mô-đun của LangChain tạo điều kiện cho nhiều chức năng, cho phép tạo ra các giải pháp tiên tiến và có khả năng tùy chỉnh cao trong lĩnh vực AI và học máy.
LangServe không chỉ làm sáng tỏ mà còn đơn giản hóa đáng kể quá trình triển khai các ứng dụng LangChain. Bằng cách thu hẹp khoảng cách giữa phát triển và triển khai, nó đảm bảo rằng các ứng dụng đổi mới tận dụng MinIO và LangChain có thể nhanh chóng chuyển từ ý tưởng sang thực tế, sẵn sàng tích hợp vào hệ sinh thái rộng lớn hơn và nâng cao trải nghiệm người dùng.
Thông qua quá trình phát triển được đề cập trong các khám phá của chúng tôi, chúng tôi đã thấy sự tích hợp liền mạch của MinIO với
Tại MinIO, chúng tôi được tiếp thêm sinh lực bởi sự sáng tạo và tiềm năng của cộng đồng nhà phát triển trong kỷ nguyên giàu công nghệ này. Không có thời gian nào tốt hơn để hợp tác và trao đổi kiến thức. Chúng tôi rất mong được kết nối với bạn! Tham gia cùng chúng tôi trên