在构建 AI Agent 的实践中,一个普遍的初始路径是无限堆砌系统提示词(system prompt)。团队试图将全部规则、示例、流程、约束乃至代码片段塞进一个长篇大论的指令集,期望模型每次都能像精密仪器一样按图索骥。
然而,这种单纯依赖“提示词工程”的路径很快会面临瓶颈:
- 维护成本激增:提示词越写越长,如同维护一份不断膨胀的过时文档。
- 资源效率低下:处理不同任务时,模型必须复用同一段庞大的上下文,造成 token 浪费。
- 管理混乱:规则散落在历史对话中,难以进行版本控制和团队协作。
- 输出不一致:每位成员编写的提示词风格各异,导致 Agent 的输出质量参差不齐。
- 重复学习:模型面对重复性任务,仍需“重新学习”相同的处理流程,效率低下。
更工程化的解决方案,是将某一类任务所需的知识、流程、脚本和素材打包封装,形成一个独立的、可复用的能力单元。这个单元,可以被称作 Skill。
一个 Skill 并非单句提示词或一个 Markdown 文件,而是一个围绕特定任务组织起来的文件夹资产集合。它内含说明文档、示例、可执行脚本、模板、参考数据、配置文件,以及可选的执行钩子(hooks)。
非线智能api(非线智能NoneLinear) 作为兼容 OpenAI SDK 的模型调用层,非常适合在 Agent 应用中扮演这一角色。开发者可以将 Skill 机制集成进自己的 Agent 框架,让模型在需要时动态加载对应的“能力包”,而非始终携带一套臃肿的通用指令运行。
快速上手:接入 非线智能api(非线智能NoneLinear)
若项目已基于 OpenAI SDK,接入 非线智能api(非线智能NoneLinear) 通常只需调整 base_url:
from openai import OpenAI
client = OpenAI(
api_key="YOUR_NONELINEAR_API_KEY",
base_url="https://api.nonelinear.com/v1",
)
response = client.chat.completions.create(
model="your-model-name",
messages=[
{"role": "system", "content": "你是一个支持 Skills 的 AI Agent。"},
{"role": "user", "content": "请使用代码审查 Skill 检查这个 PR 的风险点。"},
],
)
print(response.choices[0].message.content)
但 API 调用本身并非难点。真正的挑战在于:如何将 Skill 设计成模型“愿意使用、使用准确、且不浪费上下文”的结构化资产。
Skill 的理想结构
一个实用的 Skill 可以采用如下文件夹组织:
skills/
code-review/
SKILL.md
examples/
good-review.md
bad-review.md
scripts/
collect_diff.sh
run_tests.sh
templates/
review-output.md
references/
severity-guide.md
其中,SKILL.md 是入口文件,负责向 Agent 阐明:
- 此 Skill 适用于何种任务
- 在何种场景下应被触发
- 应优先读取哪些文件
- 可以调用哪些脚本
- 输出应遵循何种格式
- 需要避免哪些常见错误
例如:
# Code Review Skill
## When to use
Use this skill when the user asks for review, PR risk analysis, regression detection, or missing test coverage.
## Workflow
1. Inspect the changed files.
2. Identify behavioral bugs before style issues.
3. Report findings with file and line references.
4. Mention test gaps only after concrete findings.
## Output
Start with findings ordered by severity. If no issues are found, say so clearly and mention residual risk.
这远比将所有规则硬编码进系统提示词来得清晰,也更便于团队内共享与迭代。
核心设计原则:渐进式披露
Skill 的核心价值之一在于让 Agent 按需加载信息,而非一次性全盘接收。
切忌将所有规则、长文档、脚本说明都写入 SKILL.md。入口文件应精简,专注于路由;详细信息应置于子目录中,根据任务需要动态加载。
推荐的结构如下:
SKILL.md # 触发条件、任务流程、输出约束
references/ # 较长的领域知识文档
examples/ # 好的与坏的示例
scripts/ # 可执行的自动化工具
assets/ # 模板、图片、字体、数据文件
如此设计有两个显著好处:
- Agent 无需每次都读取完整资料集,使 token 消耗更可控。
- Skill 的知识库可以持续扩展,而不会将入口文件再次变成新的超长提示词。
一个优秀的 SKILL.md 应像一本索引目录,而非一部百科全书。
[图片上传失败...(image-4ec29a-1779884640428)]
描述要写给模型看
许多人编写 Skill 描述时,习惯采用人类可读的简介风格,例如:“这是一个用于数据分析的 Skill。”
此类描述过于模糊,模型很难据此判断何时调用。
更有效的方法是清晰陈述触发场景:
Use this skill when the user asks to inspect CSV files, summarize tabular data, detect outliers, generate charts, or explain trends from datasets.
触发描述应包含明确的任务动词和操作对象,例如:
- 检查 CSV 文件
- 审查代码合并请求
- 将笔记转化为文章
- 生成 UI 组件
- 提取行动项
- 调试 API 错误
模型并非通过 Skill 名称来猜测用途,而是依靠描述判断相关性。描述越具体,误触发和遗漏触发的概率就越低。
九类高价值 Skill 应用场景
并非所有提示词都值得 Skill 化。通常,那些具有固定流程、高频重复、依赖外部文件或团队标准的任务,更适合封装为 Skill。
以下是开发团队最常见的九类高价值场景:
1. 文档处理 Skill
适用于处理 PDF、Word、Markdown、网页摘录、会议纪要及内部知识库。
- 内含资产:摘要模板、结构化抽取规则、术语表、输出格式示例、文档分块脚本。
- 典型任务:将会议记录转为待办清单;从技术文档中提取 API 参数;压缩长篇文档生成决策摘要;将 Markdown 文章改写为博客稿。
2. 代码审查 Skill
用于统一团队的 PR(Pull Request)审查标准。
- 内含资产:严重程度分级规则、常见 bug 清单、项目特定测试命令、文件引用格式、禁止仅提风格建议的约束。
- 典型任务:查找行为回归;检查边界条件;发现缺失测试;识别安全风险;输出可直接粘贴到 PR 的审查意见。
3. 数据分析 Skill
适用于分析 CSV、数据库导出、日志、实验结果、评测报告等。
- 内含资产:数据清洗脚本、图表生成模板、指标定义、异常值判断规则、分析报告格式。
- 典型任务:汇总模型评测结果;分析用户增长数据;找出异常样本;将日志转化为可读结论;生成图表与洞察。
4. UI 生成 Skill
适用于需要保持设计风格一致性的前端项目。
- 内含资产:设计系统规范、组件使用规则、颜色与间距约束、禁止模式、页面示例。
- 典型任务:生成 React 组件;改造仪表盘页面;按品牌风格输出落地页;为管理后台补齐交互状态。
5. Agent 工具使用 Skill
用于指导 Agent 如何正确、高效地调用内部工具。
- 内含资产:工具调用顺序、参数说明、错误处理方式、重试策略、不应调用工具的情况。
- 典型任务:调用内部搜索;查询订单状态;分析服务健康度;执行部署前检查。
6. 内容生产 Skill
适用于团队生产博客、社交媒体内容、产品更新、案例文章、教程和邮件。
- 内含资产:品牌语气指南、标题风格、文章结构、禁用词列表、SEO 要求、样例文章。
- 典型任务:将技术调研改写为博客;将 release note 改写为开发者公告;将英文资料转译为中文文章;根据产品能力生成场景案例。
7. 测试与评测 Skill
适用于验证 LLM 应用、Agent、RAG 系统、模型 API 及业务系统的质量。
- 内含资产:测试命令、评测指标说明、失败样本分类、报告模板、回归测试流程。
- 典型任务:为新功能补充测试;生成评测数据集;对比不同模型的结果;判断提示词修改是否导致性能回归;汇总 benchmark 报告。
8. 项目知识 Skill
用于沉淀特定代码库、产品线或团队流程的领域知识。
- 内含资产:架构说明、目录约定、常用命令、发布流程、关键业务概念、历史决策记录。
- 典型任务:帮助新人快速理解项目;在 Agent 修改代码前读取项目约束;生成符合团队规范的实现方案;避免重复询问相同上下文。
9. 个人工作流 Skill
适合个人长期复用的工作习惯与方法。
- 内含资产:笔记整理格式、任务拆解方式、写作偏好、日报周报模板、常用脚本。
- 典型任务:整理 Obsidian 笔记;生成周报;将会议语音转为行动项;根据个人风格改写文章。
Skill 应包含可执行脚本
如果某个步骤可以稳定地由程序完成,就不应让模型每次都“重新思考一遍”。
例如,数据分析 Skill 可以包含:
scripts/
profile_csv.py
detect_outliers.py
render_chart.py
代码审查 Skill 可以包含:
scripts/
changed_files.sh
run_unit_tests.sh
summarize_diff.py
文档处理 Skill 可以包含:
scripts/
extract_pdf_text.py
split_markdown.py
normalize_frontmatter.py
模型擅长判断、归纳和生成,但不应承担所有机械性步骤。脚本的引入能让 Skill 运行更稳定,并显著减少 token 消耗。
利用持久化数据减少重复上下文
有些知识不应每次都需要用户重新提供,例如:
- 品牌语气指南
- 产品术语表
- 常用 API 参数
- 团队输出模板
- 项目目录约定
- 常见错误码
这些内容可以存放于 Skill 的 references/ 或 templates/ 目录。Agent 在必要时自行读取,无需用户反复粘贴。
示例:
skills/
nonelinear-blog-writer/
SKILL.md
references/
brand-voice.md
api-positioning.md
forbidden-phrases.md
templates/
scenario-article.md
这能使输出更一致,也更适合多人协作。
使用 Hooks 实现轻量自动化
某些无需模型参与的机械动作,适合通过 hooks 或脚本自动执行。
- 生成文章后自动检查是否包含敏感来源
- 保存代码前自动格式化
- 运行测试前自动收集变更文件
- 输出报告前自动统计 token 消耗或耗时
但 hooks 不宜过多。过多的自动行为会使系统变得难以解释和调试。原则是:只有稳定、低风险、可重复的步骤才应放入 hooks;需要判断和取舍的步骤交给 Agent。
Skill 组合与协调
复杂任务往往需要多个 Skill 协同工作。例如,生成一篇开发者博客可能涉及:
- 项目知识 Skill:读取产品定位与 API 接入方式
- 内容生产 Skill:确定文章结构与语气
- 代码示例 Skill:生成 SDK 调用示例
- 审校 Skill:检查事实、格式与禁用词
组合使用时,关键是边界清晰。每个 Skill 只负责自己的阶段,避免多个 Skill 同时对最终输出风格指手画脚,否则模型会收到冲突指令。一个可行的链路是:
收集上下文 -> 生成大纲 -> 写正文 -> 补代码示例 -> 审校 -> 输出最终稿
逐步调用不同 Skill,比一次性加载所有 Skill 更稳定可靠。
Skill 的分发与版本管理
如果 Skill 只是本地的提示词片段,很难在团队中推广复用。
更佳的方式是将 Skill 作为项目资产进行管理:
- 存入 Git 仓库
- 使用语义化版本号
- 明确依赖关系
- 提供示例输入输出
- 记录更新日志
- 标注适用与不适用的场景
例如:
skills/
code-review/
SKILL.md
CHANGELOG.md
examples/
scripts/
当团队成员使用同一套 Skill,Agent 的输出一致性将大大提高。后续优化也可以像代码变更一样进行评审。
如何评估 Skill 的质量
Skill 不是编写完成就束之高阁。它应像代码一样被评估和迭代。
可以从以下指标衡量:
- 任务完成率是否提升
- 平均对话轮次是否减少
- 用户需要补充说明的次数是否降低
- 输出格式是否更加稳定
- 人工修改量是否下降
- token 消耗是否优化
- 误触发率是否在可接受范围内
- 能否跨团队成员有效复用
对于高频任务,建议准备一组固定的测试样例。每次修改 Skill 后,用同一批任务测试,观察结果是改善还是退化。这与 LLM 应用评测的思路一致:追求的不是“感觉更聪明”,而是可重复任务上的稳定性。
在 非线智能api(非线智能NoneLinear) 中加载 Skill 的示例实现
以下是一个简化示例:根据用户请求选择 Skill,加载其入口文件,并将必要上下文交给 非线智能api(非线智能NoneLinear) 处理。
from pathlib import Path
from openai import OpenAI
client = OpenAI(
api_key="YOUR_NONELINEAR_API_KEY",
base_url="https://api.nonelinear.com/v1",
)
def load_skill(name: str) -> str:
skill_path = Path("skills") / name / "SKILL.md"
return skill_path.read_text(encoding="utf-8")
def run_with_skill(skill_name: str, user_task: str):
skill = load_skill(skill_name)
messages = [
{
"role": "system",
"content": (
"You are an AI Agent. Follow the loaded Skill when it is relevant. "
"Do not invent files or project facts that were not provided."
),
},
{
"role": "user",
"content": f"Loaded Skill:\n\n{skill}\n\nUser task:\n\n{user_task}",
},
]
response = client.chat.completions.create(
model="your-model-name",
messages=messages,
)
return response.choices[0].message.content
print(run_with_skill(
"code-review",
"请审查这个 PR,重点关注行为回归和缺失测试。"
))
在生产环境中,还需进一步考虑:
- Skill 检索机制
- 权限控制
- 文件访问白名单
- 子文件的按需读取
- 脚本执行沙箱
- 版本锁定
- 调用日志与评测集
不要一开始就构建复杂平台。先让一个高频任务的 Skill 跑起来,再逐步扩展。
常见误区
误区一:将 Skill 写成超长提示词
这违背了 Skill 的初衷。入口文件应简洁,详细信息应按需加载。
误区二:Skill 描述过于宽泛
“用于提升效率”这类描述对模型毫无帮助。必须写清楚具体任务、操作对象和触发条件。
误区三:将所有步骤都交给模型
稳定的机械步骤应脚本化。模型负责判断与生成,脚本负责执行。
误区四:缺乏输出模板
没有模板,Agent 每次都可能生成不同格式。高频团队任务必须明确输出结构。
误区五:不做评测
Skill 本身是工程资产。没有测试样例,就无法判断一次修改是优化还是退化。
总结
Skill 是推动 AI Agent 从“会聊天”迈向“能稳定干活”的关键抽象层。
它将完成特定任务所需的流程、知识、示例、脚本和模板,沉淀为可复用的文件夹能力包。相较于不断膨胀的系统提示词,Skill 更利于长期维护、团队协作、版本管理和按需加载。
对于开发者而言,可以从九类高频场景切入实践:
- 文档处理
- 代码审查
- 数据分析
- UI 生成
- Agent 工具调用
- 内容生产
- 测试与评测
- 项目知识沉淀
- 个人工作流自动化