Agent Skill开发实战:从SKILL.md到脚本封装与迭代
2026/9/24 20:06:33 网站建设 项目流程

搞了大半年 Agent 相关的东西,我最大的感受是:Skill 这个词被聊得太玄了。打开各种资料,要么是“Agent Skill 入门到精通”这种标题党,要么是官方文档的翻译腔,看完还是不知道手头这个需求到底该不该做成 Skill、文件放哪、提示词怎么写、脚本怎么组织。我写这篇就是想把我自己从零到一写 Skill、迭代 Skill、以及把 Skill 分享给团队其他人用的过程,原原本本拆开讲清楚。

先说结论:一个好用的 Skill,本质上就是一份可复用的操作手册加一套能跑通的执行代码,它的目标不是把功能堆得多炫,而是让 Agent 在遇到某一类问题时,能稳定地、按预期地完成“读资料—做判断—产结果”这个闭环。你不需要会多高深的算法,真正花时间的,是对需求边界的定义、对提示词的打磨,以及对异常情况的兜底。

这篇文章适合两类人:一类是刚开始接触 Agent 开发,想弄清楚 Skill 和 Plugin、Workflow 到底什么关系的人;另一类是已经在写 Skill,但总感觉 Agent 行为不稳定、经常“不听话”的人。我会把我踩过的坑和现在还在用的模板都放出来,你可以直接照着改。

1. 先搞清楚 Skill 的本质,再动手写

1.1 Agent Skill 到底是什么

Skill 在 Agent 体系里的定位,用大白话说就是“给 Agent 装一个技能”。Agent 本身是一个会思考的推理引擎,它知道“你要什么”,但不一定知道“每一步具体怎么干”。比如你让它“把这批数据整理成报表”,它能理解这句话,但如果你不告诉它报表的结构、字段口径、异常值怎么处理,它就会自己发挥——结果就是每次生成的东西都不一样,看着像那么回事,实际没法用。

Skill 要解决的就是这个问题。它不是给 Agent 增加知识(那是知识库和 RAG 的事),而是给 Agent 增加一套明确的行为流程。你可以把 Agent 想象成一位实习生,知识库是他的课本,Skill 则是你写给他的标准作业流程(SOP)。有了 SOP,Agent 才能按同样的质量标准干活。

我在实际工作中发现,很多人把 Skill 和理解成“一段提示词”,这是最容易跑偏的地方。提示词只是 Skill 的一部分。一个完整的 Skill 通常包含:描述文件(SKILL.md)、处理脚本(scripts 目录)、参考资料(assets 目录)、以及测试用例。描述文件告诉 Agent“什么时候用、怎么用”,脚本负责执行具体计算或数据处理,参考资料则是你不希望 Agent 自由发挥的那部分领域知识。

1.2 Skill 和 Plugin、Workflow、Harness 的分工差异

这几个概念经常会混在一起,我在团队内部也经常被问到“这个需求我该做成 Plugin 还是 Skill”。我自己的判断标准是:看它解决的是“集成问题”还是“行为问题”。

  • Plugin(插件)偏向解决“Agent 做不了的事”,比如连外部系统、调用某个 API、读写数据库。它更多是在做系统集成。
  • Skill 偏向解决“Agent 做不好的事”,比如生成一份格式固定的周报、按特定步骤分析数据、用特定风格写代码。它更多是在做行为约束。
  • Workflow 则是把多个步骤串成一条固定的流水线,类似传统自动化流程,适合步骤永远不会变的场景。
  • Harness 是承载 Agent 运行的外层框架,负责模型的调用、循环控制、工具分发、上下文管理。Skill 挂在 Harness 之上,好用的 Harness 会让 Skill 的加载与调用变得简单,但 Skill 本身的稳定性和边界,要靠定义者自己想清楚。

