聊天机器人需要 对话+上下文记忆
pip install langchain_community
初始化
导入库;创建模型;定义Prompt_template;构建chain
#MessagesPlaceholder (variable_name='my_msg') #占位,不限严格格式,此处用于传入历史记录
pythonimport os from langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.messages import HumanMessage from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_core.runnables import RunnableWithMessageHistory from langchain_openai import ChatOpenAI from langserve import add_routes os.environ['http_proxy'] = '127.0.0.1:7890' os.environ['https_proxy'] = '127.0.0.1:7890' os.environ["LANGCHAIN_TRACING_V2"] = "true" # 定义Langchain项目归属 os.environ["LANGCHAIN_PROJECT"] = "LangchainDemo" os.environ["LANGCHAIN_API_KEY"] = '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' # 聊天机器人案例 # 创建模型 model = ChatOpenAI(model='gpt-4-turbo') # 定义提示模板 prompt_template = ChatPromptTemplate.from_messages([ ('system', '你是一个乐于助人的助手。用{language}尽你所能回答所有问题。'), MessagesPlaceholder(variable_name='my_msg') #占位,不限严格格式, ]) # 得到链 chain = prompt_template | model
保存聊天历史
所有用户的聊天记录都保存到store{ key: sessionId,value: 历史聊天记录对象}
##**ChatMessageHistory()**保存历史聊天的
RunnableWithMessageHistory ,每次运行携带历史聊天记录,参数:chain、session_id、历史Message的Key(在Prompt_Template中定义)
python# 保存聊天的历史记录 store = {} # 所有用户的聊天记录都保存到store。key: sessionId,value: 历史聊天记录对象 # 此函数预期将接收一个session_id并返回一个消息历史记录对象。 def get_session_history(session_id: str): if session_id not in store: # from langchain_community.chat_message_histories import ChatMessageHistory store[session_id] = ChatMessageHistory() return store[session_id] ## from langchain_core.runnables import RunnableWithMessageHistory do_message = RunnableWithMessageHistory( chain, get_session_history, input_messages_key='my_msg' # 每次聊天时候发送msg的key ) # 给当前会话定义一个sessionId config = {'configurable': {'session_id': 'zs1234'}}
多轮会话:
invoke 中要有 Message、包含sessionId的config
python# 第一轮 resp1 = do_message.invoke( { 'my_msg': [HumanMessage(content='你好啊! 我是LaoXiao')], 'language': '中文' }, config=config ) print(resp1.content) # 第二轮 resp2 = do_message.invoke( { 'my_msg': [HumanMessage(content='请问:我的名字是什么?')], 'language': '中文' }, config=config ) print(resp2.content)
第三轮 流式输出:
RunnableWithMessageHistory.stream流式输出;就是逐个token输出。
因此!这里输出,就需要 for循环 .stream。
python# 第3轮: 返回的数据是流式的 # 这里如果重新给config赋值,会清空原来旧的config历史 #config = {'configurable': {'session_id': 'lis2323'}} # 给当前会话定义一个sessionId for resp in do_message.stream( { 'my_msg': [HumanMessage(content='请给我讲一个笑话?')] , 'language': 'English'}, config=config): # 每一次resp都是一个token print(resp.content, end='-')