让 AI 更懂你的项目,AI coding context 建设指南

278 阅读11分钟

摘要

这是一篇 AI coding context 建设的实战笔记:我们在一个包含 25+ React 应用与多套组件库的 monorepo 中,如何让大语言模型(下文简称 AI)“看得懂、找得着、用得好”我们的代码与组件。 文中不讨论“AI 会不会编程”这类宏大话题,而是聚焦一件具体小事——把代码库整理成真正可供 AI 消化与检索的语境文档(AI Context),并在真实团队协作中稳定产出。

通读本文,你会获得三类信息:它解决的痛点(为什么做)、设计与取舍(怎么做)、工程落地与维护(如何长期做对)。

1. 背景与需要解决的问题

我们面临的典型场景是:一个大型前端 monorepo,内部有 25+ React 应用和多个公共组件库。新同学加入项目时,即使文档齐全,也常常难以在复杂的目录结构中定位“可直接复用的组件”和“正确的集成方式”。当把这件事交给 AI 时,另一个问题出现了:AI 并不天然知道哪些组件适合当前场景、它们是否支持 SSR、是否存在副作用、导入路径写法是否规范等。

换句话说,AI 缺少可依赖的“上下文”。要让它在一次、或少量轮次的交互中给到有用的建议,我们需要为它准备一种专门的文档形态:以 AI 的认知与检索为第一目标,组织代码与知识。这就是我们要建设的 AI Context。

2. 什么是 AI Context(我们把它当成一套“面向 AI 的文档体系”)

AI Context 不是“再写一本手册”,而是一套围绕 AI 工作方式设计的文档与索引体系:

  • 面向 AI 的信息组织:把“角色/任务/要求/输出/约束”等关键信息前置,统一导入路径,避免 barrel 导入,突出类型签名、可用性与限制。
  • 面向检索的结构:分层组织与可切片(chunk)的排版,让检索服务能以较少调用拿到高价值片段,同时保留跨组件关联。
  • 面向质量的筛选:不是所有代码都值得进入 AI 的“视野”。我们只纳入“易复用、边界清晰、类型完备”的部分,并设定进入门槛与一致性规则。

这样做的直接收益是:当你问“我该用哪个文件上传组件?”时,AI 不再去全仓搜索,而是先在一份为它准备的、高密度信息的“地图”中定位,再跳转到对应组件的完整 API 与示例。这比“盲搜+拼凑答案”的方式更稳定,也更省交互成本。

3. 设计原则(以 AI 的认知与可检索性为中心)

第一,认知优先。我们按照 AI 更容易理解的顺序组织信息:先讲角色与任务,再给出约束与输出格式;把常用组件与关键约束前置;为组件打上 browserOnly、hasSideEffect、async、domRequired 等标签。

第二,质量筛选。进入 AI Context 的条目要“少而精”。我们采用 100 分制的质量评分来做纳入控制:类型安全与导出签名完整、SSR 兼容与副作用对称清理、复杂度与性能、文档清晰度与实用性。只有总分 ≥ 75 的组件才进入文档。存在明显问题(单文件超长且职责不清、标注 DEPRECATED/experimental、导出为 any/unknown 且无约束、强副作用无清理)的条目会被剔除。

第三,可检索性。我们围绕“优先级—接口—导入路径—示例—标签”的顺序组织,每个组件都配有一致的接口描述与可以直接复制运行的示例。导入路径必须指向具体文件,避免隐藏式 barrel 导入。

4. 架构方案对比:集中式与分布式

在实践中,我们尝试过两种组织方式。

分布式做法是,把每个组件的文档放在各自目录下:

monorepo_apps/
├── claude.md                   # 项目说明与约束
├── support_modules/            # 公共能力仓库
│   └── components/
│       ├── components1/CLAUDE.md
│       ├── components2/CLAUDE.md
│       └── ...
│
└── apps/                       # 业务应用
    ├── app1/                   # 业务1
    └── app2/                   # 业务2

