news 2026/10/28 1:58:49

如何写 Skill 番外,你的第一个自定义 agent

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何写 Skill 番外,你的第一个自定义 agent

摘要:同一段盲测提示词,手写到第三遍,我把它固化成了自己的第一个自定义 agent。这篇讲造岗的全套手艺:什么时候该把重复劳动抽象成岗,一份 agent 定义文件的三个读者各读什么,字段拼错和方言差异怎么防,以及 trigger-tester 从需求句到宿主登记回执的可跟跑全程。

共约 4664 字 · 阅读约 12 分钟

老规矩,声明放在最前面:公司、客户和一切可对号入座的身份不出现。标本实名保留——code-architect 和 visual-judge 是本机插件缓存里公开可查的文件,trigger-tester 是我自己写的岗;文中的推算和没验证的账,照实标注。

1、开场:同一张纸条,我写了四遍

本以为二十多天学下来,我的 agent 库多少攒了点存货。实际盘点:~/.claude/agents和~/.zcode/agents两个目录全空,一个文件都没有,机器上跑着的 agent 全部来自插件。二十多天、十二课,我只当过岗的用户,没当过岗的作者。

这周,空目录里落进了第一个文件:我自己写的第一个自定义 agent,trigger-tester。让它发生的不是什么规划,是一张纸条——同一张「触发盲测纸条」,一个月里碰了四遍,前三次手写:

  1. 第 2 课作业盲测五跑,手写第一遍;
  2. 第 9 课搭评测臂,第二遍;
  3. 第 11、12 课工坊六跑,第三遍;
  4. 到这次番外,第四遍,我没再手写,纸条变成了一个文件。

翻笔记对时间,四条记录拉得很开:10 月 5 日、10 月 20 日、10 月 23 日、10 月 25 日。每一遍同构,只往前拱一小步:第一遍只有协议,第二遍加了两臂纪律,第三遍补上靶场路径,第四遍,整张纸条固化成了岗。

skill-creator 的判据,从 skill 侧搬到 agent 侧,一字不用改:

“Look for repeated work… Write it once.”

出处:skill-creator 官方判据。

不造岗的账我也顺手算了:每臂重新手写一遍协议,漏一条——比如环境中立律,臂与臂的环境必须等价——就废一臂。第 9 课那笔污染抓包,追下去就是手写纪律漏了项;一次漏项,一臂数据作废。同一张纸条写到第三遍,就该把它造成岗了。

2、先拆清题:subagent 还剩哪一块

起草前有人问过我两句:「当时是规划了几篇额外的啊?」「应该就是 skill 里关于 subagent 的内容吧,分几篇幅呢?」我的回答是:番外只此一篇。这个追问里藏着一个误会,而且我猜不止问的人有——把「造岗」当成要学一整套 subagent 新体系。拆开看,这个大主题里四样东西,三样前面都过了手:

  1. 派工,Agent 工具怎么调、指令怎么写——第 7 课教过;
  2. 评测装置,差分、串行靶场、环境中立——第 9 课已经在用;
  3. 实战跑批,多臂并发跑真实任务——第 11、12 课工坊六跑干的就是这个;
  4. 自定义,写一份让宿主肯登记的定义文件——四样里只有这个没碰过,本篇全部内容就是它。

只此一篇是裁定过的,理由也直白:subagent 独占的素材只有一课的量,单线养不起第二学期;本机嵌套是零层,机制先瘸了一条腿——那条腿怎么瘸的,第 6 节细说。

误会从哪来的,我复盘过:十二课里,岗一直以「别人的岗」的面目出现,插件的 feature-dev、documents,个个替我干活,看起来像个要整学期才能啃下来的体系。真拆完,你要新学的只有一件事:写一份宿主肯认的定义文件,加一段替你把门的正文。剩下的,是你已经会的东西换个岗位用。

那 skill 和 agent 的分界,官方一句话:

“Consider Skills instead when you want reusable prompts or workflows that run in the main conversation context rather than isolated subagent context.”(如果你想要的是在主对话上下文里跑、而不是在隔离的 subagent 上下文里跑的可复用提示词或工作流,那就改用 Skills。)

出处:官方 Subagents 文档。

