doc-21: 面向 AI Agent 的知识工程方法论
核心问题:怎么设计一个任务,让 AI 能可靠地完成它?
核心心智模型:冷区/热区分离。 冷区(规划)投入全部认知资源理解问题,大量输入、少量输出;热区(执行)按冷区决策严格实现,少量输入、大量输出。两者对上下文窗口的需求模式完全不同,混在一轮中窗口分配必然低效——分开后每轮都能把窗口用在刀刃上。本文的所有设计(Phase/Gate、任务分解、控制单元)都服务于这个分离。
0. 建立正确预期
在学习如何设计任务之前,先建立三个基本认知:AI 能可靠做什么、你在协作中的角色、以及什么时候该介入。
0.1 能力边界 — AI 能可靠做什么
按任务规模判断工作流:
| 规模 | 特征 | 推荐工作流 | 一次性完成可靠度 |
|---|---|---|---|
| 微型 | 单函数/单修复,1 文件 | 直接指令 | 极高 |
| 小型 | 1-3 文件,无设计决策 | 直接指令 + 约束 | 高 |
| 中型 | 3-6 文件,1-2 个设计决策 | /plan → 执行 | 中(有计划则高) |
| 大型 | 6+ 文件,3+ 个设计决策 | /spec → /plan → 子代理 | 必须分解 |
按任务类型判断可靠度:
- 高可靠(一次性完成):模式化生成(CRUD/样板/类型定义)、局部推理(有明确症状的 Bug)、格式变换(重命名/迁移/i18n)、知识应用(用已知框架实现已知模式)
- 需辅助(/plan 或约束):多模块协调、有限设计选择(2-3 个已知方案)、接口与数据模型设计
- 人主导(AI 辅助但不主导):全局架构权衡、原创业务逻辑、依赖隐式上下文的决策、长链复杂调试
10 秒决策法:
Q1: 改几个文件? → 1 个:直接做 / 2-5 个:Q2 / 6+:必须 /plan + 拆分
Q2: 需要 AI 做设计决策吗? → 不需要:直接做 + 约束 / 需要:/plan
Q3: 是加东西还是改接口? → 加东西:正常流程 / 改接口:先列变更清单0.2 你的角色 — 人在协作中做什么
角色定位:你是项目经理,不是执行者也不是旁观者。 定目标、设边界、审产出、做决策——不写代码但掌控方向。
无子代理时:你 = 架构师 + 调度员 + 验收官
有子代理时:你 = 架构师 + 验收官(调度交给 Lead Agent)常见角色错位:
| 错位 | 表现 | 后果 |
|---|---|---|
| 当执行者 | 逐行指示代码怎么写 | AI 变打字机,能力浪费 |
| 当旁观者 | 丢需求就走,不审查不设 Gate | AI 写飞无人拉回 |
| 当用户 | "帮我做个 XX",无约束无边界 | 隐式假设填充,大量返工 |
底层逻辑:你在管理 AI 的认知资源分配。 通过限制输出类型(规划轮不准写代码),控制认知资源投向理解而非生成。通过提供接口契约,减少 AI 不必要的推理负担。通过拆模块,确保注意力不被稀释。"项目经理"是角色,"认知资源管理"是这个角色生效的底层机制。
0.3 介入信号 — 什么时候该打断 AI
§0.1 告诉你事前怎么判断,这里告诉你事中怎么监控:
| 信号 | 含义 | 动作 |
|---|---|---|
| 输出后半段质量明显低于前半段 | Context 漂移 | 停下来,开新会话继续 |
| 开始"赠送"你没要求的功能 | 完美主义扩散 | 明确边界,rewind |
| 改动文件数超出预期 | 粒度失控 | 回到 /plan 重新拆分 |
| 同一问题连续 2 次修不对 | 信息不足或方向错误 | 停止重试,补上下文或换思路 |
| 输出包含你不理解的设计决策 | 隐式假设填充 | 追问理由,确认或否决 |
1. 什么决定 AI 执行质量
1.1 质量方程
AI 输出质量 = 目标明确度 × 约束强度 × 粒度正确性三个因子是乘法关系,不是加法 — 任何一个为零,其他两个再高也没用:
- 目标模糊 → 约束再强也只是"正确地做错误的事"
- 约束不足 → 目标再清晰,AI 也会走意想不到的路径到达
- 粒度错误 → 目标和约束都对,但任务太大导致执行中丢失 context、太小导致看不到全局
这三个因子不完全独立。一个足够精确的目标本身就是约束("产出 auth.ts,登录返回 JWT" 既是目标也是约束)。但在设计任务时,分开思考三者能避免遗漏。
Token 不是瓶颈,清晰度才是。 一个 context 即使全是高价值信息,如果目标模糊、约束不足,AI 的输出照样发散。反过来,目标明确、约束够强,即使输入有些冗余,AI 反而能精准交付。
1.2 三个真实失败模式
以下不是理论推导,是 AI 在实际执行中确实会发生的事:
失败模式 1:Context 漂移
长会话中,即使开头有很好的目标和约束,AI 会越来越被最近几条消息驱动。到第 20 轮对话时,AI 实际在优化的是 turn 18-20 的内容,而不是 turn 1 设定的目标。不是故意的,是注意力权重的自然分布。
信号:后期输出与早期目标渐行渐远,但每步都"合理"。 对策:阶段性重新锚定目标。不是理论上应该这样,是 AI 真的会漂。
失败模式 2:隐式假设填充
用户没说的东西,AI 会用训练分布中最常见的选择来填。而且不会主动告知。比如用户说"实现一个 API 端点",没说错误处理策略,AI 会默认用 try-catch + 500,不会问"要不要用结构化错误码"。
信号:输出看起来完整,但包含用户从未要求的设计决策。 对策:约束不只是限制 AI 做什么,更是阻止 AI 在用户不知情的情况下做隐式决策。目标中的"边界"(不做什么)比"产出物"(做什么)更能约束这个倾向。
失败模式 3:完美主义扩散
当目标是"实现 X"但没说"不做 Y 和 Z"时,AI 倾向于把相关的 Y 和 Z 也做了。因为在训练数据中,"好的工程师"会考虑周全。结果是引入了用户未审查的变更。
信号:输出比预期多很多内容,"额外赠送"了没要求的功能。 对策:显式的范围边界。"做 X。不做 Y 和 Z,即使它们看起来相关。如果 Y/Z 有必要,报告为发现但不实现。"
底层机制:自回归生成惯性("写飞")
以上三个失败模式有一个共同的加剧因素:LLM 是自回归模型,每个 token 的生成依赖前序 token。一旦前几步方向偏离,后续输出会沿着错误方向自我强化,形成"逻辑惯性"。实践中表现为 AI 一旦开始生成代码就停不下来,即使方向已经偏离——称为"写飞"。这也是规划与执行必须分离(§2)的模型层面原因:在开始生成代码前先锁定方向,从根源上降低惯性偏离的风险。
1.3 控制论视角
用控制论的语言重新表述这个框架:
| 控制系统概念 | 在 AI 任务设计中的对应 |
|---|---|
| 设定值(Setpoint) | 目标声明 — AI 输出应该收敛到的位置 |
| 控制器(Controller) | 约束 + 模板 — 修正 AI 行为偏差的规则 |
| 反馈回路(Feedback) | Gate + Review Checklist — 检测偏差的机制 |
| 被控对象(Plant) | AI 模型 — 被控制的系统 |
| 扰动(Disturbance) | 训练分布默认值、context 噪音、模型随机性 |
这个类比的实用价值在于诊断:
- 输出方向偏了 → 检查设定值(目标是否足够精确)
- 输出不稳定 → 检查控制器增益(约束是否够强)
- 前期正确后期偏离 → 检查反馈频率(Gate 是否太稀疏)
- 输出收敛但到了错误位置 → 设定值本身就是错的(目标有问题)
2. 任务分解
这是最关键也最容易被忽视的一步。AI 执行质量的上限,在任务设计阶段就已经决定了。
2.1 在哪里拆
在决策边界拆,不在工作量边界拆。
不要因为"太多了"而拆任务。要在"需要人做选择"的地方拆:
✗ 按工作量拆:
"实现认证模块(估计 200 行)" → "先做前 100 行,再做后 100 行"
✓ 按决策边界拆:
"选择认证策略" → [Gate: 用户选定 JWT]
→ "设计数据模型" → [Gate: 用户确认 schema]
→ "实现认证逻辑" → [Gate: 测试通过]为什么?因为每个决策点都是 AI 可能做隐式假设的地方。在这些点设 Gate,把决策权交回给人。
2.2 沿什么维度拆
三个正交的分解维度,按不同情况选择:
纵向(阶段)— 最常用
理解需求 → 设计方案 → 实现代码 → 验证测试AI 最大的坏习惯是一步到位 — 看到需求就写代码,跳过理解和设计。纵向分解强制每个阶段独立完成。
横向(范围)— 用于并行任务
模块 A(用户认证)/ 模块 B(支付集成)/ 模块 C(通知系统)当多个模块可以独立开发时,按范围拆。每个模块是一个独立的执行单元。
维度切面(关注点)— 用于复杂单一模块
数据模型设计 → API 接口设计 → 业务逻辑实现 → 错误处理 → 测试不要让 AI 同时思考数据模型 AND 接口设计 AND 错误处理。每个维度需要不同的约束集、不同的模板、不同的审查标准。混在一起时,AI 会在维度之间跳跃,每个都浅尝辄止。
2.3 粒度校准
怎么判断一个执行单元的粒度是否正确:
太大的信号:
- 目标描述中包含"并且"(implement auth AND set up database AND...)
- 需要在单元内做 3 个以上的重大设计决策
- 输出涉及超过 5 个文件
- AI 在执行后半段的输出质量明显低于前半段(context 漂移的典型表现)
太小的信号:
- 单元的输出无法独立验证(必须和其他单元合在一起才能看结果)
- 目标/约束/Gate 的定义文字比实际工作还多(管理开销超过执行价值)
- AI 因为看不到上下文而做出不协调的局部决策
粒度正确的特征:
- 一个明确的交付物(一个文件、一个模块、一份报告)
- 1-3 个设计决策,且已被约束或已预先决定
- 输出可以用一个具体的标准验证(测试通过、格式检查通过、人工确认)
- 单个会话内可完成,不需要跨会话续作
2.4 输入-输出链
分解后的单元必须形成显式的链式关系:
单元 A 的输出 ──精确匹配──→ 单元 B 的输入常见断链模式:
| 断链 | 后果 | 修复 |
|---|---|---|
| 单元 A 输出是自由格式的文字描述 | 单元 B 需要从中"理解"并提取结构,引入解读差异 | A 的输出用模板约束成结构化格式 |
| 单元 A 输出包含未决策项标记为 TBD | 单元 B 遇到 TBD 会自行填充(隐式假设) | A 的退出条件要求零 TBD |
| 两个单元之间缺少 Gate | AI 自动进入下一阶段,跳过人工审查 | 在链接处设显式 Gate |
输入-输出链是任务分解质量的核心检验标准。 如果你画不出每个单元之间的输入-输出精确对应关系,说明分解还不够好。
3. 控制单元结构
每个执行单元是一个独立的控制单元。无论它是 Skill 中的一个 Phase、一次会话中的一个任务、还是一个子代理的工作包,都包含相同的 7 个要素:
3.1 七要素
┌─ 目标 ──────────── 做成什么样算对(产出物 + 成功标准 + 边界)
├─ 输入 ──────────── 从上游拿到什么(上一单元的输出 / 用户的原始需求)
├─ 约束 ──────────── 不能怎么做(红线 + 本阶段特有限制)
├─ 流程 ──────────── 按什么顺序做(步骤序列)
├─ 模板 ──────────── 输出长什么样(填空式格式定义)
├─ 退出条件 ────── 怎么验证做对了(可外部检验的标准)
└─ 交接物 ────────── 下游需要什么(传递给下一单元的具体产物)3.2 目标设计 — 三要素缺一不可
| 要素 | 作用 | 缺失时的后果 |
|---|---|---|
| 产出物 | 告诉 AI 交什么 | AI 不知道何时算"做完了",持续添加内容 |
| 成功标准 | 告诉 AI 做到什么程度 | AI 用训练分布中的"通常标准",可能过高或过低 |
| 边界 | 告诉 AI 不做什么 | 完美主义扩散 — AI 把相关但未要求的工作也做了 |
示例:
✗ 弱目标:"实现用户认证"
→ AI 不知道要交什么(一个文件?一个模块?一套系统?)
→ 不知道做到什么程度(要不要双因素?要不要密码强度检查?)
→ 不知道边界在哪(要不要顺便做注册和密码重置?)
✓ 强目标:
产出物:/lib/auth.ts + /app/api/auth/[...nextauth]/route.ts
成功标准:邮箱+密码登录返回 JWT,错误返回 401 统一消息
边界:不含注册、不含 OAuth、不含密码重置目标冗余是有益的。 在长流程中,每个阶段开头重复声明阶段目标。因为 AI 真的会 context 漂移 — Phase 3 执行到一半时,Phase 1 的目标已经在 context 中变"远"了。
3.3 约束设计
默认选 MUST,只在观察到过度约束信号时才降级。
| 力度 | 关键词 | 用途 |
|---|---|---|
| MUST / NEVER | 必须、禁止 | 格式、命名、安全红线、数据模型 |
| SHOULD | 应该 | 架构模式、最佳实践 — AI 可偏离但必须说明理由 |
| MAY | 可以 | 实现细节、局部决策 — AI 自行选择 |
为什么默认偏向强约束?不对称风险:过度约束的后果是输出机械化(降级可修复),约束不足的后果是输出发散(需要返工)。前者修复成本远低于后者。
约束还有一个隐藏作用:阻止隐式假设填充。 每条约束都是在说"这个决策已经做了,不需要你来决定",从而消除 AI 静默做隐式选择的空间。
约束的格式要具体到 AI 可以机械执行检查。"写清楚"不是约束,"必须包含 X、Y、Z 三个字段"是约束。
3.4 模板与流程
模板的本质:把开放式写作变成填空题。
没有模板时,AI 每次"创造性"地选择不同格式。有模板时,逐区域填充,输出格式可预期、要素不遗漏。
模板设计要求:
- 每个字段有明确含义,不留模糊的"描述"占位符
- 必填 vs 选填显式标注
- 一个好模板 = 一份结构化的验收标准
流程的本质:把自由探索变成导轨运行。
AI 的天然倾向是一步到位 — 看到需求就直接写代码。流程序列通过 Gate 约束这个倾向,强制按步骤执行。
3.5 退出条件与交接物
退出条件必须是外部可验证的,不是 AI 自判的。
✗ "需求已充分理解" — AI 自己判断"够了"不可靠
✓ "用户确认需求文档" — 外部验证
✗ "代码已完成" — AI 觉得写完了不代表对了
✓ "测试通过 + lint 零错误" — 可执行的检查交接物是退出条件的超集 — 不只是"做完了",还要明确"下游需要拿到什么"。好的交接物定义能避免输入-输出链的断裂。
3.6 Skill 文件的实例化
Skill 文件是控制单元的最典型载体。推荐结构:
# /skill-name
[一句话全局目标]
## 红线(始终生效)
[全局硬约束,~50 行]
## Phase 1: [阶段名]
**目标**:本阶段的产出物
**成功标准**:怎么判断做对了
**边界**:不做什么
### 约束
[本阶段特有的行为边界]
### 步骤
[步骤序列 + 内嵌模板]
### Gate → Phase 2
[退出条件 + 交接物]
## Phase 2: [阶段名]
[同上结构]
## 自检
[Review Checklist + Anti-pattern 列表]模板直接内嵌在 Skill 中(不在运行时 Read 外部文档),避免工具调用延迟和章节错位。300-500 行的 Skill 在 Claude Code 中完全可接受。
4. 反馈与校准
4.1 三层反馈
| 层级 | 时机 | 机制 | 作用 |
|---|---|---|---|
| 单元内 | 每个单元结束时 | Review Checklist + Anti-pattern 列表 | 在交付前拦截遗漏和偏差 |
| 单元间 | Gate 触发时 | 退出条件验证 + 输入-输出链检查 | 确保上下游衔接不断裂 |
| 跨周期 | 季度健康检查 | 约束有效性审视 | 清退过时约束、补充新约束 |
Anti-pattern 列表和 Checklist 同等重要 — 展示"看起来对但实际错"的例子,比正面规则更能防止 AI 自我合理化。
4.2 偏差诊断
当 AI 输出不符合预期时,用这张表定位原因:
| 观察到的现象 | 根因 | 调整方向 |
|---|---|---|
| 输出方向完全偏离预期 | 目标不明确或目标被 context 漂移覆盖 | 强化目标声明,增加阶段性重新锚定 |
| 格式正确但方向偏离 | 有约束无目标 — "无目标堆约束"反模式 | 先补目标声明,再审视约束 |
| 同一任务多次执行输出差异大 | 约束不足,AI 每次做不同的"合理选择" | 加强 MUST 约束,或从规则升级为模板 |
| 输出大量机械填充无实质内容 | 约束过度 | 将部分 MUST 降级为 SHOULD |
| 前半段好后半段差 | 任务粒度太大,context 漂移 | 拆分为更小的执行单元 |
| 包含大量未要求的额外内容 | 边界定义缺失,完美主义扩散 | 在目标中显式声明"不做什么" |
| 输出包含用户未决定的设计选择 | 隐式假设填充 | 补充约束覆盖该决策点 |
| 跳过中间步骤直接给结果 | 流程缺 Gate 或 Gate 条件是 AI 自判的 | 设外部可验证的 Gate |
| 不同模型输出质量差异大 | 约束依赖了特定模型的隐式能力 | 增加显式约束,减少对默认行为的依赖 |
4.3 校准节奏
- 新 Skill 上线:前 3 次使用密切观察,根据 §4.2 诊断表调整
- 季度审视:结合 doc-08 健康检查,对每条约束问"如果今天从零开始,还会加这条吗?"
- 模型升级时:重新验证约束必要性 — 新模型可能已内化某些知识,对应约束可降级或移除
5. 设计速查
5.1 任务设计检查清单
设计一个 AI 任务(Skill / 子代理工作包 / 会话任务)前,逐项确认:
- [ ] 有明确的目标声明(产出物 + 成功标准 + 边界)
- [ ] 任务粒度正确(不含 AND,≤3 个设计决策,≤5 个文件)
- [ ] 如果是多阶段任务,每个阶段有独立的目标声明
- [ ] 约束用 MUST/NEVER,不用"建议/考虑"
- [ ] 输出格式有填空式模板
- [ ] 每个阶段有外部可验证的退出条件
- [ ] 多阶段之间输入-输出链无断裂
- [ ] 末尾有 Review Checklist + Anti-pattern 列表
5.2 写作原则(速查)
| 原则 | 对比 |
|---|---|
| 具体 > 笼统 | "使用 CUID" > "选择合适的 ID 策略" |
| 约束 > 建议 | "禁止跳过测试" > "建议不要跳过测试" |
| 模板 > 规则描述 | 给四区域填空模板 > 写五段规则说明 |
| 示例 > 解释 | 一个错误码表 > 三段话解释命名规则 |
| 清单 > 叙述 | - [ ] lint 零错误 > "检查代码质量" |
| 目标/约束冗余 OK | 每个 Phase 重复目标 = 锚定强化 |
| 解释冗余浪费 | 背景说明写两遍 = 纯粹浪费 |
5.3 反模式
| 反模式 | 表现 | 修正 |
|---|---|---|
| 无目标堆约束 | 20 条 MUST,但没说成功是什么样 | 先写目标,再写约束 |
| 高密度低约束 | 全是高价值信息,但目标模糊 | 信息密度不能替代约束强度 |
| 粒度过大 | "实现整个认证模块" | 按决策边界拆分 |
| Token 焦虑 | 砍目标重复以"提高密度" | 目标冗余是锚定强化,砍解释不砍目标 |
| 人类阅读序 | 为什么→是什么→怎么做 | 目标→约束→流程→模板→清单 |
| 解释代替约束 | "状态机很重要因为..." | 用清单替代重要性论述 |
| AI 自判 Gate | "需求已充分理解"由 AI 判断 | Gate 必须外部可验证 |
6. 体系定位
6.1 与其他文档的关系
| 文档 | 关系 |
|---|---|
| doc-01 CLAUDE.md | CLAUDE.md 是全局约束层 — 始终生效的红线 |
| doc-02 Skills 体系 | Skills 是控制单元的载体 — 每个 Skill 遵循 §3 的结构 |
| doc-06 文档体系 | 文档体系定义目录结构,本文定义内容的编码方式 |
| doc-15 Prompt 工程 | Prompt 工程关注单次交互技巧,本文关注系统级任务设计 |
| doc-20 外部进化 | 外部知识引入后,按本文原则决定如何编码为控制单元 |
6.2 双版本原则
同一知识有两个版本:完整版(docs/design/,含参考级内容,给人读)和执行版(.claude/skills/,仅含控制级+约束级内容,给 AI 加载)。详细的版本管理规则见 doc-02 和 doc-06。
6.3 知识老化
约束会随模型能力提升而过时。清退信号:AI 无约束时也能稳定正确输出、约束引用的工具已 deprecated。结合 doc-08 季度健康检查,定期审视。