Agent Skill 开发实战与工程指南

一、 认知解耦:Agent Skill 解决什么问题?

1. System Prompt、Tool 与 Skill 的职责划分

在基于大语言模型的自主智能体系统中,合理组织上下文是保障模型准确执行的基础。三者在上下文架构中各司其职、分层协作:

架构要素 核心定位与职责 生命周期与注入时机 解决的核心问题
System Prompt 全局人设、交互基准与通用安全约束 全会话常驻(每轮对话均消耗上下文) "我是谁、遵守什么全局纪律"
Tool 与外部物理环境交互的强类型接口(API/CLI) 注册 Schema,大模型按需发起参数化调用 "能力是否存在、接口如何传参"
Skill 特定业务领域的实战规程、操作顺序与排雷指南 渐进展开(命中用户任务意图后按需载入) "遇到特定专业任务该怎么做、如何防坑"

2. 长上下文中的信息利用与《Lost in the Middle》论文事实

为什么不能把所有特定任务的手册一次性全部写入 System Prompt?除了上下文膨胀带来的 Token 成本线性增加外,一个关键的学术依据是长文本输入对模型信息检索与遵循能力的负面影响。

🔬 论文核心发现(TACL 2024 实证事实)

斯坦福大学、加州大学伯克利分校与 Samaya AI 的研究团队发表于 TACL 2024 的论文 《Lost in the Middle: How Language Models Use Long Contexts》 (Liu et al., 2023)对多款大语言模型在长上下文下的表现进行了严格的实证检验:

  • 位置敏感性与性能衰退:在多文档问答实验中,模型利用输入信息的能力随位置变化显著。当目标信息位于输入上下文的开头或结尾时,模型表现最佳;当目标信息位于输入文本的中间位置时,性能出现明显衰退;
  • 具体性能降幅与低于闭卷基线:论文第 2.3 节原句指出,GPT-3.5-Turbo 的多文档问答准确率可以下降超过 20%("GPT-3.5-Turbo's multi-document QA performance can drop by more than 20%");紧接着指出,在包含 20 篇和 30 篇输入文档时,最差情况(相关文档置于中间位置)的问答成绩甚至低于模型完全不看文档时的闭卷基线 56.1%;
  • 模型与任务差异性:论文同时指出,这种衰退程度因任务和模型架构而异。例如在键值检索(Key-Value Retrieval)任务中,Claude-1.3 和 Claude-1.3 (100K) 能够在所有输入位置上取得接近或达到 100% 的准确率。

工程启示:将互不相关的各领域大篇幅规则一股脑静态塞进常驻提示词中,位于中间段落的信息存在被模型忽略的风险。将规程解耦为独立的 Skill,在触发相关任务时按需将当前规程载入上下文,有助于减少不相关文本对模型注意力的干扰。


3. 渐进展开(Progressive Disclosure)的生命周期

为了高效管理上下文,Agent Skills 规范采用了渐进展开(Progressive Disclosure) 设计,将技能的使用划分为三个层层递进的生命周期阶段:

阶段 阶段名称 智能体动作 上下文开销 核心工程机制
第 1 阶段 发现阶段(Discovery) 智能体启动或初始化时,仅加载各技能的元数据(name 与 description) 极低(约 ~100 tokens/技能) 建立全局轻量技能索引,供大模型决策是否调用
第 2 阶段 激活阶段(Activation) 用户提问或意图与技能 description 匹配时,载入 SKILL.md 正文 适中(建议控制在 5000 tokens 内) 规则进入上下文,指导智能体后续执行决策
第 3 阶段 执行下钻(Progressive Disclosure) 根据正文指引,按需执行脚本或查阅深度参考文档 按需消耗(仅读取特定文件或脚本执行回执) 按需调用 scripts/ 工具、查阅 references/、使用 assets/

📌 工程事实说明 :在目前主流的智能体实现中,Skill 一旦在某轮对话中被载入上下文,其正文就会作为历史消息的一部分保留在当次会话中,直到会话重置或触发上下文滑动窗口截断,并不会在执行完单步操作后自动被系统卸载。


二、 Agent Skills 规范核心要求(agentskills.io 查证)

在开发技能时,必须准确区分规范的强制要求(Requirements) 与官方指南推荐的最佳实践(Best Practices) 。

1. 规范必填字段与可选字段(Frontmatter Schema)

查阅 Agent Skills 规范原文,每个技能的主入口文件为根目录下的 SKILL.md。该文件必须以 --- 开头和闭合的 YAML 前置元数据块(Frontmatter)起始。

规范将元数据字段明确划分为必填项 与可选项:

① 必填字段(Required fields)

字段名称 数据类型 长度限制 格式与规范约束 核心工程说明
name String 1 ~ 64 字符 必须且只能包含小写字母、数字和连字符 - • 严禁包含下划线 _ • 不能以 - 开头或结尾 • 不能包含连续双连字符 -- 必须与所在技能目录名完全一致 (例如目录为 pdf-processing,则 name 必须严格为 pdf-processing)
description String 1 ~ 1024 字符 必须是非空字符串,明确说明该技能做什么 以及在什么情境下使用 大模型评估是否激活技能的核心依据,严禁超过 1024 字符
命名合法性校验速查表
命名写法 规范校验 规则解析
pdf-processing 合法 仅含小写字母与连字符 -
data-analysis-v2 合法 包含小写字母、数字与连字符 -
pdf_processing 非法 包含下划线 _(规范禁止包含下划线)
-pdf-tools 非法 不能以连字符 - 开头
pdf-tools- 非法 不能以连字符 - 结尾
pdf--tools 非法 不能出现连续的双连字符 --
PDF-Tools 非法 包含大写字母(规范仅允许小写)

② 可选字段(Optional fields)

字段名称 数据类型 长度/结构限制 规范建议与用途
license String 自由字符串 开源协议或商业授权说明(如 Apache-2.0、MIT 或专属许可证声明)。
compatibility String 1 ~ 500 字符 运行环境与兼容性要求(如指定 Python 版本、系统依赖工具等)。
metadata Map 键值对映射 用户自定义的任意元数据(如记录版本号 version、作者、团队归属等)。
allowed-tools List 字符串列表 该技能限制或允许调用的工具列表,便于智能体做权限控制。

