问题描述
使用 AutoContextMemory 配合 ReActAgent 时,当前轮压缩(Strategy 5/6)会将工具调用历史压缩为 "I called [tool] with [args]; it returned: [result]" 格式,并以 role=ASSISTANT 存入对话历史。
这导致 LLM 在后续推理中直接模仿该格式输出给用户,而不是生成正常回复。该问题复现率极高。
复现步骤
- 创建带多个工具(含 SubAgentTool)的 ReActAgent,挂载 AutoContextHook
- 进行多轮对话,每轮触发工具调用
- 当 token 超过阈值触发
summaryCurrentRoundMessages 时,问题出现
- LLM 输出类似
"I called xxx with param=value; it returned: ..." 的内容给用户
原因分析
- 压缩消息 role 为 ASSISTANT:
generateCurrentRoundSummaryFromMessages() 中 Msg.builder().role(MsgRole.ASSISTANT).name("assistant"),LLM 会将其视为自己的历史回复并模仿
- 压缩 Prompt 使用第一人称:
getCurrentRoundCompressPrompt() 要求以 "I called [tool]; it returned: ..." 格式输出,与 ASSISTANT role 叠加后极易被 LLM 当作回复模板
- 系统指令不够强:只禁止了引用 UUID 和 offload 标记,没有禁止复述摘要内容本身
- 当前轮压缩时机不当:在 ReAct 迭代之间压缩工具调用,LLM 看到的不是
tool_use + tool_result 结构,而是一条看起来像自己说过的话
建议修复方向
- 压缩消息不要用
ASSISTANT role,改用 SYSTEM 或其他方式标识
- 压缩 Prompt 避免第一人称("I called..."),改用第三人称或元信息格式
- 系统指令增加对摘要内容本身的禁止复述约束
- 考虑在 ReAct 迭代之间跳过当前轮压缩,仅在轮次边界(用户消息之后)触发
环境
- agentscope-core / agentscope-extensions-autocontext-memory: 1.0.11
问题描述
使用
AutoContextMemory配合 ReActAgent 时,当前轮压缩(Strategy 5/6)会将工具调用历史压缩为"I called [tool] with [args]; it returned: [result]"格式,并以role=ASSISTANT存入对话历史。这导致 LLM 在后续推理中直接模仿该格式输出给用户,而不是生成正常回复。该问题复现率极高。
复现步骤
summaryCurrentRoundMessages时,问题出现"I called xxx with param=value; it returned: ..."的内容给用户原因分析
generateCurrentRoundSummaryFromMessages()中Msg.builder().role(MsgRole.ASSISTANT).name("assistant"),LLM 会将其视为自己的历史回复并模仿getCurrentRoundCompressPrompt()要求以"I called [tool]; it returned: ..."格式输出,与 ASSISTANT role 叠加后极易被 LLM 当作回复模板tool_use+tool_result结构,而是一条看起来像自己说过的话建议修复方向
ASSISTANTrole,改用SYSTEM或其他方式标识环境