15 LangChain Chat Agent
在 章节 14 中,除了 Structured Chat Agent
外,我们所介绍的 Agent 都是非 Chat
模式的 Agent。这里的 Chat
模式类似 章节 10.2.2 中介绍的 LLM 的 Chat
模式,其最主要的特点就是:他们以聊天消息列表格式的提示词作为输入。
15.1 修改 Chat Agent 的提示词逻辑
因为文心大模型 Chat
模式的 message 消息类型和 OpenAI
的不同——缺少 SystemMessage
类型,因此,如果要让 Chat Agent
支持文心,需要按照 列表 14.23 的思路对其 Prompt 的生成方式进行修改。
@classmethod
def create_prompt_for_ernie(
......-> BasePromptTemplate:
)
......= [
messages
HumanMessagePromptTemplate.from_template(template),"YES, I Know."),
AIMessagePromptTemplate.from_template(*_memory_prompts,
HumanMessagePromptTemplate.from_template(human_message_template),
]return ChatPromptTemplate(input_variables=input_variables, messages=messages)
15.2 ChatConversationAgent
参照 列表 14.9 和 列表 14.15,我们可以构建一个 chat-conversational-react-description
。
列表 15.1: Chat Conversation Agent
#encoding: utf-8
"""
@discribe: example for chat conversation agent.
@author: wangwei1237@gmail.com
"""
from langchain.chat_models import ErnieBotChat
from langchain.chains import LLMMathChain
from langchain.agents import Tool
from langchain.memory import ConversationBufferMemory
from langchain.agents import initialize_agent
memory = ConversationBufferMemory(memory_key="chat_history")
llm = ErnieBotChat(model_name="ERNIE-Bot-4")
# initialize the math tool
llm_math = LLMMathChain(llm=llm)
math_tool = Tool(
name='Calculator',
func=llm_math.run,
description='Useful for when you need to answer questions about math.'
)
# when giving tools to LLM, we must pass as list of tools
tools = [math_tool]
chat_conversation_agent = initialize_agent(
agent="chat-conversational-react-description",
tools=tools,
llm=llm,
verbose=True,
max_iterations=3,
memory=memory
)
chat_conversation_agent("4.1*7.9=?")
chat_conversation_agent("2 * 2")
但是,执行 列表 15.1 时,却报错了:
Traceback (most recent call last):
File "code/test_chat_coversation_agent.py", line 38, in <module>
chat_conversation_agent("4.1*7.9=?")
...
1ValueError: variable chat_history should be a list of base messages, got
- 1
- chat_history 变量必须是一个消息列表
15.3 MessagesPlaceholder
我们说过,Agent 本质上就是 LLM,既然 列表 15.1 执行有异常,那我们就看下他的提示词究竟是怎么实现的(具体实现位于 langchain/agents/conversation_chat/base.py
的 create_prompt()
)。
= [
messages
SystemMessagePromptTemplate.from_template(system_message),1="chat_history"),
MessagesPlaceholder(variable_name
HumanMessagePromptTemplate.from_template(final_prompt),="agent_scratchpad"),
MessagesPlaceholder(variable_name ]
- 1
-
从提示词的构造方式上,
chat_history
是通过MessagesPlaceholder
构造的。而此处的chat_history
又是通过ConversationBufferMemory
获取的。
= ConversationBufferMemory(memory_key="chat_history") memory
ConversationBufferMemory
返回的内容逻辑如下所示:
@property
def buffer(self) -> Any:
"""String buffer of memory."""
1return self.buffer_as_messages if self.return_messages else self.buffer_as_str
- 1
-
根据
return_messages
来返回不同格式的记忆。
而在 LangChain 中,return_messages
默认值为 False
,因此,实际上 buffer()
返回的是字符串格式的内容。这就是导致执行异常的根本原因。
为了解决这个问题,我们需要在初始化 ConversationBufferMemory
时,配置 return_messages
= True
。
列表 15.2: Chat Conversation Agent
#encoding: utf-8
"""
@discribe: example for chat conversation agent.
@author: wangwei1237@gmail.com
"""
from langchain.chat_models import ErnieBotChat
from langchain.chains import LLMMathChain
from langchain.agents import Tool
from langchain.memory import ConversationBufferMemory
from langchain.agents import initialize_agent
1memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
llm = ErnieBotChat(model_name="ERNIE-Bot-4")
# initialize the math tool
llm_math = LLMMathChain(llm=llm)
math_tool = Tool(
name='Calculator',
func=llm_math.run,
description='Useful for when you need to answer questions about math.'
)
# when giving tools to LLM, we must pass as list of tools
tools = [math_tool]
chat_conversation_agent = initialize_agent(
agent="chat-conversational-react-description",
tools=tools,
llm=llm,
verbose=True,
max_iterations=3,
memory=memory
)
chat_conversation_agent("4.1*7.9=?")
chat_conversation_agent("2 * 2")
- 1
-
通过设置
return_messages
为True
以返回消息列表格式的记忆内容。