过去的软件系统,核心问题是如何正确执行

我们定义数据结构、编写规则、实现算法,再通过测试、断言和 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 最值得探索的一条路。