文件和行号
internal/agent/agent_tool.go:296-299(executeToolInner 拦截,registry 查找前)
internal/agent/agent.go:547-551(newMemoryToolState 无条件初始化)
internal/agent/memory_tool.go:38,79-112(memoryToolName="memory",executeResult 无门控)
internal/provider/registry.go:29-31(声明侧有 resolved.MemoryTool 门控——不对称)
问题描述
#2506 落地的 Anthropic Memory Tool(memory_20250818)agent 侧拦截条件 tc.Name == "memory" && a.memoryTool != nil 位于 a.tools.Get(tc.Name) 之前,而 a.memoryTool 在 NewAgent 无条件初始化——拦截条件退化为 tc.Name == "memory",与 provider 是否声明(endpoint memory_tool: true)完全无关。对照同文件同型的 tool_search 拦截(agent_tool.go:290):其 executeResult 内部有 s.enabled 门控(tool_search.go:196),memory executor 无任何等价检查。
触发场景
- 幻觉调用:非 Anthropic provider(如第三方 OpenAI 兼容端点跑 Claude 系模型,对 memory tool 有训练先验)发出 tool_use name="memory"——本应
FormatUnknownToolError 一次迭代自纠,现被 memory executor 捕获:静默 mkdir <workingDir>/.ggcode/memories + 返回语义化错误 "Missing required command argument. Supported commands: view, create, ...",模型收到"工具存在但参数错"信号,按 /memories 协议补参继续幻觉迭代,在用户项目落目录
- 同名工具遮蔽(埋雷):
Registry.Register(tool/tool.go:131-139)无保留名校验;当前 stock 配置无现成注册裸 "memory" 的路径,但任何未来扩展(ACP/a2a/插件/skill)注册即中招——ToDefinitions 向模型暴露定义,调用却永远走 memory executor
- 复合:config_policy.go:147 将 "memory" 列入无条件 Allow 快路径——拦截执行同时绕过权限确认
(MCP 场景已排除:mcp__server__tool 前缀强制隔离)
预期行为 vs 实际行为
- 预期:未声明 memory tool 时,name="memory" 走 registry 查找 → UnknownToolError 自纠;已声明时才由 executor 处理
- 实际:任何 provider 任何配置下 name="memory" 恒被 executor 拦截执行
修复建议
给 memoryToolState 加 enabled 标志(provider 应用时检测 SetMemoryTool 置位,如 ApplyProviderToAgent),拦截条件改为 a.memoryTool.enabled;或先查 a.tools.Get("memory") 命中则放行 registry 工具。对齐 tool_search 的门控形态。
严重程度
medium(独立复核 sa-7 确认:触发面当前较窄+副作用 confined 在 .ggcode/memories 无安全影响;但自纠机制失效+权限快路径+未来注册埋雷+同型拦截器不一致属明确疏漏)
Co-Authored-By: ggcode noreply@ggcode.dev
文件和行号
internal/agent/agent_tool.go:296-299(executeToolInner 拦截,registry 查找前)internal/agent/agent.go:547-551(newMemoryToolState 无条件初始化)internal/agent/memory_tool.go:38,79-112(memoryToolName="memory",executeResult 无门控)internal/provider/registry.go:29-31(声明侧有 resolved.MemoryTool 门控——不对称)问题描述
#2506 落地的 Anthropic Memory Tool(memory_20250818)agent 侧拦截条件
tc.Name == "memory" && a.memoryTool != nil位于a.tools.Get(tc.Name)之前,而a.memoryTool在 NewAgent 无条件初始化——拦截条件退化为tc.Name == "memory",与 provider 是否声明(endpointmemory_tool: true)完全无关。对照同文件同型的 tool_search 拦截(agent_tool.go:290):其 executeResult 内部有s.enabled门控(tool_search.go:196),memory executor 无任何等价检查。触发场景
FormatUnknownToolError一次迭代自纠,现被 memory executor 捕获:静默mkdir <workingDir>/.ggcode/memories+ 返回语义化错误 "Missing required command argument. Supported commands: view, create, ...",模型收到"工具存在但参数错"信号,按 /memories 协议补参继续幻觉迭代,在用户项目落目录Registry.Register(tool/tool.go:131-139)无保留名校验;当前 stock 配置无现成注册裸 "memory" 的路径,但任何未来扩展(ACP/a2a/插件/skill)注册即中招——ToDefinitions 向模型暴露定义,调用却永远走 memory executor(MCP 场景已排除:mcp__server__tool 前缀强制隔离)
预期行为 vs 实际行为
修复建议
给 memoryToolState 加 enabled 标志(provider 应用时检测 SetMemoryTool 置位,如 ApplyProviderToAgent),拦截条件改为
a.memoryTool.enabled;或先查a.tools.Get("memory")命中则放行 registry 工具。对齐 tool_search 的门控形态。严重程度
medium(独立复核 sa-7 确认:触发面当前较窄+副作用 confined 在 .ggcode/memories 无安全影响;但自纠机制失效+权限快路径+未来注册埋雷+同型拦截器不一致属明确疏漏)
Co-Authored-By: ggcode noreply@ggcode.dev