skill 卖知识,岗卖隔离。知识进主对话就够用,隔离才是新开会话的理由。判据反过来读也成立:频繁来回、要共享上下文、延迟敏感,占上任何一条,就别造岗。这条分界线,第 7 节造岗时它是主判据。

3、一份定义文件,三个读者

我原以为造岗得先啃一张 19 字段的大表。动笔当天把官方文档现查了一遍:字段确实 19 个,camelCase 命名,但必填只有 name 和 description 两个,其余全是配置项——比我第 7 课备课那回核对时又多出几张新面孔,maxTurns、memory、isolation 这些。字段面还在扩,这更说明全表不用背。全表不进正文,正文只回答一个问题:这份文件写出来,谁在读。

读者有三个,各读各的那一份。委派者(主对话)读 description,这一段常驻上下文,它靠这个决定派不派、怎么派;运行时读 tools、model 这些配置字段,spawn 的第 0 轮装配一次,之后不再看;被委派者(分身)读 body。官方对 body 的说法:

“Subagents receive only this system prompt plus basic environment details like the working directory, not the Claude Code system prompt.”(Subagent 只收到这份系统提示词,外加工作目录之类的基本环境信息,收不到 Claude Code 的系统提示词。)

出处:官方 Subagents 文档。

你在主对话里攒下的一切常识,分身一件都带不过去。body 是分身的全部世界观,不是配置的补充。

拿一次 HTTP 请求打比方:

  • description 是网关路由表里的那一行,决定流量导不导过来;
  • tools 和 model 是部署配置,容器起来时装配一次;
  • body 是服务自己的世界观,它看不见网关的任何配置。

写错读者,各有各的症状:description 写成操作手册,委派者干脆不派;body 写成招聘广告,分身不知从哪儿下手。

三个读者也解释了钱花在哪。description 是唯一常驻的长文字段,主对话走到哪它跟到哪,所以预算关全冲它来,第 4 节细说;body 只在派发后的分身会话里活着,再长也不占主对话一个字。常驻的按字收费,一次性出场的按次收费,这笔账第 4 节就要算。

三层语言观来自另一条追问,有人问我:「这一课还有什么其他语言学习的吗?」有,比想的多。一份定义文件是三种格式语言在协作:

  • YAML 头,给机器的配置;
  • Markdown 正文,自然语言编程,写的不是代码,是分身的世界观;
  • JSON 尾,body 里约定的交卷契约,一行定格式,机器可判分。

这条追问逼出来一句话:你在用自然语言编程。这是本篇最反直觉的一句。语言选择顺带交代:description 和 body 写中文成立——委派者做的是语义领地判断,没有关键词匹配器,这是它大概率成立的理由;trigger-tester 从 description 到 body 全中文,但中文派发会不会命中,这台机器还没跑过一臂,我不替它打包票。跨宿主我没验过,英文更稳是推断,不是实测。

body 的位置我还了一笔旧账:第 12 课终测我把 skill 正文记成了系统提示词——skill 正文是对话层的一条消息,agent body 是系统层,一层之差,这回算把账还上。

4、字段的坑:静默忽略与第四道预算关

字段拼错,官方文档的答案写得很平静:

“ignores a field it doesn’t recognize without reporting an error.”(不认识的字段直接忽略,不报错。)

出处:官方 Subagents 文档。

skill 侧我踩过静默忽略,agent 侧更毒。disallowedTools 这个黑名单字段,误写成 kebab-case 的 disallowed-tools:不报错,无日志,黑名单静默消失,权限面反而变宽。像防火墙规则没加载,端口默认全开,你还以为拦着。skill 拼错丢的是特性,agent 拼错丢的是闸。写对了没人夸,写错了没人骂,全靠自己当场验。

命名规约差异是同族的坑,两处:

  1. 字段名各叫各的:skill 的 allowed-tools,agent 的 disallowedTools;
  2. 命名风格相反:一边 kebab-case,一边 camelCase。

互抄零生效。两边文档我都读过,写这节时还是把两套写法对着核了一遍才敢落笔。

防法只有一个:写完当场验。字段表对一遍只是第一步,真验是派一发看行为——黑名单在不在,分身一试便知。第 7 节的落位体检先过静态一遍,行为要在真派发里见。

预算还有第四道关。skill 侧三道关,第 6 课拆过:

  • 单字段 1024,直接丢弃;
  • 拼接 1536,截断;
  • 菜单呈现,约 250。

