# Study Master

> 深入学习开源项目源码、协议规范和语言框架内部机制，生成教科书风格的学习文档

- Skill: `youngxai/study-master` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add youngxai/study-master`
- Raw SKILL.md: https://api.skillmd.com/api/skills/youngxai/study-master/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: YoungXAI (https://skillmd.com/u/youngxai)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/youngxai/study-master

---


# Study-Master Skill

## 概述

帮助程序员深入学习开源项目源码、协议栈实现（如 TCP/IP、HTTP）、特定编程语言或框架的内部机制。生成深度解析型学习文档，采用教科书风格，文档规模根据主题复杂度动态调整。支持在当前运行环境提供相应能力时自动检测并使用 LSP 增强代码分析。

## CLI 兼容约定

- 本 Skill 以“能力”而非某个 CLI 的固定工具名来描述步骤。文件搜索、文件读取、文本搜索、代码编辑、LSP 查询都应使用当前运行环境中可用的等价能力完成。
- 如果当前环境缺少某项能力，必须明确向用户报告缺口、说明退化方案，并继续使用可用能力完成分析；禁止把不存在的能力当作已存在。
- 上下文预算按当前模型和 CLI 的实际上限自适应，禁止假设固定的 “1M 上下文窗口” 必然可用。

## 强制目录结构

- `source/` — 源码目录
- `specs/` — 协议规范文档
- `study/<topic>/` — 学习文档输出目录（自动创建）

**规则**：至少 `source/` 或 `specs/` 之一必须存在。两者都不存在时拒绝执行并提示用户调整目录结构。

## 教科书风格原则

1. **先整体后局部**：先展示模块在系统中的位置，再深入细节
2. **先接口后实现**：先讲清楚"做什么"，再讲"怎么做"
3. **先主流程后边界**：先追踪正常执行路径，再分析错误处理
4. **先概念后代码**：先用自然语言解释设计思想，再展示代码

## 工作流程

### Phase 1：源码加载与分析

#### 1.1 源码定位与环境准备

1. 检查 `source/` 或 `specs/` 目录是否存在
2. 按优先级查找：`source/<topic>/` → `source/*<topic>*/` → `specs/<topic>/` → `specs/*<topic>*/` → `./<topic>/`（不区分大小写，支持部分匹配）
3. 找到多个候选时列出让用户选择
4. 解析 `<topic>` 参数，判断类型（项目/协议/语言内部机制）
5. 创建输出目录 `study/<topic>/`

#### 1.2 LSP 检测（C/C++ 项目必须优先尝试，其他语言按需执行）

**必须主动执行以下两步，不允许跳过或假设结果：**

1. **搜索 `compile_commands.json`**：使用当前环境可用的文件搜索能力，在源码根目录、上级目录、`build/` 子目录中查找
2. **测试 LSP**：如果当前环境提供 LSP/语言服务能力，对源码中的一个代表性源文件执行一次等价的文档符号查询（例如 `documentSymbol`），确认能返回符号列表；如果当前环境根本不提供该能力，必须明确记录为“环境不支持”

**必须向用户报告检测结果**：`✓ LSP 可用（找到 compile_commands.json，符号查询返回 N 个符号）` 或 `✗ LSP 不可用（原因）`。如果 LSP 可用，后续分析必须优先使用 LSP 能力而非纯文本搜索。

#### 1.3 全源码深度分析

在当前上下文预算内执行全源码深度分析；如果项目规模超过当前会话可承载范围，必须采用“分批加载源码 + 保留结构化摘要”的方式继续分析，而不是省略关键模块。

1. **源码加载**：使用当前环境可用的文件读取能力，把项目核心源文件和关键规范文档加载到上下文中
2. **结构分析**：根据 LSP 可用性选择分析方法，识别核心模块、热点函数和模块依赖关系

   | 分析任务 | LSP 可用 | LSP 不可用 |
   |---------|---------|-----------|
   | 符号列表 | 文档符号查询 / 符号索引 | 文本搜索函数定义 |
   | 核心 API | 引用查询统计调用方 | 基于入口位置、调用频次和命名推断 |
   | 模块依赖 | 基于符号位置和引用关系分组 | 扫描 `include` / `import` / `require` 等依赖声明 |
   | 调用关系 | 引用查询或调用层级查询 | 文本搜索函数名并人工校验误报 |
   | 调用树 | 调用层级能力 | 手动推断并在文档中标注“推断” |

3. **深度解读**：在拥有全部源码的上下文中分析每个模块的设计意图、职责边界、关键算法、模块间耦合关系和设计决策
4. **热点函数深度分析**：对每个核心函数，阅读完整实现，理解内部逻辑、错误处理策略和与其他模块的交互方式

#### 1.4 确定章节大纲

基于深度分析，确定章节划分和学习路径，明确列出所有需要生成的章节。

**必须完成以下准备（结论保留在上下文中，不写文件）：**

1. **计算 `source_path_prefix`**：统计 `study/<topic>/` 相对于项目根的目录层数，每层一个 `../`。例如 `study/redis/` 为 2 层 → `../../`。
2. **确定章节大纲和各章节的主要标题结构**：明确各章节会包含哪些核心结构体/函数的定义标题，以便串行生成时自然地内嵌前向和后向交叉引用。
3. **识别易混淆函数组**：扫描各模块的函数列表，按"前缀 + 模块名 + 操作"拆解命名，标记名称相似但用途不同的函数组（如 `ddsi_rmsg_xxx` vs `ddsi_rdata_xxx` 委托对），为 Section 2 的命名对比表做准备。

### Phase 2：串行生成文档

**策略：主对话优先串行生成所有章节。** 如果当前上下文预算充足，就保留全部源码、分析结论和前序章节；如果预算不足，就按模块重载必要源码和前序摘要，确保链路不断。

每一章都在拥有以下完整上下文的环境中生成：
- Phase 1 加载的全部源码
- Phase 1.3 的深度分析结论
- 所有已生成的前序章节内容（上下文累积）

生成顺序：`00-overview.md` → `01-xxx.md` → ... → `NN-xxx.md` → `appendix-references.md`

#### 2.1 逐章生成

按章节大纲顺序，使用当前环境可用的写文件能力依次生成每个章节。每章生成后必须立即重新读取该章节，自检乱码（U+FFFD）、链接、锚点和章节结构；发现问题立即修正。若当前环境已经安装自动校验 Hook，则继续依据 Hook 结果补充修正，但不能把自检责任完全交给 Hook。

**Overview 章节（00-overview.md）结构：**

1. **项目/协议简介**：背景、目标、核心特性
2. **核心概念速览**：关键术语、设计理念
3. **典型场景剖析**：选择 1-2 个典型场景，追踪完整执行路径
4. **架构全景图**：Mermaid 图展示系统整体结构
5. **学习路线图**：建议学习顺序，导航后续章节

**模块章节（01~NN-module-xxx.md）结构（8 节必须齐全）：**

1. **模块概述**：模块职责、在系统中的位置

2. **命名体系与易混淆函数对比**：本节分两个部分。

   **2.1 命名规律拆解**：将本模块所有函数名拆解为"前缀 + 模块名 + 操作"的组成部分，用表格展示命名规律。格式：

   | 前缀 | 模块/对象 | 操作 | 含义 |
   |------|----------|------|------|
   | `ddsi_` | `rmsg_` | `addbias` | 为 rmsg 的 refcount 增加一个 RDATA_BIAS |
   | `ddsi_` | `rdata_` | `addbias` | 委托层：转调 rmsg_addbias，附加 debug 断言 |

   末尾给出命名规律总结（1-3 条），例如："`ddsi_rdata_xxx` 是 `ddsi_rmsg_xxx` 的委托包装层，增加了 rdata 级别的断言检查"。

   **2.2 易混淆函数对比表**：列出本模块中名称相似、容易混淆的函数组，每组一张对比表。格式：

   | 对比维度 | 函数 A | 函数 B |
   |---------|--------|--------|
   | 操作对象 | ... | ... |
   | 调用者 | ... | ... |
   | 调用阶段 | ... | ... |
   | 附加逻辑 | ... | ... |
   | **一句话区分** | ... | ... |

   每张表最后一行必须是 **"一句话区分"** ，用最简洁的语言说清两者的本质差异。

3. **API Signatures**：该模块所有函数的完整签名（代码块）。开头附带调用关系图（Mermaid），展示函数之间的调用层次。每个函数包含两行注释：第一行说明用途，第二行以 `场景：` 开头说明何时/谁调用此函数。格式：

   ```c
   static void ddsi_rmsg_addbias (struct ddsi_rmsg *rmsg);
     // 为 rmsg 的 refcount 增加一个 RDATA_BIAS 偏置
     // 场景：defrag 模块决定保留某个 rdata 时，由接收线程在 uncommitted 阶段调用
   ```

   包括公开 API 和文档中分析到的内部函数，不可省略。

4. **数据结构深度解析**：每个结构体的分析包含以下子部分。

   **4.a 结构体存在的理由**：在展示结构定义之前，先用引用块回答"为什么需要这个结构体"，说明如果没有它系统会面临什么问题。

   **4.b 结构定义**：展示完整的 struct 定义源码（遵守真实代码忠实性规则）。

   **4.c 字段三层分析表**：每个字段一行，三列分析。格式：

   | 字段 | 设计动机（为什么需要） | 反事实（如果去掉会怎样） | 替代方案（还能怎么做） |
   |------|----------------------|------------------------|----------------------|
   | `field_name` | 需要它因为... | 如果去掉会导致... | 也可以用...，但代价是... |

   **4.d 生命周期状态图**：使用 Mermaid stateDiagram-v2 展示结构体从创建到销毁的完整状态流转。

5. **函数逐行精讲**：本模块所有函数都按以下统一格式做深度分析。

   **5.a 场景卡片**（每个函数开头必须有）：

   > **函数：`function_name`**
   > - **调用时机**：何时触发
   > - **典型调用者**：哪个函数/模块调用它
   > - **前置条件**：调用前必须满足的状态
   > - **目的**：一句话说明这个函数要解决什么问题

   **5.b 逐行注释式精讲**：展示函数完整源码（通过 Read 读取，遵守真实代码忠实性规则），每一行代码后面紧跟一行中文注释行，以 `// →` 开头。格式：

   ```c
   static void example_func (struct example *obj, int param)
   // → 函数签名：接收对象指针和参数
   {
   // → 函数体开始
     assert (param >= 0);
     // → 断言：param 不能为负，负值意味着上游逻辑有 bug
     obj->field = param;
     // → 将参数存入对象字段，后续 xxx 函数会读取此值
   }
   // → 函数体结束
   ```

   **逐行注释规则：**
   - 每一行源码（空行除外）后面必须有 `// →` 注释行
   - 注释不仅要说"这行做了什么"，还要说"为什么这样做"或"如果不这样做会怎样"
   - assert / trace / debug 宏也必须注释，解释它们在防御什么错误场景
   - 函数最后一个 `}` 后附带一行总结性注释，说明"如果执行到这里意味着什么"

