ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent Skills 实战:从零构建可复用 AI 能力模块

Agent Skills 实战:从零构建可复用 AI 能力模块 1. 从skills这个模糊词说起它到底指什么第一次看到skills这个标题加上项目正文和关键词都是空的我其实愣了一下。但结合热搜词里那一串——Agent Skills、Google Cloud、GKE、Genkit、codex skills、claude agent skills——方向就很清楚了这里说的不是泛泛的技能而是给 AI Agent 挂载的能力模块也就是让大模型从只会聊天变成能干活的那一层扩展机制。我把它理解成给一个刚入职的聪明实习生配工具箱。模型本身是那个脑子好使但手无寸铁的实习生skills 就是递给他的螺丝刀、计算器、公司内部手册、报销流程模板。没有 skills他只能凭记忆瞎猜有了 skills他能按你定义的流程一步步把活干完。这套东西最近为什么火因为大家发现光靠提示词堆砌已经到瓶颈了。你把 prompt 写得再长模型该算错还是算错该调不对接口还是调不对。而 skills 的思路是把能力从提示词里剥离出来做成可复用、可版本管理、可组合的独立单元。这跟当年从写死代码到抽函数、抽库是一个道理。这篇文章我打算按一个真正上手做过 Agent Skills 的人的视角来写不讲空泛概念重点讲清楚skills 的底层结构长什么样、怎么从零写一个能跑的、在 GKE 和 Genkit 这类云原生环境里怎么落地、以及我踩过的那些坑。适合已经会用大模型 API、想往 Agent 方向深入的同学也适合团队里要搭内部 Agent 平台的技术负责人。2. Agent Skills 的底层结构为什么是文件夹 说明书而不是一段代码2.1 一个 skill 的最小构成我见过很多人第一次接触 skills以为它是什么高深的框架 API。其实拆开看一个 skill 通常就是一个目录里面至少有两样东西一份描述文件常见是SKILL.md或skill.yaml用自然语言写清楚这个 skill 是干什么的、什么时候该用、输入输出是什么若干可执行资源可能是脚本、模板、参考文档、示例数据为什么是这种文件夹 说明书的形态这里有个很关键的设计哲学Agent 决定要不要用某个 skill靠的是读描述而不是读代码。模型没法高效地理解一大坨 Python 源码来判断这个工具适不适合当前任务但它非常擅长读一段结构化的自然语言说明。所以描述文件本质上是写给模型看的使用说明书而不是写给人看的文档。这就带来一个反直觉的结论写 skill 的描述文件比写它的执行逻辑更重要。我见过功能实现得漂漂亮亮、但描述写得含糊的 skill结果 Agent 死活不调用它或者在该用的时候用了别的。反过来描述写得精准的 skill哪怕内部逻辑很朴素Agent 也能用得很顺。2.2 渐进式披露为什么不要把所有内容塞进一个文件这是我觉得整个 skills 体系里最精妙的一点。一个成熟的 skill 不会把所有细节都堆在描述文件里而是分层层级内容加载时机典型体积第一层名称 一句话简介始终加载几十字第二层完整使用说明、参数、示例被选中时加载几百到几千字第三层详细参考、脚本、大数据集真正执行时按需读取不限为什么要这么设计因为上下文窗口是稀缺资源。如果你有 50 个 skill每个都塞 2000 字说明进去光描述就吃掉十万 token模型还没开始干活上下文就满了。渐进式披露让 Agent 平时只看到技能清单需要哪个再展开哪个这跟人查手册的逻辑一模一样——你不会把整本字典背下来而是需要时翻到对应那页。提示设计 skill 时第一层简介要控制在能一眼判断用不用得上的长度。写太长浪费上下文写太短 Agent 判断不准。2.3 skill 和 tool、function calling 的区别很多人会混淆这几个概念我用自己的话捋一遍function calling / tool偏底层是模型输出一个结构化调用请求你去执行。它解决的是模型怎么把意图表达成机器能懂的调用。skill偏上层是一整套知识 流程 资源的打包。它可能内部用了好几个 tool也可能只是给模型一段操作指南。打个比方tool 是螺丝刀这个物理工具skill 是如何拆装这台洗衣机的完整教程教程里会告诉你什么时候用螺丝刀、用几号头、拧几圈。Agent 拿到 skill 后可能自己决定去调某个 tool也可能只是照着 skill 里的步骤一步步推理。理解这个区别很重要因为它决定了你该在哪一层解决问题。如果只是缺一个查天气的能力写个 tool 就够了如果缺的是按公司规范生成一份合规的周报这种带流程和格式要求的能力那就该做成 skill。3. 从零手写一个能跑的 skill以代码审查助手为例3.1 先想清楚边界再动手写我踩过的第一个大坑就是一上来就写代码结果写出来的 skill 什么都能干一点什么都不精。后来我总结出一个原则——一个 skill 只解决一类任务。假设我要做一个代码审查助手skill。先明确它的边界它负责检查代码风格、找常见 bug 模式、给出改进建议它不负责跑测试、改代码、合并 PR边界清晰之后描述文件就好写了。下面是我实际用的一个简化版结构--- name: code-review-helper description: 审查代码片段检查风格问题、潜在 bug 和可读性输出结构化建议。当用户提交代码并希望获得审查意见时使用。 --- ## 何时使用 用户贴出代码并询问质量、风格、潜在问题时。 ## 审查维度 1. 命名规范 2. 边界条件处理 3. 错误处理完整性 4. 可读性与复杂度 ## 输出格式 按严重程度分级阻塞 / 建议 / 提示注意 frontmatter 里的description这是第一层简介Agent 靠它决定要不要加载这个 skill。我反复改过好几版最后发现把触发场景写进去当用户提交代码并希望获得审查意见时比只写功能描述效果好得多。3.2 描述文件里的触发条件怎么写才准这是实操中最容易翻车的地方。写得太宽Agent 动不动就调用干扰正常对话写得太窄该用的时候不用。我的经验是遵循三要素动作这个 skill 做什么审查代码对象作用于什么代码片段、文件、diff时机什么情况下触发用户明确要求审查或提交代码后询问质量反面例子是只写帮助处理代码相关任务——太泛Agent 会把它当成万能工具。正面例子就是上面那种把动作、对象、时机都点明。还有一个技巧在描述里主动排除不该用的场景。比如加上不用于代码生成、不用于运行测试能显著减少误触发。这跟给函数写清晰的 docstring 是一个道理边界越明确调用越准确。3.3 把执行逻辑拆成模型能跟的步骤skill 的执行逻辑有两种写法一种是纯自然语言步骤让模型自己推理执行另一种是挂脚本让模型调用确定性代码。怎么选我的判断标准是需要精确计算或访问外部系统的用脚本需要判断和灵活应变的用自然语言步骤。代码审查这个例子风格检查其实可以用脚本比如跑个 linter但这段逻辑有没有边界问题这种需要理解语义的就得靠模型推理。所以我的做法是混合描述文件里写清楚先跑 linter 脚本拿到基础问题再基于结果做语义层面的审查。这里有个细节值得说给模型的步骤要写成可执行的动作序列而不是知识陈述。比如不要写代码审查很重要要注意边界条件而要写第一步扫描所有数组访问检查是否有越界可能第二步检查所有除法确认分母非零。前者是知识后者是流程模型跟流程的执行成功率远高于靠知识自由发挥。4. 在 Google Cloud 与 GKE 上落地 skills部署形态与选型4.1 为什么有人把 skill 跑在 GKE 上热搜词里出现了 Google Cloud、GKE、Genkit说明不少团队在考虑把 Agent 和 skills 部署到云原生环境。这背后的动机很实际skill 里的脚本需要隔离执行用户提交的代码、不可信的输入不能直接在主进程跑得放到沙箱容器里需要弹性伸缩Agent 调用量波动大白天高峰晚上低谷用 K8s 按需扩缩容很合适需要统一治理几十个 skill 分散在各处不好管集中部署到集群里能做版本、权限、监控GKE 在这里扮演的角色本质是skill 执行器的运行底座。每个需要隔离执行的 skill可以打包成一个容器通过 K8s 调度。Agent 主进程负责决策真正干重活、碰不可信输入的交给集群里的隔离容器。4.2 Genkit 在其中的位置Genkit 是 Google 出的一个用于构建 AI 应用的框架它把模型调用、工具编排、流程定义这些事做了封装。在 skills 场景里我理解它的价值主要是把 skill 的编排逻辑标准化——你不用自己手写一堆 if-else 来决定调哪个 skill而是用框架提供的抽象来描述流程。不过我要泼盆冷水框架能省事但也会带来抽象泄漏。我见过团队为了用某个框架的优雅写法把本来简单的 skill 逻辑绕成一团。我的建议是先用最朴素的方式把 skill 跑通确认逻辑没问题了再考虑要不要引入框架做工程化。别为了用框架而用框架。4.3 部署形态对比部署方式适用场景优点代价本地进程内个人开发、快速验证零延迟、调试方便无隔离、不安全单容器小团队、skill 数量少隔离够用、部署简单扩缩容粗放GKE 集群多团队、skill 多、流量波动弹性好、治理强运维复杂度高Serverless调用稀疏、突发流量按量付费、免运维冷启动、超时限制选哪种取决于你的 skill 里有没有碰不可信输入的部分。如果有隔离是刚需本地进程内直接排除。如果只是内部用、输入可信那本地跑跑也挺好别过度工程。5. 那些文档不会告诉你的坑5.1 skill 描述写得太聪明反而没人用我早期写描述喜欢用行业黑话觉得显得专业。结果 Agent 经常不调用。后来才明白模型匹配的是语义相似度不是你的专业度。你写执行静态代码分析以识别反模式不如写检查代码里有没有常见的写错的地方。用大白话用用户实际会说的词命中率立刻上去。这个坑的本质是你在写给模型看不是写给同事看。同事懂你的黑话模型不一定。5.2 多个 skill 抢同一个任务当你有十几个 skill 时经常出现两个 skill 都觉得自己该上场的情况。比如代码审查和代码优化两个 skill用户说帮我看看这段代码两个都想响应。解决办法有两个一是在描述里明确划清边界二是给 skill 加优先级或互斥标记。我倾向于前者因为后者是治标。边界清晰是 skill 设计的第一原则如果两个 skill 职责重叠那说明你的拆分方式有问题该合并或重新划分。5.3 脚本执行失败后 Agent 的反应skill 里挂了脚本脚本报错怎么办我见过 Agent 遇到脚本失败后自己编一个结果继续往下走的非常危险。正确做法是在描述文件里明确写脚本失败时必须如实报告不得编造结果。同时脚本本身要做好错误处理把失败原因结构化输出让 Agent 能读懂并决定是重试还是放弃。这一点在涉及数据、金额、外部调用的 skill 里尤其重要宁可失败也不能让模型脑补。5.4 版本管理被忽视skill 是会迭代的。今天改个描述明天换个脚本如果没有版本管理线上行为会莫名其妙变化。我的做法是给每个 skill 目录纳入 git描述文件里带上版本号重大变更时保留旧版本一段时间做灰度。这跟管代码是一个道理别因为它是给 AI 看的就放松要求。6. 从能跑到好用skill 的测试与迭代6.1 怎么测一个 skill 到底行不行skill 的测试跟普通代码测试不一样它测的是Agent 在什么情况下会用它、用得对不对。我通常分三层测触发测试给一批该用和不该用的输入看 Agent 调用决策准不准执行测试确认调用后步骤是否按预期走完结果测试最终产出是否符合质量要求第一层最容易被忽略但恰恰最重要。一个 skill 功能再强Agent 不调用等于零。我会准备一个触发用例集正例反例各几十条每次改描述都跑一遍看误触发和漏触发有没有变化。6.2 用真实任务反推 skill 设计我现在的习惯是先攒真实任务再设计 skill。比如团队里反复出现帮我把这段日志里的错误提取出来并归类的需求出现五六次之后我就知道该做一个日志分析skill 了。这样设计出来的 skill 天然贴合实际描述也好写因为你知道用户会怎么描述这个需求。反过来拍脑袋想出来的 skill往往描述写得别扭因为你自己都没想清楚它到底解决谁的什么问题。6.3 迭代节奏小步快跑skill 的迭代我建议比普通代码更频繁。因为它的核心是描述文件改起来成本低而且效果立竿见影。我经常一天改好几版描述每改一版就跑一遍触发测试看指标变化。这种快速反馈循环是 skill 调优的关键。但要注意每次只改一个变量。同时改描述、改脚本、改示例出了问题你根本不知道是哪个改动导致的。这跟做实验控制变量是一个道理。7. 我对 skills 这套机制的真实看法用了这段时间我最大的体会是skills 的价值不在于技术多新而在于它把给 AI 补充能力这件事工程化了。以前我们靠堆提示词、靠临时拼上下文做出来的东西没法复用、没法维护、没法协作。skills 用文件夹 说明书这种朴素到极致的形态把能力变成了可管理的一等公民。它当然不完美。描述文件的写法还很依赖经验触发准确率做不到百分之百多 skill 协作时的冲突也没有银弹。但这些问题都是工程问题会随着实践积累慢慢有套路。真正让我兴奋的是那个方向当 skill 足够多、足够好Agent 的能力边界就不再由模型本身决定而是由你给它配了多少 skill 决定。这意味着一支小团队也能通过精心设计的 skill 集合让通用模型干出接近专用系统的活。如果你刚开始接触我的建议是别贪多。先挑一个你每天都在重复做的任务把它做成一个 skill跑通、调准、用顺。这一个跑通了后面就是复制粘贴加微调的事。真正难的不是写第一个 skill而是想清楚哪些任务值得被做成 skill——这个判断力只能靠一次次实践喂出来。
返回列表