尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Agent Skill 编写实战:从提示词到稳定可复用的能力包

发布时间:2026/9/24 20:10:22

资讯中心
01
ARTICLE

Agent Skill 编写实战:从提示词到稳定可复用的能力包

Agent Skill 编写实战:从提示词到稳定可复用的能力包
前阵子有个朋友跑来找我吐槽说他在 agent 项目里一口气塞了十几个 Skill结果真正能用起来的没几个。模型要么根本不理会 Skill 的存在把指令当成普通对话闲聊要么就是照着 Skill 里的步骤执行到一半突然开始自由发挥输出结果跑偏得离谱。我让他把其中一个 SKILL.md 发过来看了一眼瞬间就明白问题出在哪儿了——那哪是 Skill分明是一份野心勃勃的“万能 prompt”既有宏大目标又有抽象要求就是没有一条能让模型老老实实照着做的具体指令。这其实是我见过最多的通病。很多人以为 Agent Skill 就是“把提示词换个文件格式装起来”实际上完全不是一回事。一个真正好用的 Agent Skill本质上是一套“可复用的能力包”它得能被路由系统准确识别得能被模型稳定执行得能在不同对话场景里反复复用还得在出错时有兜底方案。这些东西不设计好Skill 写得再多也是摆设。这篇文章我准备从 Skill 的定位讲起聊聊它的目录结构、描述写法、指令组织方式再用三个真实场景论文检索、绘图、语言学习做完整拆解最后说说怎么测试和迭代一个 Skill。内容会偏向实操适合正在做 agent 开发、项目里 Skill 效果不理想、或者刚开始接触 Agent Skills 机制的朋友。看的时候最好手边有个项目边看边改效果比单纯读一遍好得多。1. 先搞明白 Skill 在 Agent 系统里的定位1.1 Skill 不是提示词是“能力包”我们先把概念对齐一下。在 Claude、Codex、OpenCode 这些支持 Agent Skills 的框架里一个 Skill 通常是一个独立目录里面放一个 SKILL.md 作为主指令文件再加上若干辅助资源比如脚本、参考文档、模板、示例数据。模型在对话过程中会读取这个目录按照里面的说明来执行任务。你可以把它理解成给模型配了一个“固定套餐”用户点了这个 Skill 之后模型不再自由发挥自己想怎么做而是按照套餐里写的流程、用套餐里给的工具、最终产出套餐里规定的格式。所以 Skill 解决的核心问题其实是“不可控”。Prompt 只能告诉模型“你要做什么”Skill 则进一步规定了“按什么流程做、用什么工具做、交什么格式的作业”。这就是两者最本质的区别。我在实际项目里见过不少把 Prompt 直接改名成 SKILL.md 的团队结果自然是不好用。因为普通 Prompt 是在“当前这次对话”里生效的它的所有假设都建立在“模型已经理解了上下文”这个前提下。而 Skill 是脱离具体对话存在的它必须自己把一切说清楚输入是什么、输出是什么、遇到异常该怎么办。这更像是给一个完全不了解业务的新同事写操作手册而不是给一个资深大佬写需求文档。1.2 Skill 的三个核心标准稳定、可测、可复用既然说 Skill 不是 Prompt那我们怎么衡量一个 Skill 写得好不好我自己一般看三个指标。第一是稳定。同一个 Skill同样的输入跑五次结果应该基本一致而不是这次输出表格、下次输出纯文本、再下次直接回车换行。稳定性是 Skill 的底线如果这一点做不到后面所有东西都免谈。第二是可测。好 Skill 的设计者会主动给 Skill 准备一组固定测试用例比如“输入 X 时必须输出包含 Y 的结果”。这样每次改完 Skill都能拿这组用例快速回归一遍而不是每次都在真实对话里手动试错。第三是可复用。Skill 不能绑定死某一个特定对话场景它应该能在不同话题、不同上下文里被反复调用。比如“周报生成 Skill”不管用户这周干了开发、写了文档还是做了测试它都能工作。如果 Skill 里写死了某些话题假设那它本质上就是一段一次性 Prompt没有做成 Skill 的意义。1.3 为什么说现在是做 Skill 的好时候这两年 agent 框架的生态变化非常快。以前每个人做 agent 都是自己设计一套提示词工程方案代码各自为政技能没法流通。但现在越来越多的 agent 项目开始统一采用 SKILL.md 这个格式这意味着你写出来的一套技能换到另一个框架里也可以直接复用或者稍微改改就能跑起来。社区里甚至已经能看到不少人分享自己的 Skill 仓库比如有人做了“book to skill”直接把一本书的内容整理成技能包也有人做“论文 skill”“语言学习 skill”“前端 skill”之类的垂直技能。我个人的判断是Skill 正在慢慢变成 agent 生态里的“标准件”。以后做 agent 开发核心竞争力不再是你会不会写提示词而是你能不能设计出稳定、高效、可组合的 Skill 组件。现在把基本功打扎实后面会省很多事。2. 写好一个 Skill先想清楚这三件事2.1 一个 Skill 只做一件事别搞“全家桶”我在拆解别人的 Skill 时最常见的失败原因就是职责太多。一个 Skill 既想翻译又想润色还想做摘要最后模型根本不知道该优先执行哪条指令。你说做翻译它顺手给你加了一段“摘要如下”你说做润色它把内容风格改得面目全非。原因很简单指令太多会让模型在决策时产生冲突而且描述信息也被稀释了路由系统很难判断这个 Skill 到底该在什么场景下被触发。正确的做法是坚持单一职责原则——一个 Skill 只解决一类问题。如果你确实需要多种能力就拆成多个 Skill让上层 agent 根据用户请求去选择合适的那个组合使用。比如“论文检索 Skill”和“论文精读 Skill”拆开前者负责找文献、列结构化结果后者负责对一篇 PDF 做深度分析两者互不干扰路由清晰测试也容易写。单一职责还有个附带好处描述信息可以写得很精准路由命中率自然就高。不信你可以做个对比一个描述写“用于翻译、润色、摘要、邮件、周报……”另一个描述写“仅当用户要求将学术论文翻译成中文时使用”后者被正确调用的概率会明显高出一大截。2.2 你写的是使用说明书不是任务书很多人写 Skill 指令的时候语气还是“帮我做点事”的命令式。比如“整理用户的输入内容生成一份周报。”这种写法的问题在于它只告诉模型要完成什么没告诉模型怎么完成。模型拿到这种指令后只能靠自己的经验猜测最后的结果自然跟你的预期对不上。更靠谱的写法是“使用说明书式”的把执行过程拆成一个个具体、可验证的步骤每一步都给出明确的输入和产出。比如周报 Skill 可以这样写接收用户提供的本周工作内容如果没有提供请先询问用户。将内容按“开发、测试、文档、沟通、其他”五个类别分类。每个类别输出一条要点格式为“类别具体事项”如果类别下没有事项则省略。最后输出一个 Markdown 表格表头为“类别 | 事项 | 备注”不要添加额外说明。你看这样写完之后模型几乎没有自由发挥的空间了每一步该做什么、做完输出什么格式全都规定好了。你可以把这个看成是区分“普通 Prompt 作者”和“Skill 设计者”的分水岭——前者给模型派活后者给模型铺路。2.3 提前把异常分支写好别让模型临场发挥写 Skill 的时候很多人只写了“正常流程”完全没考虑异常情况。结果模型遇到不完整输入、找不到信息、权限不足、结果为空这些情况时就开始自己编造策略。有的模型会假装任务完成输出一个看起来很像回事但内容全是编的结果有的模型会直接卡住反复重复“无法执行”还有的模型会跳出 Skill 的约束开始跟用户闲聊。应对办法是在指令里明确写好“如果……那么……”的兜底分支如果输入为空先向用户询问必要信息而不是猜测。如果搜索结果不足明确告知“未找到足够结果”并给出建议关键词。如果脚本执行失败读取出错信息并尝试修复后再重试最多重试两次。如果输出格式需要特定字段但字段不存在用“暂无信息”填充而不是编造内容。这些分支在正常流程时看似冗余但在真实使用中特别管用。它相当于给模型上了一道保险让它在遇到边界情况时依然有路可走。很多Skill 之所以“时灵时不灵”往往就是因为这些兜底逻辑没有写全。3. 从零搭一套标准 Skill结构、格式与关键字段3.1 目录结构SKILL.md 是核心但别只放一个文件一个规范的 Skill 目录我一般建议至少包含三块内容my_skill/ ├── SKILL.md # 核心指令文件模型优先读取的部分 ├── scripts/ # 可执行脚本用来做确定性计算 │ └── helper.py └── references/ # 参考材料、模板、示例 └── template.mdSKILL.md 是门面也是模型第一优先读取的文件。它里面写的是“怎么执行任务”的完整指令。scripts 目录放需要确定性计算的逻辑比如文本解析、数据转换、接口调用这些事交给模型做容易出错但交给脚本做就是一行命令的事。references 目录放模板和示例用来约束输出风格和格式。很多人写 Skill 只放一个 SKILL.md其他全靠模型自己发挥。短任务还好长任务或者需要精确计算的任务就很容易出问题。比如让模型自己算字符数、做日期计算、格式化 JSON看起来很简单实际执行时经常出错。把这些逻辑抽到脚本里是提升 Skill 稳定性的关键一步。3.2 名称和描述决定模型“看不看得见你”Skill 的 name 和 description 是路由系统判断“这个 Skill 该不该被调用”的依据。如果用一句话概括就是名称要短描述要准。名称方面我建议用动词开头比如fetch_papers、generate_chart、weekly_report这样模型一眼就能看出这个 Skill 是干什么的。避免用太抽象的单词比如tool、helper、misc这类名称对路由没有帮助。描述方面要写成裁判能直接下判断的句子包含触发条件、输入要求、输出说明。我见过一个写得不错的描述description: 当用户要求检索学术论文、查询文献资料或获取引用信息时使用。输入为研究主题或关键词输出为结构化论文列表包含标题、作者、年份、摘要和原文链接。这种描述的好处是路由模型不需要额外推理只要看到用户意图和描述匹配就能直接触发。相比之下如果描述写成“用于学术相关的各种操作”那模型很可能在用户问“如何写论文”时误触发因为“学术相关”的范围太宽泛了。3.3 指令正文写法Step by Step并且每一步都可验证我们来看一个完整但精简的 SKILL.md 示例假设我们要做一个“周报生成 Skill”--- name: weekly_report description: 当用户要求生成周报、整理本周工作内容时使用。输入为本周工作描述输出为 Markdown 表格格式的周报。 --- # 周报生成 Skill ## 执行步骤 1. 接收用户提供的本周工作内容。如果用户没有提供请先询问用户本周的主要工作内容不要猜测。 2. 将工作内容按“开发、测试、文档、沟通、其他”五个类别进行分类。 3. 对每一个类别将相关事项整理为一条简洁的描述不超过 50 字。 4. 输出一个 Markdown 表格表头为“类别 | 事项 | 备注”。如果没有某一类别的事项不输出该行。 ## 输入格式 用户输入一段关于本周工作的自然语言描述例如“这周我在做登录模块的重构修复了三个 bug还写了一份接口文档”。 ## 输出示例 | 类别 | 事项 | 备注 | | --- | --- | --- | | 开发 | 完成登录模块重构 | 无 | | 测试 | 修复三个登录相关 bug | 无 | | 文档 | 编写接口文档 | 无 |注意看几个细节第一frontmatter 里的 name 和 description 是给路由用的要单独写清楚第二指令正文用“1. 2. 3.”的步骤列出来模型执行时天然会按顺序走第三我给了输入格式和输出示例这是最容易被忽略但最有用的部分——模型看到示例比看到抽象规则要理解得快得多第四我在每一步里都写了“如果……就……”的兜底逻辑防止模型瞎猜。这种写法放到不同 Skill 里都可以直接套用先接收输入再定义处理规则然后规定输出格式最后补异常分支。3.4 脚本和参考文件怎么放才不会被模型“带偏”先说脚本。在 Skill 里放脚本核心目的是把模型不擅长的确定性计算抽出去。比如解析 PDF、调用搜索 API、做数据清洗等这些事用 Python 写脚本效率和准确率都远高于让模型手写代码再执行。脚本写好后指令里直接写“运行 scripts/fetch_papers.py --keyword xxx”模型只需要知道怎么调用不需要理解脚本内部逻辑。需要注意几点。第一脚本要处理异常情况比如网络超时、API 返回错误脚本内部要有 try-except 和明确的错误输出不然模型看到一堆 traceback 就懵了。第二脚本不要硬编码任何密钥。API key 这类敏感信息一律通过环境变量注入Skill 文件本身要能公开分发。第三如果脚本需要安装依赖记得在目录里放一个 requirements.txt并且在 SKILL.md 里写清楚安装命令。参考文献和模板要克制。我见过有人往 Skill 里塞几十个参考文档看起来很全但模型在有限的上下文窗口里根本读不完这么多内容反而拖长了推理时间还稀释了核心指令的注意力。更合理的做法是只保留真正影响输出质量的材料比如一个输出模板、一个示例文件、一张对照表控制在 2000 字以内就够了。4. 三个真实场景的 Skill 拆解4.1 论文检索 Skill脚本负责“确定性”模型负责“意图消化”论文检索是很多人都会用到的场景我们拿它来拆解一下一个偏工具型的 Skill 应该怎么设计。首先定义边界输入是一个研究主题比如“大语言模型在医疗领域的应用”输出是五条相关论文的结构化列表。如果直接让模型去“搜索”它很可能会给你编造出五篇看起来非常真实、但实际上根本不存在的论文——这是大模型最容易犯的错误之一。所以这里的关键决策是搜索动作必须交给外部 API 处理模型只负责理解用户意图和整理结果。架构可以这样设计paper_search/ ├── SKILL.md # 指令先询问关键词再调用脚本最后整理输出 ├── scripts/ │ └── search.py # 调用学术搜索引擎 API返回 JSON 格式结果 └── references/ └── output_template.md # 论文列表的输出模板SKILL.md 里的指令大致是这种流程从用户输入中提取核心研究主题如果有多个主题选择最主要的那个。构造搜索关键词格式为“主题 综述/最新进展”保留原始主题词。运行python scripts/search.py --query 关键词 --limit 5。检查脚本输出如果结果为空尝试用更宽泛的关键词重新搜索。将返回的 JSON 结果按模板整理成 Markdown 列表务必包含论文标题、作者、年份、来源和摘要。如果脚本执行失败直接告诉用户“搜索功能暂不可用”不要尝试让模型自行编造论文列表。这样设计的好处很明显结果真不真实由 API 决定和模型无关模型只做翻译工作和格式整理出错空间大大缩小。论文检索最大的坑是“编造引用”而脚本加外部 API 的组合从机制上杜绝了这个问题。4.2 绘图 Skill让脚本兜底坐标计算别让模型硬抠像素Agent 画图也是一个很典型的场景。很多人的第一版方案是让模型直接输出 SVG 代码然后前端渲染。听起来很直接但实际跑起来你会发现一个问题模型在计算布局、坐标、对齐这些需要精确数字的事情上非常不靠谱。你让它画三个并排的矩形它可能给你输出两个在左上角、一个孤零零甩在右下角。我在做绘图类 Skill 时采取的策略是“模型描述意图脚本确定细节”。具体来说模型负责解析用户的绘图需求拆解成图形元素列表矩形、圆形、文字、连线等并粗略描述相对位置左边、右边、上方、居中。模型把这些元素输出为 JSON。一个 layout.py 脚本读取 JSON根据画布宽度自动计算所有元素的精确坐标和对齐关系。脚本输出最终的 SVG 文件。这样做的好处是模型不需要过于精确只需要给出“大致怎么布局”的高层指令剩下的数学计算全部交给脚本。这个 Skill 的稳定性会明显好于直接让模型生成 SVG 的版本因为坐标计算变成了确定性逻辑而不是概率性输出。我给这个 Skill 的 SKILL.md 写的关键指令片段是这样分析用户对图形的描述提取图形元素矩形、圆形、文本、箭头并标注每个元素的“逻辑位置”例如“左上角”“底部居中”“与第一个矩形右侧对齐”。将元素列表以 JSON 格式写入临时文件 /tmp/layout_input.json。运行python scripts/layout.py --input /tmp/layout_input.json --output /tmp/result.svg --width 800 --height 600。如果脚本运行成功直接把 SVG 文件路径反馈给用户如果失败读取错误信息修正后重试一次。注意这里的关键技巧把“确定性计算”外包给脚本。凡是涉及数字、格式、坐标、日期、统计的内容都应该走脚本而不是让模型自己算。模型做得好的部分是意图理解、内容组织和表达润色这部分就留给模型。4.3 语言学习 Skill状态管理和纠错机制是核心语言学习类 Skill 比前两个要复杂一些因为它是一个交互式场景模型需要和用户来回对话还要跟踪对话状态比如用户当前的等级、已学的词汇、答错的题目。这类 Skill 的难点在于模型很容易把对话变成“无脑夸夸模式”无论用户说什么都回一句“Great!”。这种体验对语言学习没有任何帮助用户根本不知道自己的问题出在哪。所以设计这个 Skill 时我特别强调了“纠错机制”。SKILL.md 里的核心设计分四步破冰阶段了解用户的母语、目标语言、学习水平初级/中级/高级然后设定一个语言等级标签。对话阶段每次只生成一个适合该等级的对话场景比如“在餐厅点餐”用户用目标语言回复。纠错阶段用户每回复一条消息模型都要做三件事指出语法错误和用词错误给出正确表达对表达的地道程度打分1-5 分如果用户连续答对 5 次自动上升一个难度等级。收尾阶段如果用户说“结束练习”输出本次练习的错题回顾列表。这里的核心设计是“纠错三件事”它强制模型在每次对话后都要给出结构化反馈而不是简单地说“很好”。为了让模型能跟踪状态我在指令里要求它在每次回复时顺便输出一个状态标签比如“当前等级: B1连续答对: 3待复习词汇: [awkward, refund]”这样即使上下文很长模型也能基于状态标签继续做判断。这个 Skill 的难点不再是“写提示词”而是“设计交互协议”。你需要在指令里定义清楚用户级别怎么变、什么时候升级、怎么记录错题这些本质上都是在写一套小型的对话状态机状态定义的越清晰模型的对话就越稳定。5. 测试、调试与迭代好 Skill 都是改出来的5.1 给 Skill 建一个回归测试集Skill 和代码一样需要测试。我习惯在写完一个 Skill 后立刻准备一组固定测试用例每个用例包含“输入”和“期望输出特征”。比如用例输入期望输出特征周报正常输入“这周修复了登录 bug写了接口文档”输出为 2 行表格包含“开发”和“文档”两类周报空输入无输入输出为询问用户周工作内容的提示绘图正常输入“画一个红色圆在画布中央下面写标题”输出为 SVG 文件路径且文件内包含 ellipse 和 text 元素绘图异常输入“画一个很复杂的不规则多边形”输出为脚本错误提示或简化图形不能无限卡住我在改 Skill 时会拿这组用例反复跑。每改一次指令就跑一遍所有用例看有没有引入新的回归问题。这个过程看起来笨重但它是保证 Skill 稳定性的最有效手段。没有测试集你根本不知道“这次改好了还是改坏了”只能凭感觉那样迭代效率太低了。5.2 四个报警信号什么时候说明 Skill 快崩了我总结了 Skill 失效的四个典型信号一旦发现就要立刻检查设计缺陷第一个信号是模型开始不由自主地“自由发挥”。比如 Skill 要求它调用某个脚本它却不调直接用自己的话说一个结果。这说明指令没有给出足够的限制模型觉得“靠猜也能完成任务”这时你需要把指令从“建议”改成“必须”并明确写出不执行的后果。第二个信号是输出格式时好时坏。有时候按模板输出有时候又自己改格式。这通常是模板给的示例不够具体或者没有强调“严格按照模板输出”。解决办法是在指令里写死输出结构并补上“不要修改模板字段名”这类约束。第三个信号是脚本报错但模型视而不见。脚本崩溃时模型应该读取错误信息并自我修复或降级处理但很多模型会选择忽略错误直接把一个不完整的结果输出给用户。解决办法是在指令里写明“如果脚本失败必须检查错误信息尝试修复脚本后重试最多重试两次超过则告知用户”。第四个信号是同一个 Skill 在不同上下文长度下表现差异巨大。有时候对话前几轮它还很稳定随着上下文变长它开始忘记 Skill 里的要求。这是上下文稀释问题解决办法是把关键约束在指令里重复强调或者在需要持久的信息比如状态标签里反复带上关键内容。5.3 像写代码一样做版本迭代我写 Skill 从来不是一个版本定稿的而是像写代码一样迭代。第一版只追求主流程能跑通比如周报 Skill v0.1 就只做“输入内容输出表格”这一件事不处理空输入不做类别缺失判断一切从简。跑通之后再加边界情况变成 v0.2然后测试异常分支再变成 v0.3最后加脚本优化到 v0.4。每次迭代只改一个东西改完立刻拿测试集回归一遍这样出了问题能快速定位。我给自己的规则是不引入一个新特性同时测试一个以上的新改动。如果上午改了描述下午改了指令结构第二天发现效果变差了你根本没法定责是哪个改动的问题。另外建议把 SKILL.md 放在 git 仓库里管理每个版本打一个 tag。Skill 是一个会持续演进的东西有历史版本记录你就能随时回退到能用的版本而不是在“新版本好像哪里不对”的焦虑中浪费时间。5.4 别忽略框架和 harness 对 Skill 的影响最后特别提醒一句Skill 不是“一次编写处处运行”的魔法。不同 agent 框架对 Skill 的支持程度不一样有的框架把 SKILL.md 当普通文本加载有的框架对脚本执行有沙箱限制有的框架会自动注入额外上下文有的框架则完全不会。你还需要注意“harness”和“agent”的分工——harness 更像是 agent 运行的脚手架它负责加载模型、管理上下文、执行工具调用这些都是你能不能在 Skill 里跑脚本、能不能联网的决定性因素。所以我的建议是在写 Skill 时先把框架的版本和限制摸清楚。比如当前框架是否支持工具调用是否允许执行外部脚本网络 API 访问有没有限制这些能力直接影响 Skill 的设计边界。换了一个框架Skill 的某些部分可能就需要调整。这不是 Skill 写得不好而是现实约束就是如此。6. 常见问题速查表最后整理一份我在实际开发中被问得最多的 Skill 相关问题和排查思路做成表格方便大家速查。现象可能原因解决办法路由系统不触发 Skilldescription 写得不够具体模型判断不了适用场景重写 description加入明确的触发条件和输入要求删除模糊表达模型调用了 Skill 但没按流程走指令正文缺少“必须”级别的约束模型觉得可有可无用“必须”“不要”“严格”等强约束词补上不执行的兜底分支输出格式不稳定模板示例不足模型没有参考对象在 references 里放一个完整的输出示例指令里强制模型对照该示例输出脚本执行报错后模型无视错误指令里没有写异常处理流程补充“脚本失败时读取错误信息、修复后重试、最多两次”的指令Skill 在不同对话里表现忽好忽坏上下文长度变化指令被稀释在关键步骤重复强调核心约束或用状态标签反复带出关键信息生成了看似正确但实际错误的内容模型在没有外部工具的情况下自行发挥把确定性逻辑搜索、计算、解析全部移入脚本模型只做意图理解和格式整理Skill 被误用在完全无关的场景description 范围太宽收窄 description 的适用范围列出“不要使用的情况”密钥硬编码在脚本里开发时图省事放进去了立即改为环境变量注入附使用说明避免提交到公开仓库再补一条特别重要的安全底线Skill 里的脚本要谨慎处理用户输入对传入给 shell 命令的参数做转义或白名单校验不要把用户输入直接拼进命令行里。模型本身对安全的理解是有限的Skill 作者必须替它守住这个环节这也是 agent 安全里最容易被忽视的一块。我个人现在的习惯是每个 Skill 都会在 README 里额外写一小段“设计决策”记录当初为什么这样拆分职责、为什么选择调脚本而不是让模型直接算、踩过哪些坑。这个习惯让我在几个 Skill 同时迭代时依然能保持清晰的思路也方便别人拿到我的 Skill 后快速理解设计意图。说到底Skill 写得好不好短期看指令写得多细长期看的是你有没有建立测试和迭代的机制。把这两件事做好了你的 Agent 才能从“会说话”进化到“会干活”。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。