尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI Agent Skill 编写指南:从结构设计到测试迭代的实战经验

AI Agent Skill 编写指南:从结构设计到测试迭代的实战经验 1. 为什么“写 Skill”这件事值得单独拿出来聊很多人第一次接触 Skill 这个概念是在 AI Agent 工具链里。你给它一段自然语言描述它就能调用某个能力去完成一件事——查数据、跑脚本、生成文档、做格式转换。看起来很简单但真正动手写的时候问题就来了为什么我写的 Skill 总是被忽略为什么同样的需求别人写的 Skill 一次就跑通我的要反复调为什么有些 Skill 换个模型就废了这些问题的根源其实不在模型本身而在于 Skill 的写法。Skill 本质上是一份“给 AI 看的说明书”它需要同时满足两个条件机器能解析人也能维护。这跟写代码不一样代码是给编译器看的Skill 是给一个“理解力很强但注意力有限”的智能体看的。你得让它一眼就知道什么时候该用这个 Skill、用了之后会发生什么、边界在哪里。我前后写过几十个 Skill覆盖数据处理、文档生成、代码辅助、格式转换这些场景踩过的坑基本能凑成一本小册子。这篇文章就把这些经验整理出来从结构设计到参数定义从测试方法到常见误区尽量讲透。不管你是刚接触 Skill 的新手还是已经写过几个但总觉得不够顺手的开发者应该都能从中找到能直接用的东西。关键词里提到的 Python、R 语言、LaTeX、AI Agent 这些其实都是 Skill 常见的落地场景。比如用 Python 写一个数据清洗 Skill用 R 语言写一个统计分析 Skill用 LaTeX 写一个论文排版 Skill。不同场景对 Skill 的要求不一样但底层逻辑是相通的。下面我按实际写 Skill 的顺序来展开从最基础的结构开始一步步往深里走。2. Skill 的基本结构一份好的说明书长什么样2.1 名称与描述第一眼决定生死Skill 的名称和描述是它被调用的第一道门槛。很多人在这里犯的错是名称写得太泛描述写得太虚。比如叫“数据处理 Skill”描述写“用于处理数据”。这种写法等于没写因为 AI 根本不知道你处理的是什么数据、怎么处理、什么时候该用你。正确的做法是名称要具体到动作和对象描述要包含触发条件和预期结果。举个例子如果你写的是一个把 CSV 转成 JSON 的 Skill名称可以叫csv-to-json-converter描述可以写“当用户需要将 CSV 格式的表格数据转换为 JSON 结构时使用支持自定义分隔符和编码格式”。这样 AI 在判断是否调用时就有明确的依据。我实测下来描述里包含“当……时使用”这个句式调用准确率会明显提升。因为 AI 在决策时本质上是在做模式匹配你给它一个明确的触发场景它就能更快地对应上。2.2 输入参数少即是多但每个都要说清楚输入参数的设计是 Skill 写作里最容易过度设计的地方。新手往往想把所有可能性都覆盖到结果参数列表长得像一份配置文档AI 看了直接懵。我的经验是核心参数控制在 3 到 5 个每个参数必须有明确的类型、是否必填、默认值、以及一个具体的示例。举个例子一个用于 LaTeX 编译的 Skill输入参数可以这样设计参数名类型必填默认值说明source_filestring是无LaTeX 源文件路径如./paper/main.texoutput_formatstring否pdf输出格式可选 pdf 或 dviclean_auxboolean否true是否清理编译产生的辅助文件enginestring否pdflatex编译引擎可选 pdflatex、xelatex、lualatex这个表格看起来简单但每个字段都有讲究。source_file给了示例路径AI 就知道要传一个文件路径而不是文件内容。output_format给了可选值AI 就不会乱传。clean_aux用布尔值语义清晰。engine的默认值选了最通用的 pdflatex同时列出了其他选项。注意参数说明里一定要给示例值。我试过只写“文件路径”四个字结果 AI 有时候传相对路径有时候传绝对路径有时候甚至把文件内容塞进来。给了示例之后这个问题基本消失。2.3 执行逻辑用自然语言写清楚每一步Skill 的执行逻辑部分是用自然语言描述“这个 Skill 被调用后具体做什么”。这里的关键是步骤要可执行、可验证避免模糊表述。比如“处理数据”这种写法就不行得写成“读取输入文件按行解析过滤掉空行将每行按逗号分割输出为 JSON 数组”。我习惯把执行逻辑写成有序列表每一步都对应一个明确的动作。如果涉及条件分支就用“如果……则……”的句式。如果涉及循环就说明循环的终止条件。这样写出来的 SkillAI 在执行时不容易跑偏。还有一个细节执行逻辑里要明确说明“不需要做什么”。比如一个格式转换 Skill你可以写“不需要验证输入数据的业务逻辑只做格式转换”。这样能避免 AI 过度发挥把简单任务复杂化。2.4 输出格式让结果可预期输出格式的定义经常被忽略但它直接影响 Skill 的可用性。如果输出格式不明确AI 可能这次返回 JSON下次返回纯文本再下次返回一个表格。对于调用方来说这种不确定性是灾难性的。我的做法是在 Skill 里明确指定输出格式并给出一个完整的示例。比如“输出一个 JSON 对象包含status字段值为 success 或 error、data字段转换后的数据数组、message字段错误信息成功时为空字符串”。然后附上一个示例输出{ status: success, data: [{name: Alice, age: 30}], message: }这样不管是谁调用这个 Skill拿到结果都知道怎么解析。3. 从场景出发不同领域的 Skill 写法差异3.1 数据处理类 SkillPython 和 R 语言的分工数据处理是 Skill 最常见的应用场景之一。Python 和 R 语言在这个领域各有优势写 Skill 的时候要根据任务特点来选择。Python 的优势在于通用性和生态丰富。如果你要写一个 Skill 来处理 CSV、Excel、JSON 这些格式的转换或者做数据清洗、特征工程Python 是首选。写这类 Skill 的时候我建议在描述里明确说明依赖的库比如“使用 pandas 读取 CSV 文件使用 numpy 做数值计算”。这样 AI 在调用时就知道需要确保环境里有这些库。R 语言的优势在于统计分析和可视化。如果你要写一个 Skill 来做 SARIMA 模型拟合、α 多样性分析、单细胞测序的 GO 富集分析R 语言更合适。写这类 Skill 的时候描述里要写清楚输入数据的格式要求比如“输入一个数据框第一列是时间序列第二列是观测值”。因为 R 语言对数据格式比较敏感提前说清楚能减少很多调试时间。我踩过的一个坑是用 Python 写了一个统计检验的 Skill结果发现 scipy 的版本不同API 有差异导致 Skill 在某些环境下跑不通。后来改成在 Skill 里明确指定“使用 scipy.stats.ttest_ind要求 scipy 版本不低于 1.7.0”问题才解决。所以写数据处理类 Skill依赖版本一定要写清楚。3.2 文档生成类 SkillLaTeX 排版的细节控制LaTeX 是学术写作和正式文档排版的首选工具写一个 LaTeX 相关的 Skill 能大幅提升效率。但 LaTeX 的细节很多Skill 里必须把这些细节交代清楚。比如一个“生成论文模板”的 Skill你需要指定文档类article、report 还是 IEEEtran、页面布局单栏还是双栏、标题作者机构的格式、摘要和关键词的位置、正文的字体和行距。这些如果不在 Skill 里写清楚AI 生成的模板可能跟你的预期差很远。我写过一个用于“将 Word 公式转为 LaTeX”的 Skill核心逻辑是读取 Word 文档中的公式对象提取其 OMML 格式然后转换为 LaTeX 代码。这个 Skill 的关键在于转换规则的完整性。我在 Skill 里列了一个映射表把常见的 OMML 标签对应到 LaTeX 命令比如m:f对应\fracm:sup对应^。这样 AI 在执行时就有明确的规则可循。还有一个实用技巧在 Skill 里加入“编译后清理辅助文件”的步骤。LaTeX 编译会产生 .aux、.log、.out 这些文件如果不清理目录会越来越乱。我通常会在 Skill 的最后一步写“执行latexmk -c清理辅助文件保留 .tex 和 .pdf”。3.3 代码辅助类 Skill让 AI 写出能跑的代码代码辅助类 Skill 的目标是让 AI 生成可直接运行的代码。这类 Skill 的写法跟前面两类不太一样重点在于约束和示例。约束方面要明确指定编程语言、版本、依赖库、代码风格。比如“使用 Python 3.10 以上版本只使用标准库和 numpy函数命名用 snake_case每个函数必须有 docstring”。这些约束能大幅提升生成代码的可用性。示例方面最好在 Skill 里附上一段“正确代码”的片段。比如你要写一个“生成邻接矩阵”的 Skill可以附上这样一段示例import numpy as np def build_adjacency_matrix(edges, num_nodes): 根据边列表构建邻接矩阵。 matrix np.zeros((num_nodes, num_nodes), dtypeint) for u, v in edges: matrix[u][v] 1 matrix[v][u] 1 return matrix有了这个示例AI 生成的代码在风格和结构上就会向它靠拢减少后续修改的工作量。4. 测试与迭代怎么知道 Skill 写得好不好4.1 用边界用例做第一轮测试Skill 写完之后不要急着上生产先用边界用例测一轮。什么叫边界用例就是那些“看起来不太正常但确实可能发生”的输入。比如空输入、超长输入、格式错误的输入、包含特殊字符的输入。我通常会准备一组测试用例覆盖以下几种情况正常输入标准格式的数据验证基本功能。空输入不传任何参数看 Skill 是否给出合理的错误提示。异常输入传一个不存在的文件路径看 Skill 是否优雅地报错。极端输入传一个超大的文件看 Skill 是否有性能问题。歧义输入传一个模糊的描述看 Skill 是否能正确理解。实测下来大部分 Skill 的问题都出在异常输入的处理上。比如文件不存在时直接抛异常而不是返回一个友好的错误信息。这类问题在测试阶段发现比在生产环境发现要好得多。4.2 观察 AI 的实际调用行为Skill 的测试跟普通代码测试有一个本质区别你不仅要测 Skill 本身还要测 AI 会不会在正确的时机调用它。有时候 Skill 逻辑没问题但 AI 就是不用它或者在不该用的时候用了。我的做法是构造几个典型的用户请求观察 AI 的调用决策。比如你写了一个“CSV 转 JSON”的 Skill可以试试这些请求“把这个 CSV 文件转成 JSON”应该调用“帮我看看这个 CSV 文件的内容”不应该调用应该直接读取“把这个 Excel 文件转成 JSON”不应该调用因为格式不匹配如果 AI 的调用决策不符合预期就要回头改 Skill 的描述。通常是在描述里补充更多的触发条件和排除条件。4.3 迭代优化的三个方向Skill 的迭代优化我一般从三个方向入手第一收窄触发条件。如果发现 Skill 被频繁误调用就在描述里加限制。比如“仅当输入文件扩展名为 .csv 时使用”。第二补充示例。如果发现 AI 对某个参数的理解有偏差就在参数说明里加一个更具体的示例。第三拆分复杂 Skill。如果一个 Skill 承担了太多职责就把它拆成多个小 Skill。比如“数据处理”可以拆成“数据读取”“数据清洗”“数据转换”三个 Skill。这样每个 Skill 的职责更单一AI 调用起来也更准确。提示拆分 Skill 的时候要注意保持 Skill 之间的衔接。可以在描述里写明“本 Skill 通常与 xxx Skill 配合使用”帮助 AI 建立调用链。5. 那些年我踩过的坑常见误区与修复方案5.1 描述太抽象AI 根本不知道什么时候用这是最常见的坑。我早期写过一个 Skill描述是“用于处理文本数据”。结果 AI 几乎从不调用它因为“处理文本数据”这个描述太宽泛了AI 无法判断具体场景。修复方案把描述改成具体的动作和场景。比如“当用户需要从一段文本中提取所有电子邮件地址时使用支持从纯文本和 HTML 中提取”。改完之后调用率立刻上来了。5.2 参数太多AI 记不住另一个坑是参数列表太长。我写过一个 Skill有 12 个参数结果 AI 经常漏传或者传错。后来我把参数精简到 5 个把一些不常用的配置项改成默认值问题就解决了。修复方案只保留核心参数其他参数用默认值。如果确实需要很多配置考虑拆成多个 Skill或者用一个 JSON 字符串参数来承载复杂配置。5.3 输出格式不固定调用方无法解析这个坑在多人协作的场景下特别致命。你写的 Skill 返回 JSON别人写的调用代码按纯文本解析结果就是各种报错。修复方案在 Skill 里强制指定输出格式并给出完整的示例。如果输出格式可能变化就在输出里加一个format字段说明当前返回的是什么格式。5.4 忽略依赖和环境要求有些 Skill 依赖特定的库或工具但描述里没写导致在别的环境跑不通。比如一个用 cv2 做图像处理的 Skill如果没写“需要安装 opencv-python”在没装这个库的环境里就会失败。修复方案在 Skill 的描述或执行逻辑里明确列出依赖项和版本要求。如果依赖较多可以单独写一个“环境准备”章节。5.5 没有错误处理一出问题就崩很多 Skill 只考虑了正常流程没考虑异常情况。比如文件不存在、网络超时、权限不足这些情况如果没有处理Skill 就会直接抛异常调用方拿到一个莫名其妙的错误。修复方案在 Skill 的执行逻辑里加入错误处理步骤。比如“如果文件不存在返回错误信息‘文件未找到请检查路径’”。这样调用方就能根据错误信息做出相应的处理。6. 进阶技巧让 Skill 更智能、更通用6.1 用条件分支处理多种场景一个好的 Skill 应该能处理多种相关场景而不是只能做一件事。比如一个“文档转换”Skill可以支持 Markdown 转 HTML、HTML 转 PDF、LaTeX 转 PDF 等多种转换。实现方式是在 Skill 里加入条件分支根据输入文件的扩展名和目标格式选择不同的转换逻辑。这样写的好处是AI 只需要记住一个 Skill就能覆盖多种需求。但要注意条件分支不能太多否则 Skill 会变得难以维护。我的经验是一个 Skill 覆盖 3 到 5 个相关场景比较合适。6.2 用示例引导 AI 的输出风格如果你对输出风格有要求比如“代码要加注释”“文档要用学术语气”“报告要包含数据来源”可以在 Skill 里附上一段示例输出。AI 在生成结果时会倾向于模仿示例的风格。我写过一个“生成数据分析报告”的 Skill在描述里附了一段示例报告的开头“本报告基于 2024 年 1 月至 6 月的销售数据共包含 12,345 条记录。数据来源为内部销售系统经过去重和异常值处理后有效记录为 11,892 条。”有了这个示例AI 生成的报告在语气和结构上就稳定多了。6.3 用版本号管理 Skill 的迭代Skill 也是代码也需要版本管理。我习惯在 Skill 的名称或描述里加上版本号比如csv-to-json-converter-v2。这样在迭代时可以保留旧版本同时测试新版本。等新版本稳定后再逐步切换。版本号的管理还能帮助排查问题。如果某个 Skill 突然表现异常可以快速定位是不是最近改了版本。6.4 多 AI 协作场景下的 Skill 设计在多 AI 协作的场景下Skill 的设计要考虑跨模型的兼容性。不同 AI 模型对 Skill 描述的理解可能有差异所以描述要尽量标准化、结构化。我的做法是用统一的模板来写 Skill包括名称、描述、参数、执行逻辑、输出格式、依赖项、示例这几个固定部分。这样不管哪个模型来解析都能找到需要的信息。另外避免使用特定模型的专有术语用通用的表达方式。7. 一个完整示例从零写一个 LaTeX 编译 Skill7.1 需求分析与参数设计假设我们要写一个 Skill用于编译 LaTeX 项目并清理辅助文件。这个 Skill 的典型使用场景是用户有一个 LaTeX 项目目录里面包含 .tex 文件和图片等资源需要编译成 PDF同时清理编译过程中产生的 .aux、.log 等文件。参数设计如下参数名类型必填默认值说明project_dirstring是无LaTeX 项目目录路径如./papermain_filestring否main.tex主 tex 文件名enginestring否pdflatex编译引擎可选 pdflatex、xelatex、lualatexcleanboolean否true编译成功后是否清理辅助文件7.2 执行逻辑的详细描述执行逻辑按以下步骤写检查project_dir是否存在如果不存在返回错误信息“项目目录不存在”。检查project_dir下是否存在main_file如果不存在返回错误信息“主文件未找到”。根据engine参数选择编译命令pdflatex 对应pdflatexxelatex 对应xelatexlualatex 对应lualatex。在project_dir下执行编译命令编译main_file。如果编译失败返回错误信息包含编译日志的最后 20 行。如果clean为 true执行latexmk -c清理辅助文件。返回成功信息包含生成的 PDF 文件路径。7.3 输出格式与错误处理输出格式定义为 JSON{ status: success, pdf_path: ./paper/main.pdf, message: 编译成功辅助文件已清理 }错误情况下{ status: error, pdf_path: , message: 编译失败Undefined control sequence \\foo }7.4 测试与验证测试用例包括正常项目编译成功PDF 生成辅助文件清理。缺少主文件返回“主文件未找到”。编译错误返回编译日志片段。不同引擎分别用 pdflatex、xelatex、lualatex 测试。clean 为 false辅助文件保留。实测下来这个 Skill 在大多数 LaTeX 项目上都能稳定工作。唯一需要注意的是如果项目使用了特殊的宏包或字体可能需要额外的编译参数。这种情况下可以在 Skill 里加一个extra_args参数来传递额外参数。8. 写在最后一些个人体会写 Skill 这件事说到底是在“约束”和“灵活”之间找平衡。约束太少AI 不知道该怎么用约束太多Skill 又失去了通用性。我的经验是核心逻辑要严格约束边缘情况要留出灵活空间。另外Skill 的写作是一个迭代过程。第一版写出来能跑通基本流程就行。然后通过实际使用发现哪里不顺手就改哪里。改个三五轮之后Skill 的质量会有明显提升。还有一个容易被忽略的点Skill 的文档不仅是给 AI 看的也是给人看的。团队里其他人要维护这个 Skill 时清晰的描述和示例能省下大量沟通成本。所以写 Skill 的时候不妨把它当成一份“给未来的自己看的笔记”尽量写清楚、写完整。最后分享一个小技巧如果你不确定一个 Skill 该怎么写可以先观察 AI 在没有 Skill 的情况下是怎么完成这个任务的。把它的执行步骤记录下来整理成结构化的描述就是一个 Skill 的雏形。这个方法我试过很多次效果很好尤其是对于流程比较固定的任务。
返回列表