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

使用LangChain |运算符组合ChatOpenAI与ChatPromptTemplate时抛出ValueError,但LLMChain可正常运行的问题排查

使用LangChain |运算符组合ChatOpenAI与ChatPromptTemplate时抛出ValueError,但LLMChain可正常运行的问题排查

这个问题的核心原因其实非常直观——你完全搞反了链组件的执行顺序!

为什么LLMChain能工作,而|运算符的链会报错?

LLMChain是LangChain的高阶封装,它内部已经帮你处理了「输入→Prompt模板→LLM→解析器」的执行逻辑,你只需要把各个组件传进去,它会自动按正确顺序流转数据。

但|运算符是基于LangChain的Runnable体系,它是严格按照从左到右的顺序执行,每个组件的输出必须能匹配下一个组件的输入类型。你的代码里写了:

conversation_chain = llm | chat_prompt | output_parser

这就意味着你先把用户输入的字典({"input_user_message": ..., "history_messages": ...})直接传给了ChatOpenAI实例,但ChatOpenAI根本不能直接处理字典类型的输入——它需要的是PromptValue、字符串或者BaseMessages列表,这就是你看到ValueError: Invalid input type <class 'dict'>的直接原因。

正确的链顺序应该是什么样的?

正确的流转逻辑是:

  1. 把包含变量的字典传给ChatPromptTemplate,它会把变量渲染成符合Chat模型要求的消息格式(ChatPromptValue)
  2. 把渲染好的消息传给ChatOpenAI,得到模型返回的BaseMessage
  3. 把BaseMessage传给StrOutputParser,转成字符串输出

所以正确的链写法应该是:

conversation_chain = chat_prompt | llm | output_parser

修正后的完整代码片段

把你原代码里的conversation_chain行替换成上面的写法即可,其他部分(比如消息修剪、会话历史)都不需要改动,完整的函数修正后如下:

def chatbot(input_user_message):
    # creating a prompt template
    chat_prompt = ChatPromptTemplate.from_messages(
        [
            ("system", "You are a helpful AI assistant."),
            MessagesPlaceholder(variable_name="history_messages"),
            ("human", "{input_user_message}"),
        ]
    )

    # initializing OpenAI Chat model
    llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)

    trimmer = trim_messages(
        max_tokens=100,
        strategy="last",
        token_counter=llm,
        include_system=True,
        start_on="human",
    )

    def get_session_history(session_id):
        if session_id not in st.session_state.store:
            st.session_state.store[session_id] = ChatMessageHistory()
        else:
            st.session_state.store[session_id].messages = trimmer.invoke(st.session_state.store[session_id].messages)
        return st.session_state.store[session_id]

    # Initializing the output parser
    output_parser = StrOutputParser()

    # 👇 修正后的链顺序
    conversation_chain = chat_prompt | llm | output_parser

    model_with_memory = RunnableWithMessageHistory(
        conversation_chain,
        get_session_history,
        input_messages_key="input_user_message",
        history_messages_key="history_messages",
    )

    session_id = "1234"

    response = model_with_memory.invoke(
        {"input_user_message": input_user_message},
        {"configurable": {"session_id": session_id}},
    )
    print(response)
    return response

(小细节:原LLMChain返回的是包含text字段的字典,而Runnable链用StrOutputParser后会直接返回字符串,所以最后不需要再取response["text"]了)

额外的注意点

在使用LangChain的Runnable体系(|运算符)时,一定要注意每个组件的输入输出类型匹配:

  • ChatPromptTemplate:输入是包含变量的字典,输出是ChatPromptValue(可被ChatLLM直接处理)
  • ChatOpenAI:输入是PromptValue、BaseMessages列表或字符串,输出是BaseMessage
  • StrOutputParser:输入是BaseMessage,输出是字符串

只要保证每个环节的输出能被下一个环节接受,链就能正常运行啦。

备注:内容来源于stack exchange,提问作者taher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 15:58:12