6. **关键算法剖析**（标题示例：`## 6. 关键算法剖析`）：算法思想、时间复杂度、边界处理
7. **设计决策分析**（标题示例：`## 7. 设计决策分析`）：为什么这样设计、权衡考虑、替代方案。**注意：标题必须用中文，禁止写成 `Design Decisions`。**
8. **学习检查点**（标题示例：`## 8. 学习检查点`）：📝 本章小结（3-5 个要点）+ 🤔 思考题（2-3 个引导性问题，每题附折叠参考答案）

   **思考题格式要求：**

   每道思考题后必须附带一个折叠的参考答案，使用 HTML `<details>` 标签。参考答案必须基于源码事实，引用具体的文件名和行号（如适用），而非泛泛而谈。格式：

   ```markdown
   1. 思考题内容？（提示：...）

      <details>
      <summary>参考答案</summary>

      答案正文，引用源码行号和具体机制。可以包含代码片段。

      </details>
   ```

   **参考答案编写原则：**
   - 答案应直接回答问题，不绕弯子
   - 涉及源码机制的结论必须附带文件名和行号
   - 如果问题有多个层次（如"会发生什么？为什么？"），逐层回答
   - 答案长度控制在 3-8 行，避免过于冗长

**生成规范：**
- 遵循教科书风格四原则
- **正文中的标识符必须尽量可点击**：函数名、结构体名、文件名在正文、表格、列表中出现时，都应带超链接，指向源码行号或其他章节的定义标题。代码块、Mermaid 节点文本、逐行注释中的真实源码不强制可点击。
- **交叉引用**：提到其他章节已分析或将要分析的结构体/函数/概念时，必须链接到该章节对应标题。每章至少应有 2-3 个指向其他章节的交叉引用，建立章节间的知识网络。
- **Mermaid 图表**：每个模块章节至少 3 个 Mermaid 图：Section 3 的调用关系图（必须）、Section 4 的生命周期状态图（每个结构体一个）、以及至少 1 个辅助图（时序图/流程图等）。Section 5（函数逐行精讲）不要求 Mermaid 图，逐行注释本身即为最细粒度的展示。

