AI Agent 防飘移:把概率的 AI,关进确定的流程

乐云一
  • 设计
  • 设计
  • AI
  • Spring
  • Agent
About 3236 wordsAbout 11 min

AI Agent 防飘移:把概率的 AI,关进确定的流程

上一篇《Agent开发Easy,But测试Max》里我吐槽了一件事:Agent 是个黑匣子,难测、会飘。

但有读者(其实是我自己扪心自问)追了一句:测出来它飘了,然后呢?

光知道它飘,治不好飘。就像体检报告告诉你血脂高,但你照样顿顿红烧肉,那这张报告除了让你焦虑,啥用没有。

所以这篇接着聊——Agent 越用越偏,到底怎么治。

结论:

别再指望"把 AI 调聪明"了。AI 是个概率系统,你调不死它的不确定性。真正的解法是——在 AI 外面套一层确定性流程,把它框死。

这篇就讲这套"框子"怎么搭。

先看清敌人:Agent 是怎么飘的

(病因上一篇讲过,这里快速复盘一下,没看过的补个课。)

最致命的现象:越用越偏

我们在 physical-ai 项目里实测,Agent 的问答准确率随会话轮次的变化是这样的:

准确率
100% ┤●
 85% ┤  ●
 70% ┤    ●        ← 整体大概在这
 55% ┤        ●    ← 聊到 20 轮,已经没法看
     └──────────────────
      第1轮  5  10  15  20+

第一轮准得像模像样,聊到第二十轮开始答非所问、调错工具、参数乱填。用户体感最差的就是这条下滑线。

三个根因(都是使用方式的锅)

顺着代码扒了一遍,根因就三个,而且全是结构性的:

根因人话类比
工具太多把几十个工具一次性全摆给 AI,让它自己挑仓库 56 件工具倒地上,让新人自己选
记忆不清理整个会话历史(旧话题、过期数据)全塞给它开会一直记着半小时前的岔题
一心三用AI 同时干"选工具 + 填参数 + 写回复"三件不确定的事边打电话边填表边写报告

注意,这三个根因,没有一个是"AI 太笨"造成的。是我们把它用错了——给了它太多自由,又没帮它清理战场。

为什么"调 prompt""打补丁"治不好

面对飘移,人的本能反应是:

  • 把提示词写到几千字,苦口婆心"千万别选错工具"
  • 哪个参数出问题,就给它塞一张"同义词对照表"
  • 出问题的地方加个 if 拦一下

这些手段,全都治标不治本。

治标(打补丁):             
─────────────────────  
提示词越写越长              
同义词表越加越多             
哪里漏风补哪里              

→ 只能堵已知的洞            
→ prompt 越长,AI 越迷    
治本(换架构):
─────────────────────
承认 AI 是概率系统
在外面套确定性流程
把 AI 压缩成"只填表单"
→ 从源头让飘移没机会发生
→ 自由度越小,跑偏率越低

补丁思路最大的问题是:你永远补不完。今天堵住"中文"这个洞,明天它给你飘个"英文";你堵了 setLanguage,它去调 setVolume。AI 的飘移是概率分布的尾巴,你堵不过来。

所以方向得反过来——不是去教 AI 别犯错,而是构造一个"它想犯都犯不了"的结构。

核心思想:用确定性,对冲概率性

一句话:

AI 不当决策者,只当受约束的执行单元。

把 AI 的职责,从"自由发挥的万事通",压缩成"在规定格子里填值的填表员"。剩下的判断、收敛、校验、兜底,全部交给确定性的工程代码

这不是我拍脑袋。这套思路是业界做商用级 AI 产品的共识:

  • 字节 Coze
  • 阿里 百炼
  • OpenAI Swarm
  • Google Dialogflow

它们做企业级 AI 产品的底层范式都一样:意图识别 + 流程编排 + 表单填充

这不是实验性想法,是被大规模商用验证过的成熟套路。

六道确定性防线

用户每说一句话,都先过六道关卡。关卡由工程代码把关(不靠 AI 自觉),跑偏在到达用户/设备之前就被拦下。

下面逐道拆。每道都讲清楚两件事:为什么需要(WHY) + 怎么做(HOW)

第 1 道 · 意图边界:问什么答什么

WHY:不声明边界,AI 会对任何问题都"硬答"。你让它管设备,它连"今天天气怎么样"都想给你扯两句设备数据,硬凑。

