代码导览 (Code Tour)
创建 CodeTour .tour 文件,用于代码库导览,这些导览可以直接打开到真实的文件和行范围。导览文件存放在 .tours/ 目录下,且应遵循 CodeTour 格式,而不是临时的 Markdown 笔记。
一个好的导览是为特定读者准备的叙述:
- 他们正在看什么
- 为什么它很重要
- 他们接下来应遵循什么路径
仅创建 .tour JSON 文件。不要将此技能用于修改源代码。
何时使用
在以下情况下使用此技能:
- 用户请求代码导览、上手导览、架构导览或 PR 导览
- 用户说“解释 X 是如何工作的”并希望得到一个可重复使用的引导式工件
- 用户希望为新手工程师或审查者提供一条快速上手路径
- 相比于平面摘要,引导式序列能更好地完成任务
示例:
- 为新维护者提供入职引导
- 为一个服务或包提供架构导览
- 锚定到已更改文件的 PR 审查导览
- 展示故障路径的根因分析导览
- 安全审查导览,涵盖信任边界和关键检查
何时不使用
| 不适合使用代码导览的情况 | 应使用 |
|---|---|
| 一次性的聊天解释就足够了 | 直接回答 |
用户想要散文风格的文档,而不是 .tour 工件 | documentation-lookup 或仓库文档编辑 |
| 任务是实现或重构 | 执行实现工作 |
| 任务是没有导览工件的宽泛代码库入职引导 | codebase-onboarding |
工作流程
1. 探索
在编写任何内容之前先探索仓库:
- README 和包/应用入口点
- 文件夹结构
- 相关配置文件
- 如果导览是针对 PR 的,则关注已更改的文件
在理解代码结构之前,不要开始编写步骤。
2. 推断读者
根据请求确定读者角色和深度。
| 请求类型 | 角色 | 建议步骤数 |
|---|---|---|
| “入职引导”、“新成员” | new-joiner | 9-13 步 |
| “快速导览”、“感受一下” | vibecoder | 5-8 步 |
| “架构” | architect | 14-18 步 |
| “导览这个 PR” | pr-reviewer | 7-11 步 |
| “为什么会出这个故障” | rca-investigator | 7-11 步 |
| “安全审查” | security-reviewer | 7-11 步 |
| “解释这个功能是如何工作的” | feature-explainer | 7-11 步 |
| “调试这个路径” | bug-fixer | 7-11 步 |
3. 读取并验证锚点
每个文件路径和行锚点必须是真实的:
- 确认文件存在
- 确认行号在范围内
- 如果使用选区,验证确切的代码块
- 如果文件经常变动,优先使用基于模式的锚点
永远不要猜测行号。
4. 编写 .tour 文件
写入到:
.tours/<角色>-<聚焦点>.tour
保持路径确定性和可读性。
5. 验证
在完成之前:
- 每个引用的路径都存在
- 每一行或选区都是有效的
- 第一步锚定到一个真实的文件或目录
ref指向一个确实包含导览中所有引用文件的分支或提交(见下文)- 导览讲述的是一个连贯的故事,而不是文件清单
ref 字段
ref 将导览绑定到一个 git 分支或提交。它比看起来更重要:当 ref 不是读者检出的分支时,CodeTour 会从该版本中打开每个步骤的文件,而不是从磁盘上的文件打开。如果该版本中不存在某个文件,步骤将无法打开——读者会看到 “编辑器无法打开,因为找不到该文件” ,即使该文件就在那里。导览及其注释仍然会显示,因此真正的原因很容易被忽略。
根据导览类型选择 ref:
| 导览类型 | 将 ref 设置为 |
|---|---|
| PR 导览 | PR 分支——永远不要设为基础分支 |
| 入职引导/架构导览 | 读者将检出的分支(通常为 main),或省略它 |
| 不确定 | 省略 ref,这样 CodeTour 会直接从磁盘读取文件 |
PR 场景是一个常见陷阱:PR 通常会添加新文件,而新文件在基础分支上还不存在。如果将 ref 指向基础分支(例如 develop),那么针对新文件的每个步骤都无法打开。
在完成之前,确认每个步骤的文件在你选择的 ref 上确实存在。
步骤类型
纯内容 (Content)
谨慎使用,通常仅用于结束步骤:
{ "title": "下一步", "description": "现在你可以端到端地跟踪请求路径了。" }
不要将第一步设为纯内容。
目录 (Directory)
用于将读者引导到一个模块:
{ "directory": "src/services", "title": "服务层", "description": "核心编排逻辑位于此处。" }
文件 + 行 (File + line)
这是默认的步骤类型:
{ "file": "src/auth/middleware.ts", "line": 42, "title": "认证关卡", "description": "每个受保护的请求都会首先经过这里。" }
选区 (Selection)
当某个代码块比整个文件更重要时使用:
{
"file": "src/core/pipeline.ts",
"selection": {
"start": { "line": 15, "character": 0 },
"end": { "line": 34, "character": 0 }
},
"title": "请求管道",
"description": "这个代码块串联了验证、认证和下游执行逻辑。"
}
模式 (Pattern)
当确切的行号可能发生变化时使用:
{ "file": "src/app.ts", "pattern": "export default class App", "title": "应用入口" }
URI
在必要时用于 PR、问题或文档:
{ "uri": "https://github.com/org/repo/pull/456", "title": "这个 PR" }
编写规则:SMIG
每个描述都应回答:
- 情境 (Situation):读者正在看什么
- 机制 (Mechanism):它是如何工作的
- 含义 (Implication):为什么这对该角色很重要
- 陷阱 (Gotcha):一个聪明的读者可能会错过什么
保持描述简洁、具体,并基于实际代码。
叙事弧线
除非任务明确需要不同的方式,否则使用这个弧线:
- 方向定位
- 模块地图
- 核心执行路径
- 边界情况或陷阱
- 结束/下一步操作
导览应感觉像一条路径,而不是一份清单。
示例
{
"$schema": "https://aka.ms/codetour-schema",
"title": "API 服务导览",
"description": "支付服务请求路径的导览。",
"ref": "main",
"steps": [
{
"directory": "src",
"title": "源代码根目录",
"description": "服务的所有运行时代码都从这里开始。"
},
{
"file": "src/server.ts",
"line": 12,
"title": "入口点",
"description": "服务器在此启动,并在任何路由被访问之前装配中间件。"
},
{
"file": "src/routes/payments.ts",
"line": 8,
"title": "支付路由",
"description": "每个支付请求在进入服务逻辑之前,都会首先通过此路由器。"
},
{
"title": "下一步",
"description": "现在,借助主要的锚点,你可以端到端地跟踪任何支付请求。"
}
]
}
反模式
| 反模式 | 修正方案 |
|---|---|
| 平面的文件清单 | 讲述一个步骤间有依赖关系的故事 |
| 泛泛的描述 | 指明具体的代码路径或模式 |
| 猜测的锚点 | 首先验证每个文件和行 |
| 快速导览的步骤过多 | 大幅削减 |
| 第一步是纯内容 | 将第一步锚定到真实文件或目录 |
| 角色不匹配 | 为实际读者编写,而不是泛泛的工程师 |
最佳实践
- 保持步数与仓库大小和读者深度成比例
- 使用目录步骤进行方向定位,使用文件步骤展示实质内容
- 对于 PR 导览,首先涵盖已更改的文件
- 对于单体仓库,将范围限定在相关包内,而不是导览全部
- 以读者现在可以做什么来结束,而不是重述
相关技能
codebase-onboardingcoding-standardscouncil- 官方上游格式:
microsoft/codetour