一个常见的错误是把所有东西都塞进 Skill。我见过有人把“发送企业微信通知”也写成 Skill,每次 Agent 调一个工具还得多转一层,纯属给自己加戏。和外部系统交互,用 Plugin 直接连更高效。Skill 更适合的场景是:问题可以被自然语言描述、步骤相对固定、且你希望输出保持一致的场景。

1.3 判断什么该拆成 Skill:三个问题法

每次我觉得“这需求好像能做成 Skill”时,都会先问自己三个问题:

第一,这个任务是不是反复出现?如果只是临时干一次,写个一次性脚本文档就行,做成 Skill 反而浪费维护成本。第二,这个任务是不是有固定的方法和步骤?比如“从论文里提取实验数据并整理成表格”,这步骤很固定,适合做 Skill;但“帮我想一个营销创意”,这没有固定步骤,更适合让 Agent 自由发挥,强行做成 Skill 只会把它的思路框死。第三,这个任务的输入输出是不是可以结构化?输入最好是明确的参数(比如文本内容、文件路径、语言类型),输出最好也是固定格式(Markdown、JSON、表格),这样 Skill 才好写、好测、好用。

这三个问题都满足,才值得动手。不然就只是一个 Prompt 的事,别搞复杂了。

2. Skill 的定义与文件结构,细节决定成败

2.1 SKILL.md 是灵魂:一份合格的技能说明书

无论你用的是哪种 Agent 框架,Skill 的核心入口基本都是 SKILL.md。这个文件的作用,相当于给 Agent 看的说明书。Agent 会先读取它,再决定要不要调用这个 Skill、以及怎么调用。所以这个文件的写法直接决定了 Skill 的召唤成功率。

我写 SKILL.md 的经验是,必须包含下面这几块内容:

  • 技能名称和一句话描述:说明这个 Skill 是干什么的,目标是什么。描述里最好带上触发场景的关键词,比如“生成周报”“分析日志中报错原因”,这样 Agent 在遇到这类任务时可以更准确地联想。
  • 适用场景与不适用场景:这一块很多人会忽略,但它非常重要。你要明确告诉 Agent“这是给什么场景用的”,同时最好也告诉它“什么场景不该用”。比如一个写代码注释的 Skill,就该注明“不适用于重构、不适用于处理非代码文件”,否则 Agent 可能拿它去乱用。
  • 运行流程:以步骤列表给出执行顺序,比如先收集输入,再调用脚本,再输出结果。
  • 命令与参数:这个 Skill 包含哪些可调用的脚本,每个脚本需要什么参数,参数的格式和默认值是什么。
  • 输出格式要求:希望 Agent 最终给用户呈现什么格式的结果。这样能避免 Agent 自由发挥导致输出结构漂移。
  • 注意事项:给 Agent 的提醒,比如“不要修改原文件”“如果数据缺失直接跳过该字段”。

下面是我的一个基础模板,你可以直接参考:

--- name: paper-survey description: 按指定主题检索论文并生成结构化调研综述。适用于论文调研、技术选型、前沿跟踪。 --- # Paper Survey Skill ## 适用场景 - 需要围绕某个主题整理 5-10 篇论文要点 - 需要对比多篇论文的研究方法 - 需要快速产出一份技术选型报告 ## 不适用场景 - 用户只是要一篇具体论文的全文 - 用户需要的是详细数学推导,而非综述 ## 运行流程 1. 向用户确认检索主题与年份范围 2. 调用 `scripts/search_papers.py` 获取论文列表 3. 对每篇论文提取摘要与贡献点 4. 使用 `scripts/build_review.py` 生成综述 Markdown 文件 5. 输出综述并在文末附上论文列表 ## 命令列表 - `scripts/search_papers.py --query <主题> --year <年份> --max-results <数量>` - `scripts/build_review.py --input <论文列表文件> --template <模板路径>` ## 输出格式 输出为 Markdown 文件,必须包含:背景摘要、分主题综述、对比表格、参考文献列表。

这里最容易被忽视的是“不适用场景”。我之前写过一版只写了“能做啥”,结果 Agent 在用户问“帮我写一篇论文的摘要”时也去调用检索 Skill,当然效果就很奇怪。后来给描述加了边界,错误调用的情况明显变少。

