DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

消息合并报角色冲突

merge_message_runs 拼接不同 role 的 ChatMessage 或不同 name 的 FunctionMessage 时失败。保留身份边界,必要时移除可选合并,另验模型输入。

两条 ChatMessage 的 role 分别是 human、assistant,单独保存都正常,经过 merge_message_runs 却报:

Cannot concatenate ChatMessageChunks with different roles.

相邻 FunctionMessage 的 name 不同,也可能报 Cannot concatenate FunctionMessageChunks with different names.。先检查错误是否来自历史整理中的消息合并,而不是模型 API 拒绝角色。

这一条件有 langchain-core 1.6.1 与后续源码反馈,已核对的正式 1.6.10 仍主要按消息类判断合并边界,没有同时比较 ChatMessage.role 和 FunctionMessage.name。

同一消息类不等于同一身份

ChatMessage 用同一个类表示不同说话者。合并器看到相邻对象属于同一类,便把它们转换成 chunk 相加;chunk 的规则却明确拒绝拼接不同 role。

FunctionMessage 也类似:同一类里的 search 与 lookup 代表不同函数结果,不能把它们合成一条再挑一个 name。异常是在阻止身份混合,删除这个检查会把显式失败变成含义错误。

这里的输入已是消息对象。缺少 role、content 的业务字典,属于另一条历史消息适配路径,不能靠补字段解决当前合并边界。

保留原来的消息边界

如果这一步只是减少相邻消息条数,可以先从整理链中移除 merge_message_runs,让原来的消息顺序、role、name 与内容继续传递。同时检查下游供应商是否接受这份未经合并的历史;不能认为少做一次合并,就替代了模型协议验收。

必须保留合并时,应用的分组边界应至少同时比较消息类型与必要身份字段:ChatMessage 的 role、FunctionMessage 的 name 不同就开始新组,同值才进入原来的合并逻辑。不能只按 class 分组,也不能把不相邻的同角色消息重新排到一起。

ToolMessage 有独立的 tool_call_id,正式合并器本来就不合并它们。这条边界应继续保留,不能因为函数名称相同就把多个调用的结果压成一条。使用较新的工具消息协议还涉及请求和结果的对应关系,不要为了绕过异常直接把 FunctionMessage 改名成 ToolMessage。

同样不要把所有 ChatMessage 强制改成 HumanMessage,或把两个函数的 name 都改成同一个字符串。这样可能不再报错,却改变了模型看到的身份与结果归属。

同值与异值都要检查

验收应覆盖同 role、不同 role、同 name、不同 name,确认应该合并的内容仍按原规则拼接,应该保留的消息仍在原位置。再检查字符串与内容块列表、消息 ID、metadata 和工具调用,不只比较拼出来的文本。

若绕过可选合并步骤,还要核对实际模型输入和原来的预算:消息条数可能增加,不能顺手删除消息来补偿。若升级或采用修订实现,则确认当前安装包确实含有边界判断;公开的修订分支并不等于正式版本已修复。