资产配置研发团队 ai-repo 的 Context / Rule / Agent 三层约束实践
作者:朱锦 团队:资产配置研发团队
团队引入大模型编码工具后,普遍会遇到"个人提效明显、团队提效失效"的现象。本文的观点是:这道坎的本质不是模型能力不足,而是团队无法向模型稳定供给可核验的上下文——事实、判据和边界三者都缺。而且模型能力越强,缺口越危险,因为它会用最合理的猜测填补空白,且不告诉你那是猜的。
资产配置 3.0 研发团队用近一年时间,把这件事当作工程问题来做:建立专用仓库 ai-repo,沿 Context(供给事实)、Rule(供给判据)、Agent(供给边界)三层构建约束系统。截至 2026 年 8 月,仓库累计 1468 次提交、12829 个纳管文件。
本文不介绍目录结构,而是讲三件事:为什么必须这样设计、我们做错过什么、代价是什么。文中数据均可在仓库直接核对,不含推算的收益比例;最后一节如实说明尚未解决的问题,包括最关键的一项——我们至今没有建立效能度量闭环。
先说一个具体的失败,它是后来所有设计的起点。
资产配置 3.0 是典型的金融微服务系统:外部请求经 kyp-webbff 网关分发到 WMS、FRS、FIS、PIC 等十余个后端服务,前端也按业务域拆成十余个仓库。一个"客户列表页某字段口径不对"的问题,链路要横跨前端页面、BFF、业务服务、Mapper 和数据库表。
开发同学把问题丢给模型,得到一份结构完整的分析:字段来自哪个接口、接口由哪个 Service 提供、取数逻辑是什么、建议怎么改。措辞笃定,路径具体,方法名看着都对。
问题在于其中一段是错的。那个字段在当前版本已经改由另一条链路提供,模型引用的是一段仍然存在但已不再被调用的旧代码。
值得注意的不是模型出错——这很正常。值得注意的是错误的形态:它没有说"这里我不确定",而是给出了一个与正确答案在文本上高度相似的版本。开发同学没有理由怀疑它,因为那份分析看起来比团队里任何一份文档都完整。
顺着这个失败往回追,责任并不在模型:它当时能拿到的上下文里,根本没有"这条链路当前版本由谁实现"这个事实,也没有任何机制告诉它"这里的信息是过期的"。它在信息真空里给出了最像的答案,这恰恰是它被训练出来要做的事。
结论因此很直接:要改善的不是提问方式,而是供给。
把团队里各种 AI 使用失败案例归拢,缺口有三类。
开发 A 花两小时让模型摸清一条链路,会话结束,上下文归零。第二天开发 B 问同样的问题,模型从零开始重新摸一遍,而且可能得出不同结论。更麻烦的是,即使团队有文档,也无从判断文档里哪句话是核实过的、哪句话是当年抄需求抄来的。
团队有开发手册、日志规范、SQL 脚本规范、分支流程规范,但它们分散在若干 Word 和 Excel 里,版本不一。很多条款只写了"禁止 XXX",没写为什么禁止、边界在哪、怎么检查。这类规则对人尚且难执行,对模型更是无从消费——它看不到,也无法据此判断新场景是否落在约束内。
给不同工种配不同助手是自然的想法,但如果只是各写一段几百字的提示词,很快会发现它们互相抢活:架构角色开始动手改代码,测试角色开始判断需求优先级,评审角色给出"我觉得这样不好"这种无法处置的意见。角色多了,协调成本反而上升。
基于这个判断,我们把工程投入从"优化提示词"转向"建设供给系统",并且明确了三层的分工:
| 层 | 供给什么 | 回答的问题 | 失败时的症状 |
|---|---|---|---|
| Context | 事实 | 系统当前到底是怎样的,证据在哪 | 自信的错误答案 |
| Rule | 判据 | 做到什么程度算合格,怎么检查 | 反复被提相同的评审意见 |
| Agent | 边界 | 谁在什么约束下作业,越界转给谁 | 越权动作与无法处置的结论 |
这三层的顺序不是随意的:没有事实,判据无处施加;没有判据,边界无从检验。下面按这个顺序展开。
这是投入最大、认知变化也最大的一层,因此展开最多。
最早的做法很自然:让模型读代码,把调用链梳理出来,画成流程图,配上说明,作为"业务知识"沉淀下来。产出速度很快,一周能出几十份,看起来相当可观。
然后一次重构就让大半份文档失效了。原因很简单:我们记录的根本不是业务,是实现。Controller 改名、Service 拆分、接口合并,图就废了,而业务本身一点没变。
这条教训后来被写成了知识模型里的一条硬约束:
不得把程序调用步骤直接冒充业务流程。Flow 是完整业务过程,不是 Controller、Service 方法或单个接口;Scene 是业务动作,接口只作为 Scene 的实现引用;调用链保存在
chain-index.tsv,不替代 Flow/Scene。
由此确立了知识分层:业务语义层(为什么做、谁在什么条件下做、经过哪些业务动作、产生什么结果)与实现证据层(当前版本由什么实现、证据在哪、核验到什么程度)必须分开,通过关系索引连接,而不是揉在一起。业务语义变化慢,实现证据变化快,混在一份文档里,快的那部分会拖垮慢的那部分。
第二个反复摇摆的问题是格式。写详细,人能看懂但机器难解析;写成结构化表格,机器好用但人读不下去。试图用一种格式同时满足两边,结果两边都不满意。
最终的做法是彻底分开,并用一份 schema 声明两者之间的语义:
人读视图 01-* ~ 06-* 的 Markdown 讲清设计、边界、使用、验证、排障
机器视图 90-index/ 的 27 个 TSV 保存可定位、可关联、可审核的原子事实
语义契约 90-index/knowledge-model.yaml 声明实体、关系、枚举与约束
这个分离带来一个不太直观的好处:人读部分终于可以写得像文章。因为不再承担"被程序解析"的义务,它可以专心解释背景、取舍和坑,而所有需要精确的东西都由 TSV 承载。
回到第一章那个失败——知识库要解决的核心问题不是"记得全",而是"能被质疑"。做法是每条确定性结论都挂证据 ID:
客户列表是理财经理在财富规划/客户列表下,按内部客户、外部客户、潜在客户、基金客户四类 Tab 查询客户……并支持导出的入口页面。
EVID-BA-0036
更关键的是把两个长期被混用的概念拆开。核验级别(verification_level)描述这条事实是怎么被验证的,有七档:引用、来源已核、索引命中、兜底命中、代码已验证、数据库已验证、运行态已验证、人工确认。可信度(confidence)只有高/中/低三档,描述我们对它的判断把握。模型里写了一句约束:
这两个概念混用是知识库失真最常见的路径:一份写得很确定的需求文档,会让人(和模型)默认事实已经核实过。区分开之后,读者能一眼看出"这句话是从需求抄的"还是"这句话有人跑过代码验证"。
另一条被写进模型原则的规则叫 unknown_is_not_absence。落到具体约束上:
unknown,不得写"无定制";这条规则同样约束模型:当它无法确认时,正确动作是写 unknown 并登记一条质量标记,而不是给一个看起来完整的答案。这正是对第一章失败模式的直接反制。
27 个索引全都必填,是不可能维护下去的。所以索引分成两层:
扩展层的启用条件写得很具体,满足其一就只启用对应索引,而不是全部启用。例如"已确认存在租户覆盖或定制"才启用租户差异索引;"结论只适用于特定版本或分支"才启用版本范围索引。
配套两条规定,都是踩坑之后加的:
未启用扩展层的资产,frontmatter 整组省略对应字段,不写"无"占位;变更扫描不因缺少扩展层记录判为不通过。
扩展层一经启用,即按完整约束执行,不允许只填一半。
"不写无占位"看似细节,实则关乎可信度:占位符会让文件看起来"填完了",但机器无法区分"未启用"和"确认为空"。而"要么不启用、要么完整启用",防的是另一种腐坏——半填的结构化数据比空着更糟,因为下游会误以为它可用。
知识会过期,这是知识库建设最难对付的部分。机制有三层:每份资产的 last_verified_at 时间戳、quality-flags.tsv 质量标记(当前 139 条)、stale-report.tsv 过期清单。
需要特别说明 139 条质量标记的含义。它不代表知识库质量差,恰恰相反:
举一个真实资产的头部信息——财富规划下的客户列表页:
status: draft
owner: 待确认
evidence_status: partial
confidence: medium
quality_flags: [QF-BA-0020, QF-BA-0021, QF-BA-0022]
last_verified_at: 2026-07-22
agent_entry: chain-index:CHAIN-BA-0029
这份资产坦白承认:还是草稿、负责人未定、证据只有部分、可信度中等、有三个已知未确认点。使用者据此可以决定信到什么程度,这比一份看不出成色的"完成版"有用得多。
最后一个字段 agent_entry 值得一提:它显式声明"Agent 从哪个索引条目进入最有效"。这是承认了一个事实——人和 Agent 的最佳阅读入口不同,人从摘要读起,Agent 从链路索引读起。
知识建好了,模型不去读,等于零。所以还有一份协议专门约束使用知识的方式。几条关键条款:
当前所在目录不是搜索边界。
涉及前后端联动时,必须显式考虑后端与前端两个知识库;禁止只搜前端或只搜后端就下结论。
禁止不读知识入口直接全仓盲搜。
最后一条是整份协议里最关键的。模型的默认行为是拿到问题就全仓 grep,在十几个仓库的微服务系统里,这既慢又容易命中误导性结果(比如第一章那段已废弃但仍存在的旧代码)。协议强制它走固定路径:先读线程交接文档,再读索引,再读项目卡;排错场景走专门的排障入口分流。
配套是把常见检索封装成命令,并规定必须使用:
./01-检索工具/search-knowledge.sh "关键词" index-only # 只搜索引
./01-检索工具/interface-tool.sh trace "接口名或URL" wms # 接口链路追踪
./01-检索工具/interface-tool.sh mock-scan "接口名" wms # mock 扫描
协议规定:凡涉及接口、URL、F12、mock、请求链路的问题,必须走 interface-tool.sh,不得自由搜索。这把"模型自由摸索半小时"变成了"查台账 → 定向验证"的固定路径。
知识库的守卫也交给机器。变更扫描标准是一份写给 Agent 的审查规则,输入就是 git diff:
git diff --name-status <base>...HEAD -- 01_claude/context-pro
它要发现的问题包括:资产放错目录、frontmatter 取值非法、关键事实没有证据 ID、未确认的表/字段/接口被写成确定结论、台账与索引未同步、程序调用链被错误建模为业务流程、verification_level 被当作 confidence 使用、保鲜字段缺失等。
这一条把前面所有原则从"约定"变成了"门禁"。
仓库里现在有两代规范并存,差别很能说明认知变化。
第一代编号形如 R-BE-001,本质是面向生成的提示词模板——"生成这类代码时按这个格式"。实用,至今在用,但只对 AI 有效、对人几乎不可读;只覆盖生成动作,不覆盖评审、测试和发版;没有生效状态、来源和变更记录。
第二代编号形如 KYP3-BE-002,面向整条交付链路。目前 8 个分类 28 条,其中 25 条生效、3 条废止。
每条规范必须尽量回答五个问题:做什么、为什么这么做、不做什么、为什么不能这样做、怎么检查。
前四问决定规范能否被理解,第五问决定它能否被执行。
以微服务日志规范为例,它不止说"禁止使用 e.printStackTrace()",而是给出完整口径:ERROR 必须打堆栈、其他级别原则上不打;循环中不允许打印 debug 及以上级别;禁止用 JSON 工具把对象整体转字符串打印;银行卡号、证件号、手机号、客户名称、密钥、Token 不得明文输出;日志文件至少保存 15 天。每一条都可以在评审和扫描中被验证。
规范体系容易死于两件事:太松等于没有,太重没人维护。因此明确了分层展开规则:
| 规范类型 | 展开要求 |
|---|---|
| 数据库、SQL、发版、分支、权限、异常、日志、数据计算等高风险规范 | 做法、原因、禁止项、禁止原因、检查方式,全部说明 |
| 命名、格式、编码风格等基础规范 | 以清晰规则为主,不逐条展开原因 |
| 工具配置、目录结构等执行型规范 | 说明目标状态、操作要求和检查方式,原因可简写 |
| 推荐类规范 | 说明推荐理由和适用边界,不写成强制口径 |
并且明确禁止两种倾向:禁止为了格式统一把简单编码规范写成长篇;也禁止只保留检查项而没有可执行规则。
规范写完进入治理流程,判断与已有规范是重复、补充、冲突、替代还是废止,结论记入台账。六份台账中,最有价值的一份是后来补上的:实际代码校准裁决记录。
起因是个很实际的冲突:某条规范要求 A 写法,但存量代码 90% 是 B 写法。改规范还是改代码?如果没有地方记录裁决,同一个争论会在每次评审时重演,而且不同评审人会给出不同结论——这恰恰是"判据缺口"最典型的形态。
台账同时记录每条规范的来源依据和关联缺陷编号。当有人质疑"这条规矩谁定的、为什么",能直接查到出处。台账也如实暴露未完成项:多条规范的"宣导日期"至今是"待补充",我们选择让它显示为空,而不是补一个假日期。
规范的读者不止研发:Reviewer 要对口径,测试要看验证点,配置管理要看交付证据要求。介质需求不同,做法是单一 Markdown 源加多态导出——HTML 电子书用于在线查阅、Word 用于正式发布评审、Excel 用于治理跟踪。
唯一的铁律是:任何修改必须回到 Markdown 源重新导出。一旦允许直接改 Word,多态会立刻退化成几份互相打架的文档,判据缺口就此重新打开。
早期的角色定义就是几百字提示词。演示效果不错,长任务里迅速失效:模型漂移、越界、被追问就改口,且不沉淀任何东西。
现在的角色是一个符合 Schema 2.1 的目录:身份档案、工作流手册、技能路由、工具与 MCP 配置、运行时工作目录、记忆文件。关键不在文件多,而在于 PROFILE.yaml 里有 version、lifecycle 和 lineage——角色本身成了可版本化、可审查、可继承的工程对象,而不是一段随时被改写的文本。
但真正让角色行为稳定的,是下面三个设计,它们都不在"能力描述"里。
绝大多数角色提示词在写"你负责 A、B、C"。实践下来,约束力更强的是反面定义。以架构师角色为例(原文英文,此处摘译):
| 字段 | 内容 |
|---|---|
anti_goal | 一个只会画图和守模式的关卡,凭品味发号施令,没有证据就阻塞交付,且不对后续负责 |
temptation | 为想象中的未来过度设计,脱离上下文强推熟悉的模式,或用架构权威去接管实现与交付决策 |
deepest_failure | 批准了一个局部可用、却悄悄让未来的变更、故障隔离或数据演进变得不安全和昂贵的改动 |
not_for 字段则直接解决角色抢活问题,每条越界行为都指向正确归属:
not_for:
- 决定产品价值、优先级或产品范围 → 归 product-manager
- 制定项目日期、指派责任人、汇报交付状态 → 归 project-administrator
- 实现代码、编写测试、合并、部署或运维生产
- 在没有验证证据的情况下,宣称性能、可靠性、安全性或数据正确性已被证明
配套的不可协商原则里,有一条把"我觉得这样不好"从合法输出中删除了:
一个架构阻塞项必须指明:被违反的约束、影响或爆炸半径、证据、需要的处置方式、以及负责决策的责任人。
角色的技能入口不是技能清单,而是一张带准入门槛的路由表。摘录两行:
| 主要诉求 | 技能 | 准入门槛 |
|---|---|---|
| 评估已实现代码的结构符合度 | code-architecture-review | 已检视 diff 及其周边依赖上下文,并有路径级证据 |
| 评估结构风险与债务 | architecture-risk-assessment | 失效模式、爆炸半径、可探测性、可逆性、证据、责任人和处置方式均已明确 |
门槛的作用直接对应第一章的失败:
角色执行任务前必须建立运行记录,工作目录有固定分区(输入、原始数据、中间产物、交付物、证据、日志)。记忆机制处理得尤其谨慎:角色不能直接改写长期记忆,候选结论先进提案文件,只有经过验证、可复用的才被提升进受控区域;写入前须加锁、重读、比对哈希、原子合并,冲突时保留提案而不覆盖。
任务收尾时,记忆结果必须记为"无 / 已提升 / 仅提案 / 冲突"四者之一,并明确写着:"无"是正常结果。
这句话看似多余,实则必要。不写它,模型会倾向于每次都"学到点什么",几十次任务之后,记忆里塞满了低价值噪声,反过来污染后续判断。这是很多 AI 记忆机制失效的实际原因——不是记不住,是记太多。
17 个角色里有三个的服务对象不是业务系统,而是这个体系自身:规范管家、知识资产管家、仓库运营专家。
前面三层都是静态资产。看它们如何在一次真实作业中串成流程,仍以第一章那个字段口径问题为例:
① 会话启动
协议入口(CLAUDE.md / AGENTS.md)强制加载,规则正文以工作区协议为准
↓
② 角色路由
问题是排障 → 进入对应角色;准入门槛检查:现象、上下文、约束是否明确
信息不足 → 回问,而不是先给分析
↓
③ 检索(禁止盲搜)
先读线程交接文档 → 索引 → 项目卡;命中接口链路主题
→ 强制走 interface-tool.sh trace 与 chain-index,而非全仓 grep
↓
④ 事实核对
查到的结论挂证据 ID,核对 verification_level 与 last_verified_at
发现该结论仅为 reference 级、且已过保鲜期 → 不直接采信
无法确认处写 unknown 并登记 quality-flag,而不是猜测
↓
⑤ 产出
修改受规范约束(如日志规范禁止在循环内打印、敏感字段必须脱敏)
规范自带检查方式,评审有统一口径
↓
⑥ 沉淀
新确认的事实回写知识资产并登记证据与核验记录
设计文档进案例库;变更扫描以 git diff 为输入校验合规性
↓
⑦ 分发
规则、角色、技能经同步脚本增量下发到各业务工程
关键的是第 ④ 步。第一章的失败正是在这一步没有任何拦截:模型拿到一段代码就当作事实。现在这一步有三道闸——证据 ID 要求可追溯、核验级别暴露成色、保鲜时间戳暴露过期风险。三道闸都不能保证结论正确,但它们能保证结论的不确定性是可见的,而这正是第一章失败中最缺的东西。
症状:让模型读代码梳理调用链,画成流程图当业务知识,一周产出几十份。
代价:一次重构让大半失效,因为记录的是实现不是业务。
现在:业务语义层与实现证据层分离,调用链单独存放,明令禁止用调用步骤冒充业务流程。
症状:一份文档覆盖多个业务类型(公募、私募、理财、信托的画像写在一起),因为"技术实现是共用的"。
代价:改一处要通读全文,没人敢删旧内容,引用时无法精确定位,文档只增不减。
现在:一叶一文件,即使共享实现也各自维护;共享部分下沉到技术组件。原聚合文档整体移入归档区——不删除,只归档,因为新资产的来源引用还要指回它们。
症状:每个角色一段"你负责什么"的提示词。
代价:角色互相抢活,架构角色动手改代码,评审角色给出无法处置的意见。
现在:not_for 逐条列出越界行为及正确归属,anti_goal 描述失败形态,阻塞权力附带证据要求。
症状:条款是一串禁令,没有原因、边界和检查方式。
代价:人执行不了(不知道边界),模型消费不了(无法推断新场景),Reviewer 反复提相同意见。
现在:五问口径强制回答"怎么检查";同时用分层展开规则防止走向另一个极端——把命名规范也写成长篇大论。
症状:在"写详细"和"写成表格"之间反复摇摆。
代价:人读着累,机器解析难,两边都不满意,文档逐渐没人维护。
现在:Markdown 给人读、TSV 给机器读、schema 声明二者语义。人读部分因此可以写得像文章。
| 指标 | 数值 |
|---|---|
| 建设周期 | 2025-09-04 起,约 11 个月 |
| 累计提交 / 纳管文件 | 1468 次 / 12829 个 |
| Agent 角色 | 17 个(另有公共能力库) |
| 技能包 | 62 个 |
| 治理态研发规范 | 28 条(25 生效、3 废止),8 个分类,导出 HTML / Word / Excel 三态 |
| 产品化知识资产 | 65 份(技术组件 6、业务组件 29、业务逻辑梳理 30) |
| 机器索引 | 27 个 TSV:资产台账 64 条、证据 239 条、链路 492 条、字段映射 230 条、质量标记 139 条 |
| 工程知识库 | 7529 个文件,含 221 个 TSV 索引、11 个检索脚本 |
| 设计出码案例 | 21 个研发版本目录,1292 篇文档 |
覆盖率仍在爬坡。65 份正式知识资产相对资产配置 3.0 的完整业务版图只是开始,尚不足以覆盖日常研发的大多数问题。
大量资产处于草稿状态。前文引用的客户列表资产就是典型:草稿、负责人待确认、证据部分、可信度中等。证据链机制在运转,但完成度远未达标。
规范宣导有缺口。相当一部分规范的宣导日期仍是"待补充"。规范写好不等于团队知道,这一步目前靠人工推动,没有机制保障。
运行时机制落地率不高。工作目录规范、生命周期记录、记忆提案与锁设计得比较完整,但实际使用中多数任务仍是直接对话,完整走运行时流程的比例不高。设计的完备性与落地的普及度之间有明显差距。
没有效能度量闭环。这是最大的短板,也是本文通篇不给"提效百分之多少"的原因。仓库的提交数、资产数只能证明"建了什么",无法证明"省了多少"。把 AI 使用情况与工时、缺陷率、返工率关联起来的度量机制,是下一阶段的重点。在此之前,任何收益比例都只是估算,写出来对读者没有价值。
脱离具体业务,以下五条我们认为值得推荐给同行。
一、先建协议入口,再建内容。常见顺序是先攒资料再想怎么用,结果资料越多越没人看。正确顺序是先定"AI 进入任务时必须读什么、按什么路径检索",内容围绕这个骨架生长。
二、人读与机读分离,用 schema 作契约。一种格式同时满足人和机器,最后两边都不好用。
三、可证伪比完整更重要。没有证据 ID 的知识库是一堆无法证伪的断言;把"文档写得确定"当成"事实已核实",是失真的主要路径;把"没查过"写成"没有",比留空更危险。
四、用分层控制维护成本。知识库和规范体系多数不是死于太松,是死于太重。明确哪些必填、哪些按条件启用、启用后不许只填一半,比要求"全部填完"可持续得多。
五、边界与门槛优先于能力。定义 AI 角色时,"不做什么、越界转给谁"的信息量大于"能做什么";让门槛前置而不是结论前置,是 AI 协作中最值得投入的行为矫正。
回到那个"看起来完全正确"的错误。
一年下来最大的体会是:大模型带给团队的真正挑战,不是学会写提示词,而是倒逼团队把过去靠口头传承、靠个人经验、靠"老员工知道"维系的隐性知识,显式地写下来、结构化、标注来源、并持续保鲜。
这件事在没有 AI 的年代也该做,只是不做也能凑合——老员工还在,问一句就是了。AI 进来之后凑合不了了,因为它不会"问一句",它只会用手头能拿到的东西给你一个看起来合理的答案。团队供给什么,它就长成什么样。
所以这套体系表面上是 AI 的配置仓库,实质是团队工程知识的显式化工程。三层各自对应一种长期缺失的东西:Context 对应业务事实与证据的显式化,Rule 对应质量判据的显式化,Agent 对应职责边界的显式化。
而它建成之后,最先受益的其实不是 AI,是新人。
注:文中所有统计数据截至 2026-08-04,均可在仓库中直接核对,不含推算指标。