## 格式规范

### 链接格式

- 必须使用相对路径（前缀为 `source_path_prefix`），禁止 `file:///` 绝对路径
- 链接文本不加反引号（反引号破坏超链接样式）
- **源码位置格式**：`> 📍 源码：[文件名:起始行-结束行](相对路径#L起始行)`（表格内只写文件名）
- **文档间交叉链接**：`[术语名](./目标文件.md#锚点)`，锚点遵循 GFM 规则（全小写，空格→`-`）
- **标题语言规则**：普通章节标题必须用中文（如 `## 1. 背景与目标`、`### 关键算法剖析`）。仅以下两类标题用英文：结构体定义标题（`### struct ddsi_xxx`）和 API 签名节标题（`## 3. API Signatures`）。子标题中出现技术术语时，中文在前、英文在括号中（如 `### 顺序分配器（Bump Allocator）`，禁止 `### Bump Allocator（顺序分配器）`）。跨文件引用英文标题时锚点自然是纯 ASCII，无需额外处理。跨文件引用中文标题时，引用方应链接到该文件中已有的英文标题（struct 或 API）而非中文小节标题。禁止使用 `{#id}` 自定义锚点语法。
- 有超链接 → 不加反引号；正文中暂时无法建立超链接的标识符 → 必须加反引号；真实源码代码块保持源码原样