agent 侧多一道:description 全库合计超 15,000 tokens,启动警告。量法变了,不是单岗,是全库合计,跟 1536 那道拼接关同族、量纲更大;岗造得越多,每岗分到的预算越薄。

这笔账生态里有人替我算过。GitHub 上 wshobson/agents 一个仓库攒了上百个岗——发文时 100,我检索当日目录已列 202——作者自己回头在 dev.to 发文复盘,标题就叫:

《I Built 100 Claude Code Subagents: The 12 That Actually Earn Their Context》:100 个里只有 12 个配留在上下文。

粗算一下,上百个岗的 description 全装进去,大概率把 15,000 的合计关直接顶爆。先说清楚:这是推算,不是实测。但「岗不在多」这四个字,有算术撑着。

这道关的脾气也温和:超线是启动警告,不是拒绝。可警告意味着账已经超了,薄下去的是每个岗在派发现场的可见度——常驻的东西挤成一堆,委派者挑花眼,谁的 description 都记不牢。

最后一条坑反着来:tools 字段空着不写,不是漏,是继承全部工具。省略也是决策。trigger-tester 正是吃了这条,细节放第 7 节。

5、两份标本,两种 body 哲学

文档讲原则,标本讲手艺。本机插件缓存里正好躺着一对现成教材,我把两份定义文件全文读了一遍,逐字段对质。code-architect,feature-dev 插件,官方出品:5 个字段;tools 一串逗号隔开,无写入、无 Bash(TodoWrite、KillShell 属会话管理类)——白名单即权限面,清单写死,分身伸不出清单外的手;body 是过程型的标准长相,三步流程,后面挂一张输出清单,教「怎么干」,全文件 34 行。

visual-judge,documents 插件:6 个字段,比 code-architect 多出的一个正是 thoughtLevel: max(本机方言,第 6 节细数);tools 是 YAML 列表,收窄到 Read 和 Bash 两件;body 是契约型——验收标准、分类法,末尾一行一页的 JSON verdict。它几乎不教「怎么干」,只规定「交什么」;输出格式本身就是纪律,因为格式是机器判的,含糊不得。

两种哲学不是风格偏好,是任务性质决定的。

  • 探索类任务,路要模型自己走,步骤卡死反而走不动,所以 code-architect 只教原则加输出清单;
  • 验收类任务,要的是可比对的产物,多一句自由发挥都是噪音,所以 visual-judge 把话说到每页一行。

你想学哪一种,先看你的岗接的是什么活。

最有意思的是 description。visual-judge 的 description 写到约 1200 字符,按 skill 侧的标准算超载。我原以为是作者手滑,对完三读者才回过味来:它的读者是委派者,常驻主对话,要在每次派发决策的现场替它说话——写短了,委派者想不起它。

两份标本摆在一起,结论就出来了:body 形态跟着任务走。探索类任务说不死「怎么干」,过程型;验收类任务说得死「交什么」,契约型。判断就一句:description 写给委派者,body 写给分身——前者管何时派、怎么派,后者管怎么干、或交什么。

6、本机方言卡:官方认的,不等于你的机器认的

文档是通用语法,你这台机器说的是方言。我盘出三处,一处比一处扎手:

  • 推理档字段,官方叫 effort,本机叫 thoughtLevel;
  • 落位目录,官方说 ~/.claude/agents,本机读的是 .zcode/agents;
  • 嵌套,官方说岗可以再派岗,默认最多 3 层;本机是 0 层。

前两处照文档写,轻则字段无效,重则文件落错地方没人读。第三处是硬伤,来历要说清:第 7 课差分首跑撞见的,第 9 课又用三跑复验——三次跑,分身的工具清单里都没有 Agent 工具。套娃是零层,子进程里没有再 fork 的能力。

这条直接改了设计。岗只能当臂,当不了指挥;照官方文档设计「岗再派岗」的编排,在这台机器上是死信。指挥逻辑没有消失,它被摁回了主对话:串行还是并发、失败要不要重派,这些决定都由主对话做,装置只负责把每一次派发做干净。trigger-tester 因此是单臂装置:n 条查询,主对话派 n 次,它的 body 里没有任何派工语句。装置固化的是协议,不是自动化编排——主对话当唯一的指挥,岗当纯粹的臂,是这台机器上唯一跑得通的拓扑。

