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),
AIMessagePromptTemplate.from_template("YES, I Know."),
*_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 MessagesPlaceholder(variable_name="chat_history"),
HumanMessagePromptTemplate.from_template(final_prompt),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]- 1
-
从提示词的构造方式上,
chat_history是通过MessagesPlaceholder构造的。而此处的chat_history又是通过ConversationBufferMemory获取的。
memory = ConversationBufferMemory(memory_key="chat_history")ConversationBufferMemory 返回的内容逻辑如下所示:
@property
def buffer(self) -> Any:
"""String buffer of memory."""
1 return 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以返回消息列表格式的记忆内容。