### 图表格式

- **所有图表必须使用 Mermaid**，禁止 ASCII art / box-drawing 字符（`┌─┐│└┘├┤` 等）
- **内存布局例外**：嵌套包含关系 Mermaid 渲染效果差，改为生成独立 `.svg` 文件到 `study/<topic>/`，用 `![描述](文件名.svg)` 引用。禁止内嵌 SVG（渲染器会过滤）
- 节点文本 ≤ 25 字符，图表节点总数 ≤ 20
- **换行必须用 `<br/>`**：Mermaid 节点文本和 note 中需要换行时，必须使用 `<br/>`，禁止使用 `\n`（会被原样渲染为字面文本）。例如 `note right of A : 步骤一<br/>步骤二`

### 代码块

- 所有代码块必须指定语言标识（C: ` ```c `，Shell: ` ```bash `，Mermaid: ` ```mermaid `）
- **伪代码用最接近的语言标识**（C 风格伪代码用 ` ```c `），禁止用 ` ```text ` 包裹有编程语言语法特征的代码

#### 真实代码块忠实性

标注为"真实代码"的代码块必须通过当前环境可用的文件读取能力读取对应行范围后生成，遵守以下规则：

- **禁止删行**：源码中的每一行都必须保留，包括 trace/debug 宏（如 `RBPTRACE`、`RMSGTRACE`）、`assert`、日志输出等。这些行是源码的一部分，不是噪音
- **允许译注释**：`/* ... */` 和 `//` 注释内容可以翻译为中文，但注释行本身不得删除或合并
- **禁止改代码**：注释以外的所有代码行（函数调用、宏调用、赋值、控制流等）必须与源文件逐字一致，不得改写、重排或简化

### 数学表达式

- 所有数学符号必须用 LaTeX（`$2^{31}$`、`$\times$`、`$\geq$`），禁止 Unicode 数学符号（²³、×、≥、≤ 等）

### CJK 加粗格式

- 中文文本中 `**...**` 的开闭标记两侧必须各有一个空格：`前文 **加粗内容** 后文`
- 原因：CommonMark 规范的 delimiter flanking 规则在"全角标点 + `**` + 汉字"边界会导致加粗渲染失败。例如 `）**的` 中闭合 `**` 前是标点、后是非标点非空白，不满足 right-flanking 条件
- 安全做法：始终在 `**` 外侧留空格，可 100% 规避此问题

### 文本编码

- UTF-8，禁止 box-drawing Unicode 字符（`│`, `├`, `└`, `─` 等）

### Phase 2.2：生成参考索引

所有章节完成后，生成 `appendix-references.md`（参考资料索引）。

### Phase 3：收尾

1. 创建 `.study-meta.json`：

   ```json
   {
     "topic": "主题名",
     "source_path": "源码路径",
     "generated_at": "时间戳",
     "lsp_enabled": true/false,
     "chapters": ["00-overview.md", "01-xxx.md", ...]
   }
   ```

2. 输出最终报告：

   ```
   ✅ 学习文档生成完成！
   📍 位置：study/<topic>/
   📚 章节数：Y 个
   🔧 LSP 增强：已使用/未使用
   ```

## 文档结构概要

| 文件 | 内容 |
|------|------|
| `00-overview.md` | 快速导览：项目简介、核心概念、典型场景、架构图、学习路线 |
| `01-module-xxx.md` | 模块深度解析（8 节）：概述、命名消歧、API 签名（含场景）、数据结构（三层字段分析）、函数逐行精讲（场景卡片 + 逐行注释）、算法、设计决策、检查点 |
| `appendix-references.md` | 参考资料索引 |
| `.study-meta.json` | 元数据 |

