关于 book-to-skill
book-to-skill 将书籍和其他文档中的结构化知识转化为可复用的 Agent 技能,适用于构建或维护技能的用户。它提取框架、原则、方法和反模式,而非生成内容摘要,并支持分析、完整转换及更新现有技能。
主要功能
- 01从文档提取结构化知识
- 02提取框架、原则与技巧
- 03支持分析后再生成
- 04更新并合并现有技能
- 05适配多种 Agent 技能目录
适用场景
- 01将技术书籍转化为可执行技能
- 02先审阅知识提取结果再生成
- 03把新资料并入已有技能
- 04为不同 Agent 环境创建技能
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ virgiliojr94/ book-to-skill --skill book-to-skill安装后在 Claude Code 中输入/book-to-skill确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreAGENTS.mdCHANGELOG.mdBACKERS.mdCLAUDE.mdCONTRIBUTING.mdREADME.mdLICENSE.mdREADME.ru.mdSECURITY.mdSECURITY-NOTICE.mdREADME.zh-CN.md.github/FUNDING.ymldependabot.ymlPULL_REQUEST_TEMPLATE.md.github/ISSUE_TEMPLATE/bug_report.mdfeature_request.md.github/workflows/codeql.ymldeploy-docs.ymlci.ymlbook_to_skill/__main__.pyconfig.py__init__.pycli.pyexceptions.pydependencies.pybook_to_skill/parsers/__init__.pycalibre.pydocx.pyepub.py详细介绍
书籍转技能转换器
通过提取结构,将书面知识转化为可操作的 Agent 技能——而不是生成摘要。
理念
书籍中凝聚着结晶化的专业知识:历经多年发展而成的框架、原则和技术。本技能将这些知识提取为一种格式,使 GitHub Copilot CLI、Amp、Claude Code、Hermes Agent、OpenCode、OpenClaw 或其他兼容 Agent 能够反复利用。 提取结构,而非摘要。 技能不是读书报告。它是一套工具包,包含:
- 命名框架(具有明确应用场景的思维模型)
- 可操作原则(指导决策的规则)
- 技术(分步方法)
- 反模式(应避免什么以及为什么)
- 语气校准(作者如何思考与表达)
保留作者的精确性。 框架之所以有特定名称,往往有其原因。「5 Why」不能与「多次问为什么」互换。要捕捉确切的表述。
恰当地分层深度。 简单的书 → 简单的技能。包含 10+ 个框架的复杂书籍 → 带有参考文件和按需章节的技能。
操作模式
提供四条路径。根据用户的请求进行路由:
1. 完整转换(默认)
触发: 用户在无特殊说明的情况下提供一个或多个文档/目录/glob 路径 操作: 运行以下所有步骤(步骤 0–9) 输出: 完整技能,包含 SKILL.md、chapters/、术语表、模式、速查表
2. 仅分析
触发: 用户说「分析」、「只提取」或「我想在生成前先审阅」 操作: 运行步骤 0–3,然后生成结构化提取报告(发现的框架、原则、技术)。停止——不要生成技能文件。 输出: 供用户审阅的分析报告
3. 基于先前分析生成
触发: 用户已有分析笔记,或之前运行过仅分析模式 操作: 跳过步骤 0–3,将提供的分析作为输入,运行步骤 4–9 输出: 基于所提供分析的技能文件
4. 更新 / 合并(现有技能)
触发: 用户提供一个或多个新源路径,并表示希望更新现有技能(通过指向现有技能文件夹、提供已存在于 SKILLS_HOME 中的技能 slug,或明确请求更新)。
操作: 运行步骤 0(范围外检查)、步骤 1(验证输入)、步骤 1.5(识别书籍类型)和步骤 2(提取新文件)。然后跳到步骤 5(识别/检测现有技能路径),并运行更新 / 合并工作流,将新内容合并到现有技能文件中。
输出: 更新后的现有技能,包含新增/修订的章节摘要以及合并后的索引/术语表。
技能位置
此转换器可以从多个技能系统运行。在查找此转换器的辅助脚本或写入生成的 book 技能时,请按顺序优先使用以下位置:
- GitHub Copilot CLI 个人技能:
~/.copilot/skills/ - 跨 Agent 个人技能(Copilot、Amp、Codex;OpenClaw 及其默认状态):
~/.agents/skills/ - Claude Code 个人技能:
~/.claude/skills/ - 项目本地 Copilot 技能:
.github/skills/ - 项目本地 Claude 技能:
.claude/skills/ - 项目本地 Amp / Copilot / OpenClaw 技能:
.agents/skills/ - Amp 全局技能:
~/.config/agents/skills/ - Amp 旧版全局技能:
~/.config/amp/skills/ - Hermes Agent 个人技能:
$HERMES_HOME/skills/(默认为~/.hermes/skills/) - Hermes Agent 项目技能:
.hermes/skills/或.agents/skills/ - OpenClaw 个人技能:
${OPENCLAW_STATE_DIR:-~/.openclaw}/skills/(活动状态;~/.agents/skills/仅与默认状态共享) - OpenClaw 项目技能:
.agents/skills/或skills/ - OpenCode 个人技能:
~/.config/opencode/skills/或~/.agents/skills/ - OpenCode 项目技能:
.opencode/skills/或.agents/skills/
对于生成的 book 技能,优先使用用户级跨 Agent 根目录 ~/.agents/skills/ —— 一份物理副本即可服务于跨 Agent 主机以及使用默认状态的 OpenClaw。Copilot CLI 和 Amp 可原生发现它;Claude Code 需要从 ~/.claude/skills/<skill_name> 创建符号链接(在第 10 步中创建,规则见第 5 步)。仅当用户明确要求时,才选择主机私有或项目本地根目录。BOOK_TO_SKILL_SCOPE=project 或 personal 可以为自动化明确该选择;不要仅仅因为两种范围都可用就询问必答的范围问题。
Step 0 — 范围外检查
如果未提供任何参数,则停止并回复:
“book-to-skill 需要一个支持的文档路径、文件夹或 glob 模式。用法:
book-to-skill <path-to-document-folder-or-glob>... [skill-name-slug]”
在整个工作流中:
- 首先解析目标根目录。 在任何现有技能查找之前,先确定本次运行将写入哪里:根据 Step 5 表格和选择规则,确定用户主机的个人根目录或项目本地根目录——项目本地请求使用其项目本地根目录,绝不使用个人根目录。下文中,“解析出的根目录”即指该目标位置。
- 识别输入路径以及可选的技能 slug。
- 如果最后一个参数不是存在的文件、文件夹,或不存在或不匹配任何文件的 glob,并且它看起来像技能 slug(例如小写连字符、字母数字),则将其视为
SKILL_NAME。 - 将所有其他参数视为
INPUT_PATHS列表。 - 如果任何输入路径是现有技能目录(包含
SKILL.md和chapters/子文件夹),或者如果SKILL_NAME与解析出的根目录中现有技能 slug 匹配,则将本次运行标记为 Update/Fold-in 操作(Mode 4)。 - 重跑防护。 在开始 Full Conversion 的提取之前,根据 Step 5 的命名选项推导出预期技能 slug——作者概念形式、按标题形式,以及任何给定的
SKILL_NAME——并在解析出的根目录中检查是否存在匹配项。若匹配,STOP 并询问用户:“<skill-name>已存在。请选择:(1) Update/Fold-in(Mode 4),(2) 验证现有技能完整并停止,或 (3) 强制完全重新生成。” 在用户选择之前,不要重新提取。在一次中断运行(网络中断、重放或继续的对话)后的上下文恢复中,重用该次运行报告的提取工作目录(其输出中的Workdir ->,或你在BOOK_SKILL_WORKDIR中设置的路径),前提是它仍然完整且仍然匹配当前输入和选项——该目录存在,其metadata.json可读,它列出的sources与当前正在转换的文件在文件名和内容指纹上一一匹配(提取器在metadata.json中记录每个源的sha256;根据每个文件当前存在状态重新计算指纹,并要求完全匹配——book_to_skill/utils.py中的reuse_is_safe()是此检查的可执行形式),并且其记录的extraction_mode是本次运行正在使用的模式(Step 2 的“确认提取内容就是你要求的文档”规则)。如果它缺失(临时清理)、其metadata.json已不存在、源不再匹配(文件名不同,或内容指纹已更改)、记录的元数据中某个源没有sha256(在指纹功能存在之前记录,因此无法确定新鲜度),或模式不同,则说明情况并开始全新提取,而不是恢复。如有疑问,在丢弃或恢复之前询问用户。
Step 1 — 验证输入
验证 INPUT_PATHS 中至少有一个受支持的文件、目录或 glob 模式。
对于目录和 glob,展开它们以查找匹配的受支持文件(.pdf、.epub、.docx、.txt、.md、.markdown、.rst、.adoc、.html、.htm、.rtf、.mobi、.azw、.azw3)。
如果未找到受支持文件,则以清晰的错误消息停止。
步骤 1.5 — 识别内容类型
在提取之前,询问用户:
“这些来源包含什么样的内容?这有助于我选择最佳的提取方法。
- 技术类 — 包含代码块、表格、公式、图表(例如编程书籍、学术论文、架构指南)
- 文本为主 — 主要是散文,几乎没有表格/代码(例如管理、生产力、叙事类非虚构作品)
- 不确定 — 我会使用快速方法,如果质量似乎有限会提醒你”
将答案保存为 BOOK_TYPE:
- 选项 1 →
BOOK_TYPE=technical - 选项 2 →
BOOK_TYPE=text - 选项 3 →
BOOK_TYPE=text
如果 BOOK_TYPE=technical,在继续之前告知用户:
“📐 已选择技术模式 — 使用 Docling 进行结构感知提取(表格、代码块、公式以 markdown 形式保留)。每页约需 1.5 秒,因此较长的来源预计需要几分钟。现在开始……”
如果 BOOK_TYPE=text,告知:
“📄 已选择文本模式 — 为每种文件类型使用最合适的快速提取器。纯文本/Markdown/HTML 通常几秒即可完成;PDF 在可用时使用 pdftotext。”
步骤 2 — 从源文档中提取文本
运行提取脚本,传入输入路径:
SCRIPT_PATH=""
HERMES_HOME_RESOLVED="${HERMES_HOME:-$HOME/.hermes}"
OPENCLAW_STATE_DIR_RESOLVED="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
HERMES_PROJECT_TRUSTED=false
if [ -n "$PROJECT_ROOT" ] && [ "${HERMES_AGENT:-}" = true ] && \
command -v hermes >/dev/null 2>&1 && \
command -v python3 >/dev/null 2>&1 && \
hermes config get skills.trusted_project_dirs --json 2>/dev/null | PROJECT_ROOT="$PROJECT_ROOT" python3 -c 'import json, os, pathlib, sys; root=pathlib.Path(os.environ["PROJECT_ROOT"]).resolve(); sys.exit(not any(pathlib.Path(p).expanduser().resolve() == root for p in json.load(sys.stdin)))' 2>/dev/null
then
HERMES_PROJECT_TRUSTED=true
fi
CANDIDATES=(
"$HOME/.copilot/skills/book-to-skill/scripts/extract.py"
"$HOME/.agents/skills/book-to-skill/scripts/extract.py"
"$HOME/.claude/skills/book-to-skill/scripts/extract.py"
"${OPENCLAW_STATE_DIR_RESOLVED}/skills/book-to-skill/scripts/extract.py"
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/book-to-skill/scripts/extract.py
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/*/book-to-skill/scripts/extract.py
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/*/*/book-to-skill/scripts/extract.py
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/*/*/*/book-to-skill/scripts/extract.py
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/*/*/*/*/book-to-skill/scripts/extract.py
"${OPENCLAW_STATE_DIR_RESOLVED}/skills"/*/*/*/*/*/*/book-to-skill/scripts/extract.py
"$HOME/.config/opencode/skills/book-to-skill/scripts/extract.py"
"$HERMES_HOME_RESOLVED/skills/book-to-skill/scripts/extract.py"
"$HERMES_HOME_RESOLVED"/skills/*/book-to-skill/scripts/extract.py
)
if [ "${HERMES_AGENT:-}" != true ]; then
# Project-local roots are resolved against the git worktree, not the current
# directory: an agent can be invoked from anywhere inside the project (e.g.
# `src/nested`) and these roots still have to be found — that is how OpenCode
# and the other hosts discover project skills. The CWD-relative forms are kept
# so the probe also works outside a git repository.
if [ -n "$PROJECT_ROOT" ]; then
CANDIDATES+=(
"$PROJECT_ROOT/.github/skills/book-to-skill/scripts/extract.py"
"$PROJECT_ROOT/.claude/skills/book-to-skill/scripts/extract.py"
"$PROJECT_ROOT/.agents/skills/book-to-skill/scripts/extract.py"
"$PROJECT_ROOT/.opencode/skills/book-to-skill/scripts/extract.py"
)
fi
CANDIDATES+=(
".github/skills/book-to-skill/scripts/extract.py"
".claude/skills/book-to-skill/scripts/extract.py"
".agents/skills/book-to-skill/scripts/extract.py"
"skills/book-to-skill/scripts/extract.py"
"skills"/*/book-to-skill/scripts/extract.py
"skills"/*/*/book-to-skill/scripts/extract.py
"skills"/*/*/*/book-to-skill/scripts/extract.py
"skills"/*/*/*/*/book-to-skill/scripts/extract.py
"skills"/*/*/*/*/*/book-to-skill/scripts/extract.py
"skills"/*/*/*/*/*/*/book-to-skill/scripts/extract.py
".opencode/skills/book-to-skill/scripts/extract.py"
)
if [ -n "$PROJECT_ROOT" ]; then
CANDIDATES+=(
"$PROJECT_ROOT/skills/book-to-skill/scripts/extract.py"
"$PROJECT_ROOT/skills"/*/book-to-skill/scripts/extract.py
"$PROJECT_ROOT/skills"/*/*/book-to-skill/scripts/extract.py
"$PROJECT_ROOT/skills"/*/*/*/book-to-skill/scripts/extract.py
"$PROJECT_ROOT/skills"/*/*/*/*/book-to-skill/scripts/extract.py
"$PROJECT_ROOT/skills"/*/*/*/*/*/book-to-skill/scripts/extract.py
"$PROJECT_ROOT/skills"/*/*/*/*/*/*/book-to-skill/scripts/extract.py
)
fi
fi
CANDIDATES+=(
"$HOME/.config/agents/skills/book-to-skill/scripts/extract.py"
"$HOME/.config/amp/skills/book-to-skill/scripts/extract.py"
)
if [ "$HERMES_PROJECT_TRUSTED" = true ]; then
CANDIDATES=(
"$PROJECT_ROOT/.hermes/skills/book-to-skill/scripts/extract.py"
"$PROJECT_ROOT/.hermes/skills"/*/book-to-skill/scripts/extract.py
"$PROJECT_ROOT/.agents/skills/book-to-skill/scripts/extract.py"
"$PROJECT_ROOT/.agents/skills"/*/book-to-skill/scripts/extract.py
"${CANDIDATES[@]}"
)
fi
for candidate in "${CANDIDATES[@]}"
do
if [ -f "$candidate" ]; then
SCRIPT_PATH="$candidate"
break
fi
done
if [ -z "$SCRIPT_PATH" ]; then
echo "Could not find scripts/extract.py for book-to-skill" >&2
exit 1
fi
PYTHON_BIN="${PYTHON_BIN:-python3}"
if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
PYTHON_BIN="python"
fi
"$PYTHON_BIN" "$SCRIPT_PATH" $INPUT_PATHS --mode <BOOK_TYPE> --install-missing ask
在提取之前,脚本会检查检测到的格式所需的可选 Python 包。如果缺少更好的提取器,它会向用户提示可用的回退方案。除非安装模式明确为 yes,否则非交互式会话默认使用回退方案。
提示 — 预检环境: 运行 "$PYTHON_BIN" "$SCRIPT_PATH" --check,即可打印一份按格式划分的报告,说明已安装哪些提取器,以及安装缺失项的确切命令,而无需处理任何文件。当用户报告设置或质量问题时很有用。
这会创建一个每次运行独立的工作目录 — 默认是 <tempdir>/book_skill_work-<pid>/,或者你在 BOOK_SKILL_WORKDIR 中设置的确切路径 — 其中包含:
full_text.txt— 所有来源合并后的提取文本,带有清晰直观的分隔边界。metadata.json— 整体合并后的大小、词数、页数、token 计数、丢弃的 EPUB 图片数量、解析后的workdir,以及各个已处理sources的详细列表。
运行完成后会打印全部三个路径(Workdir ->、Text ->、Meta ->)。请从该输出中(或从 metadata.json 自带的 workdir 字段中)获取这些路径,而不要假设固定位置 — 目录名每次运行都不同,这样同一台机器上的并发提取就不会互相覆盖结果。
读取该次运行的 metadata.json 以检查结果。
在生成任何内容之前,务必确认提取出的正是你所要的文档:检查 metadata.json 中的 filename / source_file,或 full_text.txt 第一行的 SOURCE: 头。如果你在等待某个后台运行,请等待它的特定 workdir — 轮询共享路径可能会显示另一次运行的输出。
步骤 2.5 — 预检成本估算
读取本次运行的 metadata.json(提取输出中的 Meta -> 路径),并在进行任何生成之前向用户展示估算:
📖 Sources detected: <total_sources> source(s)
<list each source filename and format from the sources metadata list>
<if images_dropped > 5: warn that N source images were not read>
📄 Combined Pages/Sections: ~<N> | Words: ~<N> | Total tokens: ~<N>K
💰 Estimated token cost (Full Conversion / Update):
Input (reading + prompts): ~<N>K tokens
Output (skill files generated/updated): ~<N>K tokens
Total: ~<N>K tokens
Cost: multiply the token counts above by your model's current
input/output per-1M-token rates (prices and model names change often —
do not hardcode them; quote today's rate and label it as an estimate).
⏱ Estimated time: ~<N> minutes
📁 Files to be generated/updated:
SKILL.md + chapter files + glossary + patterns + cheatsheet
➡ Proceed with Full Conversion / Update? (or type "analyze only" to preview first)
如何估算:
- 输入 token ≈ metadata 中的
estimated_tokens× 1.3(每章处理的提示词开销) - 输出 token ≈ 章节数 × 每章预算 + 4,000(SKILL.md)+ 4,500(术语表 + 模式 + 速查表)
- 按
BOOK_TYPE的每章预算中值(DEPTH 在步骤 4 中稍后决定,且可提高该值):text≈ 1,000,technical≈ 1,800。如果用户已表明是仅作参考还是深入学习,则使用步骤 7 矩阵中对应的那一行。
- 按
- 成本:报告 token 数量,并乘以用户当前的每百万 token 输入/输出费率。不要硬编码美元金额 — 模型名称和价格会变化;如果你展示一个,请标注为估算值并注明日期。
等待用户确认后再继续。如果他们表示“仅分析”,则切换到模式 2。
第 2.6 步 — 面向大型书籍(> 50k tokens)的 REPL 式访问
受递归语言模型(RLM)范式的启发:将 full_text.txt 视为可查询的语料库,而非一次性的读取对象。将整个文件加载进上下文会消耗你后续生成时所需的预算。
对于超过约 50k tokens 的书籍,优先使用程序化探测,而不是不带边界地 Read(full_text.txt):
# Size check before any Read
wc -w "$FULL_TEXT_PATH"
# Find chapter offsets without loading the whole file
grep -n -E "^\s*(Chapter|CHAPTER)\s+[0-9]+" "$FULL_TEXT_PATH" | head -40
# Pull only the chapter you need (lines start..end inclusive)
sed -n '<start>,<end>p' "$FULL_TEXT_PATH"
# Verify a framework is actually mentioned before claiming it in SKILL.md
grep -c -i "westrum\|dora" "$FULL_TEXT_PATH"
# Targeted Read with offset/limit avoids dumping the full file
# Read(file_path=full_text.txt, offset=<line>, limit=<lines>)
在第 3 步(结构分析)、第 7 步(逐章摘要)和第 8 步(术语表 / 模式提取)中采用此方法。对于 50k tokens 以下的书籍,单次 Read 即可。
为什么这很重要:一本 200 页的书约 75k tokens。每章重读一次(28 遍)会消耗约 2M 输入 tokens;使用 grep + sed 只提取相关片段,能让生成成本与输出成正比,而非与源文本成正比。
第 3 步 — 分析书籍结构
读取提取出的 full_text.txt 的前 8,000 个字符,以识别:
- 书籍 标题 和 作者
- 章节结构(寻找 "Chapter N"、"PART I"、编号标题、目录)
- 核心主题 和学科领域
- 大致章节数量
然后读取目录部分(如果存在),以映射所有章节。
如果模式为 "Analyze Only": 立即生成提取报告并停止。结构:
## Extraction Report — <Title>
### Author's Core Frameworks
- **<Framework Name>**: <what it is and when to apply>
### Key Principles
- <Principle>: <actionable rule>
### Techniques & Methods
- <Technique>: <step-by-step or how-to>
### Anti-patterns
- <What to avoid>: <why>
### Suggested Skill Name
`{author-lastname}-{core-concept}` — e.g. `cialdini-influence`
### Chapters Detected
| # | Title | Main Frameworks |
第 4 步 — 询问用途(仅限完整转换)
在生成之前,询问用户:
"这个 skill 应该帮助你做什么?(可多选)
- 在工作中应用作者的框架
- 用作者的心智模型进行思考
- 参考具体章节和概念
- 以上全部"
使用答案来决定 SKILL.md 核心部分中突出显示的内容。
根据答案推导 DEPTH(无需额外提示):
- 答案 仅 为选项 3(参考)→
DEPTH=reference— 精简、快速查阅的章节。 - 答案包含选项 1、2 或 4 →
DEPTH=study— 更深入的章节,包含更多实操细节、示例和推理。
DEPTH 和 BOOK_TYPE 共同决定第 7 步中每章的 token 预算。不要 单独询问 "study vs reference" 问题 — 在此处推断。(在模式 2/3 中,跳过第 4 步时,默认 DEPTH=study。)
第 5 步 — 确定 skill 名称
如果提供了 SKILL_NAME,则将其用作 skill slug。
否则,提出两个选项并让用户选择:
- 按作者-概念:
{author-lastname}-{core-concept}(例如cialdini-influence、meadows-systems) - 按标题:书籍标题的小写连字符形式(例如
designing-data-intensive-apps)
如果书籍具有强烈的方法论特征,默认使用作者-概念格式。
选择目标 skill 根目录(SKILLS_HOME)。首先根据明确的用户请求或 BOOK_TO_SKILL_SCOPE 解析 范围,然后探测 宿主。请求项目本地/项目输出会选择项目本地行;请求个人/全局输出会选择个人行。如果两个范围都未被请求,则保留既定的个人默认值(非 Hermes 宿主为 ~/.agents/skills)。不要仅因为存在项目本地根目录就强制询问范围问题。选定的根目录在写入前仍可能需要宿主批准。
| 宿主 Agent | 个人 skill 根目录 | 项目本地根目录 |
|---|---|---|
| GitHub Copilot CLI | ~/.agents/skills(原生发现) | .github/skills → .claude/skills → .agents/skills |
| Amp | ~/.agents/skills(原生发现) | .agents/skills |
| OpenAI Codex | ~/.agents/skills(原生发现;跟随符号链接) | .agents/skills |
| Hermes Agent | $HERMES_HOME/skills/<category>(默认为 ~/.hermes/skills/<category>) | .hermes/skills/<category> → .agents/skills |
| Claude Code | ~/.agents/skills + 来自 ~/.claude/skills/<skill_name> 的符号链接 | .claude/skills |
| OpenClaw | ${OPENCLAW_STATE_DIR:-~/.openclaw}/skills(活动状态;仅默认状态下为 ~/.agents/skills) | .agents/skills → skills/ |
Hermes Agent 是唯一保留自身个人根目录的宿主:它按类别划分个人技能,并且不会扫描跨 Agent 根目录。使用当前活跃 profile 的 HERMES_HOME,并选择一个与所生成技能主题匹配的类别。不要手动构造 profile 路径。如果用户选择了项目本地的 Hermes 根目录,请在生成后运行 hermes skills trust <project-root>,并用 hermes skills list 验证能否被发现;在项目被信任之前,项目技能一直不可用。 |
对于 OpenClaw,使用当前活跃状态目录的 skills/ 根目录:${OPENCLAW_STATE_DIR:-~/.openclaw}/skills/。共享的 ~/.agents/skills 兼容根目录只有在 OPENCLAW_STATE_DIR 未设置或为默认值 ~/.openclaw 时才可被发现;如果状态目录非默认,不要声称 OpenClaw 能看到共享根目录的安装。生成后用 openclaw skills list 验证能否被发现。
| OpenCode | ~/.agents/skills(可原生发现;~/.config/opencode/skills 和 ~/.claude/skills 也会被读取) | .opencode/skills → .agents/skills → .claude/skills |
Hermes Agent 是唯一保留自身个人根目录的宿主:它按类别划分个人技能,并且不会扫描跨 Agent 根目录。使用当前活跃 profile 的 HERMES_HOME,并选择一个与所生成技能主题匹配的类别。不要手动构造 profile 路径。如果用户选择了项目本地的 Hermes 根目录,请在生成后运行 hermes skills trust <project-root>,并用 hermes skills list 验证能否被发现;在项目被信任之前,项目技能一直不可用。
OpenCode 可原生扫描跨 Agent 的 ~/.agents/skills 根目录,因此上文中的生成技能默认位置已能满足它——无需符号链接,也无需信任步骤。它还会读取自己管理的 ~/.config/opencode/skills 根目录以及 Claude 兼容根目录 ~/.claude/skills;只有在用户要求时才使用 OpenCode 管理的根目录。项目技能是通过从工作目录向上查找到 git 工作树来发现的,因此如果生成后技能没有出现,请启动一个新会话。(~/.cache/opencode/skills 是来自 skills.urls 的远程技能下载缓存,不是创作根目录——绝不要把生成的技能写入那里。)
选择规则:
- 个人安装:将
SKILLS_HOME设为~/.agents/skills(如果目录不存在则创建)。有一个例外,以免默认行为在别人的地盘上凭空发明约定:如果~/.agents/skills不存在 且 宿主的私有根目录中已包含技能,则改用该私有根目录,并在报告中说明原因。 - Claude Code 不会扫描
~/.agents/skills——生成完成后,第 10 步会用ln -sfn "$HOME/.agents/skills/<skill_name>" "$HOME/.claude/skills/<skill_name>"将技能链接进去。 - Hermes Agent 个人安装使用上方的 Hermes 行,而不是跨 Agent 根目录,并且不创建符号链接。
- 如果用户明确要求使用宿主私有根目录(
~/.copilot/skills、~/.claude/skills、~/.config/agents/skills、~/.config/amp/skills),请遵照执行并跳过符号链接。 - 如果用户明确要求项目本地输出,请使用其宿主对应的项目本地行。
- 如果该选择需要知道宿主身份(项目本地输出、Hermes 个人根目录、OpenClaw 状态根目录或 Claude Code 符号链接),而你无法确定,请询问:“你运行的是哪个 Agent——OpenCode、OpenClaw、Hermes Agent、GitHub Copilot CLI、Amp、Codex 还是 Claude Code?”
- 对于 OpenClaw 个人输出,使用
${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/skills。共享的~/.agents/skills根目录只有在OPENCLAW_STATE_DIR未设置或等于默认值$HOME/.openclaw时才是有效的 OpenClaw 目标;否则请使用当前活跃状态根目录或项目/额外目录。 - 如果用户明确要求使用 OpenClaw 管理的个人根目录,请使用当前活跃状态根目录,并用
openclaw skills list验证能否被发现。 将SKILLS_HOME设置为选定的根目录,并检查$SKILLS_HOME/<skill_name>/是否已存在。在 Claude Code 上,还要检查~/.claude/skills/<skill_name>是否作为真实目录(而非符号链接)存在——之前的安装可能就位于那里;如果是这样,在继续之前主动提出迁移它(将该目录移动到~/.agents/skills/,并用符号链接替换原路径)。 如果该技能已存在,提示用户选择: - 更新 / 折叠合并(模式 4)——将新文件/内容整合到现有技能组件中。
- 覆盖——删除并从头重新生成该技能。
- 重命名——追加
-2或使用不同的自定义 slug。
如果用户选择更新 / 折叠合并,则在步骤 2.5 之后立即进入更新 / 折叠合并工作流部分(跳过步骤 3、4、6、7、8、9)。
步骤 6 — 创建技能目录结构
mkdir -p "$SKILLS_HOME/<skill_name>/chapters"
步骤 7 — 生成章节摘要
Token 预算规则 — 关键(自适应):
每章预算随 BOOK_TYPE 和 DEPTH 而缩放。技术类章节需要为代码和表格留出空间;学习深度需要为逐步推理留出空间。从以下矩阵中选择预算:
DEPTH=reference | DEPTH=study | |
|---|---|---|
BOOK_TYPE=text | 800–1,200 tokens | 1,000–1,800 tokens |
BOOK_TYPE=technical | 1,200–1,800 tokens | 2,000–3,000 tokens |
- 这些是每个文件的目标值,而非硬性上限——内容密集的章节可能超出,内容单薄的章节可能低于。密度仍然胜过长度(质量规则 #3):绝不要为了凑数而填充。
- 文件是按需加载的,因此更大的章节只有在实际被读取时才会消耗 token。
- 在两个单元格之间难以抉择时(例如混合内容的书),使用较低的预算,让深度来自精确而非体量。
DEPTH=study 是靠内容赢得的,而不是靠更大的数字。 标准章节模板(核心思想 → 关联到)自然会让内容密集的散文章节落在 700–900 tokens 左右。要诚实地——而非通过填充——达到学习预算,学习深度的章节必须添加具体材料:
- 复现一个来自该章节的完整示例或产物(例如示例新闻稿、一段对话样本、一份填好的模板、作者逐步推演的一个决策),放在
## Worked Example部分下。这是最大的杠杆,也是学习者回访的主要原因。 - 将每个框架的“如何做”扩展为明确的步骤或标准,而非一句话。
- 为排名前 1–2 的框架添加简短的“为何有效 / 失败模式”注释。
如果某个章节确实没有完整示例且难以扩展,就让它落在学习下限之下,而不是填充——并在其核心思想中注明该章节内容单薄。相比之下,reference 深度的章节会刻意省略完整示例,只保留可直接用于决策的要点。
对于在步骤 3 中识别出的每一个章节/主要部分:
阅读提取出的 full_text.txt 中对应的部分(使用字符偏移量或 grep 查找章节标题)。
使用以下结构创建 $SKILLS_HOME/<skill_name>/chapters/ch<NN>-<slug>.md。
根据 BOOK_TYPE 调整侧重:
technical→ 优先处理“代码示例”、“参考表”和“命令与 API”部分;保留精确语法text→ 优先处理“引入的框架”、“心智模型”和“关键要点”;跳过空的技术性部分
# Chapter N: <Full Title>
## Core Idea
<1–2 sentences: the single most important thing this chapter teaches>
## Frameworks Introduced
- **<Framework Name>**: <exact formulation — preserve the author's naming>
- When to use: <specific situation>
- How: <steps or criteria>
## Key Concepts
- **<Term>**: <precise definition in 1 sentence>
(5–10 most important terms from this chapter)
## Mental Models
<2–4 frameworks or thinking tools. Write as "Use X when Y" or "Think of X as Y">
## Anti-patterns
- **<What to avoid>**: <why it fails>
## Code Examples *(technical books only — omit if BOOK_TYPE=text)*
```<language>
<key code example from this chapter>
- 它演示了什么:<一行说明>
Reference Tables (仅技术类书籍——若 BOOK_TYPE=text 则省略)
Worked Example (仅 DEPTH=study——DEPTH=reference 则省略)
Key Takeaways
- <可操作的见解>
- <可操作的见解>
- <可操作的见解> (3–7 条实践者必须记住的要点)
Connects To
- 第 N 章:<为什么本章与之相关>
- <概念>:<它所连接的外部概念或标准>
---
## Step 8 — Generate supporting files
### glossary.md
Create `$SKILLS_HOME/<skill_name>/glossary.md`:
- Every significant term from the book, alphabetically sorted
- Format: `**Term** — definition (Ch N)`
- Max 1,500 tokens
### patterns.md
Create `$SKILLS_HOME/<skill_name>/patterns.md`:
- All concrete techniques, design patterns, algorithms from the book
- Format: `## Pattern Name\n**When to use**: ...\n**How**: ...\n**Trade-offs**: ...`
- Max 2,000 tokens
### cheatsheet.md
Create `$SKILLS_HOME/<skill_name>/cheatsheet.md`:
**This is the most differentiated layer of the skill — treat it as a reasoning aid, not a keyword list.** Anyone can grep the glossary for a term. The cheatsheet captures the author's *judgment*: the decisions they'd make and why. It's the file that turns "I know the words" into "I'd act the way the author would".
Prioritize, in order:
1. **Decision rules** — "When X, do Y, because Z." The if/then logic the author applies, stated so the reader can apply it without re-reading the book.
2. **Decision trees / flowcharts** (as nested bullets or a small table) — for choices with more than two branches.
3. **Trade-off matrices** — competing options scored on the dimensions the author cares about, so the reader can pick under their own constraints.
4. **Thresholds & defaults** — the specific numbers, ratios, or rules of thumb the author commits to (e.g. "keep functions under ~20 lines", "alert when error budget < 10%").
5. **Tells & smells** — fast heuristics for recognizing a situation ("if you see X, you're probably in trouble Y").
Avoid: bare term→definition rows (that's the glossary), and prose paragraphs (that's the chapters). Every line should help the reader *decide* something.
- Format mostly as compact tables and decision rules; the content you'd want on a single printed page kept beside you while working.
- Max 1,200 tokens.
---
## Step 9 — Generate the master SKILL.md
**CRITICAL TOKEN BUDGET: Keep SKILL.md body under 4,000 tokens.**
Compaction truncates from the END — put the most important content FIRST.
Create `$SKILLS_HOME/<skill_name>/SKILL.md`:
```markdown
---
name: <skill_name>
description: "Knowledge base from \"<Full Title>\" by <Author(s)>. Use when applying <author>'s frameworks for <key topics, 3–6 terms>, studying the book, or referencing its concepts."
---
# <Full Title>
**Author**: <Author(s)> | **Pages**: ~<N> | **Chapters**: <N> | **Generated**: <YYYY-MM-DD>
## How to Use This Skill
- **Without arguments** — load core frameworks for reference
- **With a topic** — ask about `replication`, `pricing`, or another indexed topic; I find and read the relevant chapter
- **With chapter** — ask for `ch05`; I load that specific chapter
- **Browse** — ask "what chapters do you have?" to see the full index
When you ask about a topic not covered in Core Frameworks below, I will read
the relevant chapter file before answering.
---
## Core Frameworks & Mental Models
<generate 2,000 tokens of the most critical frameworks and insights here>
---
## Chapter Index
| # | Title | Key Frameworks |
|---|-------|----------------|
| [ch01](chapters/ch01-<slug>.md) | <Title> | <framework1>, <framework2> |
| [ch02](chapters/ch02-<slug>.md) | <Title> | <framework1>, <framework2> |
...
## Topic Index
- **<Term>** → ch<N>[, ch<N>]
- **<Term>** → ch<N>
## Supporting Files
- [glossary.md](glossary.md) — all key terms with definitions
- [patterns.md](patterns.md) — all techniques and design patterns
- [cheatsheet.md](cheatsheet.md) — quick reference tables and decision guides
---
## Scope & Limits
This skill covers the book content only. For hands-on implementation in your codebase,
combine with project-specific tools. For topics beyond this book, check related skills
or ask the agent directly.
<if images_dropped > 5: state that N source images were not read>
第 9.5 步 — 扫描生成的 skill
在报告成功、在另一个会话中加载该 skill 或发布它之前,运行建议性安全扫描:
SKILL_CONVERTER_ROOT="$(cd "$(dirname "$SCRIPT_PATH")/.." && pwd)"
"$PYTHON_BIN" "$SKILL_CONVERTER_ROOT/tools/scan_generated_skill.py" "$SKILLS_HOME/<skill_name>"
如果扫描器以非零状态退出,请停止并让人类审查其文件/行号发现项。不要默默重写生成的文件,也不要在发现项得到解决或明确接受之前加载或发布该 skill。
第 10 步 — 清理并报告
如果宿主是 Claude Code,且 SKILLS_HOME 为 ~/.agents/skills(默认的个人安装位置),请用符号链接将该 skill 暴露给 Claude Code——Claude Code 只扫描 ~/.claude/skills:
mkdir -p "$HOME/.claude/skills"
LINK="$HOME/.claude/skills/<skill_name>"
TARGET="$HOME/.agents/skills/<skill_name>"
if [ -d "$LINK" ] && [ ! -L "$LINK" ]; then
CLAUDE_STATUS="skipped-realdir" # Step 5 migration declined; leave the old dir
else
ln -sfn "$TARGET" "$LINK" 2>/dev/null || true
# Read the link back — do NOT trust that `ln` did what was asked. On Windows/MSYS
# `ln -s` may COPY instead of link (or need Developer Mode / an elevated shell), and
# PowerShell/cmd have no `ln` at all. The report must reflect what is on disk, not the
# fact that the command ran.
if [ -L "$LINK" ] && [ "$(readlink "$LINK")" = "$TARGET" ]; then
CLAUDE_STATUS="linked"
elif [ -e "$LINK" ]; then
CLAUDE_STATUS="copy" # a real file/dir landed instead of a link
else
CLAUDE_STATUS="absent" # ln unavailable or refused
fi
fi
真实目录防护是必需的:ln -sfn 指向一个已存在的真实目录时,会把链接嵌套到该目录内部(~/.claude/skills/<skill_name>/<skill_name>),使 Claude Code 继续加载过期副本。如果用户在 Step 5 迁移中选择了拒绝,请跳过符号链接并在报告中说明——在完成迁移之前,Claude Code 会继续使用旧目录。
在报告任何关于该链接的内容之前,先读回该链接。 符号链接是一种声明,而非事实:"Discoverable by" 一行应依据 CLAUDE_STATUS(磁盘上实际存在的内容)填写,绝不能依据"命令已发出"。当链接缺失或是副本时,不要硬性失败——该 skill 存在于 hub,其他所有宿主仍能找到它;诚实的报告应是"已写入 ~/.agents/skills/<skill_name>;在创建链接之前,Claude Code 不会看到它",而不是中止。(Windows 线索,未经证实:目录联接——在提权的 cmd 中执行 mklink /J,或在 PowerShell 中执行 New-Item -ItemType Junction——既不需要开发者模式,也不需要符号链接特权;如果你尝试它,这不会改变先读回再报告的规则。)
当用户选择了宿主私有或项目本地的根目录时(Step 5,规则 3-4),跳过此步骤。
然后清理提取工作目录:
PYTHON_BIN="${PYTHON_BIN:-python3}"
if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
PYTHON_BIN="python"
fi
Remove **the work directory this run actually used** — the `Workdir ->` path from the
extraction output, which is also stored as `workdir` in `metadata.json`. Never delete a
directory you did not create: another extraction may be running beside yours.
```bash
# WORKDIR is the path this run reported; quote it in case of spaces.
rm -rf "$WORKDIR"
等价地,如果你仍有元数据文件:
"$PYTHON_BIN" - "$WORKDIR_METADATA_JSON" <<'PY'
import json
import shutil
import sys
from pathlib import Path
meta_path = Path(sys.argv[1])
workdir = json.loads(meta_path.read_text(encoding="utf-8")).get("workdir")
if workdir:
shutil.rmtree(workdir, ignore_errors=True)
PY
此文件的旧版本会删除单个固定的 book_skill_work 目录。该路径已不再使用,因此这样的清理现在是无害的空操作,而不再可能删除某个并发运行的输出。
然后向用户报告:
✅ Skill created: $SKILLS_HOME/<skill_name>/
📚 Book: <Full Title> — <Author>
📄 Pages: ~<N> | Chapters: <N>
Files generated:
SKILL.md — core frameworks + index (~X tokens)
chapters/ — <N> chapter summaries (~X tokens each, ~X total)
glossary.md — key terms (~X tokens)
patterns.md — techniques & patterns (~X tokens)
cheatsheet.md — quick reference (~X tokens)
─────────────────────────────────────────────────────
Total skill size: ~X tokens (loaded on-demand, not all at once)
💡 Tip: check your agent's session cost/usage command to see actual token usage.
Usage:
Ask for <skill_name> → load core frameworks
Ask <skill_name> about <topic> → find and explain a topic
Ask <skill_name> for ch<N> → dive into a specific chapter
Discoverable by: <only what is true for the chosen destination — see below>
Somewhere else? mv ~/.agents/skills/<skill_name> <dest_root>/<skill_name> \
&& ln -sfn <dest_root>/<skill_name> ~/.claude/skills/<skill_name>
Prompted for permission on every file? That is your host gating writes outside the
working directory. Say "save it in this project" and re-run to write inside it.
Reload (if your agent doesn't auto-detect new skills):
GitHub Copilot CLI: /skills reload
Claude Code: restart the session
Amp: restart the session
Hermes Agent: start a new session
OpenClaw: openclaw skills list (new session if watcher disabled)
OpenCode: start a new session
Share this skill (optional):
GitHub repo, installable on any host (Step 11): say "publish"
Copilot ecosystem: gh skill publish $SKILLS_HOME/<skill_name>
"Discoverable by" 一行应依据 CLAUDE_STATUS(读回结果)填写,绝不能依据 ln 已运行这一事实——对于 ~/.agents/skills 安装:
linked→ "Copilot CLI、Amp、Codex(原生);Claude Code 通过符号链接 ~/.claude/skills/<skill_name>"skipped-realdir→ "Copilot CLI、Amp、Codex(原生);不包括 Claude Code——请先迁移 ~/.claude/skills/<skill_name> 处的真实目录"copy或absent→ "Copilot CLI、Amp、Codex(原生);不包括 Claude Code——宿主无法创建符号链接(普通副本会在下次 Update/Fold-in 时发生偏移)。请启用开发者模式 / 手动创建链接,或从 ~/.agents/skills 运行该 skill"- Hermes Agent 个人根目录 → "Hermes Agent(来自
$HERMES_HOME/skills/<category>)";不声明符号链接,也不声明跨 Agent,因为其他宿主不扫描 Hermes 根目录 - 其他宿主私有或项目本地根目录 → 只列出扫描该根目录的宿主;不声明符号链接
"Somewhere else?" 重定位行必须与实际采用的路径相符,这样它才不会破坏该次运行刚刚创建的符号链接。
mv始终以最终的 skill 目录<dest_root>/<skill_name>为目标,而绝不能是<dest_root>本身。mv ~/.agents/skills/mybook ~/.copilot/skills && ln -sfn ~/.copilot/skills ~/.claude/skills/mybook读起来像是有效的,其实并不是:skill 会落到~/.copilot/skills/mybook,而链接却指向上一级的根目录,于是 Claude Code 解析到一个没有SKILL.md的目录,而这正是这一行所要避免的破坏。替换为用户实际指定的目标位置,这样打印出的命令就带有真实路径,没有任何需要解读的地方: ~/.agents/skills+ 符号链接 →mv ~/.agents/skills/<skill_name> <dest_root>/<skill_name> && ln -sfn <dest_root>/<skill_name> ~/.claude/skills/<skill_name>- 主机私有根目录,包括 Hermes Agent →
mv <src_root>/<skill_name> <dest_root>/<skill_name> - 项目本地根目录 →
mv <project_root>/<skill_name> <dest_root>/<skill_name>
"Prompted for permission on every file?" 这一行是针对会拦截工作目录之外写入的主机(任何个人范围根目录都属于 cwd 之外)给出的答案:目标位置已在上文说明,而一行修复方法——重新运行并请求使用项目本地根目录——就在其旁边。仅在个人范围安装时保留它;当用户已经选择项目本地时,将其删除。
第 11 步 — 将生成的 skill 发布到 GitHub(可选)
在第 10 步报告之后,只提供一次——并且仅当第 9.5 步扫描通过时:
"Want me to publish this skill to GitHub so any Agent Skills host can install it with
npx skills add? (yes / skip)"
如果用户拒绝,就到此为止。要求:gh 命令行,且已通过身份验证(检查 gh auth status)。如果缺少 gh 或未通过身份验证,可提出帮忙设置(brew install gh 或 https://cli.github.com ,然后 gh auth login)——或者使用无需 gh 的路径:用户在 GitHub 网页界面中创建一个所选可见性的空仓库,然后你运行下面的 git init/add/commit 命令,接着运行 git remote add origin <repo-url> && git push -u origin main。下面的可见性规则同样适用于通过网页创建的仓库。
可见性是一个单独的封闭式问题——绝不推断,绝不从先前的回答中读取。 一旦用户接受,就单独询问它,并要求用一个词回答:
"Private or public repository? Reply with one word:
privateorpublic."
回答必须就是 public,而不仅仅是包含它——这是一条硬性规则,不是建议。 除一种情况外,在所有情况下都以 --private 运行 gh repo create:对可见性问题的回答是那个光秃秃的词 public。禁止子字符串匹配,因为一句关于来源许可的话并不是可见性回答——"it's public domain"、"the book is public domain"、"it's publicly available" 都是在描述材料,而不是仓库,并且都解析为 --private。改述、一句话、模棱两可的回答、沉默,或你自己的推断都不是同意:重新询问一次,如果回答仍然不是那个光秃秃的词,就使用 --private 并在报告中说明。私有仓库之后可以转为公开;对源自书籍的内容进行公开推送则无法取消发布。
版权关卡——在创建仓库之前始终应用: 章节文件是合成的摘要,不是原始文本,但它们仍然源自源材料。根据 README 的版权与合理使用政策,由第三方受版权保护的书籍生成的 skill 必须保持私有;只有在来源是用户自己的作品、开放许可的内容,或用户明确确认其有权公开再分发的材料时,才提供公开——并说明适用的是哪种情况。能够访问公司内部材料并不等于获准披露它:源自内部文档的 skill 保持私有,除非用户声明其拥有发布权。
如果接受:
- 在
$SKILLS_HOME/<skill_name>/内添加一个仓库README.md(绝不要覆盖已有文件)——包含技能标题、一段描述(“由 使用 book-to-skill 从 生成的 Agent skill”)、下文第 3 步中的安装命令、文件清单,以及一条说明:内容是综合整理的摘要,而非原书文本。 - 将该 skill 文件夹初始化为 git 仓库并创建远程仓库(默认仓库名为
<skill_name>;允许用户覆盖——有些人偏好<skill_name>-skill后缀)。嵌套仓库防护: 首先检查该 skill 文件夹是否已位于某个 git 仓库内(git -C "$SKILLS_HOME/<skill_name>" rev-parse --show-toplevel—— 对于.claude/skills/这类项目本地根目录,情况总是如此)。如果是,切勿就地执行git init:外层仓库会将该文件夹记录为嵌入式仓库(gitlink,mode 160000)且不含.gitmodules,而外层项目的新克隆会静默遗漏该 skill。取而代之,应将 skill 文件夹复制到临时目录,从副本中运行以下命令,并告知用户:已发布的仓库——而非项目本地文件夹——才是远程仓库的工作副本。
cd "$SKILLS_HOME/<skill_name>"
git init -b main
git add -A
git commit -m "Add <skill_name> skill"
gh repo create <repo_name> --private --source . --push
# --private is the default; substitute --public ONLY under the visibility rule above
# (the visibility answer WAS the bare word "public" AND the copyright gate allows it)
- 报告仓库 URL 和跨主机安装命令:
✅ Published: https://github.com/<owner>/<repo_name> (<private|public>)
Install on any Agent Skills host:
npx skills add https://github.com/<owner>/<repo_name> --skill <skill_name>
当嵌套仓库防护被触发、且仓库是从临时副本发布时,添加一行——该本地文件夹永远不会获得远程仓库,因此其永远不会出现 Update/Fold-in 推送提示:
⚠️ Published from a copy: <skill folder> sits inside another git repository, so it has
no remote of its own. To publish a later update, re-run Step 11, or clone
https://github.com/<owner>/<repo_name> and fold new material into the clone.
根级 SKILL.md 布局正是 skills CLI 所检测的布局,因此该仓库可直接安装——无需重新组织。除嵌套仓库情况外,本地文件夹仍是本机的实时安装位置,也是远程仓库的工作副本,因此后续 Update/Fold-in 运行可以将更改提交并推送到同一远程仓库。
Update / Fold-in 工作流
对 $SKILLS_HOME/<skill_name>/ 处的现有 skill 执行 Update/Fold-in 操作时:
1. 读取现有 Skill 结构
读取并解析现有 skill 的文件:
- 读取
$SKILLS_HOME/<skill_name>/SKILL.md,解析现有的 Chapter Index、Topic Index、元数据(作者、总章节数)和 Core Frameworks。 - 列出
$SKILLS_HOME/<skill_name>/chapters/中的所有文件,找出最高章节编号(例如ch12)。 - 读取
$SKILLS_HOME/<skill_name>/glossary.md、$SKILLS_HOME/<skill_name>/patterns.md和$SKILLS_HOME/<skill_name>/cheatsheet.md,查看已索引的术语和框架。
2. 匹配内容并区分修订与新增
分析本次运行 full_text.txt(提取输出中的 Text -> 路径)中新提取的文本,判断新内容属于以下哪种情况:
- 对现有章节的更新/修订:如果新内容的某一部分直接更新或扩展了现有章节的主题,则读取现有章节文件,将新细节合并进去,并重写该文件。
- 新增内容:如果内容引入了新章节、论文或独立小节,则在
chapters/下创建新的章节摘要文件。从现有最高章节编号之后开始编号(例如,如果现有章节止于ch12,则创建ch13-*.md、ch14-*.md等)。
3. 生成或更新章节摘要文件
对于每个新增或修订的章节:
- 读取提取出的新文本中对应的部分。
- 遵循 Step 7 中的格式指南来构建摘要。
- 在
$SKILLS_HOME/<skill_name>/chapters/中写入/更新该文件。
4. 合并支撑文件
- 合并 glossary.md:
- 读取现有的
$SKILLS_HOME/<skill_name>/glossary.md。 - 从新内容中提取所有新术语和定义(Step 8 术语表指南)。
- 合并现有术语和新术语列表,并按字母顺序排列。
- 如果某个术语已存在,则向其追加新的章节/来源引用(例如
**Term** — definition (Ch 4, Ch 13))。 - 用完全合并、按字母顺序排列的列表重写
$SKILLS_HOME/<skill_name>/glossary.md。
- 读取现有的
- 合并 patterns.md:
- 读取现有的
$SKILLS_HOME/<skill_name>/patterns.md。 - 从新内容中提取任何新技术、算法或模式。
- 追加新模式,确保格式一致,并保持总长度简洁(少于 2,500 tokens)。
- 读取现有的
- 合并 cheatsheet.md:
- 读取现有的
$SKILLS_HOME/<skill_name>/cheatsheet.md。 - 提取新的比较规则、决策表或参数指南。
- 将它们整洁地整合到 cheatsheet 结构中。
- 读取现有的
5. 重新生成主 SKILL.md
更新主 skill 文件 $SKILLS_HOME/<skill_name>/SKILL.md:
- 元数据:递增章节数,更新预估页数,并在合适时添加新的来源名称。将
Generated日期更新为当前日期。 - 核心框架:融入新内容中影响最大的心智模型或原则(确保整个文件保持在 4,000 tokens 以下)。
- 章节索引:将新章节追加到索引表中,并链接到新创建的文件。
- 主题索引:按字母顺序合并新主题。如果某个现有主题也在新章节中有所涵盖,则在其行后追加新的章节链接(例如
- **Topic** → ch05, ch13)。
6. 扫描、清理并报告
文件成功写入并合并后,运行 Step 9.5,然后继续执行 Step 10,执行清理并打印自定义更新报告,汇总新增章节、合并的术语表条目以及更新后的索引。如果 skill 文件夹是一个带有远程仓库的 git 仓库(通过 Step 11 发布),则提议提交更新并推送。
质量规则
- 提取结构,而非摘要 — 捕获具名框架、精确表述、反模式;而不是章节回顾
- 保留作者的精确性 — “The 5 Whys” ≠ “多次询问为什么”;保留精确命名
- 密度优先于完整性 — 1,000 tokens 的摘要胜过 10,000 tokens 的摘录
- 实践者语气 — 写“在 Y 时使用 X”,而不是“书中解释了 X”
- 将 SKILL.md 前置 — 压缩会保留前 5,000 tokens;最重要的内容放在最前面
- 章节文件按需加载 — 在加载之前,它们不计入 skill 预算
- 绝不复制原始书本文本 — 始终综合、概括、提取信号
- 主题索引至关重要 — 这是 Agent 导航到正确章节文件的方式