公司动态
上下文工程实战:用book-to-skill把一本书变成按需加载的技能
实际使用 AI 编程助手时最常遇到的问题不是单次提问没答对而是任务进行到一半上下文窗口爆了。你刚把一本书、一份几千行的接口文档或者一套团队规范全部塞进对话里后续请求就开始变慢、变不稳定甚至出现“已进行多次自动总结但上下文大小仍超出限制”的提示。book-to-skill 就是针对这个问题出现的一类做法把资料改造成按需加载的技能而不是让模型每轮对话都背着整本书工作。标题里提到的“一本书省 51 倍上下文”并不需要当作固定指标它的价值在于提示一个方向上下文是可以被管理的资源。下文从上下文工程的角度把 book-to-skill 的目录结构、技能格式、触发机制、验证方法和排错路径完整拆开讲清楚。1. 先理解上下文工程为什么整本书不能直接塞给模型1.1 上下文窗口是资源不是无限容器上下文窗口context window指模型在单次推理中能看到的 token 总数。不同模型的上限差异很大常见的有 60K、200K、1M 等配置。很多人会陷入一个误区上下文越大越好只要不超限资料越全回答越准。实际并非如此。上下文窗口越大通常意味着每轮请求处理的 token 越多首字延迟和整体耗时上升费用随 token 数量增长长会话的成本压力更明显无关内容混入时模型需要在大量信息中定位关键片段注意力可能被稀释接近上限后工具会自动触发总结、压缩或截断结果往往是丢失细节。所以上下文工程的核心问题不是“能装多少”而是“哪些 token 该进来、哪些不该进来”。一本书十几万字一次性放入上下文等于让模型在每次回答前都先“读完”整本书但真正用到的可能只有其中几页。1.2 按需加载平时只带索引用到时才翻正文book-to-skill 的核心思路是“按需加载”。它把一本书或一份大型资料拆成两部分入口描述一小段说明告诉模型这个技能能处理什么问题、什么时候该用它正文参考一组小型文件每个文件只负责一个具体主题只有在确定需要时才被加载进上下文。这和我们在真实世界里的做法类似。程序员不会把整本《MySQL 性能调优》放在办公桌上逐字读而是遇到慢查询时翻索引相关章节遇到死锁时再看锁机制章节。技能文件就是这些“章节卡片”SKILL.md 则是封面上的检索词。这样做的好处是日常对话中模型只需要携带技能入口描述真正命中场景时再读取对应的参考文件。上下文占用从“整本书”变成“入口描述 当前任务相关的一两个小文件”。1.3 51 倍这个数字应该怎么看待标题里的“51 倍”来自特定资料、特定任务和特定工具的对比不是普适结论。节省倍数可以近似用下面这条公式理解上下文节省倍数 ≈ 原始整书 token 数 / 技能实际加载 token 数其中技能实际加载 token 数 入口描述 token 本次任务被触发的参考文件 token。如果一本书有 5 万 token而某次任务只加载了 1 千 token倍数就是 50 左右。如果任务需要连续读取十几个参考文件倍数就会明显下降。影响节省倍数的因素主要有因素对节省倍数的影响资料本身的冗余度原文越冗余拆分后节省越多参考文件拆分粒度文件越小越精细按需加载越精准任务覆盖范围只查一个点时节省明显通读全书时节省有限触发方式自动命中比手动全量读取更省实际落地时建议不要被“51 倍”绑架而是先跑通机制再对自己的资料做一次 token 前后对比得到属于自己的数据。2. 环境准备把 skill 机制跑起来需要哪些条件2.1 支持 skill 机制的 AI 编程助手当前主流 AI 编程助手已经陆续支持“技能skill”或类似机制。不同产品叫法不同有的叫 skills有的叫 commands有的叫 agents 或 rules。以常见 CLI 助手为例较新版本通常会在项目目录下预留技能目录例如.claude/skills/并在需求命中时自动加载对应技能。由于各工具版本更新快落地前先做三件事确认当前助手版本是否支持 skill 目录确认技能目录的准确路径和命名规范确认技能是被动触发还是通过命令手动调用。不要直接照抄网上的目录路径。先看工具官方文档或本机命令帮助例如执行assistant --help或查看版本信息再决定目录结构。这里以常见约定为例兼容性以你使用的版本为准。2.2 两种加载方式自动命中与手动调用技能通常支持两种加载方式设计技能时要同时考虑加载方式触发条件适用场景缺点自动命中模型根据技能入口描述判断是否相关通用知识、高频问题、流程类任务描述写得不好会导致误触发或漏触发手动调用用户通过命令指定技能名称明确任务、低频但需要深度的场景依赖用户记得主动调用推荐做法是通用且高频的技能靠自动命中专项且低频的靠手动调用。例如把“数据库慢查询分析”做成自动命中技能把“公司发布流程”做成手动调用技能避免模型在日常对话中误读发布相关描述。2.3 验证环境的最小实验先创建一个最小技能验证机制本身是否工作。以常见技能目录约定为例mkdir -p .claude/skills/hello-doc/references在技能目录下创建入口文件 SKILL.md--- name: hello-doc description: 当用户提到测试技能、演示技能或者询问技能机制是否可用时使用。 --- # Hello Doc 这是一个最小验证技能。返回一句话说明技能已经加载成功并列出 references 目录中的文件名。然后开启一次新会话输入“测试一下 hello 技能”观察模型是否读取了该技能。如果模型没有反应说明目录路径、描述格式或触发机制需要调整。这个最小实验是后续所有工作的基础不要跳过。3. 把一本书改造成按需技能完整操作流程3.1 先拆分知识结构不要直接复制原文拿到一本技术书或一份长文档先不要急着复制正文。第一步是分析目录和章节把内容分成三类判断类用于决定“现在该做什么”如故障判断流程、问题分类操作类给出具体步骤如安装、配置、修复速查类供查表使用如参数对照、命令语法、错误码说明。例如一本 MySQL 性能调优书籍可以映射成下面的结构原书章节技能目录中的文件类型EXPLAIN 结果解读references/explain-reading.md速查类索引选择原则references/index-selection.md判断类死锁排查流程references/lock-deadlock.md操作类常用参数说明references/config-parameters.md速查类慢查询定位步骤references/slow-query-steps.md操作类这个阶段的产出是一张“书籍章节到技能文件”的映射表它决定了整个技能库的结构也是后续维护时最容易更新的依据。3.2 用 SKILL.md 作为技能入口每个技能目录下必须有一个入口文件常见命名为 SKILL.md。它由 YAML 前置元信息和正文模板两部分组成。--- name: mysql-performance-tuning description: 用于 MySQL 慢查询分析、索引选择和参数调优。当用户提到慢 SQL、索引失效、explain 结果解读、数据库卡顿等问题时使用。 --- # MySQL 性能调优 本技能把 MySQL 性能调优资料整理为按需加载的步骤。 ## 使用流程 1. 确认现象慢 SQL、锁等待、CPU 飙升、磁盘 IO 高。 2. 获取 EXPLAIN 结果对照 references/explain-reading.md 判断访问类型。 3. 需要选索引时读取 references/index-selection.md。 4. 修改参数前先对照 references/config-parameters.md 确认影响范围。 5. 所有变更先在测试库执行再考虑生产环境。 ## 限制 - 本技能只负责分析和建议不执行实际变更。 - 涉及生产变更时需要人工审批后执行。这里的description是整个技能最关键的部分。它不会完整进入每次对话的使用流程但模型判断“当前问题要不要触发这个技能”时主要依据就是它。描述要写清楚三个要素技能处理什么、什么场景触发、什么场景不触发。3.3 把正文拆成小型参考文件每个文件聚焦一件事references 目录下的文件遵循“一文件一主题”原则。文件不宜过大理想情况下一个文件几百行以内控制在一次加载可接受范围。示例references/explain-reading.md# EXPLAIN 结果速查 ## 关键列含义 | 列名 | 含义 | 常见问题 | | --- | --- | --- | | type | 访问类型 | 出现 ALL 时通常意味着全表扫描 | | key | 实际使用的索引 | NULL 表示未使用索引 | | rows | 预估扫描行数 | rows 越大越需要关注 | | Extra | 附加信息 | Using filesort 需要关注排序开销 | ## 访问类型从好到差 system - const - eq_ref - ref - range - index - ALL ## 常见处理 - type 为 ALL 且条件列适合建索引优先考虑增加索引。 - Extra 出现 Using temporary检查 group by 或 order by 是否与索引顺序一致。 - rows 与实际返回行数差距大关注统计信息是否过期。文件最后尽量给出“下一步做什么”这样模型读取文件后能直接产生行动建议而不是停留在概念解释。3.4 控制何时把材料带进上下文拆分完之后最关键的问题是技能文件什么时候真正进入上下文。主流机制有两种实现方式模型自动读取当模型判断需要该技能时把 SKILL.md 以及它引用的 reference 文件读入用户或工具手动引入通过命令读取指定文件再参与后续回答。无论哪种方式都要避免一个陷阱不要在 SKILL.md 正文里贴完整参考文件的内容。SKILL.md 只写流程和指向正文内容放在 references 下这样模型平时负担的是“入口 流程”而不是整本书。一个健康的状态是日常对话中上下文只增加几百 token只有当任务命中时references 里的一两个文件才被加载进来。这样才能真正达到按需加载的目的。4. 关键设计参数描述、粒度、触发方式的取舍4.1 description 质量决定技能能否被命中description 写得不好技能机制再完善也不会生效。两种典型写法对比如下写法示例问题太宽泛处理 MySQL 问题任何数据库相关提问都可能触发误触发率高太冗长复制整章摘要模型难以快速判断重点入口本身消耗 token推荐慢查询、索引失效、explain 解读、参数调优场景词明确模型容易对号入座建议写完 description 后做一个简单测试从原书疑问中列出 10 个典型问题分别发给模型观察技能是否正确触发。触发率低于预期时优先改 description而不是改代码。4.2 文件拆分粒度决定上下文成本拆分粒度直接影响上下文占用粒度太粗一个 reference 上千行触发性地把大量无关内容带入上下文节省效果大打折扣粒度太细文件数量爆炸模型需要多次读取检索和加载成本上升维护负担也重。推荐以“一次任务需要的最小知识集合”为单位。例如“索引选择”单独成一个文件“锁与死锁”单独成一个文件而不是把“性能调优全部内容”放在一个大文件里。文件拆分完成后可以做一个简单的 token 估算单个 reference token ≈ 文件字符数 / 2中文场景粗略估算 一次技能加载 token ≈ SKILL.md token 所有被读取 reference token不同模型对中文 token 的切分方式不同上面只是估算。真正准确的数字需要从工具日志或 token 计数接口获取。4.3 检索还是固定引用两种接入方式的取舍技能文件加载有两种主流接入方式方式原理优点缺点固定引用SKILL.md 明确指定读取某个文件路径确定行为稳定容易排查文件多时代码冗余检索式选择通过检索或工具按问题匹配文件灵活性高适合大规模技能库依赖检索质量排队链路长小规模技能库几十个文件以内建议先用固定引用。等技能数量增长后再考虑引入检索式选择并在技能库入口处维护一套文件索引。不要把检索链路一开始就做复杂先跑通再扩展。5. 运行验证如何量化上下文节省而不是凭感觉5.1 记录修改前后的 token 消耗没有数据支撑的“觉得省了很多”没有说服力。验证建议从两条路径取数直接观察工具界面显示的 token 消耗开启 DEBUG 日志记录每轮请求的实际 token 数量。以 DEBUG 日志为例日志行通常包含 prompt 和 response 的 token 数。记录格式可以简化成task_id: task-001 full_book_mode_tokens: 45200 skill_mode_tokens: 1180 saved_tokens: 44020 saved_ratio: 97.4%建议建立一张对比表任务整书模式 token技能模式 token节省比例回答质量是否达标解读 EXPLAIN 结果45200118097.4%达标处理死锁案例45200240094.7%达标全文知识点问答45200420007.1%不适用第三行代表一种边界情况如果任务要求通读全书内容技能模式并不比整书模式省多少。这不是失败而是说明了该任务不适合按需拆分的模式。5.2 验证技能是否在正确场景被触发准备一份测试问题集每个问题标注预期是否触发技能测试问题预期触发实际触发结论这条 SQL 为什么没用索引是是通过帮我写一个 Python 冒泡排序否否通过数据库死锁怎么排查是否失败需要修改 description这一轮测试能发现两个问题漏触发和误触发。漏触发时强化 description 中的场景词误触发时加入“不适用场景”限制。5.3 从工具日志和会话记录中确认加载链路如果技能被触发但结果不对需要确认模型到底读取了哪些文件。此时要从三个层面检查会话输出中是否出现技能加载提示DEBUG 日志中是否出现了 references 下文件的读取记录模型回答中引用的内容是否来自技能文件。一般排查链路是先确认技能是否被触发再确认文件是否被读取最后确认读取的文件内容是否正确。不要跳过第二步直接改 prompt。6. 常见问题排查技能不触发、上下文还是爆、答案反而变差6.1 技能没有被触发现象输入了明显和技能相关的问题模型却像没看到技能一样回答。可能原因技能目录路径不对助手没有扫描到SKILL.md 的 frontmatter 格式不正确开启会话时没有重新加载技能配置新会话才开始生效当前会话仍是旧配置。检查方式先确认技能文件存在于正确目录再开启新会话测试。如果仍不触发把 description 改成更明确的场景词例如把“数据库问题”改成“慢 SQL、索引失效、EXPLAIN 结果解读”。6.2 上下文仍然超限现象即使使用了 skill仍然出现“已进行多次自动总结但上下文大小仍超出限制”或类似报错。排查顺序检查 SKILL.md 中是否复制了整段原文检查 references 文件是否过大一次性被全部加载检查会话历史本身过长与技能无关检查是否有 MCP 服务器或其他工具在每轮请求中注入大量内容。处理建议把大 reference 继续拆小明确 SKILL.md 中“只读取当前任务相关文件”必要时候手动调用技能而不是依赖自动命中如果长会话本身是问题优先考虑任务分段而不是把所有步骤放在一个会话里。6.3 用技能后回答质量下降现象上下文省了但回答明显不如直接粘贴原文时准确。可能原因参考文件丢失了关键上下文或示例拆分的文件之间缺少衔接模型只读了其中一个SKILL.md 中缺少使用顺序模型不知道该先读哪个文件。处理建议在每个 reference 文件开头加“本篇解决什么问题、前置文件是什么、下一篇是什么”在 SKILL.md 中明确读取顺序和判断条件。质量优先于节省先保证回答可用再优化 token 消耗。6.4 排查顺序表现象优先检查其次检查最后处理技能不触发目录路径和 frontmatter 格式description 场景词重建技能目录后新开会话上下文仍超限SKILL.md 是否过大reference 是否全部被加载拆分文件并指定按需读取回答质量下降参考文件内容是否完整文件间是否有衔接关系补充使用顺序说明技能误触发description 范围过宽是否缺少不适用场景说明增加限制条件这套顺序的核心逻辑永远是先确认输入是否正确再检查路径和配置最后才怀疑工具本身。7. 最佳实践与扩展方向从一本书到一套知识库7.1 可复用的技能拆分清单每次新建技能前按下面这份清单检查[ ] 明确技能一句话职责解决什么问题不解决什么问题[ ] 完成章节到文件映射表确认没有遗漏关键主题[ ] SKILL.md 的 description 包含触发场景词和不适用场景[ ] 每个 reference 文件只聚焦一个主题保持适度长度[ ] SKILL.md 中只写流程和文件指引不贴大段原文[ ] 明确加载方式自动命中还是手动调用[ ] 准备 5 到 10 个测试问题覆盖触发、不触发、边界场景[ ] 记录整书模式和技能模式的 token 消耗[ ] 确认回答质量不低于直接粘贴原文的水平。这份清单同时适用于技能库的代码审查和新人培训。每次技能变更后至少跑一遍测试问题集再提交。7.2 学习环境与生产环境的差异本地个人项目里把技能目录放在项目下验证机制、改描述、拆文件都很快。生产环境则要考虑更多维度学习环境生产环境技能目录项目本地独立技能库按版本管理文件变更直接改走评审和版本发布流程验证方式手动测试自动评测集 回归测试日志可不开必须记录加载链路和 token 消耗权限本机限制谁能修改技能文件和读取敏感资料回滚可临时修复需要保留历史版本支持快速回滚监控不需要跟踪触发率、误触发率和 token 成本不要把学习环境里的随意改法直接带到生产。尤其要注意生产环境中的技能文件可能包含团队内部规范或敏感信息权限控制和内容审核不能省略。7.3 下一步扩展从单技能到技能库当技能数量增长到几十个以上维护方式要从“单个技能”升级为“技能库”统一目录规范所有技能使用一致的结构和命名建立索引文件在技能库入口维护一份技能清单说明每个技能的适用范围降低检索成本引入自动评测把测试问题集固化成脚本每次技能变更自动回归设计更新机制书改版后技能文件需要同步更新避免旧信息继续误导模型控制每次加载范围技能库再大每次进入上下文的仍然只是入口描述和命中文件这是整个机制的底线。还有一个容易被忽略的方向把“对话历史中的重复知识”沉淀成技能。比如同一个团队频繁讨论同一份部署流程就可以把这份流程抽成技能文件下次新会话直接调用解决“新开会话丢失上下文记忆”的痛点。这比每次重讲一遍更可靠。回到最初的问题一本书省 51 倍上下文并不是一个必须达成的指标而是一个验证方向。book-to-skill 的价值在于它把“堆资料”变成了“建索引、拆内容、按需加载”的工程过程。新手建议先拿一份自己最熟悉的技术文档按第 3 节的操作流程完整做一遍记录修改前后的 token 数和回答质量。完成一次全流程之后再考虑扩大技能库、引入评测和自动化。掌握这套上下文管理思路后无论换哪个编程助手、哪种模型你都能在有限上下文窗口内做出更可控、更稳定的 AI 辅助工作流。