这一方式在维护侧更轻巧,但在 AI 侧会出现“上下文割裂”的问题:要回答同一个问题,AI 需要多次读取不同文件,容易遗漏关联信息,比如组件间的替代关系或配套使用方式。更重要的是,AI 在解决问题的时候会遵循“就近原则”,倾向于局部就近解决问题,在这种情况下 AI Context 的收益会大打折扣。

集中式做法是,把所有组件的完整说明集中在一份文档里:

monorepo_apps/
├── claude.md                   # 项目说明与约束,以及 support_modules 下所有公共包的组件和方法说明
├── support_modules/            # 公共能力仓库
└── apps/
    ├── app1/                   # 业务1
    └── app2/                   # 业务2

它的优势在 AI 侧非常明显:上下文连贯,模式与相似接口一览即明,检索成本低。AI 能更准确地做组件选型与组合建议。比如在回答“如何选择合适的文件上传组件”时,AI 可以 claude.md 中同时看到 FileSelect、ImgCropPortal 等相关组件,并据此做出更稳妥的推荐。缺点也现实:随着组件增多,这份文档会变长,单点更新成本上升。

5. 推荐:混合模式(兼顾项目规模和 AI 收益)

为了兼顾“认知连贯”和“维护友好”,我们落地了一套两层结构:

  • L1 是 AI 的首个接触点,保留全局约束、命名规范、导入路径策略,以及“按使用优先级排序”的核心组件索引。每个条目只给出最小必要信息与跳转锚点。
  • L2 提供包模块下的完整 API 文档,包括参数、示例与关联关系。
monorepo_apps/
├── claude.md                   # L1,项目说明与约束,包含工具包的文档索引
├── support_modules/
│   ├── components/
│   │   └── USEME.md            # L2,具体包模块下的完整 API 文档
│   ├── common-react-hooks/
│   │   └── USEME.md
│   └── ......
└── apps/                       # 业务应用
    ├── 业务1/                   # 业务1
    └── 业务2/                   # 业务2

在 L1 CLAUDE.md 中建立工具包的文档索引。

| 包名                 | 用途                 | 文档地址                            |
| -------------------- | -------------------- | ----------------------------------- |
| @umu/components      | 基础公共组件与工具   | `support_modules/components/USEME.md`          |
| @umu/umu-react-hooks | 无业务耦合 Hooks     | `support_modules/umu-react-hooks/USEME.md` |

在这套混合文档模式落地后,我们在日常使用中能明显感到检索路径被收敛了。AI 会先在 L1 的索引里明确范围,再把解答约束在 L2 的 API 片段与示例里,只有涉及实现背景或边界条件时才跳转到更深入的内容。这样一来,跨文档来回跳转的次数减少,无关片段被拉入上下文的概率也低了。AI 检索速度更快,可以根据具体任务和上层文档的分类选择是否跳转到 L2 进行更深入的检索。对于“选型”相关的问题,比如上传组件或异步数据请求封装,回答更稳定,组合建议也更聚焦,往往能直接给出可复制运行的代码。 维护侧同样受益:随着公共代码的合并,CI 会自动刷新 L2 的目录与锚点并重建索引,我们主要把精力放在保证示例可运行和补充少量元信息上,文档漂移现象得到控制。

6. 一个端到端的真实问题:我该用哪个文件上传组件?

这是我们在团队内最常见的问题之一。用 AI Context 驱动的流程大致是这样的:

当你提出需求,AI 会先在 L1 的“核心组件索引”里定位“文件上传相关”的条目。索引不仅包含组件名,还包含一个简短的适配说明、标签(如 browserOnly/hasSideEffect)、以及指向 L2 的锚点链接。随后,AI 跳到 L2 的具体章节,查看 FileSelectChooseCropPhoto 的接口差异、SSR 支持、典型使用示例。如果你的场景涉及裁剪与上传进度提示,AI 会建议组合 FileSelect + ImgCropPortal,并给出可以直接复制运行的示例代码。

这里没有“魔法”,只有结构化信息与一致的表达,让 AI 在有限交互内完成合适的检索与拼接。

7. 质量保证:纳入口径与一致性