③ Frontmatter 具体写法示例

在实际编写时,开发者可以根据场景需求选择极简写法或完整扩展写法:

示例一:极简合规写法(仅声明两个必填字段)

css 复制代码
---name: pdf-processingdescription: 从 PDF 文档中提取文本与表格、填写表单并合并多个 PDF 文件。当需要处理 PDF 文档,或用户提到 PDF、表单填写及文档提取时使用。---

示例二:完整配置写法(结合可选字段声明环境依赖与元数据)

yaml 复制代码
---name: pdf-processingdescription: 从 PDF 文档中提取文本与表格、填写表单并合并多个 PDF 文件。当需要处理 PDF 文档,或用户提到 PDF、表单填写及文档提取时使用。license: Apache-2.0compatibility: 需要 Python 3.10 及以上环境,并已安装 pdftk 工具metadata:  version: "1.2.0"  team: 文档平台研发组allowed-tools:  - bash  - file_reader---

2. 目录结构与文件组织规范(Directory Structure & File Layout)

本节介绍一个合规的 Skill 技能包在文件系统中的物理目录结构与组织规范 。在 Agent Skills 规范 中,"一个 Skill"的物理载体被明确定义为:一个包含 SKILL.md 文件的独立文件夹。

为了配合大模型在交互过程中的"渐进展开(Progressive Disclosure)",规范确立了"极简核心 + 按需扩展"的文件组织布局:

bash 复制代码
pdf-processing/               # 技能根目录(目录名必须与 Frontmatter 中的 name 字段严格一致)├── SKILL.md                  # 核心入口文件(规范唯一强制要求存在的文件)├── scripts/                  # 可选子目录:存放供智能体按需执行的确定性脚本(Python/Bash 等)├── references/               # 可选子目录:存放供智能体按需查阅的深层参考文档(API 表、错误码等)└── assets/                   # 可选子目录:存放供智能体取用的静态模版与资源(模板、样例数据等)

① 核心入口与三大标准可选目录分工

规范正式定义了 1 个必需文件与 3 个约定可选子目录,它们各自承担明确的工程职责:

目录/文件 规范属性 主要职责与存放内容 大模型使用方式
SKILL.md 唯一强制必需 包含 YAML Frontmatter 元数据及核心任务指导正文。是智能体加载技能后的主要上下文。 命中触发后,正文整体被载入上下文,指导智能体后续决策。
scripts/ 可选推荐目录 存放处理逻辑复杂、大模型手写容易出错的确定性代码(如 Python 工具、LibreOffice 重算脚本、脚手架)。 在正文指令指引下,由智能体在终端按需调用执行,只看执行回执。
references/ 可选推荐目录 存放非核心主干的长篇材料(如详细错误排查手册、字段映射字典、特定 API 错误码清单)。 智能体在处理边缘场景或遇到特定异常时,按需读取特定文件。
assets/ 可选推荐目录 存放静态资产(如 Jupyter Notebook 骨架模版、标准汇报模板、测试用样例文件)。 由脚本载入或由智能体在生成输出时作为原始底稿复制引用。

② 规范赋予开发者的三大自由度

很多初学者容易将 Skill 开发教条化,误以为必须像企业级框架那样创建大量特定目录和文件。官方规范特别强调了以下灵活性:

  1. 目录创建自由(按需设立) :

    • 规范唯一强制要求存在的文件只有 SKILL.md。
    • scripts/、references/、assets/ 均为官方推荐的可选目录。如果业务场景只需一段规程说明,一个 SKILL.md 即可完整交付,坚决不需要为了凑规范而创建任何空文件夹。
  2. 文件命名完全自由(无预设模板) :

    • 规范没有 硬性规定子目录内必须叫什么名字(例如从未要求必须包含所谓的 patterns.md、pitfalls.md 或 validator.py)。
    • 文件命名、文件数量以及拆分粒度,完全由开发者根据业务复杂度自主决定。
  3. 正文段落结构完全自由(重在效用) :

    • 规范明确声明,SKILL.md 中 Frontmatter 下方的 Markdown 正文没有任何固定的章节格式限制。
    • 无论是采用决策表格、编号流水线还是要点清单,只要"对智能体准确完成当前任务最有帮助",就是合格的编写方式。

3. 篇幅建议:500 行以内且 5000 Token 以内法则

💡 篇幅控制与细节下沉建议:

在编写正文长度时,业内公认的工程实践原则是:

  • 500 行以内且 5000 Token 以内 :官方建议将 SKILL.md 正文篇幅控制在 500 行以内,并且在 5000 Token 以内(两项条件均建议满足)。
  • 长篇细节下沉 :如果技能涉及非常庞杂的 API 错误码清单、冗长的格式规范,建议将详细参考放到 references/ 目录下的单独文件中,并在主干指令中指出具体的查阅时机(例如:"接口返回的不是 200,就读 references/api-errors.md")。

三、 意图触发设计:优化 Description 的真实方法

1. 智能体如何决定触发技能?

在主流兼容实现(如 VS Code Copilot、Claude Code 等)中,智能体客户端扫描默认技能目录,提取每个技能的 name 和 description 作为系统上下文注入大模型。

在处理用户提问时,由大模型自身在会话推理中决定是否要调用该 Skill 工具将其正文载入,而非依赖固定的外部向量数据库余弦相似度检索。

因此,description 的文字表述是大模型判断是否激活技能的核心依据。


2. 编写 Description 的核心原则与工程范式

在大模型自主决策的调度体系下,description 的本质是写给大模型的"触发指令" 。根据官方 优化 description 指南,撰写高命中率、低误判率的 description 应当遵循四大核心原则:

① 四大核心编写原则与正反示例

原则 1:坚持使用祈使句(Imperative Mood),直接下达行动指令

💡 核心机理 :大模型在推理过程中正在权衡"是否要加载技能",因此描述应当直接告诉它在什么条件下采取行动("在......时使用"),而不是客观陈述("该技能具有......功能")。

对比维度 示范语句 大模型认知与执行后果
❌ 反例示范(陈述句) 这是一个功能强大的 PDF 处理工具,能够支持多种复杂文档的表单填写、文本提取与合并。 模型只获取了工具的功能特性说明,无法明确在当前用户语境下是否应当由自己主动调用。
✅ 正例示范(祈使句) 从 PDF 文档中提取文本与表格、填写表单并合并文件。当需要处理 PDF 文件,或用户要求提取 PDF 内容时使用。 直接向模型下达明确的触发时机与动作指令,消除调用犹豫。

