Ý tưởng cốt lõi của Đại lý LangChain là sử dụng LLM như một bộ não tự động suy nghĩ, ra quyết định và thực hiện các hành động khác nhau để cuối cùng hoàn thành các nhiệm vụ mục tiêu của chúng ta.
Mẹo: Từ quan điểm phát triển, điều này có nghĩa là chúng ta phát triển các API khác nhau trước và sau đó giao cho Đại lý một nhiệm vụ, cho phép LLM phân tích xem API nào sẽ được gọi để hoàn thành nhiệm vụ.
Để hiểu rõ hơn về vấn đề mà Đại lý LangChain mục tiêu giải quyết, hãy xem xét một ví dụ.
Ví dụ:
Nếu chúng ta muốn nghiên cứu xem "Docker có thể được sử dụng làm giải pháp triển khai sản phẩm," chúng ta sẽ tìm kiếm "giới thiệu về Docker" trên Baidu, duyệt qua kết quả tìm kiếm, sau đó tiếp tục tìm kiếm "ưu và nhược điểm của việc triển khai Docker" và duyệt qua kết quả, và tiếp tục như vậy cho đến khi đạt được một kết luận.
Đại lý LangChain mục tiêu mô phỏng quá trình này. Tôi có thể đóng gói trước một loạt các công cụ (ví dụ: tìm kiếm Baidu, công cụ trích xuất nội dung URL), sau đó giao cho Đại lý một nhiệm vụ mục tiêu "Docker có thể được sử dụng làm giải pháp triển khai sản phẩm?" Đại lý sau đó sẽ xây dựng các lời nhắc để gọi LLM. Để đạt được nhiệm vụ này, bước tiếp theo là thực hiện hành động gì (tức là gọi công cụ nào). Trí tuệ nhân tạo sẽ trả về công cụ cần gọi, mã sẽ thực thi công cụ này, sau đó truyền kết quả thực thi công cụ trở lại cho trí tuệ nhân tạo, và hỏi về bước tiếp theo trong việc thực hiện công cụ nào. Lặp lại quá trình này sẽ hoàn thành nhiệm vụ đã đề cập trước đó.
Mẹo: Kể từ khi mô hình GPT được phát hành, đây là một khả năng bùng nổ, cho phép LLM hành động như bộ não, suy nghĩ một cách tích cực và sau đó gọi các API khác nhau chúng ta đã phát triển. Điều này nâng cao đáng kể khả năng của LLM. Hiện tại, tính năng này vẫn đang ở giai đoạn thử nghiệm và sẽ liên tục gọi LLM, do đó nó tốn rất nhiều mã thông báo. Hoàn thành một nhiệm vụ có thể tốn hàng ngàn mã thông báo trong vài phút. Nếu bạn muốn tiết kiệm tiền, khuyến nghị để trước tiếp tục cho LLM thực hiện các nhiệm vụ suy luận đơn giản.
Khái niệm cốt lõi
Hãy bắt đầu giới thiệu các thành phần & khái niệm liên quan.
Đại lý
Một Đại lý có thể hiểu đơn giản là trợ lý của chúng ta, đóng vai trò thay mặt chúng ta để ra quyết định. Trên bề mặt cài đặt của Đại lý LangChain, thông qua LLM, quyết định hành động tiếp theo (hoặc cuộc gọi API) được xác định. Chế độ ReAct mô tả quá trình ra quyết định của trí tuệ nhân tạo. Những người quan tâm có thể khám phá thêm về điều này.
LangChain cung cấp một số loại Đại lý cho các tình huống khác nhau.
Công cụ
Tôi nghĩ Công cụ được hiểu tốt hơn như là các API, đã được đóng gói trước với các API chức năng khác nhau được thiết kế để mở rộng khả năng của LLM. LLM xác định chính xác API cụ thể nào cần gọi để hoàn thành một nhiệm vụ.
Bộ công cụ
Bộ công cụ thường cung cấp cho LLM không chỉ một hoặc hai công cụ, mà một tập hợp các công cụ để đưa cho LLM nhiều lựa chọn hơn khi hoàn thành nhiệm vụ.
AgentExecutor
Trình thực thi đại diện chịu trách nhiệm thực thi công cụ (API) được chọn bởi LLM. Mã giả cho quá trình chạy này như sau:
next_action = agent.get_action(...)
while next_action != AgentFinish:
observation = run(next_action)
next_action = agent.get_action(..., next_action, observation)
return next_action
Mặc dù quá trình thực thi không phức tạp, trình thực thi xử lý nhiều vấn đề chi tiết, chủ yếu bao gồm:
- Xử lý tình huống khi đại lý chọn một công cụ không tồn tại
- Xử lý tình huống lỗi công cụ
- Xử lý tình huống khi đại lý tạo ra đầu ra không thể giải quyết được như một cuộc gọi công cụ
- Vấn đề gỡ lỗi.
Bắt đầu nhanh
Phần này giới thiệu cách sử dụng cơ bản của Đại lý LangChain.
1. Tải LLM
Trước hết, hãy tải mô hình ngôn ngữ (LLM) mà chúng ta sẽ sử dụng để điều khiển đại lý.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
2. Xác định Công cụ
Tiếp theo, chúng ta xác định một số công cụ để đại lý gọi. Chúng ta sẽ viết một hàm Python rất đơn giản để tính độ dài của từ đầu vào.
from langchain.agents import tool
@tool
def get_word_length(word: str) -> int:
"""Trả về độ dài của từ."""
return len(word)
get_word_length.invoke("abc")
Lưu ý: Nhận xét về chức năng rất quan trọng. Chúng nói cho LLM biết vấn đề mà nó có thể giải quyết bằng cách gọi chúng. Chức năng
get_word_length
cho LLM biết rằng nó có thể tính toán độ dài của một từ.
3
Xác định một tập hợp các công cụ
tools = [get_word_length]
3. Tạo một yêu cầu
Bây giờ chúng ta hãy tạo một yêu cầu. Vì OpenAI Function Calling đã được tối ưu hóa cho việc sử dụng công cụ, chúng ta hầu như không cần bất kỳ hướng dẫn nào về lập luận hoặc định dạng đầu ra. Chúng ta chỉ có hai biến đầu vào: input
và agent_scratchpad
. input
đại diện cho câu hỏi đầu vào của người dùng, và agent_scratchpad
là một nơi để chú thích cuộc gọi của trợ lý, sẽ được chèn vào mẫu yêu cầu khi chạy lệnh gọi công cụ.
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"Bạn là một trợ lý rất mạnh mẽ nhưng không hiểu rõ tình hình hiện tại.",
),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)
4. Liên kết Công cụ với LLM
Làm thế nào mà trợ lý biết được các công cụ nào mà nó có thể sử dụng?
Điều này phụ thuộc vào tính năng gọi công cụ của OpenAI (nhiều mô hình hỗ trợ các tính năng tương tự). Chúng ta chỉ cần cho mô hình biết định dạng gọi công cụ đã được xác định.
llm_with_tools = llm.bind_tools(tools)
5. Tạo một trợ lý
Bây giờ khi chúng ta đã tích hợp nội dung trước đó, chúng ta có thể tiến hành tạo chương trình đại diện. Chúng ta sẽ import hai chức năng tiện ích thực hành trước đó: một để định dạng các bước trung gian (hành động trợ lý, đầu ra công cụ) thành tin nhắn đầu vào có thể được gửi cho mô hình, và một chức năng khác để chuyển đổi các tin nhắn đầu ra thành hành động trợ lý/kết thúc trợ lý.
from langchain.agents.format_scratchpad.openai_tools import format_to_openai_tool_messages
from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser
agent = (
{
"input": lambda x: x["input"],
"agent_scratchpad": lambda x: format_to_openai_tool_messages(x["intermediate_steps"]),
}
| prompt
| llm_with_tools
| OpenAIToolsAgentOutputParser()
)
Định nghĩa bộ thực thi trợ lý
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
Hãy minh họa hoạt động của chương trình trung gian qua một ví dụ:
list(agent_executor.stream({"input": "Từ 'eudca' có bao nhiêu chữ cái?"}))
Ví dụ nhật ký đầu ra của trợ lý
> Bắt đầu một chuỗi thực thi trợ lý mới...
Thu hút: Đang chạy `get_word_length` với tham số `{'word': 'educa'}`
Có 5 chữ cái trong từ "educa".
> Hoàn thành chuỗi thực thi.
Qua ví dụ này, chúng ta đã minh họa quá trình hoàn chỉnh của chương trình trung gian.
Thêm chức năng bộ nhớ cho Trợ lý
Nếu chúng ta muốn trợ lý ghi nhớ các cuộc trò chuyện trước đó, điều này thực ra khá đơn giản: chúng ta chỉ cần chèn nội dung trả về bởi trí tuệ nhân tạo vào mẫu yêu cầu và gửi nó cùng nhau cho trí tuệ nhân tạo.
Sửa đổi mẫu yêu cầu
Dưới đây là mẫu yêu cầu được sửa đổi để bao gồm một biến mẫu lịch sử trò chuyện.
from langchain.prompts import MessagesPlaceholder
MEMORY_KEY = "chat_history"
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"Bạn là một trợ lý tuyệt vời, nhưng không giỏi trong việc tính độ dài của từ.",
),
MessagesPlaceholder(variable_name=MEMORY_KEY),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)
Sửa đổi định nghĩa quá trình trợ lý
Sửa đổi định nghĩa quá trình trợ lý để cung cấp dữ liệu lịch sử trò chuyện cho mẫu yêu cầu, như trong mã sau, thêm xử lý tham số chat_history
.
agent = (
{
"input": lambda x: x["input"],
"agent_scratchpad": lambda x: format_to_openai_tool_messages(
x["intermediate_steps"]
),
"chat_history": lambda x: x["chat_history"],
}
| prompt
| llm_with_tools
| OpenAIToolsAgentOutputParser()
)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
Cung cấp dữ liệu lịch sử cuộc trò chuyện khi gọi đến trợ lý
chat_history = []
input1 = "Từ 'educa' có bao nhiêu chữ cái?"
result = agent_executor.invoke({"input": input1, "chat_history": chat_history})
chat_history.extend(
[
HumanMessage(content=input1),
AIMessage(content=result["output"]),
]
)
agent_executor.invoke({"input": "Từ này có thực sự tồn tại không?", "chat_history": chat_history})
Trong các kịch bản kinh doanh thực tế, bạn có thể lưu trữ lịch sử cuộc trò chuyện vào cơ sở dữ liệu và chèn dữ liệu vào giao tiếp theo nhu cầu dựa trên yêu cầu kinh doanh.
Mẹo: Chức năng nhớ của các mô hình lớn (LLM) hiện nay chủ yếu được thực hiện bằng cách chèn nội dung cuộc trò chuyện lịch sử vào prompt và gửi nó đến LLM. LangChain đơn giản cung cấp một số bao bọc. Bạn có thể chọn không sử dụng và nối thủ công nội dung cuộc trò chuyện thành mẫu prompt.