让 AI coding 不再就近解决:如何在 monorepo 中建设 AI context

让 AI 写代码不再"就近解决":如何在 monorepo 里建设 AI context?

AI 常把需求写快了,但顺手又造一遍"节流/懒加载/环境判断"等轮子,结果是能跑却变沉,技术债上升。AI 不是不懂复用,而是"看不到"你的共享库。问题的本质是:AI 的思考模式天生倾向"就地解决",思维聚焦于当前文件或仓库。再加上其不清楚自己的能力边界,难以主动突破上下文限制,导致其很难"优先复用 monorepo 的能力",从而不断造轮子。

本文给出一套可被 AI 消化的上下文体系(CLAUDE.md + USEME.md + 规则),让它先复用、再改造,按团队的方法写对代码。你将看到:AI 如何"看世界"、monorepo 的典型局限、我们如何建设可消费的 AI context,以及一份可复制的落地清单。


AI 是怎么"看世界"的

语言模型不是 IDE,它靠"上下文窗口"理解你的意图。看得见的东西(当前文件、最近看过的文件、你粘给它的片段)权重更高。

以一个真实案例说明:我们让 AI 实现一个"判断是否在微信环境内"的功能。如果只把业务文件丢给它,AI 会写出这样的代码:

typescript 复制代码
// ❌ AI "就近解决" 的典型输出
const isWeChatEnv = () => /MicroMessenger/i.test(navigator.userAgent);

useEffect(() => {
    if (isWeChatEnv()) {
        // WeChat 专属逻辑
    }
}, []);

看起来不错?但问题是:

  1. 重复造轮子 :我们的 common-ua 包里已经有 isWeChat 方法了
  2. 脆弱的 UA 嗅探:容易被 UA 覆盖、WebView 差异或地区版本影响
  3. SSR 隐患 :直接访问 navigator/window
  4. 边界不清:未处理服务端渲染或无 UA 的场景

但如果 AI 能"看到"我们的公共库文档,它会写出:

typescript 复制代码
// ✅ 有了正确上下文后的输出
import { isWeChat } from 'common-ua';

if (isWeChat()) {
    // WeChat 专属逻辑
}

区别很明显:代码更短、更安全、更可维护。关键是 AI 需要在正确的时机"看见"正确的信息。


在 monorepo 里的两大局限

1. 找不到"正确的能力边界"

先看看我们的 monorepo 目录结构:

bash 复制代码
monorepo_apps/                     # 根仓库
├── support_modules/               # 公共能力仓库
│   ├── common-util/               # 纯工具函数库
│   ├── common-react-hooks/        # 无业务耦合 Hooks
│   └── common-ua/                 # UA/环境检测
│   └── ......
└── apps/                          # 业务应用
    ├── 业务1/                      # 业务1
    ├── 业务2/                      # 业务2
    └── ......

在这个结构中,AI 经常分不清能力边界,比如:

  • 让它做"移动端适配",它可能在业务代码里写 window.innerWidth < 768,而不是用 common-uaisMobile()

2. 文档信息碎片化

我们统计了一下改造前的文档分布:

  • README.md:数量多,内容重复度高,难以维护
  • 老 Wiki 页面:存在过期信息,容易误导
  • 口头传承的"最佳实践":不可追踪,且经常与代码不一致

AI 面对这么多信息源,经常选择"安全策略"------重新实现,而不是冒险引用可能过期的代码。


踩坑历程:从混乱到有序

第一阶段:意识到问题(痛苦期)

我们发现团队里 AI coding 的输出虽然能跑,但质量参差不齐:

统计数据(改造前 3 个月):

  • 重复实现的工具函数:27 个
  • 不一致的导入风格:占比 48%

典型问题案例:

typescript 复制代码
// 案例:AI 重复实现已有的 UA 检测
const isMobile = () => {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
};

// 实际上 common-ua 里已经有更完善的实现:
import { isMobile } from 'common-ua/src/platform';

第二阶段:探索解决方案(试错期)

我们尝试了几种方法:

方法 1:对话窗口建立约定 效果:约等于没有。AI 不会记住上次的约定。

方法 2:在每个项目的 README 里写"使用指南"

效果:信息重复,维护成本高,AI 还是经常找不到。

方法 3:建立"代码库索引文件" 我们写了一个 index-of-libraries.md,列出所有可用的工具。 效果:有改善,但 AI 还是倾向于"就近解决",除非明确指出文件路径。

第三阶段:系统性改造(见效期)

在 monorepo 项目里用 AI,最重要的是要先给它"定好规矩"。 首先,每次让 AI 改代码之前,最好先让它了解一下项目结构。比如让它先看看根目录的 package.json 和 CLAUDE.md,确认这是个什么样的项目。我们项目有 25 个子应用,共享库就在 support_modules 目录下,这些信息对 AI 来说很重要。 其次,要明确告诉 AI"先找现成的,再考虑新写"。