原则 2:对准用户业务意图,剔除内部实现细节

💡 核心机理 :大模型是拿用户的自然语言提问来匹配 description 的。用户通常会说"帮我把这份财务报表核对一下"或"导出一份利润分析",绝不会说"请使用 openpyxl 遍历 row 节点"。描述应当聚焦于"用户想达成什么结果",严禁堆砌底层依赖库。

对比维度 示范语句 大模型认知与执行后果
❌ 反例示范(技术细节) 基于 openpyxl 库封装,使用 load_workbook 加载工作簿 XML 结构并执行公式重算。 当用户提问"帮我核对上个月表格数据"时,大模型无法完成从业务目标到底层库的技术映射,导致漏触发。
✅ 正例示范(业务意图) 分析、编辑与验证电子表格。适用于核对两张报表的数值差异、计算汇总公式或批量更新表格列。 精准击中用户的真实业务任务目标,与自然语言意图无缝对齐。

原则 3:适度前置主动覆盖隐式意图(Cover Implicit Triggers)

💡 核心机理:在真实人机对话中,用户往往不会字正腔圆地输入显式关键词(如"请启动 Excel 分析技能"),而是随手提供一个文件路径或口语化描述。高质量的 description 会主动覆盖这些隐式提问方式。

对比维度 示范语句 大模型认知与执行后果
❌ 反例示范(机械匹配) 当用户明确输入"分析 CSV 数据"时使用本技能。 依赖生硬的显式字面匹配。当用户提问"看看 ~/data/order_2024.csv 里面有什么异常"时,技能直接漏判。
✅ 正例示范(覆盖隐式) 分析与处理结构化表格数据。用户即使只是随口发来一个表格文件路径,或者没有直接说出"表格分析"字样,只要意图是处理该数据,也应主动触发。 具备优秀的口语化容错与语义泛化能力,能够稳稳捕捉隐式触发信号。

原则 4:划清适用边界与反向排除(Negative Triggers)

💡 核心机理 :大模型具有语义泛化能力,如果描述只写"能做什么",极易在相近领域产生"抢跑误触发"(例如用户想写 Python 爬虫,表格技能却误以为是数据处理而强行接管)。最有效的防误触手段是在结尾直接写明"不做什么" 。

对比维度 示范语句 大模型认知与执行后果
❌ 反例示范(边界模糊) 处理各类表格与数据文件。 范围宽泛无边界。当用户要求"写个 Python 脚本把 CSV 导入 PostgreSQL 数据库"时,技能因捕捉到"表格/数据"而误触发强行接管。
✅ 正例示范(显式排除) 当电子表格是任务的核心输入或最终产出时使用。如果任务目标是开发独立的后端 Python 脚本、构建数据库 ETL 流水线或编写 SQL 查询,即使涉及表格数据,也严禁触发。 精准设立负向"防火墙",划清职责红线,杜绝在普通编码任务中越权误触发。

② 编写结构公式:高命中率的"三段式"工程范式

综合工业界落地与官方最佳实践,一条结构完整、辨识度极高的 description 通常由三个逻辑段构成:

📐 Description 三段式结构公式:

Description = 【核心能力:能做什么】 + 【正向触发:何时必须用 / 覆盖隐式意图】 + 【反向排除:何时坚决不用】

组成部分 核心功能 典型句式示范
第一段:能力定义 阐明处理的核心业务对象与交付产出 从 PDF 文档中提取文本与表格、填写表单并合并多个 PDF 文件。
第二段:正向触发 明确适用情境、口语化表达与隐式意图兜底 当需要处理 PDF 文档,或用户提到 PDF、表单填写及文档提取时使用。即使未直接输入指令,只要意图是处理 PDF 亦应触发。
第三段:反向排除 明确排除易混淆的相近场景,防止越权争抢 如果用户目标是编写通用 Python 脚本或操作数据库,即使涉及文件解析,也不要触发。

③ 典型写法对比:Bad Case vs Good Case

维度 ❌ 不合格写法(Bad Case) ✅ 工业级优秀写法(Good Case) 核心差异解析
句式与视角 本项目基于 pypdf 库封装,能解析 PDF 的二进制流并提取表格。 从 PDF 文档中提取文本与表格、填写表单并合并多个 PDF 文件。当需要处理 PDF 文档,或用户提到 PDF、表单填写及文档提取时使用。 前者是对内部实现的技术说明,智能体无法有效关联用户意图;后者是指向智能体的祈使指令,直击任务目标。
触发边界 处理各类电子表格数据。 当电子表格文件是主要输入或输出时使用。适用于打开、读取、编辑或计算表格数据。用户即使只是提到文件名,只要希望处理表格也应触发。如果主要交付物是数据库流水线或后端脚本,不要触发。 前者边界极度宽泛,极易在普通的日常问答中误触发;后者明确了文件形式、覆盖了隐式提问,并设置了反向排除。

3. 实战校验与调优:如何科学验证 Description 效果?

写完 description 之后,很多开发者最容易犯的错误是:随手在对话框里敲了一两句测试问句,看到技能触发了,就以为大功告成。

真实场景往往残酷得多------换个同事提问,或者换一种口语化的说法,大模型可能就完全不触发了;或者反过来,用户明明只是想写一段普通的 Python 脚本,技能却不管三七二十一跳出来抢跑。

编写高命中率的 description,必须告别"凭感觉碰运气",建立清晰的自测与调优心智。


① 建立"红白名单"自测清单:别靠单句话测效果

检验一个技能是否灵敏且克制,最接地气的方法是准备两张测试问句清单(建议各准备 8 ~ 10 条真实提问):

测试清单 角色定位 问句特征与典型例子 预期表现 核心检验目的
正向清单(白名单) 必须触发 用户的真实口语、简写、随手丢一个文件路径。 例: "看看 data/order.csv 里有没有异常数值" 稳定唤醒 检验对真实口语提问的容错度与唤醒率
反向清单(红名单) 坚决不触发 业务领域相近、包含相似字眼但目标截然不同的任务。 例: "写个 Python 脚本把 CSV 导进 PostgreSQL" 坚决不触发 检验技能的边界防御力,防止越权抢跑

