【从零构建AI Code终端系统】06 -- 技能系统:把经验装进书架

06 -- 技能系统:把经验装进书架

每天从零推理同一件事

子代理隔离了中间产物,上下文干净了。但隔离解决不了另一个浪费------重复推理

让模型执行一次代码提交,它从头推理:检查变更、逐文件暂存、写提交信息。这套流程你每天用十次,模型每次从零走一遍------耗 token、路径不同、质量不稳定。人会把反复执行的流程内化为习惯,agent 需要同样的机制:把反复使用的推理路径预编译成指令,用到时直接加载。 一个技能就是一份写给模型看的操作手册。


知识,不是代码

工具和技能容易混淆。工具 = 能力 ------执行命令、读写文件,硬编码在程序里。技能 = 知识------提交规范、审查标准、测试策略,写在纯文本里。

两者的变更节奏完全不同。改一行提交规范不应该需要重新部署;任何人都能写纯文本,不需要编程能力;纯文本天然适配版本控制和团队共享。代码定义机制,文本定义内容,各自以自己的速率演进。


SKILL.md 的结构

技能以目录为单位,每个技能的存放路径遵循固定约定:

复制代码
.agents/skills/<skill-name>/SKILL.md

<skill-name> 就是技能名------小写字母加连字符,1-64 字符,全局唯一。目录名即技能名,SKILL.md 是入口文件。一个项目可以有多个技能,并排放在 .agents/skills/ 下:

复制代码
.agents/skills/
├── commit-workflow/
│   ├── SKILL.md           # 必须:指令 + 元数据
│   ├── scripts/           # 可选:可执行脚本
│   ├── references/        # 可选:参考文档
│   └── assets/            # 可选:模板、资源
├── code-review/
│   └── SKILL.md
└── security-guidance/
    └── SKILL.md

扫描器启动时遍历 .agents/skills/ 下的每个子目录,解析其中的 SKILL.md。目录结构保持一层深度------扁平意味着模型不需要递归查找,人也不需要翻找。

SKILL.md 由 YAML frontmatter 和 Markdown body 两部分组成:

yaml 复制代码
---
name: commit-workflow            # 必需,1-64 字符,小写 + 连字符
description: |                   # 必需,1-1024 字符
  代码提交工作流。用户要求提交代码时激活。
license: MIT                     # 可选
allowed-tools: Bash Read         # 可选,空格分隔,限制可用工具
---

## 提交规范
1. 运行 git status 检查变更
2. 逐文件暂存,不要 git add -A
3. 提交信息使用祈使语气,首行不超过 72 字符

两个必需字段各有职责。name 是唯一标识,扫描和覆盖靠它定位。description 不只描述"做什么",更要说"什么时候用"------模型靠这行描述判断当前任务是否匹配,描述越准确,激活越精准。

Body 部分无格式限制,推荐包含分步指令、输入输出示例和边界情况处理。引用资源文件用相对路径(scripts/lint.sh),与目录结构的扁平原则一致。


三层渐进式披露

20 个技能全量注入约 40K tokens,占窗口 20%,大部分与当前任务无关。解法是按需逐层展开------先看书脊,感兴趣翻目录,确定相关了才读正文:
任务匹配描述
指令引用文件
Metadata

name + description

≈100 tokens/技能
Instructions

完整 SKILL.md body

推荐 <5000 tokens
Resources

scripts/ references/ assets/

按需加载

Metadata。 启动时从所有 SKILL.md 的 frontmatter 提取 namedescription,注入上下文。20 个技能约 2000 tokens------模型扫一眼就知道书架上有什么,几乎不占空间。不相关的技能永远停留在这一层。

Instructions。 模型判断某个技能与当前任务相关时,调用 load_skill 工具,加载完整 body。内容作为工具返回值追加到消息历史,一次性成本。Body 推荐控制在 5000 tokens 以内------太长会稀释上下文,违背"预编译"的初衷。

Resources。 执行 body 中的指令时,才读取 scripts/references/assets/ 下的文件。这些资源从不主动加载,只在指令明确引用时按需获取。

成本曲线很陡:大部分技能停留在第一层(约 100 tokens),少数进入第二层(几千 tokens),资源文件只在执行时才产生开销。


注入位置:追加,不改前缀

技能内容追加到最后一条用户消息的末尾,不修改系统提示词。原因是缓存:大模型 API 普遍支持前缀缓存------请求前缀相同就复用已缓存的 KV 向量。改系统提示词一个字节,缓存全部失效。追加到消息末尾,前缀始终不变,缓存始终命中。

复制代码
beforeModel(state):
    // autoload 技能:每轮直接注入正文,跳过 Metadata 直入 Instructions
    for skill in registry:
        if skill.autoload:
            inject(skill.body)

    // 其余技能:只注入 Metadata 层
    summary = registry
        .filter(s => !s.autoload)
        .map(s => "- {s.name}: {s.description}")

    append_to_last_user_message(summary)

autoload 是一个特殊标记。标记了的技能(如输出风格规范)每轮自动注入完整正文,跳过 Metadata 直接进入 Instructions。适合每次对话都必定用到的基础规范------数量少、体积小,省去模型每次主动加载的开销。


小结

技能把运行时的重复推理转移到编写时。SKILL.md 用 frontmatter 声明身份,用 body 承载指令,用子目录挂载资源。三层渐进式披露------Metadata、Instructions、Resources------确保模型只为真正用到的知识付费。追加注入保护缓存命中率。

但不管书架管理得多精细,对话本身一直在增长------每轮工具调用、每次文件读取都在往窗口里堆东西。窗口终会满,届时需要的不是更聪明的加载,而是压缩。


相关推荐
故乡de云11 分钟前
Cursor + Claude Code 接入 API 实战:国内稳定使用 Claude 4.7 配置全攻略
大模型·ai编程·策略模式·claude·cursor·claude code
Chef_Chen12 分钟前
transformer知识补足
transformer·agent
前端不太难13 分钟前
AgentTeam注入:OpenClaw如何破解串行任务灾难
状态模式·agent·openclaw
维元码簿25 分钟前
Claude Code 深度拆解:工具系统——30+ 内置工具地图与 MCP / Skills 协作
ai·agent·claude code·ai coding
花千树-01040 分钟前
ReAct 思考-行动-观察循环的底层实现机制
langchain·agent·react·ai编程·ai agent·langgraph·mcp
knight_9___1 小时前
RAG面试篇10
人工智能·python·机器学习·agent·rag
knight_9___1 小时前
RAG面试篇11
java·面试·职场和发展·agent·rag·智能体
倔强的石头_13 小时前
高吞吐+免配置!腾讯云轻量的 Hermes Agent部署指南
agent
Rubin智造社14 小时前
04月24日AI每日参考:GPT-5.5正式发布,DeepSeek获腾讯阿里争相入局
人工智能·claude code·deepseek v4·gpt-5.5·deepseek融资
米小虾16 小时前
从"工具"到"同事":AI Agent 自主决策能力的工程化实践
人工智能·agent