ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent Skills实战:从SKILL.md到跨工具复用

Agent Skills实战:从SKILL.md到跨工具复用 “agent-skills”这个词最近频繁出现在我的信息流里一开始我以为又是某个新的 Agent 框架套壳结果扒了一圈发现它并不是某个具体仓库的名字而更像是一整类项目和讨论的集合把“技能”做成标准化的、可复用的、能跨平台安装的资源包然后让 Claude Code、Codex、opencode、pi agent 这些不同的执行壳harness直接调用。我自己前后折腾了一个多月的 skills从照着别人仓库抄结构到自己写、给团队用、再跑评测最大的感触是skill 不是把提示词换个后缀它解决的是 agent 工程里“能力复用”和“行为稳定”这两个老大难问题。这篇文章不打算给你罗列“十大推荐 skill”而是把 agent-skills 这类项目的里子拆开一个 skill 包到底长什么样、放在哪里才会被 agent 发现、写之前要想清楚什么、以及我在实际使用中最容易翻车的地方。读完你至少能把一套能用的 skill 跑起来还会踩得比别人少一点。适合刚开始玩 agent 开发、或者正给团队做内部 agent 统一规范的人看。1. 先把概念捋清楚Skill 到底是给谁用的1.1 Skill、Prompt、Tool、Agent 各管哪一段我先说一个特别常见的混淆Skill 是不是就是“优化过的提示词”不完全是但它和提示词绑定得非常紧密。你可以把 Prompt 理解成一张“临时任务说明”它跟着对话走说没就没了而 Skill 是一份“有目录、有前置技能说明、有可执行脚本”的完整能力包它可以被 agent 在对话中途主动“发现”并加载。我习惯用一个生活化的类比Prompt 是老板当场交代你怎么做Tool 是给你一把电钻而 Skill 是“一份工作手册配套工具操作禁忌”甚至还包括了完工验收标准。Agent 拿到任务后会先看手册再决定是否调用电钻做完还要按验收标准自查一遍。所以 Skill 不是替 agent 思考而是把某类任务的做法固化下来让 agent 不用每次从零发挥。再反过来说 Tool。现在大家熟悉的是 MCP 或 Function Calling 里的外部工具他们解决的是“agent 能调用什么”偏向动作本身但 tool 本身不会告诉你什么时候该用、用完怎么检查。Skill 在结构上比 tool 更靠上它是“会判断要不要用 tool 的一层”。所以如果你在项目里只做了一堆函数让 agent 调那还只是 tool 集合谈不上 skills 体系。Agent 这个词就更大了。它是整个执行流程的编排者负责理解任务、规划步骤、调用资源、交付结果。Skill 是 agent 的“内功模块”Agent 框架则是“运功的经脉”。我一直觉得让 Agent 直接吞一篇长文档当提示词是最容易失控的玩法把它拆成若干个 Skill让 agent 在需要的时候才读对应的那部分既不占上下文行为也可控——这才是 skill 机制设计的核心动机。1.2 Harness 负责执行Skill 负责规范“harness 和 agent 区别”这个问题我见过不下十次。Harness 是装 agent 的那个壳负责读配置、管理上下文窗口、跟模型 API 通信、把模型输出转成可执行动作比如 Claude Code、Codex CLI、opencode 都属于 harness。Agent 是大脑harness 是身体和感官。一个 Skill 会被放进 harness 能找到的目录里harness 在合适的时机把它作为资料、动作规范或脚本注入给当前 agent。同一个 Skill只要格式兼容就能在不同 harness 间迁移。比如我在 Claude Code 里调试好的一个“输出项目结构图”的 skill放到 Codex 的 skills 目录下也能被识别只是加载方式和触发语法略有差异。所以这些热词里反复出现的“skill 和 agent 的区别”本质是Skill 是被复用的知识/动作单元Agent 是组织这些单元完成目标的执行者。前者的质量决定 agent 的下限后者的框架决定上限。Skill 格式目前没到 “USB-C 统一”的程度。Anthropic 带火了 Claude Skill 的 SKILL.md 目录风格后很多工具开始兼容类似结构但命名、目录位置、触发方式仍有差异。这是我建议你动手前先锚定一个主要 harness 的原因不要一开始就想着全平台通吃否则光是适配就够你烦的。2. 核心细节拆解一个 Skill 包的三层结构2.1 最小可用包SKILL.md 才是灵魂先看我在内部项目里使用的一个最小 Skill 结构my-skill/ ├── SKILL.md ├── scripts/ │ └── generate_structure.py ├── references/ │ └── naming_convention.md └── assets/ └── templates/如果时间特别紧你甚至可以只保留一个 SKILL.md。它是 agent 能否正确使用这个技能的关键。SKILL.md 通常分成两个区块meta 信息区域和正文指导区域。我这里不贴某一个平台的官方模板而是给一个你手动改也能通过的通用骨架--- name: generate-project-structure description: 输出指定目录的树状结构图。当用户想了解项目文件布局、或需要给新成员展示目录概览时使用。 allowed-tools: - bash - glob --- # 项目结构图生成技能 ## 适用场景 - 用户询问“这个项目怎么组织的” - 需要在文档中插入项目结构图 ## 操作步骤 1. 使用 glob 或 bash 列出目标目录下的文件与文件夹。 2. 忽略 node_modules、.git、dist、build 等生成目录。 3. 输出 markdown 格式的树状图。 ## 验收标准 - 结构图包含主要目录与顶层文件 - 忽略规则生效description 一定要写清楚“什么时候用”因为 harness 通常是靠 description 做意图匹配的。你写“生成结构图”这种过于简单的描述agent 很可能没意识到这个技能也能用于“介绍项目框架”这类任务。description 就是技能的检索入口写得好不好直接决定被调用的频率。正文部分不要写一堆模型的“角色扮演”而是写“怎么做”与“边界”尤其是规则和禁区比如哪些目录不要管、哪些文件必须展示、输出格式长什么样。Agent 在触发技能后会把整个 SKILL.md 注入上下文你说得越具体它的动作越稳定。2.2 示例脚本让 Skill 真正跑起来只有一个文档的技能只能约束行为跑不了活真正提升效率的是配套脚本。拿上面这个结构图技能来说我会放一个 Python 脚本这样 agent 不用自己临时写代码直接调用脚本即可。#!/usr/bin/env python3 # scripts/generate_structure.py import os import sys from pathlib import Path IGNORED_DIRS {.git, node_modules, dist, build, __pycache__} IGNORED_FILES {.DS_Store, .env.local, *.pyc} def render_tree(root: Path, prefix: str , is_last: bool True) - list[str]: lines [] entry root.name if root.name else str(root) arrow └── if is_last else ├── lines.append(prefix arrow entry) if not root.is_dir(): return lines children [p for p in sorted(root.iterdir(), keylambda x: (not x.is_dir(), x.name.lower())) if should_ignore(p) is False] next_prefix prefix ( if is_last else │ ) for i, child in enumerate(children): lines.extend(render_tree(child, next_prefix, i len(children) - 1)) return lines def should_ignore(path: Path) - bool: if path.name in IGNORED_DIRS or path.name in IGNORED_FILES: return True return any(pattern.endswith(*) and path.name.endswith(pattern[:-1]) for pattern in IGNORED_FILES if * in pattern) if __name__ __main__: target Path(sys.argv[1]).resolve() if len(sys.argv) 1 else Path.cwd() print(\n.join(render_tree(target)))这个脚本只做一件事打印 ASCII 结构树默认忽略一堆噪音目录。你在 SKILL.md 的“操作步骤”里明确要求 agent 优先执行python scripts/generate_structure.py path而不是现场现写一段遍历代码能避免好几个小时的路径问题和大小写问题。Script 不是炫技是为了卡住 agent 的“自由发挥”让结果可复现。2.3 设计技术要点为什么 SKILL.md 的“边界”是核心我见过新手写技能特别喜欢在 SKILL.md 里塞大段“你是专家你很厉害请用严谨的态度分析”。坦白讲这些语义放在模型权重里可能有点用但放在 Skill 里纯粹浪费 tokens。Harness 注入技能后这些口号并不会提高输出质量反而稀释了真正有用的指令。真正该写的是边界什么时候不用这个技能遇到权限不足怎么办输出超长时如何截断数据敏感时是否只输出统计信息我在实际项目里写了一个“数据库 schema 分析”技能核心内容不是“怎么执行 SQL”而是“哪些库不能碰、哪些表脱敏、查询超时要主动降级”。这几个限制比三页专业术语都管用。所以在设计一个技能时把 60% 的时间花在定义边界上30% 写步骤10% 写验收标准。步骤写得再好边界没定agent 容易跑飞边界清晰了哪怕是第一次写也能把事办得八九不离十。3. 实操过程与核心实现从零写一个可复用的文档解析 Skill3.1 明确目标和输入输出为了让整个过程不悬空我拿一个我做“数学建模求职辅助”的 skill 举例。这个技能的目标是给 agent 一份多文件 Markdown 报告让它提炼出关键结论、假设、局限和下一步建议。为什么选这个任务因为数学建模场景里面的报告通常又臭又长模型初次阅读后经常抓不住重点。Skill 的目标是强制输出固定结构避免 agent 自由发挥成一篇散文。输入若干 Markdown/PDF 文件链接或内容附带用户指定要关注的维度比如“只看总结和参数敏感性”。输出一份固定格式的九宫格摘要通常是“问题定义 / 假设 / 方法 / 关键结论 / 局限 / 下一步”。3.2 编写 SKILL.md 与辅助文件项目结构长这样math-model-report-reader/ ├── SKILL.md ├── references/ │ ├── report_focus.md │ └── output_template.md └── scripts/ └── extract_headers.pySKILL.md 里我重点写了“触发条件”当用户提供多页报告并要求归纳时可用也明确了“不要做什么”不逐段翻译不重新建模不脑补数据。references 里放的是输出模板凡是 agent 要返回固定结构的场景我都推荐把模板拆到单独文件保证 SKILL.md 的主干仍然简洁。extract_headers.py 这个脚本的作用是把 Markdown 文档里的所有标题按层级抽出来形成一张目录索引。Agent 拿到目录索引后不再需要通读全文才能决定从哪读起这会让长文档分析快很多也减少 token 浪费。#!/usr/bin/env python3 # scripts/extract_headers.py import re import sys from pathlib import Path def extract(md_text: str): lines md_text.splitlines() result [] for line in lines: m re.match(r^(#{1,6})\s(.*), line) if m: level len(m.group(1)) title m.group(2).strip() result.append(f{ * (level - 1)}- [{title}]) return result if __name__ __main__: for p in sys.argv[1:]: text Path(p).read_text(encodingutf-8) print(f## {p}) print(\n.join(extract(text)))3.3 安装到 Claude Code 与 Codex这个技能我在 Claude Code 里是这样安装的mkdir -p ~/.claude/skills cp -r math-model-report-reader ~/.claude/skills/如果只想当前项目生效就放进项目根目录的.claude/skills下。Claude Code 会同时扫描用户级和项目级目录。个人使用放用户级团队项目建议放项目级并提交到代码仓库这样大家拿到的版本一致。Codex 的 skills 安装逻辑类似但对目录命名比较敏感我一般把技能包直接放进~/.codex/skills或者项目的codex/skills下。opencode 最近也开始支持 skills 目录大致可以给它设置opencode skills add ./my-skill这类命令。harness 之间没有完全统一装之前先看一眼官方文档别用同一个路径去猜所有工具。3.4 流程演示让 Agent 调用新 Skill装好后我测试时会直接输入请分析 docs/report01.md 和 docs/report02.md输出建模要点摘要。如果 agent 判断这个问题匹配了 description就会把 SKILL.md 注入上下文然后调用 extract_headers 脚本先拿目录再定向读取关键段落。最终输出一份按 output_template.md 组织的内容。第一次跑就完美命中不太现实我通常会在测试后调整 description 的措辞让匹配更准确。这个调参过程其实和 SEO 的标题优化很像你想让某个搜索意图命中你的内容就得反复试。3.5 安装第三方技能库superpower skills 与 awesome-claude-skills如果是小白上手不想自己写可以直接装现成技能仓。最常用的是 superpower skills 这类集合里面有一堆针对 Claude Code 或 Codex 的预置技能覆盖代码 review、SQL 分析、文档生成等场景。安装方式一般就是 clone 到本地再把对应目录软链到 skills 目录。git clone https://github.com/xxx/superpower-skills.git ln -s $(pwd)/superpower-skills/frontend-skill ~/.claude/skills/frontend-skill但我不建议全量塞进去skill 太多会加重 agent 的检索负担。装五六个真正高频用到的就够。可以先把仓库 clone 下来手动挑选需要的子目录软链进去。在“agent-skills”这个生态里数量从来不是优势精准才是。4. 常见问题与排查技巧实录4.1 技能不触发八成是 Description 的问题这个问题我遇到得太多了。明明 Skill 已经放进目录但 agent 就是不用。你问它“能不能分析这个项目”它只会跟你说“可以我来看看”完全不读 SKILL.md。排查第一步查 Description。Description 里的触发条件写得越像用户可能使用的表达命中率越高。比如“前端开发 skills”如果描述成“提供前端开发最佳实践”那用户问“帮我优化这个页面加载速度”时模型可能不会联想到这个描述。改成“用于帮助优化前端页面性能、分析打包体积、诊断加载瓶颈”命中明显改善。第二步查目录是否正确。Claude Code 只认特定目录你放错一层它连扫描都不会扫。Codex 则对文件命名有要求有的版本要求 SKILL.md 必须放在 skill 根目录下不能嵌套太深。第三步看上下文中的说明。有些 harness 要求用户显式 技能名或输入 /skill 命令否则只是待命状态。Claude Code 里你可以直接输入/skill 技能名把它拉进上下文。4.2 Agent execution terminated due to error切分脚本要最小化这个报错我看到过无数次。你把一个技能写得特别大脚本里又依赖了一堆第三方库结果 agent 执行时刚好缺库、缺环境变量、路径不对整个管道直接终止。这类错误其实不是模型的问题是 skill 实现得太脆弱。我的经验是技能里的脚本必须保持最小依赖最好只用 Python 标准库或者提前写死可 pip 安装的依赖清单并在 SKILL.md 里写明安装命令。此外给脚本加上清晰的参数校验和错误提示agent 看到报错后能自己根据提示修正而不是卡死。一个重要心得不要把一个需要交互式确认的操作写进 skill。Agent 无法像人一样在终端里输入 y/n它只能通过内部工具与 shell 交互。遇到需要确认的步骤要么改成非交互要么提前用环境变量指定默认值。4.3 Skill 与 Tool 的命名冲突当你的 agent 环境中同时存在同名函数、同名 MCP 工具、同名 skill 时执行顺序和优先级经常很谜。我发现最稳妥的策略是给 skill 名称加上业务前缀如frontend-audit、>
返回列表