② 为什么看"多数表现"而非"单次结果"?(理解大模型的概率特性)

初学者调优时常感到困惑:"为什么同一句提问,刚才触发了,现在再问一次又不触发了?"

大模型在生成决策时具有自然的概率波动,单次测试存在偶然性。因此科学的自测方法是:

  • 多次抽检:针对同一条测试问句,重复测试几次(如 3 次);

  • 看多数胜出(即触发率大于 50%) :

    • 对于正向问句:3 次测试中有 2 次及以上能够唤醒(触发率大于 50%),就说明该意图已经能被大模型稳定捕捉,判定为合格;
    • 对于反向问句:3 次测试中绝大多数情况下都不被唤醒(误触发率小于 50%),判定为合格。
  • 认知准则 :不要苛求某条生僻句型达到绝对的 100% 机械死锁。大模型匹配的是语义意图,只要在多数概率下决策正确,就说明整体泛化能力健康。


③ 调优最大的误区:切忌"死记硬背硬塞词"(避免过拟合)

在测试过程中,如果发现某条正向问句(例如 "把这两份报表拉通对一下" )未能唤醒技能,开发者最容易犯的典型错误是:

❌ 错误做法(头痛医头、死记硬背) :

发现模型不触发,直接把测试句里的特定字眼"拉通对一下"生硬地抄进 description 里。

后果 :这种做法本质上是让模型"死记硬背"。下次另一个用户说"把这两份报表串一下核对下",模型依然会漏判;而且还会把 description 越改越长、越改越臃肿。

✅ 正确做法(向上抽象业务本质) :

思考这句口语背后的真实业务意图到底是什么 ?

"拉通对一下"的本质是"对比两张表格的数值差异"。我们应该站在更高的抽象层面去润色描述,例如补充:"适用于比对两份表格的数据差异、核对汇总项"。

用更高维度的业务概念去覆盖更广泛的同义口语表达,而不是死记具体的字面字眼。


④ 划分"练习题"与"模拟考":用隔离集检验泛化

为了防止自己在修改 description 时陷入"只记住了眼前测试题"的陷阱,建议将测试问句做简单的分组隔离:

  • 自测调试集(约 60%) :平时改描述时参考这批句子,用来寻找语义漏洞并提升抽象概括能力;
  • 盲测验证集(约 40%) :独立封存,在改写 description 的过程中坚决不看这批句子。改完之后,用这批从未参与调试的全新问句做一次"模拟考"。

如果从未见过的盲测问句也能达到理想的通过率,就充分证明你的 description 已经真正做到了意图精准、边界清晰、泛化稳健,可以放心交付部署!


四、 正文编写:指令松紧度该如何把控?(Calibrate Specificity)

1. 指令颗粒度的黄金法则:脆弱时写死,灵活时讲清原因

在编写 SKILL.md 正文时,很多开发者面临两难困境:到底该写得多具体?是像保姆一样下达死命令,还是给大模型留出自由发挥的空间?

写得过死,大模型遇到细微变动的场景就频繁报错罢工;写得太松,大模型又容易信马由缰、漏洞百出。

把握指令颗粒度,核心取决于当前任务本身的 "脆弱性(Fragility)" :

策略 A:高危脆弱操作 ------ 必须"写死步骤",严禁大模型擅自发挥

当操作极易出错、顺序颠倒会导致严重后果、或者必须与外部环境产生绝对一致的结果时(如数据库迁移、依赖安装、核心代码编译):

  • 编写原则:明确给出确定的命令,直接下达禁令,不给模型多余猜测或自由改动的空间。

📌 实战范式:数据库迁移规程

严格按以下命令顺序执行,严禁自行修改参数或更换执行顺序:

css 复制代码
python scripts/migrate.py --verify --backup

策略 B:开放灵活任务 ------ 应当"讲透原因与检查项",赋予模型自由度

当任务本身具有多种合理做法、允许灵活处理时(如代码审查、排版优化、接口设计):

  • 编写原则 :此时下达僵硬死命令,往往会抹杀模型的逻辑推理与上下文适应能力。向模型说明"为什么这么做"并给出检查清单,远比下达死命令更有效。

📌 实战范式:代码评审规程

进行代码评审时,重点核对以下安全与稳定性目标,并解释发现的问题:

  1. SQL 注入风险:检查所有数据库查询,确保必须使用参数化查询;
  2. 接口鉴权完整性:核对每个对外端点均有前置认证检查;
  3. 并发竞态条件:审视并发数据写入路径,避免无锁竞争;
  4. 敏感信息泄露:确认返回给客户端的错误信息未泄露堆栈或内部配置细节。

2. 路由前置:用"结构化速查表"替代大段碎碎念

大模型在阅读 Skill 正文的第一屏时,最容易被大段分散的条件判断绕晕(比如:"如果你要做 A,记得去用工具 1;如果你要做 B,可以考虑工具 2,不过做 C 的时候千万别用......")。

工业级优秀案例的做法是:在开篇第一屏,直接用一张高浓度的速查路由表,把任务场景与推荐工具一次性映射清楚。

以处理电子表格(xlsx)的生产技能为例,其正文开篇第一屏直接提供了如下决策速查表:

任务场景与目标 推荐处理方式与工具 核心决策点与边界限制
带公式或格式创建/编辑表格 使用 openpyxl 库 必须严格遵守文末提到的缓存与公式保存限制
纯数据批量导入或导出 使用 pandas(read_excel / to_excel) 吞吐效率高,但会丢弃格式与单元格公式
快速轻量预览表格内容 终端命令行执行 markitdown file.xlsx 速度极快;但输出不含单元格精确坐标,不可据此规划单元格编辑
同时读取公式字符串与计算值 使用两次 load_workbook(分次载入) 第一次读取公式本身,第二次提取计算缓存值

💡 认知收益 :

结构化速查表的价值在于信息密度极高、路由关系一目了然。大模型在第一遍扫描时就能迅速建立"任务目标 ➔ 底层工具"的清晰认知,从根源上杜绝了后续调用工具时反复摇摆或用错库。


3. 补其所缺,删其已知:剔除通用常识科普