2.2 代码与资源怎么组织才不混乱

Skill 不是一个单文件,它是一个目录。我常用的目录结构长这样:

paper-survey/ ├── SKILL.md ├── scripts/ │ ├── search_papers.py │ └── build_review.py ├── assets/ │ ├── review_template.md │ └── field_list.md └── tests/ ├── test_search_papers.sh └── test_build_review.sh

scripts 目录放可执行代码,assets 目录放模板、参考文档、静态资源。为什么要分开?因为有些 Skill 的体积会膨胀,如果所有资源都堆在 SKILL.md 里,Agent 每次加载都要消耗大量上下文 Token。我在实践中发现,SKILL.md 控制在 200 行以内效果最好,详细的参考资料放进 assets,用时再读,省上下文,加载也更快。

tests 目录是很多人不写的,但我强烈建议至少放一个最基础的冒烟测试脚本。每次改完 Skill,都跑一遍测试,确认核心脚本还能正常工作。这个习惯帮我挡掉了不少低级错误,比如改了一个参数名忘了同步调用处。

2.3 API 设计:一个 Skill 最好只解决一个能力

写 Skill 的时候,我见过一个非常典型的问题:为了省事儿,把所有相关功能都塞进一个 Skill。比如我最初写“文档处理 Skill”,在里面同时放了“摘要生成”“OCR 识别”“表格提取”三块能力。结果就是 SKILL.md 描述很长,Agent 经常选错子功能,明明用户要的是表格提取,Agent 却先去调 OCR,浪费了大量时间。

后来我把它们拆成了三个独立 Skill,每个只干一件事。这样做的收益很明显:描述文件更短,触发更准确,每个 Skill 的调试影响面也更小。如果确实需要在一次任务里用多个能力,可以让 Agent 按顺序依次调用多个 Skill,这属于编排层的事情,而不应该靠一个臃肿的 Skill 硬撑。

另外,Skill 提供的 API 数量也要克制。一个脚本能解决的问题,不要拆成三个脚本让 Agent 自己串联。脚本之间互相调用的链路越长,出问题的概率越大。

2.4 命名、版本与描述优化:Agent 靠这个找到你

Skill 的命名是门学问。你起的名字,既要让 Agent 在语义上能理解,也要尽量避免和其它 Skill 冲突。我建议用“动词+宾语”的形式,比如generate-reportanalyze-logsreview-code。别用那种特别宽泛的词,比如utilstoolhelper,这种名字 Agent 根本不知道什么时候该用。

Skill 的 description 也值得反复打磨。我有一版 skill 的 description 写的是“generate report”,结果在任务“把这个季度数据整理成表格”时,Agent 完全不触发它——因为这句话里没出现 report 相关的关键词。后来我把描述改成了“按指定模板生成周期性的销售、运营或项目报告,支持从数据文件读取统计结果”,触发率一下子就上来了。说白了,description 是给 Agent 看的索引,close 到实际任务语义,越具体越好。

版本管理方面,我在每个 Skill 目录里放一个VERSION文件,比如v1.2.0,并维护一份CHANGELOG。这样当 Agent 行为异常时,我可以快速知道当前用的是哪一版,回溯是谁改了什么。

3. 实操一个完整 Skill:从需求到落地

3.1 选一个真实需求来拆解

为了把上面的理论落到地面上,我用一个我最近写的 Skill 来完整演示——需求是“按主题检索论文并生成调研综述”。这个需求出现的频率很高:技术选型要看论文、新方向入门要读论文、写季度报告要列参考文献。而且它的流程相对固定:搜论文、读摘要、提取关键信息、汇总成文。非常适合做成 Skill。

先做需求拆解。我把整个过程拆成四步:第一步,根据用户提供的主题和年份范围调用论文检索接口;第二步,对返回的论文标题、摘要、作者、年份等信息进行清洗和筛选;第三步,按主题对筛选出的论文进行分组合并,提取每篇的核心贡献;第四步,用固定模板生成 Markdown 综述文件。