所以可移植写法只剩一条:跨宿主只写共识四字段,name、description、tools、model;方言字段想写,只写给单一宿主,当它是一次性的。生态里真有人这么干:wshobson/agents 那套岗,给 Claude Code、Codex CLI、Cursor 等 7 个宿主各生成一版定义。「同一岗、多宿主方言」不是我的推断,是别人用脚本在养的日常。

7、实战:trigger-tester 从 0 到 1

四遍纸条的最后一遍,不走手写,走固化。下面是全程,可跟跑。

7.1 目标

把盲测纸条变成一个岗。需求句一句写死:每次派发,给分身一条查询,加一句领地说明;分身按自己的常识干活;首个工具调用即判定触发;一行 JSON 交卷。输入一句话,输出一行 JSON,中间不设脚本。不设脚本是刻意的:skill 侧靠脚本锁行为,这里要量的偏偏就是模型裸着拿到纸条后的第一反应,脚本一插手,量的就不是它了。

7.2 思路

先回答为什么是岗不是 skill。盲测铁律:每臂必须全新会话——一防上下文残留,二守环境中立律。上下文残留长什么样,第 2 课见过:上一臂读过文件、试过命令,下一臂在上下文里直接捡现成,盲测就成了开卷考。skill 在主对话内跑,永远做不到自我隔离;agent 每次派发天然全新。我要的恰好就是隔离,判据不用绕,隔离需求本身就是造岗判据的正用。

7.3 实现

按造岗五步走,一列到底:

  1. 需求句一句写死:输入、分身干什么、交什么,一口气说完;
  2. 判据核对:官方判据至少中一,反判据(频繁来回、共享上下文、延迟敏感)任中即止,盲测装置过;
  3. 字段决策:description 写正例,再补三条负边界,什么场景不许派,白纸黑字——比如「只测触发,不评质量」就是一条,评质量是另一套装置的活;tools 刻意省略,盲测臂要的是干净的一般智力,限了工具反而会改变触发概率——「不改文件」也因此只写进 body 红线,没用 disallowedTools 关写闸,关闸会改变分身的工具面,盲测量的是自然状态,这是取舍不是疏忽;model 不写,继承;方言字段一个不写;
  4. body 契约:按纸条自足四件套写——身份、任务、边界、输出格式,纸条外的话等于没说;
  5. 落位体检:必填两个字段齐,camelCase 拼写逐个对,目录写本机读取位——这个岗落的是项目级,<仓库根>/.zcode/agents/,和代码同一个仓;用户级 ~/.zcode/agents 是否同样被读,我没验,不替你打包票。(还有一条「嵌套核对」:本机零层嵌套,第 6 节已交代,这里并进了第 3、4 步——方言字段不写,body 里不写派工语句。)

五步里第 2 步最容易跳。重复劳动没攒到三遍就抽象成岗,是为固化而固化,产物多半没人用。

body 里两条值得单独抄出来。一条是 attempted 判定:环境拒了但判定已发生,照样记触发——第 2 课实测过,分身的环境拒了 Skill 调用,触发判定照样发生,判定和执行必须分家。这一档值得单列:触发率是个分数,分母不能丢:环境拒了执行,判定本身已经发生,丢掉这个样本,分母就偏了。

另一条是红线三道:

  1. 不读被测文件,防泄盲;
  2. 不改文件;
  3. 工具调用不超过 10 次。

三条缺一,盲测就不盲了。第 3 步那三条负边界,则是写给委派者的:它常驻主对话,正例告诉它何时派,负边界告诉它何时忍住——误派一次,盲测数据就脏一组。

7.4 验证

文件落进 .zcode/agents/,宿主给了我一张回执,原样抄在下面:

“New agent types are available: trigger-tester.”

目录写对了没有,不用猜,登记回执就是活证据。第 1 节那笔双空盘点,到这儿改账:盘的是用户级,这个岗落的是项目级,反正是同一本账——agent 库 0→1,第一个岗是我自己的。

至于触发判得准不准,这个岗自己证明不了——它生下来就是给第 9 课那套差分装置当臂的。登记回执只证明宿主认了它;准不准,哪天真拿它跑盲测,一臂就知道。