许多初学者容易把 SKILL.md 写成"技术名词百科全书",花费大量篇幅向模型解释什么是 PDF 格式、HTTP 协议的基本原理、或者 Python 的循环语法。

大模型的大脑里已经预训练了海量的计算机通用知识,它缺的从来不是通用常识,而是你这个业务专属的特殊规程!

内容分类 是否应写入 SKILL.md 为什么?(大模型认知机理) 典型内容示例
✅ 必须写:领域特有规程 是 大模型未接触过你内部的私有代码和环境陷阱,不写必然瞎猜。 项目特有代码约定、非显式环境限制、专属工具调用参数、业务数据校验标准
❌ 严禁写:通用基础常识 否 白白浪费上下文窗口,稀释模型对核心规程的注意力。 什么是 HTTP 状态码、什么是 JSON 格式、什么是 Python 基础语法、什么是 SQL 基础语法

一条简单的判别准则:如果这段内容是一个普通初级程序员在公开文档里随便一搜就能看到的通用常识,直接删掉;如果这是你的团队在踩坑无数次后才总结出来的"内部经验与避坑指南",务必保留并清晰加粗说明。


五、 领域暗坑防御:为什么 Skill 必须用"正反代码块"驯服大模型?

1. 认知拉齐:智能体干活靠写代码,教大模型靠"正反示范"

很多读者读到这里会产生一个巨大的疑问:

"我们不是在学怎么写 Agent Skill(提示词文档)吗?为什么教程里突然开始贴 Python 代码和 SQL 语句了?这是在教我学编程吗?"

答案是:完全不是! 要理解为什么 Skill 必须包含代码,首先必须看清智能体(Agent)在后台到底是怎么替你干活的:

css 复制代码
graph TD    UserPrompt["1. 用户下达自然语言指令<br>(例:帮我把报表里的税率调整为 6%,重新保存)"] --> LLMReadSkill["2. 智能体激活并阅读 SKILL.md 指南"]    LLMReadSkill --> LLMWriteCode["3. 大模型在后台现场编写一段 Python 脚本或 SQL 查询"]    LLMWriteCode --> EnvExec["4. 智能体调用终端/环境,真实执行这段生成的代码"]    EnvExec --> FinalResult["5. 文件被修改或查询完成,交付结果给用户"]

看懂这个工作流后,核心逻辑就豁然开朗了:

  1. 大模型干活靠现场写代码 :大模型没有手指,不能打开 Excel 点击鼠标,也不能手动去翻数据库。它完成任务的手段,就是在后台现场生成一段 Python 脚本或 SQL 查询,并调用终端去运行它;
  2. 大模型看代码比看大段自然语言听话得多 :如果你在 SKILL.md 里只写人类自然语言("请注意不要把表格原有的公式破坏了哦"),大模型在生成代码时往往"左耳进右耳出",依然凭概率生成出带有隐蔽致命 Bug 的代码;
  3. 最硬核的约束手段就是"正反代码示范" :在 SKILL.md 针对高危暗坑,直接贴出 ❌ 错误示范 与 ✅ 正确示范 代码块(Few-Shot Code) 。大模型在现场写代码时,就会像抄作业一样,严格规避 ❌ 写法,直接套用 ✅ 范式!

以下两个工业级实战案例,完整还原了"大模型本能写出灾难代码 ➔ Skill 用正反代码块立规矩"的真实过程:


2. 案例实战 A:Excel 动态公式破坏陷阱(openpyxl 的读写分离规程)

① 真实业务场景

用户对智能体说:"帮我把这份财务报表 financial_report.xlsx 里的税率调成 6%,然后保存文件。 "

智能体接单后,在后台准备生成一段 Python 脚本使用 openpyxl 库来修改该文件。

② 如果你的 SKILL.md 没写避坑示范,大模型会写出什么?

大模型会凭预训练直觉,在后台写出并执行下面这段毁灭性代码:

shell 复制代码
# ❌ 大模型凭本能生成的翻车代码:以为读完修改再 save 就万事大吉wb = openpyxl.load_workbook("financial_report.xlsx", data_only=True)# ... 进行业务单元格修改 ...wb.save("financial_report.xlsx")  # 💥 灾难发生!

⚠️ 翻车机理与致命灾难 :

openpyxl 中使用 data_only=True 载入工作簿时,只读取了上次计算缓存的字面值,工作簿内存中原有的全部函数公式(如 SUM、VLOOKUP、财务计算模型)已被彻底丢弃 !

此时大模型一旦调用 wb.save(),原表格中所有动态公式被永久覆盖替换为静态纯文本,整份财务模型瞬间报废!

③ 优秀的 SKILL.md 是如何用代码立规矩的?

在成熟的表格处理技能(如 Anthropic 开源的 xlsx 技能)中,作者不会只泛泛地说"小心公式",而是直接把以下正反代码规程贴在 SKILL.md 的正文开头:

sql 复制代码
# 规程:使用 openpyxl 时严禁在 data_only=True 模式下直接 save,必须读写分离:# 场景 1:如果仅需提取静态计算数值(只读查阅),必须显式声明只读模式以杜绝误保存:wb_readonly = openpyxl.load_workbook("financial_report.xlsx", data_only=True, read_only=True)# 场景 2:如果需要修改数据并保存,必须使用默认公式模式(保留原表公式):wb_formula = openpyxl.load_workbook("financial_report.xlsx", data_only=False)# 写入新数据后安全保存,公式不会被冲掉wb_formula.save("financial_report.xlsx")

大模型看到这两段代码模板后,在后台生成 Python 脚本时就会自觉采用"读写分离"范式,从而彻底杜绝毁坏用户原表公式的事故。


3. 案例实战 B:SQL 对账数据静默漏判陷阱(三值逻辑防漏模板)

① 真实业务场景

用户对智能体说:"对比订单表 a 和支付表 b,找出所有状态不一致的异常记录。 "

智能体接单后,在后台准备生成一条 SQL 语句发送给数据库执行。

② 如果你的 SKILL.md 没写防漏模板,大模型会写出什么?

大模型随手就会写出一条看似天经地义的 SQL:

css 复制代码
-- ❌ 大模型随手写出的漏判 SQLSELECT a.order_id, a.status, b.status FROM orders a JOIN payments b ON a.order_id = b.order_idWHERE a.status <> b.status;  -- 💥 致命隐患:单边缺失行被静默丢弃!

