关于 project-blueprint
project-blueprint 是用于梳理代码库实际结构的技能,通过发现重复的文件与目录模式,生成架构蓝图。它适合需要理解单体项目或 monorepo 的开发团队,并在需要判断时暂停询问,避免把推测写成事实。
主要功能
- 01识别单项目与 monorepo
- 02发现重复结构切片并记录实例
- 03依据代码证据描述架构
- 04区分观察事实与人工判断
- 05生成项目蓝图及 monorepo 系统图
适用场景
- 01为新加入的开发者梳理代码库结构
- 02记录新增同类功能时可参考的项目模式
- 03检查 monorepo 内项目及其依赖边界
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ carlitose/ agent-skills --skill project-blueprint安装后在 Claude Code 中输入/project-blueprint确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlassets/blueprint-template.mdsystem-map-template.mdreferences/patterns.mdslice-discovery.mduniversal-checks.md详细介绍
项目蓝图
通过发现代码库中的 切片 来梳理代码库——当开发者添加同类新功能时反复出现的结构模式。输出一份书面参考,记录项目实际做了什么,而不是它应该做什么。
这项技能是描述性的,而非指导性的。它记录现实情况。
核心原则
- 发现优先于理论。通过阅读结构来寻找模式,而不是套用 DDD/Hexagonal/Clean 检查清单。
- 人在环路中。凡是需要判断的地方,都要暂停并询问。不要臆造名称。不要对模糊的事物进行分类。
- 蓝图是唯一的持久产物。审计和 PR 审查是将蓝图应用于代码时产生的临时输出——不会提交到代码库。
- 证据优先于断言。每项陈述都要指向真实路径/文件/行号。如果无法提供证据,请标注 ⚠️ 或移至未解决问题。
- 尊重有意为之的决定。在
CLAUDE.md或决策规范中记录的选择不属于反模式。只有未记录的差异才算。
此技能的产出
| 情况 | 输出文件 |
|---|---|
| 单个项目 | docs/architecture/BLUEPRINT.md |
| 包含 N 个项目的 Monorepo | docs/architecture/SYSTEM_MAP.md + 每个项目对应的 docs/architecture/<project>/BLUEPRINT.md |
默认不生成可选的跨领域发现(UNIVERSAL_NOTES.md)——只有用户明确要求进行通用检查时,才会在聊天中提供。
工作流
步骤 1 — 检测 Monorepo 还是单个项目
查找顶层目录及以下 3 层内的所有清单文件:
find . -maxdepth 3 -type f \( \
-name '*.csproj' -o -name '*.sln' \
-o -name 'package.json' \
-o -name 'pyproject.toml' -o -name 'requirements.txt' -o -name 'setup.py' -o -name 'Pipfile' \
-o -name 'go.mod' \
-o -name 'Cargo.toml' \
-o -name 'pom.xml' -o -name 'build.gradle' -o -name 'build.gradle.kts' \
-o -name 'composer.json' -o -name 'Gemfile' -o -name 'mix.exs' \
\) -not -path '*/node_modules/*' -not -path '*/.venv/*'
按目录对清单分组。包含清单文件的顶层目录或第 2 层目录均为子项目候选项。忽略依赖、构建、缓存、生成和供应商目录。
⏸ 停下并询问检查点 1:
"检测到以下 N 个项目:[列表]。这样对吗?有没有遗漏或不该包含的项目?"
等待确认。如有不确定之处,不要继续。
步骤 2 — 针对每个项目,阶段 A:技术栈与分层
对于每个已确认的项目,阅读:
- 清单文件 → 语言、框架版本、关键依赖项
README.md、CLAUDE.md、docs/architecture*→ 已声明的约定、禁止使用的库、迁移说明.csproj引用 /package.json工作区 /go.mod模块 → 模块间依赖图
如果层级结构清晰可见,则映射该结构:
- 对于 .NET:
Api → Application → Domain ← Infrastructure / Persistence - 对于 Node/Python/Go:如果存在等效结构,则记录;否则注明 "flat structure"
步骤 3 — 针对每个项目,阶段 B:词汇检测
遍历目录树(深度为 3-4 层,排除 bin/obj/node_modules/.venv/dist/target/__pycache__)。
对于每个构建块,检查其是否已实例化:
| 构建块 | 检测方法 |
|---|---|
| Entity / Aggregate | Domain 文件夹中带有 id 和不变量的类 |
| Value object | 按值相等的小型不可变类型 |
| Repository | I*Repository 端口及其实现 |
| Domain service | Domain 中的服务类 |
| Application service / Use case | 协调器类(服务、用例、命令处理程序) |
| Domain event | 事件类型及发布点 |
| Driver adapter | HTTP 控制器、CLI 处理程序、WebSocket、队列消费者 |
| Driven adapter | DB、HTTP 客户端、消息生产者 |
| Port (interface) | Domain 中的 I*(或在 Application 中——若如此,请注明不对称) |
| Options / Config class | 绑定自 IConfiguration / 设置的类型化配置 |
必要时,参考 references/patterns.md 中的架构模式特征(DDD、Hexagonal、Clean、Layered、CQRS 等),为发现的内容贴上标签。
第 4 步 — 每个项目,阶段 C:切片发现
切片是重复出现的文件夹/文件结构——开发者添加同类新内容时遵循的结构模板。
检测方法:
- 列出项目根目录下深度为 2–3 层的目录
- 对每个目录,记录其子文件名
- 将子文件名符合相同正则表达式/模式的目录聚类
- 包含 N ≥ 2 个实例的聚类 → 候选切片
- 包含 N = 1 个实例的聚类 → 单例候选(需要人工分类)
对于每个 N ≥ 2 的候选切片:
- 结构:定义成员资格的文件名正则表达式
- 实例:完整路径列表;如适用,按维度标记(见第 5 步)
- 规范参考:使用下方的启发式规则选取
- 共同创建的文件:同一提交中还会添加哪些内容(DI 注册、测试镜像、控制器端点、选项类)
- 约束:规范参考中观察到的允许/禁止导入项、命名规则、框架选择
- 变体:与规范结构不同的实例;描述它们的具体差异
- 状态:
active(新工作首选)/frozen(遗留,不要扩展)/deprecated(将移除)
规范参考选择启发式规则(按优先级排序):
- 非平凡地涵盖完整结构(没有空文件)
- 有配套测试
- 最近修改过(≤ 6 个月)
- 审计历史中没有针对它的发现
- 名称具有描述性
- Response/输出并非平凡内容
如果两个实例按启发式规则排序不分上下,则采用双层规范参考:主参考(从此处开始,较简单)+ 进阶参考(更丰富的示例)。
⏸ 停下并询问检查点 2(如有需要):
"切片 X 有两个同样有力的规范参考:A 和 B。哪个是主参考,哪个是进阶参考?还是二者都是共同规范参考?"
第 5 步 — 检测维度(在单个项目内)
查找用于区分内部业务垂直领域的文件夹/命名空间模式:
- 基于渠道:例如,在具有多个输入渠道的项目中,使用
Voice*与Whatsapp*标记 - 基于租户:例如,使用
Internal*与External*标记 - 基于模块:明确命名的有界上下文
如果发现维度,为每个切片实例添加其维度标记(voice | text | channel-agnostic | 等)。
⏸ 停下并询问检查点 3:
"检测到维度 X,标记为 [...]. 请确认或更正维度标签。"
第 6 步 — 对 N=1 的候选进行分类
将发现的所有 N=1 项整理成列表。对每一项,提出一个问题:
⏸ 停下并询问检查点 4(将所有 N=1 项合并为一批):
"发现 N 个 N=1 候选项。请逐项分类:" • [路径/名称]:单例(独特角色,不会复制)| 模板(首个此类实例,后续还会有更多)| 异味(本应拆分为多个)?
等待整批答复后再继续。
第 7 步 — 跨领域约定与不对称情况
记录贯穿整个项目但不属于切片的规则:
- 映射器 — 按边界划分的存放位置
- 序列化 — JSON 大小写格式、BSON 等
- 验证 — 框架与注册方式
- 错误模型 — 封装结构、代码约定
- 依赖方向 — 根据清单图确认
- 日志/追踪 — 单一来源、约定
明确记录已知的不对称情况——历史遗留的放置方式、命名例外、正在进行的迁移。读者需要知道“这看起来很奇怪,但这是有意为之”,以免试图“修复”它。
第 8 步 —(仅限单体仓库)构建 SYSTEM_MAP
每个项目的蓝图完成后,构建系统映射,涵盖:
- 项目清单及每个项目的作用
- 跨项目调用(调用方 → 被调用方 → 协议 → 契约)
- 明确标注跨语言边界及其规则
- 同语言边界(如有)
- 共享外部依赖(数据库、SaaS、队列)
对于每个跨项目边界,记录:
- 谁负责契约
- 哪些类型的更改需要协调
- 已采取的缓解措施
Step 9 — 写入前摘要
写入任何文件之前,先呈现:
Summary
- Projects: [list]
- Slices per project: [count]
- N=1 classified as: [singletons | templates | smells]
- Dimensions: [if any]
- Files to be written: [list of paths]
⏸ 停下并询问检查点 5:
"现在写入以上文件吗?还是先调整?"
Step 10 — 写入文件
仅在获得确认后执行。使用 assets/blueprint-template.md 和 assets/system-map-template.md 作为结构模板。
写入后,列出每个文件路径,并询问:"要我提交这些文件,还是你先审阅?" 未获得明确许可前,不要提交。
停下并询问检查点摘要
| # | 检查点 | 时间 |
|---|---|---|
| 1 | 项目列表 | Step 1 之后(始终) |
| 2 | 规范选择的决胜因素 | Step 4 期间(仅在有歧义时) |
| 3 | 维度标签 | Step 5 之后(仅在检测到维度时) |
| 4 | N=1 分类 | Step 6 之后(始终,批量询问) |
| 5 | 写入前 | Step 10 之前(始终) |
运行过程中,如果确实出现歧义,可选择询问:
- 切片命名:结构清晰,但名称不明显时
- 变体分类:有意变体还是意外偏差
- 切片状态:
CLAUDE.md未说明时,确认其状态(活跃/冻结/已弃用)
Agent 观察什么 vs 人类决定什么
Agent 观察(事实,无需询问):
- 文件夹结构及其重复次数
- 模块之间的导入关系
- 文件大小、方法数量
- 源码中的默认值
- 测试/DI 注册是否存在
- 与架构模式特征的匹配情况
人类决定(始终询问):
- N=1 属于单例、模板还是代码异味
- 名称不明显时的切片命名
- 规范项并列时,选择主要项还是高级项
- 变体是否有意设计
- 文档未说明时的状态(活跃/冻结/已弃用)
这一区分很重要:如果 Agent 擅自决定由人类判断的事项,蓝图就会掺入主观意见;如果由人类提供判断,蓝图就能以事实为依据。
此技能不会做什么
- 将反模式审查生成为持久文件(审查差异请使用
pr-antipattern-review;如有要求,也可临时运行通用扫描) - 建议重构
- 根据蓝图比较 PR(请使用
pr-antipattern-review) - 代替团队做架构决策
另请参阅
references/slice-discovery.md— 查找切片的详细启发式方法references/patterns.md— 架构模式特征(DDD、Hexagonal、Clean 等)references/universal-checks.md— 与项目无关的观察项(仅按需输出)assets/blueprint-template.md— 各项目的输出模板assets/system-map-template.md— 单体仓库的输出模板