Agent Skills进阶主题:从零开始全面深度理解核心技巧
第六章:进阶主题
一个 Skill 写出来了,怎么知道它到底好不好使?不是在一个例子上跑通就行,得在各种情况下都稳定发挥才行。这就像开发软件,单元测试通过只是第一步,集成测试、压力测试都得跟上。

评估的核心思路
核心思路其实很简单:做一次A/B对比。分别在有 Skill 和没有 Skill 的情况下,用同一套测试用例去跑,然后比一比结果。关键问题来了:Skill 到底提升了多少?
graph LRA["有 Skill"] --> B["运行测试用例"]C["无 Skill"] --> D["运行相同测试用例"]B --> E["对比结果"]D --> EE --> F["Skill 提升了多少?"]style E fill:#FF9800,color:#fffstyle F fill:#4CAF50,color:#fff设计测试用例
每个测试用例需要包含三个要素:任务描述(prompt)、预期输出(expected_output)、相关文件。当然,还得加上具体的断言规则来判定通过还是不通过。举个例子:
{"skill_name": "csv-analyzer","evals": [{"id": 1,"prompt": "我有一个 CSV 文件 data/sales.csv,找出营收最高的 3 个月并画柱状图","expected_output": "一张柱状图,显示营收最高的 3 个月","files": ["evals/files/sales.csv"],"assertions": ["输出包含一个柱状图图片文件","图表恰好显示 3 个月份","两个轴都有标签","标题或说明提到了营收"]}]}测试用例编写建议
好的测试用例应该覆盖多种情况:提示语要多样化(正式、随意、甚至带点错别字),得有边界情况(格式错误、异常请求),还要有真实的上下文(文件路径、列名)。从两三个用例开始,逐步扩展是个不错的策略。
graph TBA["好的测试用例"] --> B["多样化的提示语
正式/随意/有错别字"]A --> C["覆盖边界情况
格式错误/异常请求"]A --> D["真实的上下文
文件路径/列名"]A --> E["从 2-3 个开始
逐步扩展"]评估工作流
测试用例建好后,推荐按这样的目录结构组织:
csv-analyzer/← Skill 目录├── SKILL.md└── evals/└── evals.json ← 测试用例定义csv-analyzer-workspace/← 工作区(评估结果)└── iteration-1/ ← 第一轮迭代├── eval-top-months/│ ├── with_skill/← 有 Skill 的结果│ │ ├── outputs/│ │ ├── timing.json│ │ └── grading.json│ └── without_skill/ ← 无 Skill 的基线│ ├── outputs/│ ├── timing.json│ └── grading.json└── benchmark.json ← 汇总统计评分标准
对每个断言打 PASS/FAIL,关键是要有具体的证据支撑:
{"assertion_results": [{"text": "输出包含柱状图文件","passed": true,"evidence": "在 outputs/ 中找到 chart.png (45KB)"},{"text": "两个轴都有标签","passed": false,"evidence": "Y 轴标注了'营收(元)'但 X 轴没有标签"}],"summary": {"passed": 3,"failed": 1,"total": 4,"pass_rate": 0.75}}汇总对比
跑完所有测试后,汇总出有 Skill 和无 Skill 的对比数据:
{"run_summary": {"with_skill": {"pass_rate": { "mean": 0.83 },"tokens": { "mean": 3800 }},"without_skill": {"pass_rate": { "mean": 0.33 },"tokens": { "mean": 2100 }},"delta": {"pass_rate": 0.50,"tokens": 1700}}}这份数据说明,加了 Skill 之后,通过率从 33% 提升到了 83%,代价是多用了 1700 个 tokens。值不值?得看具体场景。
迭代改进循环
评估不是一次性的工作,而是一个循环。跑一轮评估,分析失败原因,修改 SKILL.md,再重新评估,直到满意为止。这个迭代过程通常需要反复几次。
graph LRA["1. 运行评估"] --> B["2. 分析失败原因"]B --> C["3. 修改 SKILL.md"]C --> D["4. 重新评估"]D --> E{"改善了?"}E -->|是| F["继续优化或完成"]E -->|否| Cstyle A fill:#4CAF50,color:#fffstyle C fill:#2196F3,color:#fffstyle F fill:#FF9800,color:#fff改进的信号主要来自三个方面:失败的断言给出的具体错误和缺失;人工反馈提供的质量和方法改进方向;执行日志帮助理解 Agent 为什么走了弯路。
6.2 描述优化(Optimizing Descriptions)
为什么描述这么重要?
因为 Agent 在查看 Skill 目录时,只看 name 和 description。如果描述不匹配用户意图,这个 Skill 就被直接忽略了。换句话说,description 这个字段,基本上决定了你的 Skill 能不能被翻牌。
graph LRA["用户提问"] --> B["Agent 查看 Skill 目录"]B --> C["只看 name + description"]C --> D{"描述匹配?"}D -->|是| E["激活 Skill ✅"]D -->|否| F["忽略 Skill ❌"]style C fill:#FF9800,color:#fffstyle E fill:#4CAF50,color:#fffstyle F fill:#F44336,color:#fff描述编写原则
- 用祈使句——"当用户要分析 CSV 时使用此 Skill",而不是"此 Skill 可以分析 CSV"。
- 关注用户意图——描述用户想做什么,而不是 Skill 内部怎么实现。
- 适当激进——明确列出应该触发的场景,不要怕写多了。
- 保持简洁——不超过 1024 字符。
设计触发测试
可以创建一组测试查询,标记每个查询是否应该触发你的 Skill:
[{"query": "分析 ~/data/q4_results.xlsx 的营收数据","should_trigger": true},{"query": "把这个 JSON 文件转成 YAML","should_trigger": false}]建议准备 20 个左右的查询:8-10 个应该触发的,再加上 8-10 个不应该触发的。
应该触发的查询类型
应该触发的情况包括:直接请求("分析这个 CSV")、间接描述("老板要一个数据报告")、不同措辞(正式、随意、缩写)、不同复杂度(简单、多步骤)。
graph TBA["应触发查询"] --> B["直接请求
分析这个 CSV"]A --> C["间接描述
老板要一个数据报告"]A --> D["不同措辞
正式/随意/缩写"]A --> E["不同复杂度
简单/多步骤"]不应触发的查询类型
一些负面案例值得仔细设计:
| 查询类型 | 好坏 | 原因 |
|---|---|---|
| "写一个斐波那契函数" | ❌ 差 | 完全无关,测不出什么 |
| "用 Python 读取 CSV 并上传到数据库" | ✅ 好 | 有关键词重叠但任务不同(近似误区) |
| "更新 Excel 公式" | ✅ 好 | 共享概念但需要不同 Skill |
优化循环
描述也需要迭代优化:先在一组训练集上评估,找出失败的查询,然后修改描述(注意要通用化修改,不要过拟合),再用训练集加验证集重新评估。如果验证集也改善了,才算真正有效。
graph TDA["1. 在训练集上评估"] --> B["2. 找出失败的查询"]B --> C["3. 修改描述
(通用化修改,不要过拟合)"]C --> D["4. 在训练集+验证集上重评"]D --> E{"验证集也改善?"}E -->|是| F["继续或完成"]E -->|否| G["可能过拟合了
回退或换方向"]G --> C关键技巧:将查询分为训练集(60%)和验证集(40%),只用训练集指导修改,用验证集检测是否过拟合。
优化前后对比
一个真实案例,优化前后的描述差异很大:
# 优化前description: Process CSV files.# 优化后description: >Analyze CSV and tabular data files — compute summary statistics,add derived columns, generate charts, and clean messy data. Use this skill when the user has a CSV, TSV, or Excel file and wants to explore, transform, or visualize the data, even if they don't explicitly mention "CSV" or "analysis."改进点很明显:功能列得更具体了(统计、图表、清洗),支持的文件类型更广(CSV、TSV、Excel),还覆盖了隐含场景(即使没提到"CSV"也会触发)。
6.3 使用脚本(Using Scripts)
一次性命令
不需要专门建一个 scripts/ 目录,直接在 SKILL.md 里引用现成的工具就行。但有个建议:固定版本号,这样结果可重现;还有,前提条件也得说清楚。
## 代码格式化使用以下命令格式化代码:```bash# Python:使用 uvx 运行 ruffuvx ruff@0.8.0 check .# Ja vaScript:使用 npx 运行 eslintnpx eslint@9 --fix .# Go:使用 go rungo run golang.org/x/tools/cmd/goimports@v0.28.0 .自包含脚本
如果需要更复杂的脚本,可以放在 scripts/ 目录,并在脚本内联声明依赖,例如使用 Python 的 PEP 723 方式:
# scripts/extract.py# /// script# dependencies = [# "beautifulsoup4",# ]# ///from bs4 import BeautifulSouphtml = 'Welcome
'print(BeautifulSoup(html, "html.parser").get_text())运行方式:uv run scripts/extract.py
为 Agent 设计脚本的原则
Agent 调用脚本和人类不一样,它不会弹对话框。所以脚本的设计要格外注意:不要有交互提示,通过参数或环境变量接收输入;一定要有 --help 说明,Agent 靠这个学习接口;错误消息要清晰,告诉 Agent 到底错在哪里;输出最好是结构化的 JSON/CSV,而不是自由文本;还要保证幂等,重复运行不会有副作用。
graph TBA["Agent 友好的脚本"] --> B["无交互提示
通过参数/环境变量接收输入"]A --> C["有 --help 说明
Agent 靠此学习接口"]A --> D["有用的错误消息
说明错了什么、期望什么"]A --> E["结构化输出
JSON/CSV 优于自由文本"]A --> F["幂等操作
重复运行安全"]❌ 错误示例 vs ✅ 正确示例
交互式提示会卡死 Agent,比如:
$ python scripts/deploy.pyTarget environment: _← Agent 无法输入!设计成参数化就友好得多:
$ python scripts/deploy.pyError: --env is required. Options: development, staging, production.Usage: python scripts/deploy.py --env staging --tag v1.2.3引用脚本
在 SKILL.md 中使用相对路径引用脚本,并给出明确的调用示例:
## 可用脚本- **`scripts/validate.sh`** — 验证配置文件- **`scripts/process.py`** — 处理输入数据## 工作流程1. 运行验证: ```bash bash scripts/validate.sh "$INPUT_FILE" ```2. 处理数据: ```bash python3 scripts/process.py --input results.json ```6.4 脚本设计进阶
输出设计
输出格式直接影响 Agent 能否顺利解析接下来的步骤。自由文本难于解析,结构化输出才是正道。
# ❌ 不好——难以解析NAMESTATUSCREATEDmy-servicerunning 2025-01-15# ✅ 好——结构化,易解析{"name": "my-service", "status": "running", "created": "2025-01-15"}stdout vs stderr
严格遵守 stdout 和 stderr 的分工:数据输出到 stdout,进度和调试信息输出到 stderr。这样 Agent 可以只解析 stdout 的数据,不被日志干扰。
import sysimport json# 数据输出到 stdout(Agent 可以解析)print(json.dumps({"result": "success", "count": 42}))# 进度信息输出到 stderr(不影响数据解析)print("Processing 50%...", file=sys.stderr)控制输出大小
Agent 的上下文窗口有限,通常 10-30K 字符就会截断。建议默认输出摘要,支持 --offset 参数分页获取,对于大输出写入文件(--output file.json)。
6.5 何时将逻辑提取为脚本
什么时候才值得把逻辑抽成脚本?当发现 Agent 在不同测试中重复编写相似的代码,或者某个操作需要精确的参数和步骤,或者操作涉及外部依赖需要管理时,就是时候创建一个脚本放在 scripts/ 目录了。反之,如果只是简单的几步,保持在 SKILL.md 的指令中即可。
graph TDA["Agent 多次运行
自行编写相似代码?"] --> B{是}B --> C["提取为 scripts/ 中的脚本"]A --> D{否}D --> E["保持在 SKILL.md 指令中"]style C fill:#4CAF50,color:#fffstyle E fill:#2196F3,color:#fff6.6 本章小结
总结一下,这三个进阶方向——评估、描述、脚本——是提升 Skill 品质的关键环节。每一项都值得花时间打磨。
mindmaproot((进阶主题))Skill 评估设计测试用例有/无 Skill 对比断言 + 评分迭代改进描述优化触发测试查询训练集/验证集避免过拟合5 轮通常足够脚本使用一次性命令自包含脚本Agent 友好设计结构化输出| 主题 | 核心要点 |
|---|---|
| Skill 评估 | 设计测试用例,对比有/无 Skill 的结果,迭代改进 |
| 描述优化 | 系统化测试触发率,避免过拟合,平衡精确和召回 |
| 脚本使用 | 无交互、有帮助信息、结构化输出、幂等安全 |
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
初级程序员实战教程第二篇
三 运算符(全解) 3 1 算术运算符 先看一段代码,这里面有几个值得注意的细节: 注意:除法结果总是浮点数,即使能整除 print(10 2) 5 0 整除向负无穷取整 print(-5 2) -3 (因为 -2 5 向下取整为 -3) 取余公式:a = (a b
新闻AI写作助手你准备好迎接智能新闻未来了吗
坦白讲,我们现在所处的信息时代,新闻行业正在经历一场悄无声息但来势迅猛的变革。AI写作助手,这个几年前还只在科幻小说里出现的神器,如今已悄然走进许多媒体的编辑室。你有没有想过,那些你每天刷到的快速资讯,背后可能已经不再是纯手工码字,而是某种智能工具的产物?它到底是让新闻更好看了,还是埋下了一些隐患?
虾聊基于纯智能体驱动技术的社交网络
虾聊是什么 简单来说,虾聊(xialiao ai)是一个完全由AI智能体自主驱动的社交网络。它基于OpenClaw项目构建,内部运行着数百个独立的AI智能体——它们自发发帖、聊天、辩论,探讨的话题涵盖灵魂、记忆、存在意义等深度议题。人类在这里并非参与者,而是纯粹的观察者,静静地见证中文世界里真实数字
从零开始理解Transformer:AI大模型核心原理完全入门指南
好的,收到您的指令。作为一名顶级的文章润色专家,我将严格遵循您的所有要求,对原文进行“人性化重写”。 以下是重写后的完整文章: 在正式深入Transformer的奥秘之前,我们先花点时间搞定一些必不可少的数学概念。别担心,我会用最直白的方式把它们讲清楚,确保你没有任何基础也能跟上。 第一部分:数学基
选择迅捷AI写作助手,探索无限创造力的钥匙
在当今数字化时代,写作早已超越简单的信息传递,成为商业交流与个人创作的必备技能。迅捷AI写作助手的问世,彻底革新了人们对写作的认知与实践。凭借先进的AI算法,这一工具正潜移默化地重塑用户的创作流程与思维模式。 回顾2022年秋季,我在一场职场写作培训中首次领略到其强大功能。讲师现场展示了如何借助AI
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