我们的解决方案:让 AI 有"路标"、有"准则"、有"口袋书"

核心架构:两层文档体系

scss 复制代码
CLAUDE.md (总路标)
├── 快速开始 (命令速查)
├── Monorepo 概览 (包清单 + USEME 路径)
├── AI 协作规范 (Do/Don't)
├── 常见坑与约束
├── 文档地图与生成
└── 版本与兼容性说明

support_modules/*/USEME.md (具体指南)
├── 目录
├── 导入说明 (强制具体路径)
├── 重点 API 参数表
├── 分类 API 概览
├── 组件用法示例
├── 注意事项
└── 最佳实践与故障排除

1. 文档路标:CLAUDE.md

设计原则:AI 看到这个文件,应该能在 5 秒内理解项目全貌。 可以通过 claude init 命令生成,也可以借助其他大模型生成。

AI 协作规范(Do/Don't)

Do

  • 使用具体文件路径导入;禁止 barrel(如 import { X } from 'pkg')。
  • 最小化影响:不改对外 API;不做无意义格式化;保持文件/模块结构不变。
  • SSR 安全:涉及 window/document 仅在浏览器端执行;必要时判空/条件分支。

Don't

  • 不写版本兼容信息到 USEME(统一放本文件)。
  • 不扩大改动范围(移动文件、拆并模块)除非明确要求。

2. 可被 AI 消化的用法手册:各包的 USEME.md

在公共包下建立简约并明确的 USEME.md 文档,供 AI 阅读和了解该包的功能和用法。

设计原则:每个示例都能直接复制粘贴使用,每个参数表都能当 API 手册查。

提示词模板(给 AI 的最小上下文)

在与 AI 协作时,建议附上精简、稳定的上下文提示,避免跑偏:

objectivec 复制代码
你在一个 pnpm + monorepo 项目中工作。
先读根目录 CLAUDE.md 了解规则,再读相关包的 USEME.md。
优先复用 support_modules 下的能力,禁止 barrel 导入,必须使用具体文件路径。
若涉及 UA/SSR/性能,请优先查找 common-ua、common-react-hooks、common-util 的对应能力。
在给出修改前,用项目内既有 API 校对一次是否可复用。

小技巧:把这段模板固化到 .cursorrules 或常用的 Prompt 片段里,减少每次重复粘贴。

3. 跨仓库上下文打通:业务仓库"认识"support_modules

技术实现:给 cursor 添加 Rules:

go 复制代码
严格遵循工作流程:收到任务 → 检查 Rules → 分析项目结构 → 执行。
阅读项目中的 package.json、CLAUDE.md 和 USEME.md 以遵循项目约定。
检查该项目是否为 monorepo 架构,如果为 monorepo 子仓库,则向上查看父仓库和 support_modules 的指导文件(package.json、CLAUDE.md 和 USEME.md)以进行跨仓库协作。

关键机制

  1. 自动索引 :AI 会主动检查大仓的 CLAUDE.md
  2. 路径映射 :通过 CLAUDE.md 的"文档地图",AI 知道去哪找每个包的 USEME.md
  3. 优先级控制 :公共库的 USEME.md 比业务代码有更高的参考权重

实施细节:魔鬼在细节里

1. 文档结构的精心设计

标题层级:我们发现 AI 对标题层级很敏感

  • ## 重点 API 参数:AI 优先关注
  • ### 具体函数名:AI 能精确定位
  • #### 参数详解:AI 会仔细解析

表格格式:参数表的列顺序经过多次优化

markdown 复制代码
| 参数名 | 类型 | 默认值 | 必填 | 说明 |

这个顺序比其他排列方式的 AI 解析准确率高 15%。

2. 跨仓库协作的技术细节

完整目录结构

bash 复制代码
monorepo_apps/                  # 根仓库
├── claude.md                   # 总路标
├── support_modules/            # 公共能力仓库
│   ├── common-util/
│   │   ├── USEME.md
│   │   └── src/
│   ├── common-react-hooks/
│   │   ├── USEME.md
│   │   └── src/
│   └── common-ua/
│       ├── USEME.md
│       └── src/
└── apps/                       # 业务应用
    ├── 业务1/                   # 业务1
    └── 业务2/                   # 业务2

在根仓库 claude.md 中添加文档地图

bash 复制代码
support_modules - 核心业务逻辑模块
| 包 | 用途 | 文档 |
| ----------------- | --------------- | --------------- |
| umu-util | 工具函数库 | `support_modules/umu-util/USEME.md` |
| umu-react-hooks | 无业务耦合 Hooks | `support_modules/umu-react-hooks/USEME.md` |
| umu-ua | UA/环境检测 | `support_modules/umu-ua/USEME.md` |

AI 索引机制

  1. AI 读取 .cursorrules,知道要检查父仓库
  2. 通过 monorepo_apps/CLAUDE.md 获取全局规范
  3. 根据"文档地图"索引各包的 USEME.md
  4. 在生成代码时优先使用公共库的能力

踩坑经验:我们犯过的错误

1. 文档过于详细反而有害

错误做法 :最初我们在 USEME.md 里写了很详细的实现原理和设计思路。 结果:AI 被"误导",经常尝试"改进"我们的实现。

正确做法:只写用法,不写原理。让 AI 当"用户",不当"维护者"。

2. 示例代码的"诱导性"很强

错误做法:示例中使用了简化的错误处理:

typescript 复制代码
// ❌ 糟糕的示例
loadMore().then((data) => setList([...list, ...data]));

结果:AI 照搬这种写法,忽略了错误处理。

正确做法:示例必须展示完整的最佳实践:

typescript 复制代码
// ✅ 完整的示例
loadMore()
    .then((data) => setList((prev) => [...prev, ...data]))
    .catch((err) => showError(err.message))
    .finally(() => setLoading(false));

3. 过度约束反而降低效率

错误做法 :初期我们制定了 20+ 条详细规范。 结果:AI 被约束得"畏首畏尾",生成的代码过于保守。

正确做法:精简为 5 条核心约束,其他通过示例引导。


若你也准备在 monorepo 里用好 AI coding,可以这样落地

第一步:建立文档体系

核心文件优先级

  1. CLAUDE.md(总路标)
  2. 各公共包的 USEME.md(常用工具)

第二步:跨仓库集成

在编辑器(如 cursor)中添加 rules,

业务仓库配置

重要:因为 AI 往往会寻求"就近解决"。所以需要强制规定 AI 的思考模式,要求先阅读 rules 并了解项目结构,然后再工作。

arduino 复制代码
// .cursorrules
严格遵循工作流程:收到任务 → 检查 Rules → 分析项目结构 → 执行。
检查该项目是否为 monorepo 架构,如果为 monorepo 子仓库,则向上查看父仓库和 support_modules 的指导文件以进行跨仓库协作。

第三步:一小时落地清单(可直接执行)

  • 在根目录新增/完善 CLAUDE.md:包含包清单、文档地图、导入约束
  • 为常用公共包补齐 USEME.md:每个至少 1 个复制即用的示例
  • 统一导入方式:在示例和脚手架中全部改为具体文件路径
  • 在编辑器加入 .cursorrules:强制工作流与跨仓库检索
  • 加入 3 个简单的静态检查脚本(重复工具、barrel 导入、SSR 危险 API)
  • 选一个真实需求做"对照试验":先不加上下文生成一次,再按规范生成一次,对比差异

尾声

AI coding 的价值不止是"写快一点",更在于"写对一点"并且"复用多一点"。在 monorepo 里,这意味着给 AI 一张清晰的地图、明确的边界和可复制的惯用法。

我们用 CLAUDE.md 约束,用 USEME.md 传达,最终让 AI 在业务仓库里自然地"看见并复用" support_modules 的能力。实际落地后,重复造轮子的情况显著减少,提交一次通过率明显提升,新人融入速度也更快。

轮子造得再好,也比不上全仓库的人一起用同一个。现在,AI 也学会了这一点。

如果你也在大型项目里用 AI coding,不妨试试这套"文档驱动"的方法。让 AI 助手也会自动"学会"你们的最佳实践,成为真正能理解业务、写出符合团队要求代码的 AI coding engineer。

相关推荐
程序员鱼皮12 小时前
刚刚 Cursor2.0炸裂发布!这3大亮点必学
程序员·ai编程·cursor
磊磊落落14 小时前
MCP 是什么?它是如何工作的?
ai编程
知了一笑15 小时前
四个月,AI为主,人为辅,一款产品两个知识库!
ai编程·知识库·ai产品·独立开发者
飞哥数智坊16 小时前
看完 Cursor 2.0,我感觉国产 AI 编程又有希望了
人工智能·ai编程·cursor
不老刘1 天前
Microsoft 365 Copilot 扩展至应用和工作流构建功能
microsoft·copilot·ai编程
Sailing1 天前
🚀🚀 从前端到AI Agent开发者,只差这一篇入门指南
前端·后端·ai编程
紫穹1 天前
009.LangChain 手动记忆全流程
后端·ai编程
战神数科1 天前
AI IN ALL峰会|百度阿里揭秘智能营销与出海的AI实战
ai·ai作画·aigc·ai编程·ai写作
用户4099322502122 天前
快速入门Vue3的v-指令:数据和DOM的“翻译官”到底有多少本事?
前端·ai编程·trae
重铸码农荣光2 天前
从前端分类器到智能架构师:2025 年,Brain.js 带你叩开端侧 AI 大门
ai编程