这四步对应两个脚本:search_papers.py负责前两步,build_review.py负责后两步。为什么不写成一个脚本?因为检索和综述生成是两种不同类型的操作,检索偏数据获取,综述偏文本生成,拆开后可以让 Agent 在生成综述前先和用户确认检索结果是否准确,避免白生成一大段。

3.2 编写 SKILL.md 的核心部分

先写描述文件。我在 2.1 节里已经给了模板,这里补充一个落地时的写法思路。description 一定要带上“场景+产出物”,我写的是:“检索指定主题下的学术论文,并按主题生成结构化调研综述,输出 Markdown 格式报告,适用于论文调研、技术选型、研究方向梳理。”相比“写一篇论文综述”,这句话给 Agent 的信息量更足,它知道什么时候该用、最终产出是什么。

在“运行流程”部分,我会明确写出步骤之间的等待条件。这一点很关键,我发现如果流程里没有“先获取脚本运行结果,再基于结果进行下一步”,Agent 有时会在脚本还没跑完时就凭想象生成综述,结果就是用户看到一篇看起来很真、但参考文献全是编造的报告。所以我在流程里明确写了一句:“search_papers.py执行完成后,将返回结果展示给用户确认,确认后再调用build_review.py。”

3.3 编写核心处理逻辑

接下来是脚本。search_papers.py我用 Python 来写,因为它处理数据和文本最方便。核心逻辑是接收查询参数,调用检索接口,解析返回结果,清洗字段,最后输出结构化的 JSON 到 stdout。下面是一个非常精简但完整的示例:

#!/usr/bin/env python3 """Search papers by keyword and output structured JSON.""" import argparse import json import urllib.parse import urllib.request def search(query, year_from, max_results): params = { "query": query, "year_from": year_from, "max_results": max_results, } url = "https://api.example.com/papers?" + urllib.parse.urlencode(params) with urllib.request.urlopen(url, timeout=15) as resp: data = json.load(resp) results = [] for item in data.get("papers", []): results.append({ "title": item.get("title", "").strip(), "authors": item.get("authors", []), "year": item.get("year", ""), "abstract": item.get("abstract", ""), "doi": item.get("doi", ""), "topics": item.get("topics", []), }) return results def main(): parser = argparse.ArgumentParser() parser.add_argument("--query", required=True) parser.add_argument("--year", type=int, default=None) parser.add_argument("--max-results", type=int, default=10) args = parser.parse_args() results = search(args.query, args.year, args.max_results) print(json.dumps(results, ensure_ascii=False, indent=2)) if __name__ == "__main__": main()

这个脚本的重点在两个地方。一是超时设置,我给urlopen设置了 15 秒超时,避免 Agent 在接口无响应时卡死等很久。二是字段清洗,titleabstract全部做 strip,去掉多余换行和空格,因为后面综述生成时,这些文本会直接拼接进 Markdown,脏格式会让输出的排版很乱。

build_review.py的职责是读取上一步的 JSON 文件,按照模板渲染成 Markdown。这里有一个设计要点:它的输入不要直接读管道里的 stdout,而是读一个中间文件。这样做的好处是调试方便,Agent 把 JSON 写到某个路径后,你可以人肉打开这个 JSON 看数据质量,再决定要不要进入生成环节。