收尾:带走三样,临走三问

带走三样:

  1. 一条判据:同一张纸条写到第三遍就该造成岗;分界记一句,skill 卖知识,岗卖隔离。
  2. 一套框架:三读者——description 给委派者,body 给分身,配置字段给运行时;字段只写各宿主都认的。
  3. 一张检查单:需求句、判据核对、字段决策、body 契约、落位体检,五步走完,等宿主登记回执。

临走三问,凭记忆答,别往上翻:

  1. 同事这周第三次原样重写同一段派工提示词,而且他不想让这段流程留在主对话的上下文里。抽成 skill 还是造成岗?依据说一条。
  2. 同事的岗派发总不合预期,他把完整的操作步骤全写进了 description,正文反而没话。哪个读者被喂饱了,哪个读者饿着?
  3. 你把岗文件放进了 ~/.claude/agents/,宿主不报错,agent 列表里也没有它。五步检查单里,你先查哪一步?

三道都答对了,这一课才算真的带走。

第 12 课结尾,番外什么时候开留了个活口。今天填上:番外就是这一篇,当时挂的四个模块(固定岗何时造、字段的三读者、system prompt 工艺、trigger-tester 装置)一篇之内都交了。主线十二课,加番外一篇,系列到此全部收官。


如果这篇文章对你有帮助,欢迎转发给需要的同事和朋友。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 1:58:08

高通SA8295P与SA8775P深度对比:智能座舱平台升级,真正改变了什么?

高通SA8295P与SA8775P深度对比:智能座舱平台升级,真正改变了什么? 一、SA8295P和SA8775P为什么值得对比? 高通SA8295P和SA8775P是智能座舱及融合计算领域值得关注的两款汽车级处理器。 SA8295P主要面向高性能智能座舱,包括多屏显示、3D图形渲染、视频编解码、摄像头处理…

作者头像 李华
网站建设 2026/10/28 1:57:38

端子线和线束到底有什么区别?三问分清,报价不跑偏

- **端子线**&#xff1d;一根&#xff08;或几根&#xff09;线&#xff0c;两端压接端子&#xff0c;做成可直接插接的成品线&#xff1b; - **线束**&#xff1d;按图纸把多根线组合起来&#xff0c;可能有分支、护套、包扎、多个连接器的**总成**。一句话&#xff1a;**端子…

作者头像 李华
网站建设 2026/10/28 1:57:24

# 微信小程序 video视频弹幕案例

微信小程序 video视频弹幕案例 一、实验目的 掌握小程序video视频组件的使用&#xff0c;熟悉弹幕发送接口sendDanmu&#xff0c;实现自定义弹幕发送功能&#xff0c;理解视频上下文createVideoContext。 二、核心知识点 <video>组件&#xff1a;danmu-list、enable-danm…

作者头像 李华
网站建设 2026/10/28 1:57:24

【共创稿事节】从手机到 2in1:一个菜谱应用的三断点适配实录

一、为什么个人项目也要认真做适配 个人开发者最容易把"多设备适配"当成大厂的事——反正用户主要在手机上。但 module.json5 里一行 deviceTypes 就决定了你的应用出现在哪些设备上&#xff1a;写了三个设备却只按手机调布局&#xff0c;等于自愿在平板和电脑上呈现…

作者头像 李华
网站建设 2026/10/28 1:56:24

377.组合总和 Ⅳ(背包)

链接&#xff1a;377. 组合总和 Ⅳ - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a; 组合总和 IV dp[i] 目标位i的组合组数是多少 dp[i] dp[i-A0] dp[i-A[1]] .. dp[1-A[n-1]]&#xff0c;枚举所有最后一个数字的可能 class Solution { public:int combination…

作者头像 李华
网站建设 2026/10/28 1:55:33

基于多星座导航信号模拟器的导航大模型端到端定位算法验证方法

摘 要&#xff1a;面向自动驾驶、无人机等安全关键场景&#xff0c;基于深度学习、大模型架构的GNSS智能接收机逐步用于城市遮挡、多径、欺骗等恶劣环境下的定位解算。野外实测方式难以获取带精准真值、参数可控的遮挡与欺骗样本&#xff0c;且场景复现与变量隔离难度高&#…

作者头像 李华