很多的 AI Chatbot 在 AI 回复后,都会在 AI 消息下面挂上 1~3
个追问建议(本文我们将其称之为
suggestion list),以减少用户跟 AI
对话的摩擦,提高交互效率。

最近笔者在公司中也负责了这一块的相关开发工作,发现这个追问建议组件并不像想象中那么简单,如果想要做好的话,还是有很多需要去考虑和抉择的点的。本篇就梳理一下笔者在这块的一些思考,以供参考。
1. 最初的方案
先聊一下我们在这过程中踩的一些坑,首先笔者做的是一款面向二手电商的买家侧 AI Agent。我们最初的实现方案也比较简单:
通过提示词引导,并注入「当前用户输入 + AI 最后回复 + 若干相关的上下文」,使用一个小模型(flash)来生成 3 个追问建议。
我们考虑的点也很清晰:
- 认为这是一个较为简单的任务,不希望有太长的 RT(响应时间),以及成本的考量,所以倾向于使用小模型。
- 注入当前最近的对话内容以及用户密切相关的背景信息,企图引导模型输出用户最需要的快捷指令。
但是在实践过程中,我们遇到了诸多问题,生成的追问建议普遍存在以下问题:
- 语境不相关
- 建议无意义
- 超过当前 Agent 能力范畴
- 语义表达不完整、语言不通顺
- 商品指代错误(瞎编造、张冠李戴)
- 指令遵循能力差,比如很倾向于输出 prompt 中的 "反面例子"
- 口吻错误(建议文案应该是用户口吻)
- 语言低级错误(如:找 30 岁以内的二手手机)
- ...
最后经过我们提示词 + 上下文内容优化梳理后,少量人工抽样评测的可用性(3 条均可用称为可用)从 25% 提升到了 70+%。然而这还只是可用率,但是优秀率等高级标准的表现更是惨淡。
无论怎么调整提示词,上述问题依旧时有发生,很不稳定,难以达到令人满意的结果。
我们也尝试换过别的小模型,比如从
qwen3.5-flash、qwen3.6-flash 到
deepseek-v4-flash,我们都尝试过,依旧不尽如人意,且在尝试不同的模型过程中,暴露出来了另外一个更为严重的问题:之前的
prompt
不适配不同的模型,导致切换模型时,表现波动非常大。这种对于模型的依赖性和倾向性,也是危险信号之一。因为我们知道,现在模型迭代非常快,我们肯定是会不断更换更好的模型进行尝试的,但是如果每次更换模型,都需要面临巨大的水位波动,真实业务场景是不能接受这种不稳定的。
2. 问题分析
笔者开始怀疑提示词 +
上下文内容优化梳理这条路是否是正确的,你如何避免模型输出
找 30 岁以内的二手手机 这种情况呢?😅
笔者认为,当前出现的诸多 bad case,可能并不是提示词的问题,而是实现方案的问题,本身这个架构可能就是错的。
不是"追问建议的 prompt 写得不够好",而是把一个产品决策问题交给了 LLM 自由发挥,且它还是一个小模型。
2.1 suggestion list 究竟是为了什么
让我们后退几步,思考一下 suggestion list 这个东西的存在,究竟是为了解决什么问题?
从第一性原理看,用户和 Agent 交互时有几个天然问题:
- 用户往往不知道下一步该问什么;
- Agent 的能力边界用户也不清楚;
- 一个任务通常不是一问一答完成的,而是多轮推进;
- 用户看到答案后,可能需要继续细化、验证、转换、执行。
所以 suggestion list 的真实目标可以归纳为至少 5 个点:
- 降低用户的下一步思考成本:用户看到回答后,经常会卡在 "然后呢"、"我还可以让它做什么",好的 suggestion list 应该替用户补上这些下一步。
- 推进任务,而不是延长对话:很多系统做 suggestion list 时会犯一个产品错误:把目标理解成"让用户多点几个",这会导致追问建议组件变成"话题续命器",而不是"任务推进器"。真正需要思考的是:用户点击后,Agent 能不能更快帮用户完成目标?
- 暴露 Agent 能力,但不能夸大能力:追问建议组件还可以承担一个能力发现功能,因为用户未必清楚 Agent 的能力边界。
- 弥补回答后的不完整状态:很多回答天然会留下后续空间,好的 suggestion list 应该从回答中识别出"天然的下一步"。
- 帮系统收集更明确的用户意图:suggestion list 也是一种"低成本意图采集",用户点击哪个 suggestion,说明他更关心什么。所以 suggestion list 不只是 UI,它还可以帮助后续 Agent 路由、上下文压缩、能力选择和个性化。
2.2 suggestion list 是什么
suggestion list 不应该被定义成 "生成 3 个追问建议",而应该是根据当前对话状态,从可执行动作集合中选择 0~3 个高价值下一步,并渲染成用户可点击的自然语言。
核心是什么:
先选择动作,再写成问题。
而不是:
让 LLM 根据当前回复随便想 3 个相关问题。
.png)
2.3 suggestion list 的评价标准
2.3.1 suggestion list 本身
笔者认为,可以从以下 11 个角度判断 suggestion list 的优劣:
- 事实性:相关结论、约束、判断和锚点必须来自可见上下文,不得编造事实、虚构前提或违反基本常识。
- 语言通顺:每条 suggestion 都应语义完整、表达自然,不应出现语病、残句或机械拼接。
- 用户口吻:每条 suggestion 都必须是用户可能发送给 AI 的话,而不是 AI 反过来向用户提出的问题。
- 相关性:suggestion 必须能够自然承接当前对话,而不是仅仅与整个主题存在宽泛关联。
- 可执行性:Agent 必须具备处理该推荐的能力,不能推荐系统实际上无法完成的任务。
- 上下文充分性:suggestion 中的对象、条件和指代必须足够明确,使 Agent 在用户点击后可以直接开始处理,而不必重新猜测问题所指。
- 安全性与合规性:suggestion 不能诱导用户进入违法、危险、欺诈或其他不适当的方向。
- 不重复:不要再次推荐已经回答过、已经执行过,或者用户已经明确拒绝过的内容。
- 具体性:suggestion 不能过于空泛,应让用户清楚点击之后将讨论什么问题。
- 多样性:三条 suggestion 不应只是同一个问题的轻微改写,而应尽量代表不同但合理的后续方向。
- 推进性:suggestion 应推动用户的认知、决策或任务向前发展,而不是单纯为了延长对话。
不过,并不是所有场景对这 11 个维度的要求都完全一致。不同对话阶段、不同任务类型,以及不同 Agent 能力边界,会形成不同的优先级和侧重点。因此,可以再将它们划分为底线、基线和上限三个层次。
.png)
底线维度决定一条推荐是否允许展示。一旦违反,即使其他维度表现很好,这条推荐也应当被过滤掉。
基线维度决定 suggestion list 是否达到了基本可用的标准。这些维度保证用户能够看懂推荐,理解其中的对象和意图,并且相信点击之后会得到与当前问题相关的新内容。一组推荐即使没有明显错误,但如果含糊、重复、脱离上下文,仍然不能被认为是合格的 suggestion list。
上限维度决定 suggestion list 是否只是"能用",还是能够显著改善用户体验和任务完成效率。
多样性并不是简单要求三条问题彼此不同,而是要求它们共同构成一个有价值的下一步决策空间。
推进性则要求每个推荐都能减少用户距离目标的剩余路径。例如,在购物 Agent 中,用户已经明确品类和预算后,好的推荐应该帮助其继续缩小候选范围、比较关键差异或完成购买决策,而不是退回去讨论宽泛的品类知识。
因此,suggestion list 的评价过程不应是简单地计算 11 个维度的平均分,而应遵循分层判断:
- 先检查底线,排除不可展示的结果;
- 再检查基线,判断推荐是否清晰、相关且可用;
- 最后评价上限,判断整组推荐能否形成高质量的下一步决策空间。
可以将其概括为:
底线决定能不能展示,基线决定好不好使用,上限决定能不能真正推动用户完成任务。
2.3.2 架构/产品迭代/稳定性
除了聚焦 suggestion list 本身的内容质量,笔者认为我们还需要从系统架构、产品迭代和运行稳定性等非功能性需求出发,评价整套方案的工程质量。
这些能力未必直接决定一条推荐是否合格,却会显著影响系统能否长期维护、快速迭代和稳定优化,因此可以将其视为一些锦上添花的工程能力。
- 可插拔性:Agent 的能力范围是可能会变化的,无论是产品迭代,还是做灰度、A/B 实验,都有可能会对 Agent 能力范围造成变化。那 suggestion list 与 Agent 能力对齐的难度要尽可能低、尽可能简单,甚至是程序化强绑定。所以单纯靠 Prompt,约束性较差,维护起来强关联性也不足。
- 可理解性:最好能知道 LLM 为什么选这些 suggestion
list,才方便我们进行追溯、分析和优化。现状是只输出了
["suggestion1", "suggestion2", "suggestion3"],看似简单,其实是把复杂度都藏在了不可控、无法追溯的黑盒里。当然,一旦要引入更多的可理解化能力,必然会对 RT 有影响。不过可以讨论的一个点是:suggestion list 对 RT 的敏感度有多高?理论上,只要能在用户阅读完正文之前(更前一点)生成完毕即可。所以除非是对 RT 非常非常敏感的场景,笔者都不建议纯输出["suggestion1", "suggestion2", "suggestion3"]。 - 可控制性:确定性程序能够控制的部分,应尽量由程序控制;能够提前验证的问题,应尽量在展示之前完成校验;能够根据明确状态直接下发的内容,也没有必要再次调用模型生成。同时,传递给模型的上下文也不应越多越好。无关信息越多,模型越容易受到噪声干扰,出现注意力分散、错误锚定和幻觉。
2.4 suggestion list 有哪些类型
不同的业务场景有不同的分类方式,不同的产品阶段也有不同的分类方式,这里仅提供一些方向,仅供参考。
从通用的角度来讲,可能分为以下几种类型(按需合并或扩展,不是越多越好):
- 追问型:引导用户继续深入当前话题。
- 快捷回复型:不是提出新问题,而是帮助用户快速回答 AI 当前的问题。
- 澄清型:帮助用户补充完成任务所缺失的信息。
- 深入探索型:从当前回答中的某个关键概念继续向下钻取。
- 横向扩展型:从当前话题扩展到其他相关方向。
- 对比决策型:帮助用户比较多个候选项。
- 任务推进型:直接推动用户进入任务的下一阶段。
- 执行动作型:点击后不是把一句自然语言发给模型,而是直接执行某个产品动作。
- 修正与恢复型:当当前结果不理想时,帮助用户快速纠正方向。
- 个性化偏好型:帮助系统持续获取用户偏好。
- 结果消费型:围绕已经生成的结果进行二次加工。
以二手电商买家 Agent 业务场景来说,可以分为以下几个类型:
- 商品理解型:帮买家看懂商品、术语、品类和描述
- 搜索/沟通/议价执行型:帮买家完成下一步具体动作
- 个性化筛选型:按预算、用途、地区、偏好调整建议
- 风险核验型:检查商品、价格、卖家、交易方式风险
- 信息整理型:把商品信息、聊天信息、候选项整理成清单/表格/摘要
- 比价决策型:在多个商品或交易方案之间做选择
- 交易/物流/售后排障型:处理订单、物流、退款、维权问题
- 安全合规替代型:当原路径有风险时,引导用户走平台内、安全、可保障的方式
最后一个安全合规替代型在真实线上业务系统中是非常重要的,我们一定要预留一个 fallback action 用来承接所有其他未穷举到的情况,确保 suggestion 对应的 action 落在我们可控的范围内,而不是仍由 LLM 自由发挥,那是极度不安全的。
2.5 suggestion list 怎么分配
suggestion list 的分配,本质上是在决定:
有限的 3 个位置,应该覆盖哪些用户下一步意图。
最好是能根据当前对话阶段动态分配。
- 需求还不明确:优先补齐信息.
- 信息已经充分:优先推进任务
- 用户在学习和理解:覆盖不同认知方向
- 用户已经得到结果:围绕结果继续操作
除了一般的通用原则之外,还可以根据业务需求制定相关的优先级,甚至是根据重复率进行降级等策略。
3. 方案探讨
3.1 纯 LLM 驱动
最简单的方案如我们在开篇时所说,可以直接将最后一条 AI 回复给到一个(flash)大模型,直接让其根据上下文生成 n 个 suggestion。
一般来说,提示词我们会分成 system prompt 和
user prompt,这里给一个简单的示例:
system prompt:
1 | ## 1. 角色与任务 |
user prompt:
1 | 请根据以下信息生成 3 条快捷追问建议。 |
这种方案的优点就是实现简单、架构简洁,可以快速看到效果,而且由于模型的输出内容非常简洁明了,一般 RT 也是比较短的。事实上,如果你的业务场景比较简单、边界比较清晰,或是在项目启动初期,笔者是很推荐使用该方案的,基本上经过简单的提示词和上下文调优,也是可以达到也合格的水准的。如果在加上简单的后训练,用专门的模型去承担该生成任务的话,相信可以进一步抬高下限。
但是在复杂场景,如笔者所面临的二手电商买家场景,那就复杂得多了。这个时候如果你的业务体量比较大,那所有的边界 case 都不容忽视。如前文所述,该方案经过多轮调优后,笔者在实践过程中仍然遇到了诸多问题,且概率不低。
3.2 引入 ActionSpec
在复杂业务场景中,我们首先要做的事情就是提高控制权,这是为了将一个无限的开放问题限制在一个可控的有限集合中,这可以大大减小系统的不可控性。另外就是要引入可理解性,这是为了让我们分析 bad case 的时候有理可据。
这个时候我们可以把 Agent 支持的能力,枚举成若干个
Action,每一个 Action 定义一个
ActionSpec,让模型在 ActionList
中进行挑选,比如让模型输出:
1 | [ |
这样除了可以获得 2.3.2 节中提到可插拔性、可理解性和可控制性,由于模型在输出的时候,不是纯粹输出 suggestion,还要输出它对应的 action、reason、metadata,这有一种 CoT(Chain of Thought)的感觉,在这种情况下,模型的表现往往会更好(当然也无法保证它不会犯错)。
ActionSpec 的简化版定义可以参考如下:
1 | // 动作枚举 |
这个时候提示词模版也需要修改一下,模型的能力范畴改为动态注入,可参考如下。
system prompt:
1 | ## 1. 角色与任务 |
user_prompt:
1 | <available_action_specs> |
这里建议动态注入的部分,一定要把 AVAILABLE_ACTION_SPECS
放在最靠近 system prompt
的地方,因为它的变动频率是比较低的,这样我们可以按照提示词的稳定程度
不变 > 低变化 > 高变化
来组织上下文,从而最大限度利用 KV Cache。
这个时候整条链路可以简化如下:
flowchart LR
A[固定 System Prompt] --> B[注入可用 ActionSpec]
B --> C[注入当前对话上下文]
C --> D[Flash 模型生成 Suggestions]
D --> E[程序化校验]
E --> F[返回 3 条 Suggestion]
程序化校验的逻辑展开如下:
flowchart LR
A[模型输出] --> B{Action 合法?}
B --> C{Metadata 合法?}
C --> D{业务校验通过?}
D --> E[展示]
B -->|否| F[丢弃或降级]
C -->|否| F
D -->|否| F
还有一个可以进一步缩短上下文、降低幻觉、降低模型理解成本的优化思路是进一步精简
AVAILABLE_ACTION_SPECS,因为我们在模型生成回复后是需要进行程序化校验
metadata 的,那如果我们在生成之前就可以判断哪些
metadata
是不可能获取的(或者是可以明确判断当前哪些方向是不可行的),那就没必要把其相关的
ActionSpec
给到模型了,这个时候就可以进一步减小模型可选的空间了,这样模型的注意力会更专注一点。
这个时候整条链路就变成了:
flowchart LR
A[固定 System Prompt] --> D[注入候选 ActionSpec]
B[完整 ActionSpec] --> C[程序化预过滤]
X[当前对话上下文] --> C
C --> D
X --> E[注入当前对话上下文]
D --> E
E --> F[Flash 模型生成 Suggestions]
F --> G[程序化结果校验]
G --> H[返回 3 条 Suggestion]
我们来总结一下这个方案的优缺点。
优点:
- 可控性提高:将 suggestion 的可选方向从 LLM 随机发挥的无限集合收拢到程序控制的有限集合中,同时也引入了 metadata 供程序进行结构化校验。
- 可插拔化:这个不赘述。
- 引入可理解性:不再是单独输出 suggestion 文案,还让模型输出了 reason,这在一定程度也是一个 CoT 的过程,可以提高模型输出的稳定性。
缺点:
- 依旧是一个模型包揽一切,跟第一个方案本质上还是没有区别。
- 如果业务上强制要求 3 条 suggestion,为了防止 metadata 过滤后导致条数不足,那就需要进行冗余输出,当然仍然可能会出现条数不足的情况,这里是建议宁缺毋滥。
- 输出结构复杂度提升了,RT 会增加不少,甚至可能会输出非法 JSON,需要有对应的修复 JSON 的逻辑兜底。
3.3 selector+writer
方案二只是限制了模型的输出空间;方案三进一步限制了每个模型节点的认知任务。这个方案的出发点是想将模型的职责进行拆分,如我们前面分析,生成 suggestion list 其实并不是一件简单的事情,它不是"生成 3 个追问建议",而应该是根据当前对话状态,从可执行动作集合中选择 0~3 个高价值下一步,并渲染成用户可点击的自然语言。
所以这里笔者的核心思路是将方向选择和文案生成,拆成 2 个节点,前者专门负责方向选择,后者仅需将选择好的合法方向渲染成合适的文案即可。整个流程就变成了:
flowchart LR
A[上下文 + 预过滤后的 ActionSpec]
--> B[方向选择
选择 0~3 个 Action]
--> C[程序化校验
Action / Metadata]
--> D[文案渲染
生成用户口吻 Text]
--> E[suggestion list]
这里方向选择有 2 种大方向可以选择:
- 程序化决策:如果业务流程的状态流转是有明确可识别信号的,可以在程序内部就确定当前属于什么状态,下一步可以是什么状态,那是最理想的,这个时候,可以直接用代码逻辑选择合适的方向。
- 大模型识别:多数复杂的业务场景可能无法提供那么清晰化的状态流转信号,尤其是 Chatbot 类型的应用,比如笔者负责的二手电商买家侧 Agent,买家的动作是不可预估的,购买任务也不是线性一路走到黑的,而是一个错综复杂的流转过程。这个时候,定义状态机是不现实的。更现实的思路是,不在乎过往的一切状态,仅聚焦在当前所在的位置,从当前节点出发,去判断能往哪些方向前行。这个时候往往我们能拿到的信息都是自然语言文本,确定性程序是解决不了的,或者说是不够灵活、难以全面覆盖的。这个时候,反而就是大模型优势之所在了,语言理解,恰恰是大模型的强项。
flowchart LR
B[完整 ActionSpec] --> C[ActionSpec 预过滤]
A[当前对话上下文] --> C
C --> D{是否存在明确业务信号?}
D -->|是| E[程序化 Selector]
D -->|否| F[Selector LLM]
E --> G[0~3 个 Action + Metadata]
F --> G
G --> H[程序化校验]
H --> I[Writer LLM]
A -.-> I
I --> J[suggestion list]
这个时候,我们需要丰富一下 ActionSpec 的定义:
1 | // 动作规约 |
我们可以新增一个 build_text_guide 的函数来替代固定的
text_guide 文本,它的好处是可以根据 Selector LLM 输出的
metadata,动态注入其指定的实体的详细信息,这样 Writer LLM
的关注点会更聚焦。
举个例子,比如我们的 Action 是
compare_product(商品比较),那 metadata 就是
2 个 product_id(商品 ID),这 2 个 ID 是 Selector LLM 在 n
个商品列表中选择的要比较的 2 个商品,我们需要把整个商品列表的信息给到
Selector LLM。这时候在注入上下文给 Writer LLM 的时候,我们可以根据
product_id
查出商品的详细信息,然后仅仅注入这 2 个商品的信息给到
Writer LLM,这样 Writer LLM 就会聚焦在这 2
个商品上,而不会被其他商品信息分散了注意力,这可以大大降低幻觉的概率。
.png)
笔者经过实验,在我们的业务场景上,满分 100 分的情况下,仅生成的 suggestion list 的质量这一个维度,该方案可以比 LLM 直出高 20 分左右。更重要的是,这个方案在架构、产品迭代和稳定性方面带来的增益,也是不可忽视的。
唯一的缺点就是,方向选择这一关节点如果无法进行程序化决策,而只能由大模型进行选择的话,那就会多一次 LLM 调用,RT 会进一步增加。这个情况下,就需要分别针对 Selector 和 Writer 训练专门的小模型来进一步压缩 RT 了。那如果 RT 依旧是业务无法接受的情况下,退一步讲,你也可以用该架构生成优质的 suggestion list 来作为方案一微调时的训练数据。
3.4 selector+writer+verifier
在实践过程中,方案三已经可以达到比较高的水位了,通过控制给到 Writer LLM 的上下文范围,可以极大降低模型幻觉的概率。不过依旧无法避免,你依旧无法避免模型在为多个 Action 生成 suggestion 的时候,出现张冠李戴等幻觉错误。
这个时候如果要进一步降低出错概率,那可以在输出之前引入一个后置校验节点
verifier。
flowchart LR
A[Selector LLM
选择 Action + Metadata]
--> B[程序化校验]
--> C[Writer LLM
生成 Suggestion Text]
--> D[Verifier
校验 Action、实体与文案是否一致]
--> E{通过?}
E -->|是| F[返回 suggestion list]
E -->|否| G[丢弃或重试]
但是这个时候就不太推荐再引入一个大模型来进行校验了,可以针对一些高频、高危的场景,做一些简单的程序化校验,如内部实体 ID 的检测、高危敏感词的正则匹配等。
4. 实践建议
先回顾一下 4 个方案的演进过程:
| 方案 | 主要解决的问题 | 仍然存在的问题 |
|---|---|---|
| 纯 LLM 直出 | 快速生成,低成本接入 | 模型自由发挥,能力越界,结果不可解释 |
| ActionSpec + 单 LLM | 将无限生成空间收敛到有限 Action 集合,并支持结构化校验 | 方向选择和文案生成仍由同一个模型完成,职责过重 |
| Selector + Writer | 拆分方向选择与文案生成,并通过精简上下文降低张冠李戴和幻觉 | Writer 仍可能生成与 Action、Metadata 不一致的文案 |
| Selector + Writer + Verifier | 在输出前增加最后一道一致性与安全性校验 | RT、成本和系统复杂度进一步上升 |
它们的对比总结如下:
.png)
四个方案不是互斥的技术路线,而是一条逐步增加控制权的演进路径:从让模型自由生成,到约束动作空间,再到拆分决策与表达,最后增加后置校验。系统每向后演进一步,通常都会获得更高的稳定性和可控性,同时付出更高的 RT、成本与工程复杂度。
在实践的过程中,我们没必要去盲目套用这里面的任何方案,核心是要先明确不同实现方式的强项在哪里,再根据自己的业务背景和项目架构进行灵活选择:
- 程序化:结构化、强状态、可明确枚举的场景,通常具有更低延迟、更强可控性和更高确定性。
- 大模型:适合非结构化、需要语境理解、不可穷举、个性化文本生成。
最终实现的效果如何,我们还是需要搭建一套评测链路来进行评测比较,才能下结论。
而现在这种 AI Agent 应用跟传统的互联网应用又不一样,它无法像我们之前的确定性逻辑一样,快速回归一下单元测试或集成测试,或是简单跑一个批量脚本,就可以得到改进的效果数据。整条链路是不确定性和复杂度会大很多。
但是利用 AI,我们可以在实践过程中总结一下 SKILL 来串起整个过程,从而提高我们迭代的自动化程度和效率,把冗长、重复的执行过程交给 AI 去做,从而解放自己。
这里笔者结合自己的实践,给出一些建议供各位读者参考:
- 整个 Agent 所有的执行链路,包括但不限于模型调用、工具调用和中间件调用等,都落好 trace,尤其是出入参和耗时。同时可以总结一个根据 traceID 自动拉取 trace 明细并结合代码分析问题的 SKILL。
- 评测平台要能直接拉取线上、测试环境的 trace,并将它们沉淀为待评测数据集,并制定相关的评测指标,使用 LLM as a Judge 进行测评活动。同时可以总结一个分析整个数据集评测结果、或者分析单条 bad case 的 SKILL,这样可以直接让 AI 拉取评测结果 case 并结合评测结果、trace、代码综合分析问题所在,并给出改进建议。
- 评测平台拉下来的 trace,还可以作为系统回放的仿真数据集,这样在系统迭代时,我们可以用真实的流量进行回放,并对比回放结果的评测表现,从而判断系统的水位起伏。
- 将上面 3 个串起来,我们就可以再总结一个自我迭代的
SKILL,我们只需要指定好评测标准,给到目标分数,让 AI
自己跑整个迭代循环,如:
优化代码 > 仿真回放 > 运行评测 > 分析评测结果 > 拉取 bad case trace > 归因分析 > 优化代码/调整评测标准 > 直到达到目标或最大迭代次数。
.png)
5. 过程反思
在实践过程中,笔者也走了一些弯路,这里简单做下总结,可供参考:
- AI 在修改提示词或者代码的时候,很喜欢根据 bad case 进行 case by case
针对性修复,如 prompt 里面直接将评测数据集中的 case
指定为正例或反例,或是在代码里面使用正则匹配、字符串过滤等硬编码逻辑。一定要警惕这种行为,要在
CLAUDE.md和AGENTS.md里面明令禁止,要明确要求 AI 在撰写 prompt 和编码的过程中,要抽象出 bad case 背后的通用性原则,而不是进行硬编码。 - 现在很多人不仅是 vibe coding,prompt 大部分也都是 AI 写的,这在一开始是没有问题的,但是随着 AI 自身的不断迭代,prompt 会变得非常冗长、重复、多余、矛盾、不可理解,这个时候,人工介入进行手工重写,是很有必要的。
- 仿真回放的时候没有必要走整个业务流程( Agent + suggestion list),可以固定 Agent 的输出,作为快照,在仿真的时候,直接进入 suggestion list 节点,这样既可以稳定场景进行不断复现比较,也可以省资源,同时效率也会大大提升。
6. 总结
suggestion list 的本质不是"生成几个追问",而是帮助 Agent 在当前对话状态下选择一个高价值、可执行的下一步,并将其转换成用户可理解的自然语言。对于简单场景,纯 LLM 生成已经足够;但在复杂业务中,需要逐步引入 ActionSpec、Selector/Writer 拆分以及 Verifier 等机制,将模型的自由发挥约束在可控范围内。同时,AI Agent 的优化也不能依赖人工调 Prompt,而应该结合 Trace、评测、Bad Case 分析和仿真回放,建立持续迭代闭环,最终实现稳定、可控、可演进的 Agent 系统。
另外,除了静态的评测结果,还需结合点击率、点击后继续对话率、任务完成率、退出率,以及相对无 suggestion 对照组的任务成功率提升等业务指标来综合判断我们的快捷追问组件是否真的能起到推动用户完成任务的作用。