You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ChatMessageHistory正确传入LangChain Runnable链?

解决LangChain中ChatMessageHistory传入RunnableParallel的报错问题

报错原因是RunnableParallel要求每个键对应的值必须是Runnable、可调用对象或字典,而ChatMessageHistory实例本身不属于这些类型。核心解决思路是把历史消息格式化为模板可用的字符串,并将这个格式化逻辑包装成符合要求的Runnable类型。

具体解决方案

步骤1:格式化历史消息

将ChatMessageHistory中的消息转换为模板能识别的字符串格式,可使用LangChain内置的format_messages函数,也可以自定义格式逻辑。

步骤2:包装为Runnable

用RunnableLambda将格式化逻辑包装成Runnable类型,再传入RunnableParallel。

修改后的完整代码:

from langchain_core.runnables import RunnableLambda, RunnableParallel, RunnablePassthrough
from langchain_core.messages import format_messages
from langchain_core.output_parsers import StrOutputParser

# 初始化ChatMessageHistory对象(原代码保留)
history = ChatMessageHistory()
for message in messages:
    if message['is_from'] == 'human':
        history.add_user_message(message['message'])
    else:
        history.add_ai_message(message['message'])

# 模板保留不变
math_template = """You are a very good mathematician. You are great at answering math questions. \
You are so good because you are able to break down hard problems into their component parts, \
answer the component parts, and then put them together to answer the broader question.

{history}

Answer the question only based on the context provide below:
{context}

Here is a question:
{question}"""

# 修改链的构建,将history包装为Runnable
chain = (
    RunnableParallel({
        "context": retriever,
        "question": RunnablePassthrough(),
        # 用RunnableLambda包装历史格式化逻辑
        "history": RunnableLambda(lambda _: format_messages(history.messages))
    })
    | RunnableLambda(prompt_router)
    | model
    | StrOutputParser()
)

自定义历史格式(可选)

如果需要自定义对话显示格式(比如中文前缀),可以替换格式化逻辑:

def custom_format_history(_):
    formatted_lines = []
    for msg in history.messages:
        if msg.type == "human":
            formatted_lines.append(f"用户: {msg.content}")
        elif msg.type == "ai":
            formatted_lines.append(f"AI: {msg.content}")
    return "\n".join(formatted_lines)

# 链中替换为自定义函数
chain = (
    RunnableParallel({
        "context": retriever,
        "question": RunnablePassthrough(),
        "history": RunnableLambda(custom_format_history)
    })
    | RunnableLambda(prompt_router)
    | model
    | StrOutputParser()
)

内容的提问来源于stack exchange,提问作者KhoPhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:42:28