#!/usr/bin/env python3 """Build a structured review Markdown from paper JSON.""" import argparse import json from datetime import date from pathlib import Path def build_review(papers, template_path, output_path): today = date.today().isoformat() lines = [] lines.append(f"# 论文调研综述\n") lines.append(f"生成日期:{today}\n") lines.append(f"共筛选论文 {len(papers)} 篇。\n") # 按年份分组 by_year = {} for p in papers: y = str(p.get("year", "unknown")) by_year.setdefault(y, []).append(p) for year in sorted(by_year.keys(), reverse=True): lines.append(f"\n## {year}\n") for p in by_year[year]: authors = ", ".join(p.get("authors", [])[:3]) lines.append(f"- **{p.get('title')}** ({authors}, {year})") abstract = p.get("abstract", "").strip() if abstract: lines.append(f" - 摘要:{abstract[:300]}") output_path.parent.mkdir(parents=True, exist_ok=True) output_path.write_text("\n".join(lines), encoding="utf-8") print(f"review written to {output_path}") def main(): parser = argparse.ArgumentParser() parser.add_argument("--input", required=True, help="path to paper json") parser.add_argument("--output", required=True, help="output markdown path") args = parser.parse_args() papers = json.loads(Path(args.input).read_text(encoding="utf-8")) build_review(papers, None, Path(args.output)) if __name__ == "__main__": main()

这个脚本里我故意把摘要截断到 300 字,原因很实在:综述文档如果每篇论文都贴完整摘要,读起来会非常冗长,而 300 字内基本能把一篇论文的核心贡献说清楚。这个决策对应的场景是“综述”,如果你写的是“论文精读笔记”,那就不该截断,所以模板参数化是必要的。

3.4 构建、调试与回归测试

写完两个脚本后,我先在本地手动跑了一遍,构造了一个测试 JSON 文件,然后运行build_review.py看输出。第一次跑就发现了一个问题:有些论文的year字段缺失,我代码里默认按unknown分组,结果 Markdown 里多了一个“unknown”大标题,很难看。后来我改成:年份缺失的论文统一标记为“未标注年份”,并且排到所有分组最后。这种小坑特别多,只有跑真实数据才能发现。

接下来做回归测试。我在tests/目录放了一个test_build_review.sh,内容是固定输入一个 JSON 文件,输出到一个临时目录,然后对比输出的 Markdown 是否包含期望的标题和数量统计。这样每次我改脚本,只要跑一遍这个脚本,就能确认基本功能没坏。

再把这个 Skill 挂到 Agent 框架里做一次集成测试。测试方式是给 Agent 一个自然语言任务:“帮我调研一下大语言模型评估方法,重点看近两年的综述类论文,10 篇以内。”观察 Agent 是否正确触发了paper-survey、是否先调用search_papers.py、是否在拿到结果后和用户确认、最后是否生成了格式正确的 Markdown。

3.5 一次完整的运行实录

我这里给出一段实际运行中 Agent 的执行轨迹,方便你理解 Skill 是怎么被用起来的。

用户输入:“我想看一下 2024 到 2025 年关于 RAG 知识库优化方向的论文,做技术选型参考。”

Agent 先是判断这个任务属于paper-survey的适用范围,然后在内部生成命令:

python scripts/search_papers.py --query "retrieval augmented generation optimization" --year 2024 --max-results 8

脚本返回 JSON 之后,Agent 把论文列表整理成简易表格展示给用户,并问:“这 8 篇是检索到的近两年论文,我按相关度排序了,是否需要剔除部分或增加检索主题?”用户确认后,Agent 再调用:

python scripts/build_review.py --input /tmp/paper_results.json --output /tmp/rag_survey.md

最后 Agent 把生成的 Markdown 内容按章节展示给用户,并说明参考文献列表在文末。整个过程里,Agent 不需要理解论文内容本身,它只需要严格按流程执行,真正的内容组合和模板渲染由脚本完成。这就是 Skill 的价值:让不可控的大模型行为,变成可控的工程流程。

4. 实测下来的坑与排错思路

4.1 常见问题速查表

我把自己在实际开发和团队使用中记录的常见问题整理成了一张表,你可以直接参照排查。

