模块一-全景认知 | 第03讲:架构决策为什么不能交给 AI - 人类判断力的不可替代性
开场:如果 AI 能解释 CAP,为什么你还不能把它踢出架构评审?
有一个在团队里反复出现的「聪明误会」:某人让大模型解释 CAP、BASE、两阶段提交、Outbox 模式,模型回答得头头是道,于是得出结论——架构这件事已经可以外包给 AI 了。随后在一次关键评审里,AI 给出了一份看似均衡的方案:加缓存、加消息队列、加读写分离、再加一个搜索索引。每个单点听起来都合理,拼在一起却可能让运维复杂度、成本曲线与故障爆炸半径同步失控。
本讲要澄清一个边界:AI 擅长生产与解释模式(pattern),人类擅长在约束条件下做不可逆选择(decision)。架构决策之所以难,不在于「懂不懂名词」,而在于你是否掌握 业务上下文、组织能力与风险接受度,并愿意为结果负责。
我们会用真实世界里常见的决策类型说明 AI 为什么容易「错得自信」,并引入一个贯穿本课程工程实践的概念:概率性外壳问题——LLM 的输出本质是概率性生成,而线上系统的大部分关键属性必须确定性满足。最后,我们会把 Clean Architecture 重新表述为:在概率性执行周围构建确定性边界,并解释 CodeSentinel 为何要把人类裁决与规则门禁放在中心位置。
全局视角:AI 的能力边界不是「智商边界」,而是「责任边界」
从「问答正确」到「决策正确」:中间隔着一整条组织链
当你问 AI「什么是幂等」,它往往能答对;但当你问「我们这次改动要不要保证强一致性」,正确答案取决于:
- 业务是否能接受短暂不一致的用户体验
- 财务/合规是否要求强审计
- 团队是否能运维得住相应的基础设施
- 当前阶段是验证期还是规模化期
这些信息通常分散在产品经理、法务、财务、SRE 与业务负责人的脑子里,并不在代码仓库的上下文窗口里。因此,AI 很容易用「通用最佳实践」填补缺失上下文,而通用最佳实践在特定公司里常常是错的。
Mermaid:AI 与人类在软件生命周期中的分工(全局)
flowchart TB
subgraph AIStrong["AI 更强:高带宽模式任务"]
A1[代码生成与改写]
A2[测试样例与脚手架]
A3[文档草稿与知识摘要]
A4[静态缺陷模式识别辅助]
A5[检索增强的规范对照(在证据充分时)]
end
subgraph HumanStrong["人类更强:不可逆权衡"]
H1[业务目标与优先级]
H2[风险接受度与合规]
H3[组织协作与政治成本]
H4[长期演进与迁移策略]
H5[最终合入裁决与责任承担]
end
subgraph CodeSentinel["CodeSentinel:把分工产品化"]
C1[规则引擎:确定性门禁]
C2[LLM:语义审计(带引用与校验)]
C3[报告:证据链 + 待裁决项]
C4[看板:债务与趋势度量]
end
AIStrong --> C2
HumanStrong --> H5
C1 --> C3
C2 --> C3
C3 --> H5
C4 --> HumanStrong
Mermaid:何时用 AI、何时必须人类裁决(决策树)
flowchart TD
Start([遇到一个架构/质量问题]) --> Q1{是否有明确可执行规则?}
Q1 -->|是| R1[优先静态规则/自动化门禁]
Q1 -->|否| Q2{是否缺少关键业务上下文?}
Q2 -->|是| H1[人类补齐上下文与目标函数]
Q2 -->|否| Q3{失败后果是否高且不可逆?}
Q3 -->|是| H2[人类做权衡并留ADR证据]
Q3 -->|否| Q4{是否需要创造性探索多种方案?}
Q4 -->|是| A1[AI生成方案草案+对比表]
A1 --> H3[人类选方案并定义约束]
Q4 -->|否| A2[AI辅助实现/审计]
A2 --> R2[输出结构化findings]
R2 --> H4[人类最终裁决合入]
核心知识点:AI 擅长什么(把它用对地方)
1)模式匹配与局部重构
在明确的文件、明确的函数、明确的风格指南下,AI 能快速完成重复性高、模式清晰的工作,例如:
- 把一组类迁移到新的包结构(在规则清晰时)
- 按统一模板补全异常处理与日志字段
- 生成与接口契约一致的 stub 测试
2)代码生成与「从 0 到可运行」的加速
对原型系统、内部工具、数据管道脚本,AI 能显著缩短路径。但要注意:可运行 ≠ 可维护 ≠ 安全。
3)缺陷模式的辅助发现(在提供足够上下文时)
例如:明显的 SQL 拼接、敏感信息打印、不安全的临时文件写入。这里的关键词是 辅助:它应当作为 CodeSentinel 的一个信号源,而不是唯一真理。
4)文档化与知识压缩
把冗长讨论压缩成 ADR 草案、把复杂模块生成阅读笔记,能提升团队带宽。但要警惕 幻觉型引用:需要 RAG 与人工核对。
核心知识点:AI 不擅长什么(这些正是架构师阵地)
1)权衡分析(trade-off):不是计算题,是价值判断
典型权衡包括:
- 一致性 vs 可用性 vs 延迟
- 成本 vs 性能 vs 交付速度
- 可维护性 vs 短期功能冲刺
- 安全默认 vs 业务摩擦
AI 可以列出表格,但 无法替你回答「我们此刻更在乎什么」。
2)业务语境:同一技术选择在不同商业模式下完全相反
举例:一个内容平台与一个金融支付系统在「最终一致性容忍度」上可能截然相反。模型若缺失语境,会倾向输出「中庸方案」,而中庸往往意味着 复杂度上升但关键属性不突出。
3)长期演进规划:涉及迁移、组织节奏与学习能力
架构决策必须考虑:
- 团队是否能掌握新栈
- 是否有培训与值班体系
- 是否存在历史包袱与迁移窗口
AI 很难准确获取这些「软约束」,除非你把它们结构化写进规范库——这又回到了人类治理。
4)组织动态:谁支持、谁反对、如何推进
技术里最难的部分经常是人:推动规则落地、处理例外、协调多团队接口。这不是 LLM 的强项。
核心知识点:真实案例切片——AI 很容易「错得自信」的架构决策
说明:以下案例为教学合成,来源于常见工程模式与公开讨论中反复出现的失误类型,不指向特定公司。
案例 A:为「性能」引入分布式缓存,却扩大了一致命名空间
团队遇到读多写少瓶颈,AI 建议加 Redis 缓存。实现上却把 用户会话、权限、业务实体 混在同一 key 命名体系里,TTL 策略不一致,导致偶发 读到过期权限 的事故。架构师本应先定义:
- 缓存对象的 一致性模型
- key 规范与 失效策略
- 命中失败时的 降级路径
AI 能给代码,但很难自动推导出你们公司对「安全默认」的底线。
案例 B:微服务拆分「看起来很专业」,实际形成分布式单体
AI 按领域名词生成了多个服务,但共享数据库、共享库版本、同步链式调用一样不少。结果是:发布仍要协调、故障仍互相牵连,复杂度却上升。人类架构师需要判断拆分是否满足:
- 独立部署
- 独立扩展
- 故障隔离
- 团队边界匹配
案例 C:技术债务「先合并再重构」滚雪球
AI 倾向于给出最短路径补丁让测试通过,这在高压迭代里很受欢迎。但累积的临时方案如果没有 债务台账与偿还节奏,会在六个月后变成「无人敢动」的核心模块。债务决策需要业务参与:哪些债可以欠,哪些债不能欠。
案例 D:安全与合规的「文字正确」与「系统正确」
AI 可能生成看似完善的权限检查,但遗漏了 管理后台路径、内部接口 或 多租户隔离 的特殊规则。此类错误往往不是语法问题,而是 威胁模型 问题——威胁模型必须人类主导。
核心知识点:CAP 定理作为试金石——AI 能讲清楚,但不能替你选
CAP 的经典解释这里不重复。关键结论是:分布式系统必须在分区发生时做选择倾向,而「你的系统到底更需要 CP 还是 AP,抑或在业务细分上分别处理」取决于:
- 用户可接受的错误类型(不可用 vs 不一致)
- 数据类别的监管强度
- 是否已有成熟的冲突解决策略
AI 可以给你一份「通用建议」,但真正的架构产出应是:
- 明确分区场景下的行为
- 明确监控与告警如何证明系统处在哪种模式
- 明确回滚与数据修复预案
这正是人类架构师要把 决策写进 ADR 的原因:决策不是信息,而是承诺。
核心知识点:技术债务决策需要业务上下文,AI 默认缺失
技术债务可以分为:
- 有意识的债:为抢占窗口,明确记录利息与偿还计划
- 无意识的债:在不知不觉中腐蚀架构
AI 更容易加剧第二类:因为它优化的是 当下可运行,而不是 组织长期成本。因此 CodeSentinel 的设计里,我们会强调:
- findings 不仅指出问题,还要标注 债务类型 与 建议偿还路径
- 对「临时方案」要求附带 到期条件(例如下个季度必须重构)
核心知识点:概率性外壳问题(Probabilistic Shell)
我们可以把 LLM 视作一个 概率性执行核:在相似提示下也可能输出不同细节。工程系统的大多数关键属性却需要确定性:
- 鉴权必须确定
- 计费必须确定
- 数据完整性约束必须确定
- 关键审计日志必须确定
如果让概率性执行核直接触碰这些区域,你会得到 偶发正确、难以追责 的系统行为。解决思路不是「不用 AI」,而是:
- 把 AI 放在 明确的输入输出契约 内
- 对外部世界的作用通过 确定性网关(规则、校验、人工裁决)完成
核心知识点:Clean Architecture 的一种新表述
本课程采用的表述是:
Clean Architecture 是在概率性智能(模型)之外,为系统建立确定性边界与依赖方向,使关键规则可测试、可审计、可替换。
这意味着:
- 领域规则尽量不依赖框架
- 外部交互通过接口隔离
- 「AI 生成的实现」如果进入核心层,必须经过更严格门禁
CodeSentinel 自身也应当遵循这一原则:审核编排可以复杂,但鉴权、审计、密钥与持久化策略必须清晰可控。
代码实战:用「确定性外壳」包裹一次 LLM 调用(教学示例)
下面示例展示一个常见的反模式与改进模式对比:绝不要把 LLM 的原始输出直接当作 blocker 结论;应通过 schema 校验、证据字段与非 LLM 规则交叉验证。
反模式(不要在生产使用)
import json
def bad_review(diff_text: str, llm_client) -> dict:
raw = llm_client.complete(f"请审核以下diff并返回JSON:\n{diff_text}")
return json.loads(raw) # 可能抛异常,也可能结构不对,更可能胡编字段
改进模式:Pydantic 校验 + 严重级别策略 + 人工裁决入口
from __future__ import annotations
import json
from typing import Any
from pydantic import BaseModel, Field, ValidationError
class LLMFindingModel(BaseModel):
severity: str = Field(pattern="^(info|warn|suggested_blocker)$")
title: str
evidence: str = Field(min_length=8)
class LLMReviewPacket(BaseModel):
findings: list[LLMFindingModel]
needs_human: bool = True
class DeterministicShell:
"""
CodeSentinel 设计哲学示例:
- 模型只能输出 suggested_blocker,最终 blocker 需要规则/人工确认
- 任何解析失败都必须可观测、可重试、可降级
"""
def __init__(self, llm_complete_fn):
self._llm_complete_fn = llm_complete_fn
async def review(self, diff_text: str) -> LLMReviewPacket:
prompt = (
"你是代码审核助手。请仅输出 JSON(不要Markdown),schema如下:\n"
'{"findings":[{"severity":"info|warn|suggested_blocker",'
'"title":"...", "evidence":"必须包含定位信息,如文件路径/函数名/片段"}],'
'"needs_human":true}\n'
f"DIFF:\n{diff_text}\n"
)
raw_text: str = await self._llm_complete_fn(prompt)
try:
data: Any = json.loads(raw_text)
packet = LLMReviewPacket.model_validate(data)
except (json.JSONDecodeError, ValidationError) as exc:
# 生产环境:记录 task_id、模型版本、提示哈希;这里教学省略
return LLMReviewPacket(
findings=[
LLMFindingModel(
severity="warn",
title="LLM 输出未通过结构化校验",
evidence=f"解析/校验失败:{type(exc).__name__}",
)
],
needs_human=True,
)
# 关键:即使模型给了 suggested_blocker,也默认需要人类复核
if any(f.severity == "suggested_blocker" for f in packet.findings):
packet = packet.model_copy(update={"needs_human": True})
return packet
从这段代码你可以读出三条工程原则,它们会直接写进 CodeSentinel 的后续实现:
- 结构化输出是第一道门
- 模型的 blocker 只是建议,不是裁决
- 解析失败本身也是一个可审计事件
生产环境实战:把「人类判断力在中心」落实为平台机制
1)ADR + CodeSentinel:决策与审查要互相引用
建议在团队流程里规定:
- 影响架构红线的改动必须关联 ADR 编号或链接
- CodeSentinel 报告里出现
suggested_blocker时,PR 模板要求填写 人类结论
2)双轨发布:模型升级不应悄悄改变门禁语义
生产常见问题:换了一个模型版本,审核口径漂移。应对:
- 提示模板版本化
- 模型路由配置可回滚
- 对门禁结果做 回归集(固定 diff 样本)
3)成本与延迟:把 AI 用在「最值得语义理解」的地方
确定性规则能解决的,不要浪费 token。CodeSentinel 的推荐顺序:
- import 图 / 静态规则 / 单测
- 低成本模型初筛
- 高成本模型仅在疑似高风险且证据链不足时触发
4)数据边界:审核系统也是高敏感系统
CodeSentinel 会接触代码与评审讨论,必须:
- 最小化留存
- 脱敏与访问控制
- 审计日志记录谁触发了哪些外呼
CodeSentinel 设计哲学(本讲结论句)
CodeSentinel 不是「让 AI 当架构师」,而是 把人类架构判断流程工程化:
- 规则引擎承担确定性门禁与可重复证据
- LLM承担高带宽语义分析与草案生成
- 人类承担上下文补齐、权衡裁决与责任承担
- 看板与度量让治理从个人习惯变成组织系统
换句话说:CodeSentinel 是 AI 时代 Reviewer 工作台 的平台化。
本讲小结:记住三句话就够用了
mindmap
root((第03讲小结))
AI强处
模式与生成
文档与检索辅助
人类强处
权衡与责任
业务与组织上下文
关键概念
概率性外壳
确定性边界
CleanArch新表述
平台落点
CodeSentinel分层
suggested_blocker机制
ADR与门禁联动
思考题
- 回顾你们最近一个线上事故:如果当时让 AI 做架构选择,它更可能给哪种「中庸方案」?人类实际应该选择哪种取舍?
- 你认为哪些审核结论 永远不应 由 LLM 直接关闭(例如直接 approve)?请列出清单并说明理由。
- 如果把 CodeSentinel 接入你们 CI,你最先想固化哪三条 确定性规则?它们能否在不使用 LLM 的情况下独立运行?
下一讲预告
模块一将继续把全景认知落到工程骨架:我们将进入 CodeSentinel 项目启动与仓库治理(环境与目录结构、依赖注入雏形、最小 CI 门禁),并开始把「给 AI 立规矩」的规范文件与审核输入字段对齐,为模块二的架构基础功与模块四的 AI 审核实战打地基。
附录:建议你今天完成的 30 分钟练习
- 选一个你正在维护的模块,写一段 ADR 草案:只回答三个问题——我们为什么这样做?备选方案是什么?我们接受了哪些代价?
- 列出你团队中 3 个高频 AI 生成走捷径点(例如随意跨层 import),把它们改写成可检测的约束句子,准备未来写进 CodeSentinel 策略包。