当团队同时使用多个 AI 编程工具时,如何避免每个工具各写各的,都绕开你精心设计的框架?本文记录了一套从零演进到工程化的解决方案。上一篇,我们通过Skill让Claude实现代码库和AI实现协同进化,这一篇我们进一步讨论,把Claude扩展到多个AI工具。
一、问题背景:框架存在,AI 视而不见
1.1 自研框架的价值与代价
在一个成熟的工程团队里,自研框架是领域知识的结晶。它把反复出现的模式封装成宏,把约定俗成的分层结构固化成接口,让开发者不必每次从零思考。
以本文的案例为例——一个基于 DDD(领域驱动设计)思想的 Rust 框架,已经封装了以下核心模式:
// 聚合根,不需要手动 impl 生命周期管理#[aggregate_root]pubstructOrder { ... }// 值对象,自动派生相等性和不变性保证#[value_object]pubstructMoney { ... }// HTTP handler,自动注册路由、处理序列化#[auto_router]asyncfncreate_order(ctx: Context) -> Result<Response> { ... }// 仓储层,自动生成 CRUD 模板#[repository]pubstructOrderRepository { ... }每一个宏背后,都是数周的设计与打磨。它们不只是语法糖,更是团队对"正确写法"的共识载体。
1.2 AI 编程助手的引入
当 Claude Code、OpenAI Codex 等 AI 编程工具进入开发流程,效率的确提升了——但随即暴露出一个根本性的问题:
AI 不认识你的框架。
它写出的代码语法正确,编译通过,逻辑合理,但全是原生 Rust 写法。聚合根用手动 impl,值对象不用宏,HTTP handler 直接用 axum 的原始 API。框架形同虚设。
更糟糕的是,团队同时在用 Claude Code 和 Codex——两个工具,各自为政,写出来的代码风格完全不同,既不符合框架规范,彼此之间也缺乏一致性。
1.3 问题的精确定义
在深入分析之前,先精确定义问题的边界。
这不是 AI 能力的问题。Claude 和 Codex 都有足够的能力理解和使用自定义宏,前提是它们能看到足够的上下文。
这是一个知识传递问题,具体表现在三个维度:
时效性:每次对话,AI 都从零开始,没有项目记忆 准确性:告知不足则写错,告知过多则被噪音淹没 一致性:多工具协作时,规范如何保持同一
二、初步尝试:直觉方案的局限
2.1 全量注入的失败
最直觉的方案是把框架文档全部注入给 AI。
这条路走不通,且失败得很有规律。一个完整的框架文档动辄数万字——所有宏的签名、所有工具函数的说明、所有使用禁忌,全塞进去。上下文窗口迅速饱和,AI 的注意力被大量无关信息稀释。更糟的是,当开发者只是在写一个路由 handler,他不需要知道数据库迁移宏的用法,但 AI 已经被这些信息占据了宝贵的推理空间。
全量注入的本质问题:把字典当作工作手册来用。
2.2 按需查询的前提假设
意识到全量注入的问题后,下一个想法是引入 MCP(Model Context Protocol)Server,让 AI 按需查询宏文档。
这个思路方向正确,但隐藏着一个致命的前提假设:AI 必须提前知道宏的名字,才能发起查询。
一个 AI 从未见过 #[aggregate_root],它不会主动去问"这个项目里有没有聚合根宏"。它只会沿用自己训练数据里见过的写法——手动 impl、自己造轮子、绕过框架。MCP 解决的是"如何高效获取知识",但没有解决"如何触发知识需求"。
2.3 单工具方案的天花板
即便为 Claude 单独设计了一套 skill 文档系统,放在 .claude/目录下,并取得了不错的效果,新的问题很快暴露:
当 Codex 也进入工作流,是否要为它再维护一套文档?
这个问题的答案几乎注定是痛苦的。两套文档意味着两倍的维护成本,以及随时间推移不可避免的内容漂移——Claude 文档更新了,Codex 文档忘了同步;框架宏重构了,某一套文档滞后了两个版本。
工具越多,维护负担越重,一致性越难保证。
三、问题的重新定义
经过以上尝试,我们需要退一步,重新定义问题的本质。
3.1 真正需要解决的是什么
将问题拆解之后,核心诉求其实很简单:
无论用什么 AI 工具,写具体代码之前,AI 都能找到并读取当前任务所对应的框架规范。
注意这里的关键词:找到和对应。不是全部读完,不是随机读取,而是在正确的时机读到正确的那一份。
3.2 知识库 vs. 工具配置
由此引出一个重要的概念区分:
框架规范是项目级知识,不是工具级配置。
.claude/里的 skill 文档,从属性上讲,不应该是"Claude 的配置文件"。它是"这个项目的开发规范",恰好以 Claude 能读懂的格式写就。当 Codex 也需要这份知识时,本质上是在消费同一份规范——只是入口不同。
这个区分,是整个方案演进的关键转折点。
四、核心方案:项目级 AI 知识库
4.1 设计原则
基于以上认识,最终方案遵循三条原则:
原则一:单一事实来源(Single Source of Truth)框架规范只维护一份,任何 AI 工具都从同一个地方读取,不允许为不同工具维护平行文档。
原则二:工具无关的知识层规范存放在中立目录,不绑定任何具体 AI 工具。工具可以换,规范不需要随之迁移。
原则三:入口与内容分离各 AI 工具只需要维护自己的"入口"——告诉工具去哪里找规范,入口本身不包含规范内容。
4.2 目录结构
最终方案的文件结构如下:
project-root/├── CLAUDE.md # Claude 入口├── AGENTS.md # Codex 入口├── .ai/ # 唯一共享知识库│ ├── routing.md # 路由表(意图→文档映射)│ ├── domain.md # 领域层规范│ ├── repository.md # 仓储层规范│ ├── web.md # Web 层规范│ ├── transaction.md # 事务规范│ ├── error.md # 错误处理规范│ ├── migration.md # 迁移规范│ ├── config.md # 配置规范│ ├── utils.md # 工具函数规范│ └── testing.md # 测试规范├── .claude/│ ├── settings.json # Claude 运行时配置│ └── hooks/│ └── update-skill.sh # 框架变更时自动更新文档的 hook└── .codex/ └── skills/ └── my-rust-ddd/ └── SKILL.md # Codex skill 入口每个目录的职责边界非常清晰,不存在模糊地带。
4.3 各层详细设计
知识层:.ai/目录
.ai/是整个系统的核心,也是唯一需要深度维护的地方。
其中 routing.md是整个系统的枢纽,它维护一张意图关键词到领域文档的映射表:
# AI 路由表写 Rust 代码前,先根据任务意图在下表中找到对应文档并读取。| 任务意图 / 关键词 | 读取文档 ||--------------------------------------|----------------------|| 聚合根、实体、值对象、领域事件 | .ai/domain.md || Repository、仓储、数据库查询、持久化 | .ai/repository.md || HTTP handler、路由、接口、Controller | .ai/web.md || 事务、Transaction、跨聚合操作 | .ai/transaction.md || Error、错误处理、Result、异常 | .ai/error.md || 测试、Test、mock、断言 | .ai/testing.md || 数据库迁移、schema 变更 | .ai/migration.md |规则:1. 一个任务可能匹配多个意图,对应文档都要读2. 不确定时,先读 domain.md3. 不允许凭记忆写框架代码路由表本身只有约 1-2KB,是整个系统中唯一需要"常驻上下文"的内容,其余文档均按需加载。
各领域文档遵循统一格式:
# [Domain] 规范## 适用场景(明确描述何时需要读这份文档)## 核心宏速查### `#[macro_name]`**作用**:一句话说清楚**签名**:完整函数/宏签名**示例**:来自项目真实代码的可运行示例## ✅ 正确写法(DO)(来自项目 examples/ 或 tests/ 的真实代码)## ❌ 禁止写法(DON'T)(框架希望替代的原生写法,明确列出)## 完整示例(覆盖该领域 80% 场景的完整可运行代码)DO/DON'T 并列的设计是关键。只有正确示例,AI 在"看起来也行"的原生写法和框架写法之间会摇摆。明确的禁止模式才能斩断这条退路。
Claude 入口:CLAUDE.md
CLAUDE.md是 Claude Code 每次对话必然加载的文件,但它不再承载规范内容——它只负责两件事:项目背景说明,以及指向 .ai/routing.md的强制跳转。
# 项目说明这是一个自研 DDD Rust 框架项目。框架通过宏封装了大量领域模式。## ⚠️ 写 Rust 代码前的强制步骤1. 读 `.ai/routing.md`2. 根据当前任务匹配对应领域文档3. 读完对应文档后再写代码不允许绕过框架宏使用原生写法。整个文件不超过 20 行。轻量是刻意为之:CLAUDE.md 必然被加载,因此它越小,对上下文的"占用税"越低。
Codex 入口:AGENTS.md与 Codex Skill
Codex 有两个入口,各有分工。
AGENTS.md是项目级的 Codex 配置文件,类比 CLAUDE.md,承担同等职责:
# Project: [项目名]## 框架说明这是一个自研 DDD Rust 框架。所有领域模型、仓储、Web handler 都有对应的框架宏。## 写 Rust 代码前必须执行1. 读 `.ai/routing.md`2. 按任务意图加载对应领域文档3. 严格遵守 DO/DON'T 规范.codex/skills/my-rust-ddd/SKILL.md是更精细的触发器,负责在 Codex 识别到 Rust 相关任务时自动激活:
# my-rust-ddd Skill## 触发条件涉及以下任意内容时激活:- 创建或修改 Rust 源文件- 定义领域模型、仓储、Web 接口、测试## 激活后必须执行1. 读 `.ai/routing.md`2. 根据任务加载对应 .ai/*.md3. 按规范写代码,不允许绕过框架宏两个入口互为补充:AGENTS.md 是项目级的全局约束,SKILL.md 是任务级的精确触发。
运维层:Claude Hooks
.claude/目录保留,但职责收窄为运行时配置和自动化钩子,不再存放规范内容。
其中最重要的是 update-skill.sh,通过 Claude 的 PostToolUse Hook 在框架源文件被修改后自动触发:
#!/bin/bash# 检测被修改的文件路径MODIFIED_FILE="$1"# 判断是否属于框架核心目录ifecho"$MODIFIED_FILE" | grep -qE "core-(common|errors)-macro/"; then# 通过 additionalContext 注入更新指令echo"检测到框架宏变更:$MODIFIED_FILE"echo"请立即检查并更新 .ai/ 下对应的文档,确保示例代码与当前宏签名一致。"fi这个 Hook 解决了文档腐烂问题——框架变更和文档更新之间的延迟,从"等开发者记起来"缩短到"当次提交内自动完成"。
五、系统演进路径
理解了最终结构之后,回顾整个演进路径有助于理解每一个设计决策的动机。
阶段一:无结构AI 完全依赖训练数据,原生写法,框架形同虚设阶段二:全量注入把所有文档塞进系统提示,上下文爆满,噪音过大阶段三:Claude 专属 skill(.claude/*.md)按需加载,效果改善;但绑定单一工具,无法扩展阶段四:共享知识库(.ai/)+ 多工具入口工具无关,单一事实来源,支持 Claude / Codex / 未来工具每一次演进都是在解决上一阶段暴露的新矛盾。关键的认知跃迁发生在阶段三到阶段四:从"给工具配置文档"变成"为项目建立知识库"。
六、可扩展性分析
这套方案的设计中,可扩展性是一等公民。
6.1 接入新 AI 工具
当 Cursor、Windsurf、Aider 或任何新工具进入工作流,所需的工作量极小:
了解该工具的"项目入口文件"规范(类似 CLAUDE.md 或 AGENTS.md) 创建该入口文件,内容只写:去读 .ai/routing.md如果该工具支持 skill/rule,创建对应的轻量触发器
.ai/中的规范内容完全不需要改动。
6.2 框架规范演进
框架宏新增、重构或废弃时,只需要更新 .ai/下对应的文档。所有 AI 工具在下次任务中自然读到最新版本。Claude 的 Hook 机制进一步将这个更新动作从"手动记得做"变成"框架变更时自动提醒"。
6.3 团队协作
这套文档放在项目仓库中,随代码一起版本管理。每个团队成员、每次 CI 流水线、每个 AI 工具读到的都是同一份规范。新成员加入时,.ai/目录同时是他们了解框架的学习材料。
七、设计决策对照表
以下表格记录了方案中的关键决策及其背后的工程动机:
.ai/而非 .claude/ | |
.sh脚本 | |
八、结论
回顾整个方案的演进,核心洞察可以浓缩为一句话:
框架规范是项目的一等公民,不是 AI 工具的二等配置。
当我们把文档从 .claude/迁移到 .ai/,变化的不只是目录名,而是整个心智模型——从"给 Claude 配置 skill"变成"为项目建立 AI 知识库"。后者天然支持多工具,天然要求单一来源,天然被纳入版本管理。
具体来说,这套方案实现了以下目标:
零重复维护:规范只在 .ai/里写一次,所有工具读同一份。
工具无关:接入新 AI 工具的成本是一个入口文件,而不是一套新文档。
自动更新:框架变更通过 Hook 触发文档更新提醒,文档腐烂的速度大幅降低。
符合工程直觉:AI 规范像代码规范一样存在于仓库中,被版本管理,被 code review,被所有人共享。
最终目标从未是让 AI 记住所有规则——那不现实,也不必要。真正的目标是:让 AI 每次写代码之前,都能找到正确的规则。这套系统正是为此而设计的。
本文方案基于 Claude Code 的 CLAUDE.md 机制、Hook 系统与 OpenAI Codex 的 AGENTS.md 及 skill 机制实现。核心思路(单一事实来源 + 工具无关知识层 + 轻量入口)对所有支持自定义上下文的 AI 编程工具均适用。 未完待续!
夜雨聆风