现象可能原因解决办法
Agent 完全不触发 Skilldescription 写得不贴近任务语义把触发场景、动作、产出物写进 description,用真实任务语言描述
Skill 触发过于频繁,用户没明确要求也调用描述过于宽泛,缺少“不适用场景”在 SKILL.md 中写清限定条件,比如“仅在用户明确要求调研论文时使用”
Skill 执行到一半就停止,没有产出脚本报错或超时,提示词里没有兜底策略给脚本加超时与异常捕获,并在流程中写明“脚本失败时输出错误信息并停止”
生成的内容格式不一致,有时有表格有时没有输出格式约束不够强在 SKILL.md 的输出格式章节用精确模板示例
脚本生成了无用文件没人清理没有约定临时文件路径统一约定临时输出目录为/tmp/<skill_name>/,并在流程结束后提示清理
Agent 调用了 Skill,但传参格式错误参数定义不清晰在 SKILL.md 中写明每个参数的类型、范围、示例值
Skill 的脚本在本地跑正常,在 Agent 里跑报错工作目录不同,或依赖缺失脚本入口统一使用绝对路径或基于 skill 目录的相对路径,并在 SKILL.md 中声明依赖
两个 Skill 互相抢任务描述之间有重叠明确两者的边界,避免出现“A 也能做 B 也能做”的语义模糊

最常见也最隐蔽的问题是第一种和第二种——它们都和 description 的质量有关。我一直提醒身边同事:Description 不是写给用户看的,是写给模型的索引,它的质量会直接影响 Agent 在任务路由阶段的判断。你的描述越接近用户真实说话的方式,触发越准。

4.2 排查工具与调试方法

遇到 Skill 行为异常时,我不会直接改提示词,而是先做一轮“最小复现”。比如发现build_review.py生成的综述里年份排序不对,我会先构造一个只有两篇论文的 JSON,手动跑一遍脚本,确认是脚本逻辑问题还是 Agent 调用时的参数问题。人肉跑通后再回到 Agent 环境里验证,这样能避免把脚本问题和编排问题混在一起。

还有一个习惯是给脚本加--debug参数。在 debug 模式下,脚本会打印更详细的中间日志,包括接收到的参数、API 返回的原始数据、清洗后的结果等。集成调试时让 Agent 先以 debug 模式调用一次,日志会直接暴露问题出在哪一步。

如果你用的 Agent 框架支持 eval,建议给关键流程固化几个评估用例,就是“输入固定任务,检查输出是否满足预期”。我的习惯是每做完一个重要 Skill,就维护 5 个左右的 eval case,覆盖正常路径和 2-3 个异常路径。比如上面的paper-survey,我会有一条例外用例是“当我提供的主题过于宽泛时,Agent 应要求我先收敛主题再检索”,这是一个好的交互设计,也防止 Agent 愣头愣脑地返回几百篇论文。

4.3 权限与安全的边界别踩线

Skill 免不了要执行脚本,有些脚本还会访问网络,这就引出一个安全边界的问题。我在团队内部定的几条原则,分享出来供你参考。

第一,Skill 默认只做只读操作。凡是会修改用户文件、发送消息、删除数据的动作,必须显式声明在 SKILL.md 里,并且最好加一个二次确认步骤。第二,不在 Skill 的提示词或脚本里写死任何密钥。密钥放在环境变量里,脚本通过os.environ读取;如果 Agent 框架不支持环境变量,那就用单独的配置文件并设置权限。第三,对外部网络请求统一加超时和错误处理,不要让 Agent 因为一个外部接口的异常就一直卡在那里。第四,发的过于危险的操作(比如批量删除、格式化输出)不应该通过 Skill 静默完成。

这些原则不一定能堵住所有问题,但能挡住大部分低级风险。我在社区看到过一些公开的 Skill 会直接让 Agent 执行 shell 命令,如果这个 Skill 被恶意修改或在不可信环境里运行,后果会很严重。写 Skill 的人必须对代码的执行边界负责。

5. 让 Skill 真正“好用”的进阶经验

5.1 一次构建、多处复用:分发与加载

Skill 写出来如果只能自己用,价值会大打折扣。我在团队里推动的做法是:每个 Skill 独立成一个 git 仓库或一个目录,包含 SKILL.md、scripts、tests、README。README 写给人类看,SKILL.md 写给模型看,两份文档不能互相替代。人类维护者需要知道“为什么这样设计”,模型只需要知道“怎么执行”。