⚠️ 翻车机理与业务事故 :

真实对账场景中,最严重的异常往往是"单边状态缺失"(即 b.status 为 NULL)。

根据 ANSI SQL 标准的三值逻辑(Three-Valued Logic),任何值与 NULL 进行常规比较(<>、=),其求值结果均为 UNKNOWN,而 WHERE 子句只保留求值为 TRUE 的行,UNKNOWN 的行会被静默过滤掉!

结果:最需要被揪出来的单边缺失异常记录,一条都没被查出来,造成严重业务漏判!

③ 优秀的 SKILL.md 是如何给大模型"套模版"的?

在数据对账与分析类技能的 SKILL.md(或其配套 references/sql-edge-cases.md)中,开发者会直接给出无死角的标准防漏 SQL 模板:

比对方式 语法范式(写进 SKILL.md 供模型参考) 遇到 NULL 时的求值后果 真实业务影响
❌ 直接不等号比较 WHERE a.status <> b.status 若某表单边记录缺失(b.status 为 NULL),结果为 UNKNOWN 严重对账漏判!单边缺失行被 WHERE 条件静默丢弃
✅ 现代标准安全谓词 WHERE a.status IS DISTINCT FROM b.status 将 NULL 视为已知值比对:双方皆为 NULL 为 FALSE,一有一无为 TRUE 现代 SQL 首选(PostgreSQL 等支持)
✅ 全数据库通用展开式 如下方展开式代码块所示 在 WHERE 过滤机制下,与 IS DISTINCT FROM 达到 100% 一致的行筛选效果 全数据库通用(MySQL / Oracle 等不支持该语法时的标准范式)

并在手册中明确给大模型备好通用展开式模板:

vbscript 复制代码
-- ✅ 写在 SKILL.md 中让大模型直接套用的防漏范式:WHERE (a.status <> b.status)   OR (a.status IS NULL AND b.status IS NOT NULL)   OR (a.status IS NOT NULL AND b.status IS NULL)

有了这个模版,大模型在生成对账 SQL 时就不会再随手写 <>,而是直接复制该模式,保障对账逻辑 100% 严密。


💡 核心总结 :

在 SKILL.md 里贴代码,不是在给人类读者上编程课,而是在为大模型现场编写代码提供'标准安全母模' 。

文字越长,模型越容易走样;正反代码越精准,模型执行越稳健!


六、 软硬协同:为什么成熟的 Skill 必须搭配确定性脚本(Scripts)?

1. 协同机理:大模型"肉身手扛" vs 确定性脚本"底层兜底"

很多开发者在编写 Skill 时容易走向极端:试图把所有业务逻辑都塞进提示词,指望大模型"肉身手搓"搞定一切。

