LangChain 0.2 里用 ChatPromptTemplate.from_messages 拼模板,其中一条写成 ('placeholder', '{history}'),调用时传 history='上一轮内容',抛 ValueError: Invalid input type
一开始怀疑是「模板里同时用了 MessagesPlaceholder 和普通占位符,格式化阶段就失败」,查了一圈,方向不对。
把日志和配置对完,能解释这个现象的基本就这几处。placeholder 类型要求传入消息对象列表,字符串不是合法输入。另一种情况是历史消息是纯文本存的,没有转成 HumanMessage 与 AIMessage。
另外,版本升级后 placeholder 的校验从宽松变成严格。
先看模板里到底声明了哪些占位
python -c "from langchain_core.prompts import ChatPromptTemplate;t=ChatPromptTemplate.from_messages([('system','x'),('placeholder','{history}')]);print(t.input_variables)"
然后把历史文本切成消息对象再传
python -c "from langchain_core.messages import HumanMessage, AIMessage;h=[HumanMessage(content='退款怎么申请'),AIMessage(content='在订单页点售后')];print(len(h))"
接着用两元素元组构造消息列表再渲染
python -c "from langchain_core.prompts import ChatPromptTemplate;t=ChatPromptTemplate.from_messages([('system','客服'),('placeholder','{history}'),('human','{q}')]);print(t.format_messages(history=[('human','hi'),('ai','ok')],q='继续'))"
空历史时传空列表而不是空字符串
python -c "print({'history': []})"
别只看报错消失,验证要多做一步。带历史与不带历史两种调用都能渲染出正确条数的消息,system 在最前,历史顺序与入参一致,不再出现 Invalid input type。
补一句。占位符的名字是消息级约束而不是字符串拼接,历史消息最好一开始就以消息对象存,后面换模板才不用来回转换。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