HOW:系统提示词里把能力边界写死——"你只会设备管理"。超出范围的问题,礼貌拒答,不允许调用设备工具去凑答案。

系统提示词(节选):
  你的能力范围:仅限【会议设备管理】(开关机、音量、信号源、语言)。
  超出范围的问题(如查天气、写代码、闲聊),直接回复:
  "这个问题我帮不上忙,我主要负责会议室设备控制。"
  绝不允许调用设备工具来回答非设备问题。

这道关治的是答非所问

第 2 道 · 意图分诊 + 工具收敛:别让它在一堆工具里挑花眼

WHY:工具越多,选错概率越高。前面说了,几十个里挑,远不如 3~5 个里挑准。

HOW:先用一次轻量分类,判定"用户到底要干嘛",再把对应业务的 3~5 个工具装给它。像医院分诊台,先领号再排队,别让病人自己满大楼乱窜。

// 伪代码
Intent intent = intentClassifier.classify(userMessage);   // "设备控制·语言切换"
List<ToolCallback> tools = toolRouter.routeByIntent(intent);
// 只给 setLanguage、resolveDeviceOrGroup 这两个工具,其余全收掉
chatClient.prompt().toolCallbacks(tools)...

工具一收敛,AI 的选择空间从 N 选 1 降到 3 选 1,选对率立竿见影。

第 3 道 · 记忆隔离:别让旧话题串台

WHY:这是"越用越偏"的元凶。 历史不清理,旧话题会持续干扰当前判断。前 15 轮在聊查统计,第 16 轮让它切个语言,它脑子里还想着统计的上下文,能不串?

HOW:每次只带与当前问题强相关的最近几轮,无关的、过期的清掉。会话再长,AI 看到的都是干净短上下文

// 伪代码:按当前意图裁剪上下文
ConversationContext ctx = dialogManager.loadContext(sessionId);
Intent cur = intentClassifier.classify(userMessage);
// 只保留和当前意图强相关的历史,无关的扔掉
List<Message> relevant = ctx.filterByIntent(cur).keepLast(5);

这道关直接把"越用越偏"那条下滑线拍平——会话长度不再影响准确率。

第 4 道 · 表单式填空:要的是精准裁剪,不是自由发挥

WHY:让 AI 自由生成参数,它会多填、少填、乱填。要的是"精准裁剪到必需字段"。

HOW:每个意图声明"我需要哪些字段",AI 只能填这些格子,缺必填项就反问用户(而不是自己瞎猜)。借助 function calling 的 schema 约束,参数被物理裁剪。

// 意图"语言切换"声明的表单
{
  "name": "setLanguage",
  "parameters": {
    "type": "object",
    "properties": {
      "deviceKey": { "type": "string" },
      "lang":      { "type": "string", "enum": ["zh_CN", "en_US"] }
    },
    "required": ["deviceKey", "lang"]
  }
}

AI 只能填这两个格子,多一个没有,少一个就回来问你。

第 5 道 · 参数质检 + 自动纠错:最后一道闸门

WHY:即使用了表单,AI 仍可能给你填个 lang: "English" 而不是协议要的 en_US。表单约束了"有哪些字段",约束不了"值对不对"。需要最后一道闸门。

HOW:参数下发前自动归一(中文/English → en_US)、校验范围(音量 999 直接拦截)。错了就把正确选项告诉 AI,触发自动重填

// 伪代码:参数归一 + 校验
String lang = normalizeLanguage(rawLang);   // "English" → "en_US"
validateRange("volume", volume, 0, 100);    // 999 → 抛异常,带正确范围提示给 AI 重填

这道关治的是参数乱填,目标是0 非法值下发

第 6 道 · 高危确认 + 兜底:最后的人肉保险丝

WHY:删除、重置这种不可逆动作,光靠前面五道还不够,必须有人工兜底;系统异常时还得能自保。

HOW:高危动作生成"红色确认按钮",用户点了才执行;飘移率超阈值时自动降级为只读模式。(本项目已经有一套 @DangerousOperation 的确认机制,这里直接复用加强。)

走一遍真实案例

光说设计不直观。拿一句话端到端走一遍。

📎 用户输入:「把会议室那台大屏切换成英文」 ⏱ 背景:这是该会话第 16 轮,前 15 轮在聊别的(查统计、发消息)。

新架构下,这句话的完整旅程

