面试知识库

M11 · 动态工具权限与阶段状态机#

简历 Bullet Point: 四阶段状态机(PLANNING→SEARCHING→COMPARING→CONCLUDING)动态收缩可用工具子集,执行层哨兵拦截越权调用而非摘工具——保住 prompt cache 前缀稳定;终结工具豁免阶段门解决”漂移检测要求收尾但阶段门拦住终结工具”的互矛盾


开场钩子#

第一轮端到端测试,模型第二轮直接调 shopping_summary——手上一条候选都没有,吐出空清单。它跳过了 planner 和 item_search,直接进了收尾。原因很简单:13 个工具摆在面前,模型觉得”用户说要推荐,我直接推荐不就行了”。

解决方案不是在代码里焊死调用顺序(那就成了 Workflow),而是做阶段状态机——每个阶段只允许调对应工具子集。


一、模块运作流程#

1.1 四阶段#

阶段允许的工具转移条件
PLANNINGplanner, category_insight, web_search, ask_userplanner 调用完成
SEARCHINGitem_search, dispatch_tool, web_search候选数量足够
COMPARINGprice_compare, shipping_calc, item_pickeritem_picker 返回
CONCLUDINGshopping_summary, chat_fallback终结工具调用

终结工具(shopping_summary / chat_fallback)豁免阶段门——任何阶段都可以调用。

1.2 拦截而非摘除#

关键设计选择:不从模型可见的工具表里移除被禁工具。摘工具改 system prompt → 破坏 prompt cache 前缀匹配。执行层 phase_check Hook 在 pre_tool_call 检查阶段权限,越权返回 sentinel 消息。

代价:模型白花一次 tool_call 解码(~50-100 token)。收益:保住 cache 命中率(miss 一次 ~11000 token)。

1.3 与漂移检测的互矛盾#

漂移检测触发”连续严重”→ 强制收尾 → 授权阶段机到 CONCLUDING → 模型调 shopping_summary。如果终结工具受阶段门约束,在 PLANNING 阶段漂移检测要求收尾但阶段门又拦住 shopping_summary → 死锁。

解法:终结工具豁免阶段门。任何时候 Agent 想收尾都不应该被拦。

1.4 回退机制#

ItemPicker 返回空 → 回退到 SEARCHING(候选不够,需要再搜)。只有这一个回退条件,其他阶段转移都是单向的。


二、面试问答#

Q1: statewright 说”缩小工具空间效果更好”,你怎么看?#

我的哨兵实现了等效效果——模型调 item_search 被拦后下一轮不再调,选择空间被等效缩小。区别只在”看不到”(摘工具)vs”调了被拦”(哨兵)。做过 A/B 对比:摘工具版延迟更低(65.3s vs 79.3s),但 cache 命中率不可预测。长对话场景选保 cache。

Q2: 为什么终结工具豁免阶段门?#

终结工具的作用是”Agent 想收尾了”。如果收尾被拦,Agent 就只能继续跑——可能已经跑偏了、预算已经快用完了。任何时候 Agent 想收尾都不应该被拦。

Q3: 阶段状态机会不会太严格?#

有一个”补搜闸”场景:item_picker 返回空(没有候选满足条件),需要回到 SEARCHING 补搜。如果只有单向转移,Agent 就卡在 COMPARING 阶段出不来。所以保留了这一个回退条件。


三、诚实边界#

维度做了没做
阶段控制4 阶段 + 执行层哨兵动态调整阶段工具子集
终结豁免任何阶段可收尾
A/B 对比摘工具 vs 哨兵大规模线上实验