上下文工程实战:让 AI 理解大型 monorepo 的分层
一、monorepo 给 AI 出的难题
大型 monorepo 里,包与包层层依赖。
一个需求要改五六个包,跨十几层目录。
把整个仓库塞给模型?窗口早爆了。
更麻烦的是"分层关系"。
底层工具包、中层业务包、上层应用包,各有边界。
模型若不懂分层,可能在上层直接改底层,破坏封装。
让 AI 理解 monorepo 的分层,是上下文工程的高阶题。
本文探讨如何把仓库结构"翻译"成模型能用的上下文。
二、分层上下文的构建机制
核心是把"结构知识"显式喂给模型。
不是丢源码,而是丢"地图":包清单、依赖方向、公开 API、改动的合理边界。
模型据此知道"该改哪层、不该越界"。
再按需展开具体文件,而非全量载入。
下面是分层上下文的构造:
flowchart TD A[monorepo 结构] --> B[抽取包清单+依赖图] B --> C[生成分层地图文本] C --> D[拼接为系统提示] D --> E[用户请求+相关包展开] E --> F[LLM 在边界内生成] style C fill:#e1f5fe style F fill:#e8f5e9关键在"地图先行,代码后展"。
先用结构约束范围,再展开细节。
避免模型在不知全貌时乱改。
三、生产级实现
下面用代码描述分层地图的生成。
from dataclasses import dataclass from pathlib import Path from typing import dict @dataclass class Package: name: str layer: str # base / biz / app depends_on: list[str] def build_map(packages: list[Package]) -> str: """把 monorepo 分层压成模型可读的地图文本""" lines = ["# 仓库分层地图"] by_layer: dict[str, list[Package]] = {} for p in packages: by_layer.setdefault(p.layer, []).append(p) order = ["base", "biz", "app"] for layer in order: lines.append(f"## {layer} 层") for p in by_layer.get(layer, []): deps = ",".join(p.depends_on) or "无" lines.append(f"- {p.name} (依赖: {deps})") return "\n".join(lines) def allowed_target(layer: str) -> set[str]: # 上层可改下层,下层不可反向改上层 rules = {"base": {"base"}, "biz": {"base", "biz"}, "app": {"base", "biz", "app"}} return rules.get(layer, set()) if __name__ == "__main__": pkgs = [ Package("utils", "base", []), Package("order", "biz", ["utils"]), Package("web", "app", ["order"]), ] print(build_map(pkgs))真实系统会从workspace配置与package.json自动抽包。
并标记公开 API 边界,让模型知道"哪些能改、哪些只能调用"。
四、上下文工程实战的代价与边界
分层上下文有用,但有前提。
结构抽取的准确度。依赖图抽错,地图就误导模型。
应基于真实的依赖声明,而非目录猜测。
并定期刷新,反映重构后的新结构。
地图与代码的同步。地图过时,模型按旧分层改,踩坑。
结构变更时要同步更新上下文源。
可接 CI 校验地图与声明一致。
边界限制的软硬。强限制模型"不准改某层",可能误伤合理改动。
应区分"硬边界"(公开 API 不可破)与"软建议"(优先改本层)。
硬边界进门禁,软建议进提示。
大 monorepo 的尺度。包上千时,地图本身也长。
应分层级展开:先给顶层地图,按需下钻。
避免地图比代码还占窗口。
分层上下文的"边界冲突"处理要预案。现实里模型可能"合理越界",比如为修上层 bug 必须动底层工具函数。此时硬禁止会卡住合理改动。建议区分"硬边界"(公开 API 契约不可破、跨团队接口不可擅自改)与"软建议"(优先改本层),硬边界进门禁拦截,软建议进提示引导。另一个实践是"依赖方向校验":用 lint 或构建规则禁止上层反向依赖下层实现细节,从机制上固化分层,而非只靠上下文提示。最后,分层地图要随重构更新,结构变了地图不变,模型又会按旧认知改错地方。
五、总结
让 AI 理解 monorepo,本质是把"结构知识"显式化。
机制上先抽分层地图约束范围,再按需展开代码。
工程上保证地图与依赖声明同步、边界分软硬。
落地路线:先从依赖声明抽包与分层;生成地图文本进系统提示;标记公开 API 硬边界;按需下钻展开。模型懂分层,改动才不越界。