1. 用户输入:「把会议室那台大屏切换成英文」
        │
2. ┌─ 关卡① 意图边界 ──────────────────────────┐
   │ 判定:属于"设备管理"范围 → 放行            │
   └──────────────────────────────────────────┘
        │
3. ┌─ 关卡② 意图分诊 + 工具收敛 ───────────────┐
   │ 意图 = "设备控制·语言切换"                  │
   │ 只装载 2 个工具:resolveDeviceOrGroup,      │
   │                 setLanguage                │
   └──────────────────────────────────────────┘
        │
4. ┌─ 关卡③ 记忆隔离 ─────────────────────────┐
   │ 检测到新意图(前 15 轮是别的任务)           │
   │ → 清掉无关历史,只带本轮 + 用户长期偏好     │
   └──────────────────────────────────────────┘
        │
5. ┌─ AI 调用(只剩这点自由度)─────────────────┐
   │ 在 2 个工具里选 → 调 resolveDeviceOrGroup │
   │ ("会议室那台大屏")                        │
   │ 解析:唯一设备命中 → deviceKey=TEID_88FA   │
   └──────────────────────────────────────────┘
        │
6. ┌─ 关卡④ 表单填空 ─────────────────────────┐
   │ 按语言切换表单填参:                        │
   │ { deviceKey: TEID_88FA, lang: "English" } │
   │ (只这两个字段,无多余)                      │
   └──────────────────────────────────────────┘
        │
7. ┌─ 关卡⑤ 参数质检 ─────────────────────────┐
   │ "English" 自动归一为 "en_US" → 校验通过   │
   └──────────────────────────────────────────┘
        │
8. ┌─ 关卡⑥ 高危确认 + 下发 ──────────────────┐
   │ 生成红色确认按钮 → 用户点击确认            │
   │ → 下发精准指令 lang=en_US                 │
   │ ✓ 设备切换成功                            │
   └──────────────────────────────────────────┘

零跑偏、零非法值、与会话长度无关。

作为对比:旧架构下,同一句话会怎样

旧架构(自由发挥)                 新架构(流程管控)
─────────────────────             ─────────────────────
输入 + 前 15 轮历史全塞            输入先过 6 道关卡
几十个工具全摆出,自己挑           意图分诊后只给 2 个工具
可能被旧话题带偏,选了别的工具     无关历史已隔离,不受干扰
参数自由填,lang 可能是            按表单填空,只填必需字段
  "中文"/"English"/"english"      参数质检归一为 en_US
直接下发,设备不认 → 失败/异常     确认后下发,精准成功

→ 跑偏、失败、事故风险             → 精准、稳定、可控

一个关键洞察

数一数新架构里 AI 真正"自由发挥"的环节——只剩第 5 步(在 2 个工具里选)和第 6 步(填 2 个字段)。其余全是确定性工程把关。

自由度越小,跑偏概率越低。这就是"根治"的本质。

和"测试"怎么配合:一个闭环

回到上一篇的话题。这套防飘移架构,和【黑匣子对话测试工具】是配套的,不是二选一:

  • 流程管控:从源头让飘移"没机会发生"。这是预防。
  • 测试工具:持续盯着还剩多少飘移,告诉你哪一关在漏水。这是体检。
  • 测试报告反过来告诉你下一版该加固哪道关——闭环。

光有预防不体检,你不知道防线到底顶不顶用;光有体检不预防,天天看着血脂高顿顿红烧肉。两个都得有。

最后

错误的执念:  把 AI 调聪明,让它自己别犯错
正确的姿势:  把 AI 关进笼子,让它没机会犯错

这两件事看着像,其实差了一个维度的工程量。

开发 Agent Easy,但让 Agent 商用级稳定,才是真正吃功夫的地方。Spring AI 帮你把 Agent 跑起来,可没人帮你把它框住——这六道防线,得自己一砖一瓦砌。

所幸,砌防线的全是 Java 工程师的老本行:拦截器、参数校验、路由、状态机、确认流程。打败不确定性的,从来不是更强的 AI,而是更扎实的工程。


下篇预告:等【黑匣子对话测试工具】和这套防飘移架构都跑稳了,我打算把"测试 + 防飘移"两个工具的开源/落地情况一起写一篇。Agent 这摊事,开发只是入场券,质量才是护城河

Last update:
Contributors: LeYunone
Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v2.14.7