经过了上一篇关于 Context 的讨论,一个自然的问题是:上下文构建完成之后呢?
上一篇文章的结论是,Context 构建永远不可能完美——五重约束互相冲突,完备性和最小性无法兼得。这意味着一个让人不太舒服的现实:工程决策,永远是在信息不完整的情况下做的
这听起来是个缺陷。但这正是「工程判断力」之所以存在的原因。如果每次决策之前信息都是完备的,那就不需要判断力了——按规则执行就行
在整个 AI Native 软件开发的链路中:
1 | Knowledge → Context → Decision → Specification → Execution |
Decision 是第三环。它是整个链路的价值兑现点——前面收集 Knowledge、构建 Context,全部是为了支撑这一环。如果 Decision 的判断质量低,上游的一切投入都白费了
更重要的是,Decision 可能是整个链路中最需要人的一环
四种决策
回到第一篇里提过的四个核心问题。它们其实对应了四种不同类型的工程决策:
1 | 改哪里 → Location Decision (定位决策) |
四种决策不是孤立的,它们有依存关系和先后顺序:
1 | Location → Approach → Impact → Verification |
而且这不是一条单向流水线。你在 Approach 阶段发现方案太复杂,可能回头质疑 Location——「是不是改错地方了?」你在 Impact 评估中发现影响面太大,可能推翻原来的 Approach——「这个方案风险太高,换一种改法。」
决策之间有反馈回路。 四种决策不是四个步骤,是一张网。举个例子:你在评估 Impact 时发现改退款流程要同步改五个地方——MQ 消费者、定时任务、报表、通知、对账。你回头质疑 Approach——是不是不该直接修改 refund() 方法,而是抽一个独立的退款校验服务?于是 Location 也跟着变了——不是改退款模块,而是新增一个模块。一种决策的反馈,改变了上游两个决策
拆开来看,每种决策的核心挑战不同。
1. Location Decision —— 定位决策
核心问题:改哪里?还有没有别的入口?
这个决策看似简单,但有两个容易出错的地方。
第一是入口不唯一。退款流程的入口可能不止一个——用户手动申请退款是一个入口,后台客服操作退款是另一个入口,支付回调自动退款是第三个入口。你只看到了第一个,改了,后两个还是老逻辑——上线之后行为不一致。
第二是看似相关但可能不是正主。在一个大项目里,搜索「退款」可能返回十几个模块——历史退款、退款报表、退款对账。你花时间读了三个,发现都不是要改的地方,但你已经消耗了时间和注意力。
Location Decision 错误是整个决策链中最贵的错误——因为方向错了,后面的 Approach、Impact、Verification 全部建立在错误的基础上。它的核心能力是定位精度——在最短的路径上找到所有入口,不多找,不漏找
2. Approach Decision —— 方案决策
核心问题:怎么改?直接修改还是扩展?是新增还是替换?
找到该改的地方之后,怎么改通常不只有一个选项。比如在退款流程中增加一个校验:
- 方案 A:直接在
refund()方法里加 if 判断。简单直接,但方法会越来越长。 - 方案 B:抽一个校验链(Chain of Responsibility,责任链模式),新增一个校验节点。扩展性好,但修改面大,测试覆盖要跟上
- 方案 C:在退款入口加一个 AOP 切面(不侵入主流程代码,通过配置拦截请求做前置处理),拦截后做校验。不改主流程代码,但切面里的逻辑对后来的人不直观
每个方案有各自的成本和收益。而且你通常不是在真空中决策——你是在一个已有系统的约束下决策。系统里可能已经有一套校验模式(方案 B),你选方案 A 是因为简单,但三年后会有另一个同事加校验,他还是选方案 A,然后 refund() 方法膨胀到 500 行
Approach Decision 的核心不是「哪种方案最好」,而是「在当前系统的约束下,哪种方案代价最小、最符合演进方向」
3. Impact Decision —— 影响评估决策
核心问题:改了这个,会影响谁?哪些地方需要同步修改?
这是最容易出遗漏的地方。因为影响链在代码里往往是隐形的
改了退款流程 → MQ 消费者需不需要改?定时任务需不需要改?下游的三个系统需不需要适配?报表的统计口径会不会受影响?
一个常见的错误是:只评估了直接依赖,漏掉了间接依赖。你改了 A,知道 B 依赖 A,所以改了 B。但 C 依赖 B——这个依赖关系你没有意识到
举个实际的例子。你修改了退款 Service 的一个异常处理逻辑,把异常码从 REFUND_FAILED 改成了 REFUND_REJECTED。你改了对应的单元测试,提测通过,上线。但上线后积分服务的补偿逻辑静悄悄地失效了——原来积分服务的 MQ 消费者在接收到退款失败事件时,会反查退款 Service 的这个异常码来做补偿决策。你改了异常码的值,积分服务那头的 switch-case 永远走不进对应的分支了。而这个依赖关系,藏在积分服务仓库的代码里,不在你当前仓库的任何地方
Impact Decision 的核心是完备性——在影响链上不遗漏节点。但完备性有一个天然的上限:你只能评估你知道的依赖。如果某个系统通过 Event 间接依赖你的模块,而这个 Event 的路由逻辑在你完全不熟悉的配置中心里——你大概率会漏掉它
4. Verification Decision —— 验证策略决策
核心问题:测什么?哪些场景必须覆盖?哪些可以放?
前三个决策做完之后,你需要设计验证策略。这包括:
- 需要测的正常路径
- 需要测的异常路径(边界值、异常输入)
- 需要测的回归场景(哪些旧功能必须确认没被破坏)
- 需要关注的跨系统交互点
Verification Decision 的核心是风险覆盖——在有限的测试资源下,覆盖最高风险的场景。这需要判断力:不是所有边界都值得测,但漏掉一个关键边界就会出事
这个决策特别依赖历史知识——「这个模块两年前出过 MQ 消息丢失的事故,所以回归测试需要覆盖消息异常重试的场景」。没有这段历史知识,你不会把「MQ 消息重试」标记为高优先级测试场景。还记得第二篇文章里讨论的「因果性知识」吗?知道一个校验存在,和知道它为什么存在,是不同的两件事——后者才决定了你能不能在正确的场景里意识到风险
信息永远不完整
四种决策拆完之后,一个共同的困境浮出水面:它们全部是在信息不完整的情况下做的
你不是不知道 Location Decision 可能有多个入口——你是不知道那些入口在哪里,不知道是否存在
你不是不知道 Approach Decision 应该参考历史设计原则——你是不知道那段历史是否存在、去哪找
你不是不知道 Impact Decision 需要评估间接依赖——你是不知道那些间接依赖在哪里
Context 构建的成果,决定了 Decision 的地基。但 Context 永远有缺口——所以 Decision 永远有盲区
这就引出一个很实际的问题:在知道信息不完整的情况下,怎么做决策?
可逆与不可逆
一个有用的区分是:决策的可逆性。
可逆决策:改了之后,如果出问题,可以低成本回滚。比如改一个内部私有方法的实现,对外不可见,错了再改回来就行。
不可逆决策:改了之后,很难回头。比如修改 API 的返回字段、变更数据库表结构、调整消息队列的 Event schema——一旦发布,下游系统可能已经依赖了新的行为,回滚意味着要协调多个系统一起回滚。
对于可逆决策,你可以容忍更高的不确定性——信息不够全也可以先做,错了再改。对于不可逆决策,保守是唯一合理的策略——如果对影响面不确定,停下来再补一轮 Context,比贸然动手更划算。
但这里有一个微妙的地方:判断一个决策是否可逆,本身也是一种决策。你以为是内部实现改了不影响别人,但实际上有另一个模块通过反射调了你的方法——你不知道这个依赖存在,所以你错误地把一个不可逆决策判定为可逆
这个悖论没有彻底解法,但有一个降低风险的实践:对于影响面不确定的改动,先以小范围灰度或 feature flag 的方式发布。这样即使出问题,回滚也只是一次配置变更——原来的「不可逆决策」被人工降级为「可逆决策」,用技术手段给自己多留一条退路
知道自己不知道什么
既然信息不完整是无法避免的,那一种重要的能力就不是「知道一切」,而是知道自己不知道什么。
一个好的 Decision Maker——不管是一个人还是一个 AI——在做决策时,能够同时输出三样东西:
决策:选择方案 A。
依据:基于 Context 中的 X、Y、Z 信息——方案 A 的复杂度最低,且与现有校验模式一致,影响面仅限退款模块内部。
盲区:以下信息本轮未覆盖——定时任务补偿逻辑、跨系统的 Event schema、A 团队关于退款校验的历史设计决策。如果这些盲区中有新的信息,可能导致决策变更。
第三样东西特别重要,但往往被忽略。传统的工程决策(比如技术方案评审)通常只包含前两样。但在信息不完整的常态下,标注盲区比隐藏盲区更有价值——它让后续的验证更有针对性,也让团队知道应该重点 review 什么
AI 在 Decision 中的角色
这引出了系列定位「AI 时代」的核心问题:AI 能做决策吗?
答案是:能做一部分,但不能做全部。而且不能负责
AI 能做到的:
- 生成候选方案:基于 Context 中的信息,列出可行的 Approach 选项
- 对比方案优劣:评估每个方案的复杂度、风险、与现有系统的适配性
- 检查一致性:方案 A 的 Impact 评估和 Verification 策略是否匹配?有没有遗漏的影响面?
- 标注盲区:基于 Context 的构建过程,指出哪些知识领域未覆盖
AI 做不到的:
- 业务价值判断:「为了更好的扩展性,这个 trade-off 值不值得?」这需要业务上下文,AI 不在那个语境里
- 组织约束判断:「方案 A 需要 B 团队配合,但他们这季度没有排期」——AI 不知道组织的资源约束
- 价值排序:两个影响面都需要关注,但测试资源只够覆盖一个——先测哪个?这是优先级判断,背后的逻辑是业务影响、用户规模、历史事故频率的综合权衡
更重要的是:AI 不能为决策负责。 人可以。当决策导致线上故障时,承担责任的是一个具体的人或团队,不是模型。这意味着最终的 Decision 权,必须留在人手上
AI 在 Decision 中最好的角色,不是决策者,而是决策放大器——让做决策的人,在更短的时间内看到更多的选项、更全面的风险、更清晰的盲区
写在最后
这篇文章讨论了 Decision——链路中需要人的判断力最密集的一环。
四种决策各自有不同的核心挑战:定位决策要精度,方案决策要适配,影响评估要完备,验证策略要覆盖。而它们共同面对一个困境:Context 永远不完备,决策永远在信息不完整的情况下做。
这听起来让人不安。但换个角度看,这恰恰是工程判断力不可替代的原因。如果信息永远完备、决策永远正确,那就不需要人了——自动化脚本就能做。正因为信息有缺口,才需要判断力来跨越缺口。
把决策分成可逆和不可逆、在决策时标注盲区、让 AI 辅助而非替代——这些都是在不完美条件下逼近好决策的策略。
下一个问题:Decision 做出之后,如何将它转化为 AI 可以精确执行的描述?
这就是 Specification 要解决的问题。下一篇继续。
这是 AI Native 软件开发系列的第四篇。前三篇分别讨论了软件开发管理的对象是知识、知识的六个层次、从知识到上下文的筛选。如果你有不同的理解或者实践经验,欢迎一起讨论。