然而,大语言模型的概率生成机理决定了它存在两个物理层面的软肋:

  1. 复杂结构拼装的脆断性 :对于由层层嵌套括号与特殊转义组成的物理文件(如 Jupyter Notebook 的 .ipynb 底层 JSON),大模型在直接手写拼装时,极易因几十个单元格中漏掉一个逗号或花括号,导致整份文件彻底损坏打不开;
  2. 缺乏运行时反馈的"盲目自信" :大模型写完一段 Python 计算逻辑或 Excel 复杂公式后,它无法在脑内真实执行它,根本"看不见"公式是否引用错误(如出现 #NAME?、#REF!)。它会盲目自信地宣布"已为您修改完毕",将隐蔽 Bug 原样交付给用户。

这就是为什么标准规范在 Skill 结构中专门设立了 scripts/ 目录:

大模型擅长充当"决策大脑(Brain)",负责意图理解、逻辑规划与参数决策;确定性脚本则充当"工兵骨骼(Muscle)",负责模板脚手架生成与真实运行时的环境校验。

二者软硬协同,在实战中沉淀出了两种最经典的标准协作模式:


2. 模式一:脚手架生成(以 jupyter-notebook 为例)

当目标输出文件的物理底层结构过于脆弱复杂时,最稳健的做法是:在 scripts/ 中提供一个初始化脚手架脚本,大模型只需调用一行命令。

在成熟的 Jupyter Notebook 技能实践中,为了彻底避免大模型手写几百行脆弱的 Notebook JSON 结构,提供了配套脚手架脚本:

  • 目录结构与工具准备 :

    技能在 scripts/ 目录下放置 new_notebook.py,并在 assets/ 目录下准备好经过测试的标准模板(如 assets/experiment-template.ipynb)。

  • 智能体的标准调用指令 :

    模型在需要新建 Notebook 时,不需要自己直接拼装 JSON,只需在终端执行一行命令(引自其实战手册):

    bash 复制代码
    uv run --python 3.12 python "$JUPYTER_NOTEBOOK_CLI" \  --kind experiment \  --title "Compare prompt variants" \  --out output/jupyter-notebook/compare-prompt-variants.ipynb
  • 核心工程收益 :

    脚本以毫秒级的确定性完成模板读取、元数据注入、标题单元格填充,并稳妥写出 100% 格式合规的文件。大模型随后只需要通过专门的小工具去追加代码单元格(Cell),从根源上消除了大模型手搓复杂 JSON 时的语法崩溃风险。


3. 模式二:闭环重算与自我修复(以 xlsx 公式校验为例)

当大模型编写的代码或公式在保存后无法自证正确性时,成熟的做法是:提供一个能执行真实运行计算并输出结构化 JSON 回执的脚本,驱动大模型自我纠错。

在处理电子表格的知名实践 xlsx 技能中,模型通过 openpyxl 写入复杂函数公式后,模型自己并不知道公式语法是否正确、参数是否引用错误。为此,技能在 scripts/ 中配套了 recalc.py 验证脚本:

① 真实无头环境重算机制

  • 执行命令:

    bash 复制代码
    python scripts/recalc.py output.xlsx [timeout_seconds]   # 默认超时 30 秒
  • 工作机制 :

    脚本在后台无头静默启动真实的办公套件引擎(如 LibreOffice Headless),触发全局公式重新计算,并将计算后的新工作簿原地写回文件。

② 机器可读的结构化 JSON 回执

脚本执行完毕后,不是在终端打印让人类阅读的大段日志,而是输出标准的结构化 JSON 回执:

json 复制代码
{  "status": "errors_found",  "total_errors": 2,  "error_summary": {    "#NAME?": {      "count": 1,      "locations": [        "Sheet1!B12"      ]    },    "#REF!": {      "count": 1,      "locations": [        "Sheet1!D5"      ]    }  },  "total_formulas": 14}

③ 规程细节:破除对"进程退出码"的迷信

这里包含一个极为关键的工程实践细节:

  • 当脚本正常重算完成、即使检测到表格内存在公式错误(errors_found)时,脚本本身的进程退出码(Exit Code)仍然是 0;
  • 只有在真正发生系统级崩溃时(如文件损坏、磁盘不可写、进程超时等),脚本才会返回非 0 退出码;
  • 因此,Skill 必须白纸黑字指导大模型: "严禁把进程正常退出(Exit code 0)误当成表格没有错误!必须显式解析 JSON 中的 total_errors 字段。若 total_errors > 0,必须根据 error_summary 中指明的错误类型与单元格坐标(如 Sheet1!B12 的 #NAME?),立即发起精准的自我修复重写!"

这就是为什么顶级 Skill 往往具备极高鲁棒性的秘密------它不仅指挥大模型做,还给大模型配了"标尺(脚手架)"和"质检员(校验脚本)"。


七、 交付验收与 Checklist 机制:治愈大模型的"交差幻觉"

1. 认知拉齐:为什么大模型特别需要"交付自检清单"?

与人类工程师相比,大语言模型在软件工程与复杂任务执行中,存在一个顽固的人性化弱点------ "半成品交付"与"伪完成幻觉" :

  • 只写不跑,盲目交差:大模型生成完代码,根本没有执行过一次,就自信宣告"任务已圆满完成";
  • 隐式状态依赖 :修改了某个单元格或中间变量,依赖此前运行遗留在内存里的临时数据,用户一重启环境就抛出 NameError;
  • 甩锅与伪造成功:中间某些数据缺失或 API 执行异常,大模型为了"让交付看起来很完美",擅自编造假数据或忽略报错,伪造全部通过的假象;
  • 遗留半拉子 TODO :在代码核心位置留下 # TODO: implement this logic later,却在最终答复中假装功能已全部就绪。

单纯靠提示词喊口号("请仔细检查")根本无法根治这个毛病 。

成熟的工业级方案是:在 Skill 中显式建立"验收退出标准(Definition of Done)",并在 references/ 目录中挂载机器质检 Checklist,强令大模型在交付前的最后一步必须"对照清单逐项画钩"!


2. 标杆拆解:智能体交付前的 7 条硬核质检军规

在业界知名的复杂环境操作技能(如针对 Jupyter Notebook 的成熟实践)中,其 references/quality-checklist.md 沉淀了以下 7 条极简、却刀刀见血的交付前质检军规。每一条都在精准克制大模型的某种交付恶习:

质检军规(写进 quality-checklist.md 供模型参考) 它在防范大模型的什么恶习?(机理深度剖析) 违反后的典型翻车事故
1. 从头到尾至少完整运行一次 (Run from top to bottom) 防范大模型只局部运行单个修改点,未能发现全流程上下文冲突或运行环境缺包。 用户拿到 Notebook 或脚本,第一次运行就中途报错崩溃中断。
2. 确保前置步骤显式设置全部所需状态 (Avoid implicit state) 防范大模型依赖交互历史中内存里残留的"隐式变量",导致脚本不可复现。 所谓"在我这能跑",别人重启内核(Restart Kernel)后变量直接丢失。
3. 保持输出整洁,杜绝海量无意义刷屏 (Suppress verbose output) 防范大模型为了"证明自己在干活",打印几万行循环日志或原始 Dump,打爆用户终端或上下文。 几千行滚动日志把关键结果淹没,不仅极度难看,还导致下游解析崩溃。
4. 优先输出小型数据表与关键指标 (Prefer small tables & metrics) 防范大模型直接倾倒巨型 JSON 或嵌套字典,给用户造成认知负担。 交付界面被巨型复杂结构占满,用户根本看不清核心分析结论。
5. 叙述利于快速浏览,多用短列表与标题 (Make narrative easy to skim) 防范大模型生成大段大段密不透风的"学术论文式"段落。 人类一眼扫过去全是密集文字,无法快速抓取核心交付要点。
6. 仅在必要时保留有帮助且标记清晰的 TODO (Actionable TODOs only) 防范大模型在代码核心关键分支偷偷摸摸留下无用的半拉子占位符。 用户自以为逻辑完整,实际核心计算被一行空 TODO 糊弄了过去。
7. 无法执行时,显式披露风险并说明本地验证方法 (Disclose execution limits) 防范大模型在受限沙箱中无法运行却"假装成功",坚守工程诚实底线。 用户把代码放上生产才发现从一开始就无法在目标系统运行。

3. 落地范式:如何用 Progressive Disclosure 优雅挂载质检表?

既然质检清单如此重要,那我们是不是应该直接把它贴在 SKILL.md 正文的最显眼位置呢?

答案是:恰恰相反!千万不要把完整的质检长文直接堆在 SKILL.md 正文里!

根据前文讲过的渐进展开(Progressive Disclosure)与上下文效率法则:

  • 在任务的前期与中期(意图识别、参数规划、代码编写阶段),大模型的大脑必须高度集中在"怎么完成业务",此时若把几百字的质检细则常驻在上下文里,不仅白白浪费 Token,还会严重稀释大模型对核心业务规程的注意力;

  • 工业级成熟解耦方案:

    1. 将详细的检查条目独立存放在可选资源目录 references/quality-checklist.md 中;
    2. 在主入口 SKILL.md 正文的末尾退出段(Exit Criteria) ,只保留一行极其轻量的触发引线:
scss 复制代码
## 交付退出检查(Exit Criteria)在向用户提交最终结果前,你必须查阅 [references/quality-checklist.md](references/quality-checklist.md) 对本次生成的代码与产物完成逐项自检,确认无隐式状态依赖且真实落盘后,方可宣布任务完成。

大模型只在最后临门一脚准备宣布完成时,才会由智能体客户端按需加载 quality-checklist.md 进行"临门自检"。既保障了全流程交付的极致严密,又实现了会话全程上下文消耗的最小化!


八、 发布准入自查:Skill 生产上线检查清单

📌 使用说明 :本检查表面向 Skill 开发者,用于在将技能包发布、集成或部署至智能体环境前,对技能本身的文件规范、上下文预算及触发健壮性进行最终准入确认(区别于第七章供智能体在运行时使用的交付 Checklist)。

为确保技能在各类 Agent 客户端(如 Claude Code 等)中稳定加载并不引发上下文衰退,发布前建议对照以下三道生产门禁完成逐项核验:


1. 第一道门禁:物理结构与 Schema 阻断项(红线项)

此门禁为强制标准(Hard Requirements),任何一项不合格都会直接导致智能体解析器报错或技能彻底无法加载:

  • 1. 入口文件唯一性 :根目录下是否存在且仅存在一个作为主入口的 SKILL.md?(大小写严格匹配,严禁写成 skill.md 或 Skill.MD)。
  • 2. 命名字符集合法性 :Frontmatter 的 name 是否仅由小写字母、数字和连字符 - 组成?(严禁包含下划线 _,禁止以 - 开头或结尾,严禁出现连续 --)。
  • 3. 目录与标识一致性 :name 的值是否与该 Skill 所在的父目录名称 100% 绝对一致?字符长度是否严格在 1 到 64 字符以内?
  • 4. 描述非空与上限拦截 :Frontmatter 的 description 是否为非空字符串?字符总数是否严格控制在 1024 字符以内?

2. 第二道门禁:上下文预算与渐进展开(Token 效率项)

此门禁关乎运行成本与长文本性能,防止因为 Skill 过于臃肿导致大模型发生《Lost in the Middle》上下文衰退:

  • 5. 正文篇幅预算 :SKILL.md 正文篇幅是否控制在建议的 500 行以内,且整体 Token 开销严格在 5000 Token 以内?
  • 6. 非核心细节渐进解耦 :背景原理、长篇数据库语法兼容表、详细真值表是否已剥离至 references/ 目录?
  • 7. 确定性脚本工具下沉 :脆弱的复杂文件模板(如 .ipynb 脚手架)与无头运行重算逻辑是否已封装进 scripts/,供模型通过终端命令调用?
  • 8. 剔除已知通用常识:正文是否聚焦于当前业务特有的规程与暗坑,彻底删除了 Python 基础语法、HTTP 状态码、JSON 格式科普等大模型已知常识?

3. 第三道门禁:意图触发与防御性规程(实战稳健项)

此门禁关乎真实场景下的召回准确率与任务执行质量,防止大模型误触、漏触或在代码执行中翻车:

  • 9. 祈使句行动指令 :description 是否使用祈使句明确点出"在什么具体条件下使用"(Trigger),对准用户业务意图,而非堆砌内部库函数等技术细节?
  • 10. 触发鲁棒性自测过关 :是否准备了 510 条正向业务问句与 510 条反向混淆问句,自测验证在多轮对话中触发率稳居 50% 以上,且未发生误触发?
  • 11. 领域高危暗坑代码对撞 :对于工具库的破坏性缺陷(如 openpyxl 抹杀公式、SQL 3VL 空值漏判),正文是否提供了醒目的 ❌ 错误示范 与 ✅ 正确示范 代码块?
  • 12. 明确交付退出标准 :SKILL.md 末尾是否设立了退出标准(Exit Criteria),并显式指引模型在交差前对标质量自查表完成闭环?

4. 快速自检矩阵:发布准入速查表(Release Matrix)

门禁分类 核心检查维度 合规合格线 违规严重等级 对应教程章节
第一道门禁 物理与 Schema 阻断 name 与目录一致性 description 长度 <= 1024 合法字符集无下划线 100% 绝对合规 🔴 致命阻断 (直接解析崩溃或加载失败) 第二章:规范核心要求
第二道门禁 上下文与渐进展开 正文 <= 500 行 & 5000 Token 长文收纳进 references/ 脚本收纳进 scripts/ 建议预算内 🟡 性能衰退 (上下文爆炸、中间信息丢失) 第一章:渐进展开 第四章:指令松紧度
第三道门禁 调度与防御规程 祈使句描述对准用户意图 红白测试集命中率 > 50% 高危操作正反代码对撞 稳定达标 🟠 实战翻车 (意图无法命中、运行破坏数据) 第三章:意图触发设计 第五章:领域暗坑防御

九、 参考文献与出处索引

  1. Anthropic PBC. The Agent Skills Specification . 规范文档: agentskills.io/specificati...
  2. Anthropic PBC. Best practices for skill creators . 最佳实践指南: agentskills.io/skill-creat...
  3. Anthropic PBC. Optimizing skill descriptions . Description 优化指南: agentskills.io/skill-creat...
  4. Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F., & Liang, P. (2024). Lost in the Middle: How Language Models Use Long Contexts . Transactions of the Association for Computational Linguistics (TACL), 12, 157--173. arXiv:2307.03172
  5. ISO/IEC 9075:2016. Information technology --- Database languages --- SQL --- Part 2: Foundation (SQL/Foundation) . Clause 8.2 Comparison Predicate.
  6. Anthropic PBC. xlsx Skill Repository and recalc.py script.
  7. OpenAI, Inc. jupyter-notebook Skill Repository and new_notebook.py script.
相关推荐
雨中飘荡的记忆2 小时前
Claude Code 保姆级入门:从安装到跑通第一个项目
后端
茉莉玫瑰花茶2 小时前
GO [ 标准库 · unsafe ]
后端·go
肌肉娃子2 小时前
20261016 从定时任务到主明细入库:Spring Boot 对接亚马逊订单的数据同步设计
后端
Ysx2 小时前
比"本地全绿"更可怕的坑:"交付了"不等于"生效了"
java·后端
武子康2 小时前
ESP32-S3 分核后仍报 AFE 缓冲区满?先查输入合同
人工智能·后端·agent
Zheone2 小时前
《Java开发者视角:利用AI辅助审计Spring Boot接口越权漏洞的初步实践》
后端
god_cvz2 小时前
第三章:4、补充:对话记忆与会话管理
后端·ai编程
弈栈录2 小时前
用户、会话与消息表应该如何设计
数据库·后端
maozhenzhong2 小时前
接口加解密与安全通信方案
后端