过去的软件系统,核心问题是如何正确执行。
我们定义数据结构、编写规则、实现算法,再通过测试、断言和 CI 验证系统是否按照预期运行。虽然传统软件同样存在监控、回归和反馈,但大多数时候,反馈主要承担的是质量保障角色:发现问题,然后由人修改系统。
LLM 的出现改变了一个重要前提。
当系统中的关键决策开始由概率模型完成时,同一个输入,即使使用相同的 Prompt、Context 和工具,也可能得到不同的结果。
这意味着,AI 系统不仅需要回答:
“系统执行得对不对?”
还需要回答:
“系统在哪些地方无法稳定地做出决定?”
我是在一次非常具体的工程问题里意识到这一点的。
一、从 208 张表开始
当时我们需要对 208 张财务报表进行表内字段角色标注。
最初的方案很直接:
208 张表
↓
Agent
↓
字段角色标注
↓
确定性检查器
很快遇到两个问题。
第一,任务串行执行,耗时过长。
第二,也是后来真正推动整个方法形成的问题:
同一个输入,Agent 的结果会发生翻转。
例如同一个字段连续运行:
Run 1 → detail
Run 2 → detail
Run 3 → group_head
Run 4 → detail
Run 5 → group_head
最开始我们自然会把它理解成一个错误:
“模型怎么又答错了?”
但当我们把同一个输入重复运行很多次后,问题的性质发生了变化。
我们发现:
翻转本身就是信息。
它说明,在当前系统提供的上下文、结构和约束下,这个输入还没有形成稳定的决策。
于是问题从:
“这一次为什么错了?”
变成了:
“系统为什么在这里无法稳定判断?”
这一步很重要。
因为它让我们第一次把 LLM 的随机性,从一个需要尽快消灭的噪声,变成了一个可以观察系统边界的信号。
二、不要急着消灭不确定性,先把不确定性暴露出来
对于一个可以重复运行的 LLM 系统,我们可以把同一输入运行 (N) 次,观察输出分布。
例如:
A A A A A A A A A A
说明这个输入非常稳定。
而:
A A B A B B A A B A
则说明这个输入处于明显的不稳定区域。
因此,多轮运行增加的并不是“更多答案”,而是一个新的系统维度:
我们开始知道系统对一个问题有多确定。
这也是“翻转”的真正价值。
翻转不是优化目标,而是系统不确定性的一个可观测投影。
但这里必须小心。
我们不能把:
Flip = 错误
简单画等号。
因为一个系统可以非常稳定地做错事。
同样,一个系统也可能在两个不同答案之间翻转,但两个答案最终产生完全相同的行为。
所以我们真正关心的不是“模型输出是否变化”,而是:
这种变化是否改变了系统的行为。
三、从语义翻转,到行为翻转
假设两次运行得到:
Run 1 → amount
Run 2 → amount_balance
语义标签发生了变化。
但如果这两个结果进入后面的确定性检查器后:
Behavior(amount)
=
Behavior(amount_balance)
最终执行路径和检查结果全部一致,那么这次翻转虽然存在,却没有造成实际的系统风险。
于是我们把翻转进一步分成两个层次:
语义发生变化
↓
行为是否发生变化?
↓
No → 无害波动
Yes → 真正值得诊断
这也推动我们加入了等价性重放。
对于一个发生翻转的字段,不再依赖 LLM 自己解释“两个值是不是等价”,而是直接把两个候选结果分别强制送入确定性引擎:
Candidate A
↓
Deterministic Consumer
↓
Behavior A
Candidate B
↓
Deterministic Consumer
↓
Behavior B
然后比较:
Behavior A == Behavior B
如果相同,这个翻转可以被视为 check-neutral variation。
如果不同,它才真正进入系统优化主线。
于是,一个原本只能靠感觉描述的现象:
“模型好像在抖。”
开始变成一个可以:
重复、重放、比较、度量
的工程问题。
四、翻转不是正确性的替代品
这也是整个方法必须建立的边界。
一个系统至少存在四种状态:
| 稳定性 | 正确性 | 含义 |
|---|---|---|
| 稳定 | 正确 | 理想状态 |
| 稳定 | 错误 | 稳定地错,属于系统性缺陷 |
| 不稳定 | 正确 | 真实歧义或无害波动 |
| 不稳定 | 错误 | 高优先级系统病灶 |
所以:
Flip 是问题发现信号,不是正确性的 Oracle。
我们的目标也绝不是机械地把 Flip Rate 降到零。
否则最简单的做法就是:
所有输入 → 永远输出 A
稳定性可以达到 100%,系统却可能彻底错误。
真正需要降低的是:
有害的不确定性。
因此,稳定性必须和确定性执行结果、检查覆盖、回归情况一起评价。
五、真正的问题开始从模型层进入系统层
当高影响翻转样本被集中起来以后,我们开始问:
为什么这里会不稳定?
这时候才发现,很多问题根本不是“模型不够聪明”。
它们来自系统本身:
- 上下文没有提供足够信息;
- Schema 无法表达某种语义;
- Role 定义边界不清;
- 结构信息没有显式建模;
- 数值证据没有进入决策;
- 工具无法提供必要证据;
- 本来可以确定的问题,却仍然交给了 LLM;
- 有些地方本身就存在真实语义歧义。
于是优化流程发生变化:
重复运行
↓
发现翻转
↓
行为重放
↓
归因
↓
提出假设
↓
修改系统
↓
离线重放
↓
再次运行
这时候,我们实际上已经不再是在“调 Prompt”。
我们是在做:
系统诊断。
六、最重要的发现:很多决定根本不应该由 Agent 做
不断处理翻转以后,我们发现一个很明确的规律:
很多看起来需要 LLM 判断的问题,其实是可以确定的。
例如:
行序可以确定层级
编号可以确定结构关系
Σ(明细)可以确定合计关系
配对关系可以由结构唯一确定
某个候选是否成立可以由公式证明
如果一个结论已经可以被确定性证据证明,那么继续把它交给 LLM,本质上是在主动把确定的问题放回概率空间。
所以我们逐渐形成了一条原则:
凡是系统已经可以确定的事情,都应该尽可能从 Agent 的决策空间中拿回来。
例如:
LLM → 提出候选
代码 → 验证证据
代码 → 做最终裁决
这不是为了削弱 Agent。
恰恰相反:
越多低价值、确定性的问题被系统接管,Agent 剩下的问题就越接近真正需要智能的部分。
七、Agent 的权利应该是动态的
一开始,一个复杂系统可能把大量决策权交给 Agent:
Agent
████████████████████████████
System
但随着系统不断运行,会逐渐发现:
结构可以证明
→ System 接管
数值可以证明
→ System 接管
规则可以证明
→ System 接管
等价关系可以证明
→ System 接管
于是边界逐渐发生变化:
Agent
██████████░░░░░░░░
System
░░░░░░░░██████████
这里真正发生的不是:
Agent 越来越弱。
而是:
Deterministic Region 与 Probabilistic Region 的边界不断重新划分。
有些问题今天还只能让 Agent 判断,明天可能已经有了足够的结构和证据,可以被代码接管。
反过来,新业务、新数据、新语义也可能让某些原本确定的规则重新进入 Pending。
因此这不是一次性的“代码接管”,而是持续的决策权迁移。
八、系统优化的目标,是让确定性边界不断收敛
所以我们后来发现,“Agent 自调优”其实不是最准确的描述。
更准确的是:
系统不断扩大自己能够确定的区域,缩小不必要的概率决策区域。
最开始:
确定性 ███████████░░░░░░
概率性 ░░░░░░░░░░░░░░░░░
经过一次系统优化:
确定性 █████████████░░░░
概率性 ░░░░░░░░░░░░░
再经过一轮:
确定性 ███████████████░░
概率性 ░░░░░░░░░░
每一次优化,都在把一些原本只能靠模型猜测的判断,迁移为:
- Schema;
- Rule;
- Validator;
- Structure;
- Numeric Proof;
- Tool;
- Deterministic Execution。
因此,系统进化并不是单纯追求:
“让 Agent 越来越强。”
而是:
“让系统越来越少地依赖 Agent 猜测。”
九、从执行,到反馈
这也改变了我对“AI 系统”的理解。
传统软件当然也有测试、监控和回归,反馈并不是 AI 时代才存在。
真正发生变化的是:
反馈不再只是系统完成之后的 QA 手段,而开始直接参与系统构建。
传统的软件迭代更接近:
人设计
↓
系统执行
↓
测试发现问题
↓
人分析
↓
人修改
而一个更成熟的 AI 系统可以逐渐形成:
System
↓
Execute
↓
Observe
↓
Evaluate
↓
Diagnose
↓
Intervene
↓
Replay
↓
System Update
↺
也就是说:
Feedback moves from the QA layer into the system construction loop.
这可能是 AI-native Software 和传统软件工程之间一个值得认真讨论的变化。
十、让 Agent 参与系统诊断,而不是让 Agent 自己给自己评分
这里很容易走进一个误区:
Agent
↓
“我刚才做得不好”
↓
再反思一次
这种方式仍然把评价交给模型自己。
更可靠的方式是:
Agent
↓
Structured Decision
↓
Deterministic Consumer
↓
Objective Feedback
↓
Flip / Diff / Pass / Fail / Coverage
↓
Diagnosis Agent
↓
System Modification
↓
Replay
↓
Accept / Reject
这里的 Agent 不负责定义最终真值。
它负责:
- 观察异常;
- 提出假设;
- 分析可能的系统缺口;
- 提出修改方案。
最终是否真的改善,由确定性执行、历史快照、Golden、回归测试等客观反馈决定。
所以:
Agent 可以参与优化,但不能拥有最终评价权。
这也是为什么“尺子”本身必须稳定。
尺子不稳,所有优化都是伪优化。
十一、因此形成了一套很朴素的优化纪律
在实际工程中,我们逐渐收敛出一套工作方式:
1. 基线采集
同一输入重复运行 (N) 轮,逐字段落盘。
单次结果永远不作为验收依据。
2. 翻转度量
统计跨轮不一致,并按照下游影响分类。
3. 行为重放
强制回放不同候选结果,验证它们是否真的改变系统行为。
4. 归因
寻找缺失的上下文、结构、规则、工具和数值证据。
5. 单变量干预
一次只改一个东西,并在实验前明确预期变化。
6. 离线重放
新规则先在历史快照上验证。
目标翻转必须下降,同时不能引入新的关键回归。
7. Golden 回归
冻结已确认的正确行为,防止优化过程中“为了稳定而稳定地错”。
8. 残余问题挂账
对于真实歧义、坏数据、无法确定的边界,不为了追求零翻转而强行裁决。
这套纪律背后的核心不是“把所有问题解决掉”,而是:
只让有证据、有收益、可验证的修改进入系统。
十二、真正值得优化的,不是“模型”,而是“系统边界”
到这里,我对 Agent 的理解开始发生了一个变化。
以前很容易把 Agent 看成系统的中心:
Prompt
↓
Agent
↙ ↓ ↘
Tool Memory Planner
但如果系统已经具备:
- 结构化状态;
- 确定性规则;
- Validator;
- Replay;
- Golden;
- Behavioral Evaluation;
- Feedback;
那么 Agent 更像是系统中的一个概率性决策组件。
它并不需要拥有整个系统的控制权。
它只需要负责:
系统目前还无法证明的事情。
这也意味着,一个成熟的 AI 系统,不一定是:
Agent 无所不能。
反而可能是:
Agent 只负责系统还无法证明的部分。
十三、这也重新定义了人的角色
传统的复杂系统里,人往往承担大量逐 Case 的工作:
人
↓
发现异常
↓
理解原因
↓
设计规则
↓
修改代码
↓
测试
↓
再观察
如果 AI 系统只是把执行环节交给 Agent,而这些工作仍然全部由人完成,那么系统只是换了一个更复杂的执行器。
反馈系统提供了另一种可能:
System
↓
自动暴露不稳定区域
↓
Agent 诊断
↓
Agent 提出假设
↓
自动实验
↓
自动验证
↓
关键边界进入人工审核
这并不意味着“AI 替代专家”。
更准确地说:
把专家逐 Case 的判断,逐步迁移成系统级的结构、约束、评价标准和治理规则。
人的角色也从:
Case-level Operator
逐渐变成:
System-level Governor
人不再需要盯着每一个结果,而是负责定义:
- 什么可以自动确定;
- 什么必须保留不确定性;
- 什么结果能够作为真值;
- 什么修改允许进入系统。
十四、但“稳定”永远不是终点
这里还有一个非常重要的边界。
系统不能为了降低翻转而强行消灭所有不确定性。
因为现实世界里一定存在:
- 真正的语义歧义;
- 信息缺失;
- 新的数据类型;
- 脏数据;
- 尚未建模的知识;
- 模型真正无法判断的问题。
因此一个成熟的系统必须允许:
Pending
并明确记录:
为什么无法决定?
缺少什么证据?
不决定会影响什么?
是否值得继续优化?
是否应该进入人工审核?
有些问题应该被解决。
有些问题应该被记录。
还有一些问题,应该承认:
系统目前不知道。
与其把“不确定地错”变成“稳定地错”,不如保留不确定性。
所以真正成熟的 AI 系统,不是消灭所有未知,而是:
清楚知道自己哪里知道,哪里不知道,以及不知道时应该怎么办。
十五、从一个工程技巧,到一种系统设计方式
回头看,这套方法最初只是为了处理 208 张表。
我们只是想:
让 Agent 跑得快一点、标得稳一点。
后来我们发现翻转。
再后来发现,有些翻转根本没有意义。
再后来发现,很多翻转其实在暴露系统设计缺口。
再后来发现,其中一些问题根本不应该继续交给 Agent。
再后来又发现:
如果系统能够把自己的状态、规则、验证器、历史快照和实验结果结构化,那么 Agent 本身也可以参与这个诊断与优化过程。
于是问题逐渐从:
“怎么把 Agent 调好?”
变成:
“怎么设计一个能自己暴露问题、验证假设并持续进化的系统?”
这可能才是今天做 AI 系统时值得重新思考的问题。
结语
传统软件的核心问题是:
如何正确执行。
AI 系统新增了一个同样重要的问题:
如何知道自己哪里不确定,以及如何利用这种不确定性改进自己。
因此,一个更成熟的 AI 系统,至少需要具备四种能力:
Observe
观察自己的行为
Evaluate
评价行为产生的确定性后果
Diagnose
定位为什么会出现问题
Evolve
利用反馈改变系统
这四件事情组合起来,才形成真正意义上的反馈闭环。
所以,我现在越来越倾向于这样理解 AI 时代的系统设计:
不是让 Agent 无所不能,而是让系统不断识别哪些事情不应该再交给 Agent。
不是把不确定性当成纯粹的噪声,而是把可观测的不稳定行为变成系统设计的信号。
不是让人不断追着问题修补,而是让系统自己暴露边界,让 Agent 参与诊断,再用确定性反馈验证每一次改变。
最终,系统的能力不只是来自它一次能执行什么。
还来自:
它能从每一次执行中获得什么反馈,以及能否把这些反馈沉淀成下一次更确定的系统。
从执行,到反馈。
从让 Agent 更强,到让系统更确定。
这可能就是 AI-native Software 最值得探索的一条路。