分发方式主要看框架。有的框架支持从远程仓库拉取 Skill,有的需要你手动放置到指定目录,还有的可以通过配置文件声明加载路径。无论哪种方式,我建议维护一份“Skill 索引文件”,把你装了哪些 Skill、各自版本、负责人是谁列清楚。当 Agent 行为变差时,索引能帮你快速定位是不是某个 Skill 升级导致的回归。

我自己还有一个习惯:新 Skill 先在自己环境跑一周,记录 Agent 触发失败的案例,再放给团队试用。试用的同事会给很多反馈,最有价值的反馈往往是“我说话的时候它没识别到”“它生成出来的格式和我要的不一样”。这些反馈会直接回流到 description 和输出格式的定义里。

5.2 从“单点 Skill”到“多 Skill 协作”

单个 Skill 能力有限,多个 Skill 配合才能完成复杂任务。比如上面的论文调研 Skill,它要真正变成好用的工作流,可能还要搭配“PDF 下载 Skill”和“纪要整理 Skill”。Agent 先检索论文,再下载几篇关键论文的 PDF,再对 PDF 做精读并整理成纪要,最后汇总成综述。

这里容易踩的坑是 Skill 之间的接口不兼容。A Skill 输出的是 JSON,B Skill 却期待接收一份 Markdown 文件,Agent 夹在中间还需要做格式转换,凭空增加一层出错概率。我现在的做法是:Skill 之间尽量约定统一的中间格式。比如凡是输出文档摘要类的 Skill,统一输出 Markdown 文件到指定目录,路径写入一个last_output.json。后续 Skill 读取这个文件就能知道上一个 Skill 的产出在哪。这个约定在团队内形成规范后,多 Skill 协作的稳定性提升非常明显。

5.3 评估与持续迭代

很多人写完 Skill 用了两天就扔在那不管了,等再过几周发现 Agent 行为怪怪的,也不知道是不是某个 Skill 的问题。我建议建立三个简单习惯:

一是每次修改 SKILL.md 或脚本后,跑一遍 tests 目录里的回归脚本,确保最基础的功能没有挂掉。二是定期(我一般两周一次)翻看 Agent 的调用日志,统计每个 Skill 的触发成功率和输出被用户修改的比例。如果一个 Skill 生成的东西经常被用户大改,说明这个 Skill 的输出格式或内容质量有问题,该迭代了。三是关注版本变更历史。Skill 也是一个软件,不是写一次就完了。

在迭代上,我的经验是一次只改一个变量。比如这周只优化 description,下周只改输出模板,不要同时动。否则当你发现效果好与坏时,根本不知道是哪个改动起的作用。保持单一变量,才能积累出真正有效的迭代经验。

5.4 写 Skill 最需要的能力其实是“边界感”

做了这么多个 Skill,我越来越觉得,写一个“好用”的 Skill,核心竞争力不是编程能力,而是对边界的理解——知道哪些事情该交给 Agent 自由发挥,哪些事情必须用代码固定下来。如果你把所有东西都写死,Skill 会非常机械,用户稍微换个句式它就不适用了;如果你什么都不写死,Skill 又形同虚设,输出飘忽不定。

我的判断标准是:凡是输入输出格式、计算逻辑、数据来源这些“需要确定性”的部分,全部用脚本和相关资源文件固定下来;凡是流程顺序、中间判断、用户交互的节奏这些“需要灵活性”的部分,用提示词和描述去约束。代码负责确定性,提示词负责灵活性,两者各管一块,Skill 才能又稳又不呆。

我最后再分享一个小技巧:每次写完 Skill,不要急着做复杂的场景测试,先用一个最简单的任务让它跑通跑顺。成功一次之后,再逐步增加复杂度。这个小习惯帮我避开了很多“一步到位结果全崩”的局面。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询