治理模型
前面三篇文章讲了三个使用场景:历史项目入库、日常维护、新项目初始化。这篇文章把视角拉回来,讲它们背后的治理机制:治理等级怎么选、Hook 做什么不做什么、三级文档结构怎么落点、工具链怎么配合。
治理等级
不同团队对文档治理的强度需求不同。一个两人的初创项目和一个五十人的多产品线项目,对文档一致性的要求完全不同。
AIOps 用四个等级来控制自动化程度:
| 等级 | 变更记录 | 维护提醒 | 自动提交文档 | 阻断开发 |
|---|---|---|---|---|
low | ✓ | 不提醒 | 不自动 | 不阻断 |
medium | ✓ | 温和提醒 | 不自动 | 不阻断 |
high(默认) | ✓ | 主动提醒 | 达到阈值后自动 | 不阻断 |
xhigh | ✓ | 主动提醒 | 自动 | 必要时阻断 |
怎么选
- low:适合快速原型阶段,或者文档暂不是当前优先级的项目。Hook 仍然在记录变更,只是不催促不自动处理——相当于把记录攒着,后面可以一起处理。
- medium:适合小团队、文档变更不频繁的项目。agent 会提醒"这些变更可能影响某几篇文档",但提交权在人手里。
- high:默认推荐。agent 在 pending 累积到一定阈值后,自动执行维护并提交。提交范围限定为文档和治理文件,不会把源码改动一起交。
- xhigh:适合对文档一致性要求极高的项目。pending 记录积累更快,维护触发更早,在文档未更新时可以阻止继续开发。
实际使用中,大多数项目用 high 就够了。low 和 xhigh 是两个极端,分别适合"先不管"和"必须管"的场景。
自动提交的范围
不管哪个等级,自动提交都有限制:
- 只提交
.aiops/下的文件和guides/目录 - 不自动提交源码、配置、测试的改动
- 提交信息使用
docs(aiops): 更新 <project> 知识库格式
这个限制的原因是:文档维护不应该和代码变更混在同一个自动提交里。代码提交是人控制的,文档维护是系统控制的,分开才能追溯。
Hook 机制
Hook 是连接代码活动和知识维护的桥梁。目前在 Claude Code 和 Codex 两个平台上实现了。
Hook 做什么
三个 Hook 各司其职:
| Hook | 触发时机 | 做什么 |
|---|---|---|
aiops_inject_context | 任务开始时 | 注入项目知识库上下文给 agent |
aiops_record_diff | 代码变更后 | 在 pending.md 追加变更记录 |
aiops_trigger_maintenance | 会话结束时 | 检查 pending 阈值,决定是否提醒或触发维护 |
Hook 不做什么
这个边界很重要:Hook 不改文档。它不打开 canonical 文档往里写内容,不修改 PRD,不更新架构图。
原因是 Hook 运行在受限的时机和上下文里——它能看到"文件 X 改了",但看不到"这个改动意味着认证流程从 JWT 迁移到了 OAuth"。理解语义、找到所有受影响的文档、判断怎么更新——这些需要 agent 在完整的技能流程里做。
安装方式
Hook 配置通过 CLI 的 init 命令写入平台配置文件:
- Claude Code:
.claude/settings.json - Codex:
.codex/hooks.json
写入是追加式的。已有配置存在时,只追加 AIOps 条目,不覆盖已有内容。条目已存在时跳过。配置无法解析时报错让人处理。
三级文档结构
项目级知识根仍是 .aiops/projects/<project>/,但 canonical docs 按项目、产品、微服务三级组织:
.aiops/projects/<project>/
iterations/<project-iteration>/
products/<product>/
prd/
architecture/
workflows/
specs/
adr/
services/<service>/
architecture/
specs/
workflows/
adr/
项目级文档描述项目迭代、产品范围、共同约束和交付风险。产品级文档描述产品版本、能力边界、产品内微服务划分和产品级流程。微服务级文档描述单个代码服务的接口、模型、运行形态、业务规则和验证入口。
外部上下游关系不创建独立跨域文档层。由发起调用或承载业务依赖的一方在自己的产品或微服务文档中说明调用入口、协议、责任边界、错误口径和验证路径;被调用方文档只作为接口和行为事实补充。
五类文档的写法
Canonical 层下的五类文档各管一摊。它们可以出现在项目、产品或微服务目录中,具体落点取决于事实属于哪个治理对象。
PRD(产品需求文档)
写的是为什么做——项目存在的理由、服务的用户、要解决的问题。
- 写:项目服务的用户、要解决的问题、核心功能、不做的范围
- 不写:技术实现细节、API 设计、数据库表结构
- 关联:和
specs/里的功能规格互相引用
Architecture(架构文档)
写的是系统长什么样。
- 写:系统边界、子产品关系、模块职责、依赖方向、数据流、部署形态
- 不写:单条 API 的参数细节(那是 specs 的事)、代码实现(那是代码本身的事)
- 关联:和
specs/里的接口定义、workflows/里的流程节点互相对应
Specs(技术规格)
写的是具体的技术约定。
- 写:接口、命令、配置项、数据结构、协议、任务调度规则
- 不写:设计理由(那是 adr 的事)、用户场景描述(那是 PRD 的事)
- 关联:被
architecture/引用,被workflows/调用
ADR(架构决策记录)
写的是已经做出的选择和背后的权衡。
- 写:决策背景、备选方案、选择理由、后果和限制
- 不写:待讨论的想法(放
open-questions.md)、纯技术实现细节 - 关联:被
architecture/和specs/引用
一条好的 ADR 只有几百字,但让后面接手的人(以及 agent)知道"当时为什么选了这条路"。
Workflows(工作流文档)
写的是端到端业务流程。
- 写:触发条件、参与模块、数据流转、异常路径、对应的源码和配置路径
- 不写:单个函数的执行细节(那是代码本身的事)、静态架构描述(那是 architecture 的事)
- 关联:调用
specs/中的接口,经过architecture/中的模块
五类文档的关系
PRD(为什么做)
↓ 驱动
Architecture(怎么做——结构层面)
↓ 引用
Specs(怎么做——细节层面)
↓ 记录选择
ADR(为什么这样做)
Workflows(走通什么流程)
← 经过 Architecture 的模块
← 调用 Specs 的接口
一个变更进来时,维护流程沿着这些关联找到所有受影响的文档,一起更新。
证据优先级
文档里的说法要有依据,尤其是从历史项目逆向生成的知识。依据分四个等级:
- 源码、测试、迁移脚本、配置文件、构建脚本 — 最可靠的证据。代码不会撒谎。
- 已有的 README、设计文档、接口文档 — 有用但要交叉验证。和源码冲突时以源码为准。
- 图谱工具结果(CodeGraph、Understand Anything)— 辅助定位调用关系和模块边界。
- 人的补充说明 — 有价值但需要标注来源。事后被人推翻的情况很常见。
一条底线:不能证明的内容不要写进 canonical 正文。放进 open-questions.md,标注哪些是推测、需要什么证据来确认。
迭代绑定
文档维护以项目迭代为锚点,绑定关系写在 .aiops/projects/<project>/iteration-bindings.yaml:
项目迭代 -> 产品版本 -> 微服务主分支
Agent 修改 canonical docs 前,应先读取 project.yaml 和 iteration-bindings.yaml,解析本次迭代包含的产品版本和微服务主分支。产品只定义版本,微服务只定义主分支;不定义微服务版本,也不把本地临时源码分支写入配置。
如果受影响微服务的本地源码分支与 required_branch 不一致,默认提醒人工切换源码分支或确认继续。确认后维护结果仍归属该项目迭代,不为本地临时分支创建文档版本。
工具链
CLI 在安装技能时,会同时安装三个辅助工具:
| 工具 | 版本 | 用途 |
|---|---|---|
| CodeGraph | 0.9.9 | 代码调用关系图谱,帮助定位模块依赖和影响范围 |
| Understand Anything | 2.7.6 | 通用代码理解,从源码提炼项目结构和业务概念 |
| Trellis | 0.5.19 | 任务执行和上下文注入层(辅助,不作为 canonical source) |
可以跳过工具链安装(--with none)或选择性安装(--with codegraph,trellis)。
Trellis 的定位
Trellis 在这里是一个辅助工具。明确分工:
.aiops/projects/<project>/— canonical 知识,经过确认的事实.trellis/spec/— 任务执行用的操作描述.trellis/tasks/— 任务执行记录和证据.trellis/workspace/— 会话记忆,不作为事实来源
Trellis 中要进入知识库的信息,需要经过 agent 判断和人类确认,不能直接把临时任务状态当事实。