工具缺少 context 参数
ChatPromptTemplate 追加 context 后,as_tool 参数仍只有 q。核对消息、输入变量和工具 schema,完整重建模板与注册签名,保留 partial 和可选历史契约。
给 ChatPromptTemplate 追加一条含 {context} 的消息,再把链转换为工具,公开参数却只有 q;调用时即使带上 context,也可能报 KeyError: 'context'。先比较提示词的消息列表、input_variables 与工具的输入 schema,检查它们是否还描述同一份模板。
这条路径有 langchain-core 1.6.5、1.6.9 的反馈,已核对的正式 1.6.10 仍只在 append、extend 中修改消息列表,没有重新推导输入变量。它与提示词里字面 JSON 花括号被误当变量不同。
消息变了,声明的输入没跟着变
ChatPromptTemplate 构造时会从消息模板推导需要的变量,并处理可选 placeholder、partial variables 与输入类型。get_input_schema 再根据这些派生字段创建结构化输入模型。
追加消息后,新的 context 占位符已经参与渲染,旧 input_variables 却可能仍只有 q。as_tool 沿旧 schema 生成参数,工具入口就无法可靠地把新增字段交给后面的提示词。
直接渲染时若把 context 显式传入,可能暂时看不出问题;这不能说明转换后的工具签名正确。应检查真正提供给调用方的参数,而不只看消息列表里已经出现了那条 system 消息。
在生成工具之前完成模板组装
可以先收集完整消息,再一次构造模板,让输入字段重新推导。下面只创建提示词,不调用模型或工具:
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("human", "{q}"),
("system", "Context: {context}"),
])
这是最小模板示例,真实应用应保留原来的消息顺序、角色与内容。已有 partial variables、输入类型、模板格式、可选历史消息和 tracing 配置时,也需要带入重新构造的模板,不能用一份默认示例覆盖业务约定。
依赖模板的链和 as_tool 结果要重新构造。旧工具已经发布的输入 schema,不会因为旁边又创建了一份新 prompt 自动更新;注册表、缓存或远端调用方若仍使用旧签名,还需要沿应用流程同步。
不要只手改 input_variables 增加 context。MessagesPlaceholder 的类型、可选变量和 partial 参数也会影响 schema,绕过整套推导容易留下下一处不一致。
比较缺字段与多字段两种输入
检查新 prompt 的输入 schema 与重新生成的工具参数都包含实际必需字段,再用获准的本地无副作用链确认 q、context 都能到达模板。缺少必需 context 时,应按输入契约拒绝,而不是让模型自行补一个值。
固定的上下文若本来应该由 partial 提供,就不应突然变成调用方必填参数;可选历史 placeholder 也应维持可选。验收比较的是原来的业务契约,不是所有变量名字都越多越好。
如果缺少的名字实际来自 JSON 字段,而不是追加的占位符,可以再检查模板里的字面花括号。工具参数已经完整却仍报错时,继续核对链中是否引用了旧模板、字段是否被其他输入适配器过滤,不要直接删除新增上下文。