我们采用一个 100 分制的质量评分模型来决定组件是否进入 L2:类型安全(导出签名完整、显式类型、合理泛型)、SSR/副作用(有对称清理、兼容 SSR)、复杂度与性能(避免频繁重渲染、无明显低效循环)、文档完整度(接口定义与参数说明清楚)、以及实用性(功能完备、场景明确)。只有评分不低于 75 分的组件会进入 AI Context。明显不符合预期的条目将被剔除,等整改后再纳入。

评分过程可以做到自动化。示例伪代码如下(注意命名为 typeSafety):

function evaluateComponent(component: ComponentInfo): QualityScore {
  const score = {
    typeSafety: evaluateTypes(component), // 25 分
    sideEffectsSSR: evaluateEffects(component), // 15 分
    complexity: evaluateComplexity(component), // 10 分
    performance: evaluatePerformance(component), // 10 分
    documentation: evaluateDocs(component), // 15 分
    usability: evaluateUsability(component), // 25 分
  };

  return calculateTotal(score);
}

// 阈值控制:只有 ≥75 分的组件才被纳入文档
const qualifiedComponents = components.filter(
  (c) => evaluateComponent(c).total >= 75
);

一致性同样重要。接口描述采用统一表格字段(属性、类型、是否必填、默认值、说明),示例代码必须可直接复制运行,导入路径使用具体文件路径,标签系统统一(browserOnly、hasSideEffect、domRequired、async),并与代码真实行为保持一致。

8. 如何把文档变成“可用的 AI 语境”

文档写好只是第一步,它需要与检索/索引协同工作。我们在落地时做了三件事:

其一,分层组织与切片。L1 只放“约束与索引”,每个条目保持极简;L2 的章节以 H2/H3 为边界切成语义片段,并为每段保留“导入路径、标签、导出签名”这类元信息,供检索时一并返回;

其二,建立轻量的组件关系图。在生成文档时,同时解析导出签名、依赖与常见组合,形成“相似组件/可替代/可搭配”的链接。AI 在回答时不必穷举,而是沿着这张关系图给出更聚焦的选项。

其三,控制信息密度。优先返回高价值片段,避免一次性塞入所有内容。对于通用问题,先给 L1 的索引摘要;当需要动手时,再引入 L2 的接口与示例;

9. 规模增长下的治理与迁移

集中式文件不可避免会变长。我们采用两条简单的约束:

  • L1 只保留“全局约束 + 索引 + 少量 Top 入口”,其余跳转到 L2;
  • 当 L2 超过可维护的长度时,按模块拆分为多文件,并由脚本维护一个聚合索引,保证检索入口不变。

在更大的项目(>50 个组件)里,我们建议转向分布式,但保留统一的元数据与索引层。这样既能按需维护,又能保证跨组件的检索与推荐不丢失。

10. 我们目前的自动化

AI 文档通过自动化的方式维护:当提交公共代码(组件、类型或影响文档的元数据)时,CI 会在流水线中自动更新文档与索引,无需人工参与。

在实际流水线中,我们把“文档生成—评分—索引构建”做成一体化流程:从 TypeScript 源码解析导出签名,生成接口表与示例校验(保证能编译通过并且导入路径可解析),根据评分阈值决定是否纳入,生成带 frontmatter 的元数据(标签、评分、路径、SSR/副作用特性),最后构建可检索的索引。提交前做链接有效性与示例可运行性检查,避免回归。

11. 未来工作

后续我们计划继续补全自动化:进一步增强基于源码的文档生成、引入更稳定的质量评估方法、按使用频率动态调整文档内容的展示优先级,并探索开发支持 AI Context 的 VSCode 插件来降低团队使用门槛。

12. 结语

AI Context 的目标不是“写更多文档”,而是把已有知识组织成 AI 能快速理解与复用的形式。对于开发者来说,它带来的直接收益很直观:更快找到合适的组件,少踩 SSR 与副作用的坑,集成代码一次写对。我们在 monorepo 中的小规模实践证明了它的可行性;随着团队与代码的增长,这套结构也能顺畅地演进。关键在于,把“认知优先、质量筛选、可检索性”这三件事长期做下去。