此前给网站发布一篇带插图的文章时,本地构建和已有检查都通过了,部署到预览环境后,正文图片却打不开。Markdown 里的相对路径被保留在 HTML 中,图片文件没有进入部署产物。改由构建阶段处理图片、输出部署资源,再检查预览页上的图片确实能解码,问题才算解决。

这类失败很适合拿来检验 Skills:操作说明里写了“运行测试”,究竟要求 Agent 证明什么?

The Pragmatic Engineer 于9月17日发布的《AI Skills with Matt Pocock》,用访谈要点整理了 Matt 关于技能、上下文与交付证据的看法。他强调用工程方法指导 Agent,并没有承诺一份 Skill 能包办质量。

这份整理文提出了一个值得继续追问的方向:经验可以封装复用,但执行条件和验收标准,如何跟着不同项目一起维护?前端、数据、排障与发布,对“做对了”的要求并不相同。以下用公开规则包作工程对照;除开头的网站实案外,其余场景都是方法示例,不是厂商的实测报告。

把工程知识接到一个小任务上

Agent Skills 开放规范规定,技能至少包含一个 SKILL.md:开头是 name、description 等元数据,后面写操作指令,还可以配脚本、参考文档和其他资源。按需加载能减少无关内容的前置负担,但如何发现和选择 Skill,仍取决于宿主实现。

对工程任务而言,先把适用范围写清楚,比把描述写得无所不包更有用。“优化前端”很宽;“排查页面数据加载瀑布与包体积,不处理业务权限变更”,才开始交代它该接什么工作。

调试记录应能区分:选中了哪份 Skill,读取了哪些依据,实际调用了什么工具,最后验收了什么。读取记录只能证明文件被打开,不能证明约定已被正确执行。没有相应记录时,也不能猜测模型一定读过。

整理文提到 Matt 借用 tracer bullets 的思路:先跑通一条小而完整的路径,让层与层之间的连接尽早接受检验。这条方法可以写进 Skill,但能否在当前项目里跑通,仍要看接口、测试数据和工具是否齐全。技能作者整理了操作顺序,项目维护者还需要说明这次执行的具体条件。

例如,入口保留适用范围和执行顺序,细节按任务取用:

frontend-performance/
├── SKILL.md
├── references/data-loading.md
└── scripts/check-build.mjs

这是组织示意,不是可直接安装的实现。参考文件需要对应项目技术栈,脚本也要按实际构建方式编写。一个目录本身还没有证明任何性能收益。

工程证据示意:前端、数据、排障与发布需要不同的上下文和验收产物

前端:先画请求依赖,再改 await

Vercel 的 React 规则包把异步瀑布与包体积列为重点。其中的并行规则带着一个重要前提:异步操作之间没有相互依赖。

设想一个报表页面,现有代码先查询摘要,完成后再取趋势。若彼此独立,可以考虑并发。确认查询参数、身份和访问范围后,示意代码可以写成:

// 示例:两项查询互不依赖,且都使用已确认的访问范围
const [summary, trend] = await Promise.all([
  loadSummary(scope),
  loadTrend(scope),
]);

但如果后一项必须使用前一项返回的标识,或者请求涉及授权结果、速率限制和共享资源,机械地替换为 Promise.all 就可能出错。并发也会改变失败处理:其中一项拒绝时,聚合 Promise 会拒绝,另一项已经启动的操作并不会因此自动取消。界面是否允许部分数据先展示,需要另作设计。允许部分成功时,可以用 Promise.allSettled 分别处理结果;确需中止请求,则要使用底层操作支持的取消机制。

因此,这个 Skill 应先取得组件代码、数据依赖和请求时序,再决定改什么。验收也应回到同一页面、同一数据条件:请求是否还在无意义地排队,加载与错误状态是否正确,权限边界有没有变化。

包体积优化同理。把一个大型依赖改成动态加载,可能减少初始加载负担,却把等待移到了用户点击之后。对首屏必需组件与低频打开的编辑器,取舍可以不同。构建分析和浏览器时序应说明等待移到了哪里,而不是只报告代码里多了一个动态导入。

验收这次前端改动,也可以回查 Playwright trace。前提是已经记录轨迹,再借助 Trace Viewer 查看动作、DOM 快照及网络、控制台信息。它让检查更容易回溯,但仍需要明确断言:页面能打开,与核心功能可用,各自应有什么证据。

前端 Skill 的交付可以是一次有边界的修改,加上修改前后的请求与构建记录。 若没有可比较的测量,就先报告代码层面的变化,不把规则包里的提速倍数移植到自己的项目上。

数据与后端:查询要快,也要查对

Supabase 的 Postgres 规则包涉及查询、索引、连接与安全等内容。对慢查询,Skill 可以帮助 Agent 找到相关规则;具体是否要改,仍取决于表结构、数据分布和真实负载。

以报表导出为例,输入不能只有一段 SQL。还应包含查询参数、现有索引、表规模、结果要求,以及执行身份可见的数据范围。测试时需要判断筛选是否生效、无权限用户是否被拒绝,并检查允许导出的用户有没有拿到超出可见范围的数据。

性能侧可以先看执行计划。EXPLAIN 给出规划器的估计,带 ANALYZE 的形式会实际执行语句并收集运行信息。两者不能当成同一种只读说明。尤其是写语句,不能未经安排就在生产环境中“顺手分析”;即使是查询,也可能消耗大量资源。实验应有受控环境、代表性数据和明确的执行范围。

加索引也需要看条件。返回很大比例的数据时,顺序扫描可能是合理选择;新索引会占用空间,也增加写入维护。查询变快以后,还要检查估计行数与实际行数的差异、参数变化下的计划,以及是否把成本转移给写入。

数据库 Skill 的交付,应保留同一查询在可比较条件下的计划、耗时和结果校验。一个 CREATE INDEX 还没有交代这些变化。“用了索引”是一种执行现象,“满足业务要求且成本合理”才是工程判断。

同样的思路可以延伸到异步任务。假如导出被改成后台作业,前端提交任务后轮询结果,就要追问失败后能否重试、重复请求会产生几个文件、状态写入与文件生成中断时如何恢复。

这里可以设计业务幂等标识、任务状态和重试检查,但不能仅凭加了一个幂等键,就宣称整个流程恰好执行一次。Skill 应指导 Agent 在测试环境中构造重复提交、超时与中途失败,观察最终数据和文件是否符合约定。请求返回正常,只覆盖了链路中的一小段。

排障:把错误连回对应版本的代码

Sentry 的公开 sentry-debug-issue 技能,会引导 Agent 获取错误堆栈、breadcrumbs、trace 和日志等上下文,再与本地代码对照。它也明确把自动根因分析视作需要验证的假设。

假设一次发布之后,报表下载开始出现错误。只把堆栈末行交给 Agent,很容易得到一个局部补丁:某个字段为空,就给它默认值。但这个空值可能来自接口约定改变、旧缓存,或任务状态尚未完成。默认值可能消除异常,也可能让错误的数据继续流下去。

排障 Skill 需要把问题约束到具体事件、环境和版本:哪类请求失败,是否从某次变更之后开始,相关调用链做过什么,本地检出的代码能否对应堆栈。时间上的先后只提供线索,不能独自证明某次部署就是原因。

监控告警也不一定带有异常堆栈。一次定时任务漏跑,或某项指标超过阈值,需要查的是调度和指标上下文。若工具没有返回某种证据,就应记录缺口,不能为了套流程拼出一个不存在的调用栈。

修复前可以用合成样本保留一条能触发问题的回归用例,修复后重跑,再观察对应版本的事件是否继续出现。观察期短、流量不足或环境不同,都应影响结论。告警数量变成零,也可能是流量没来或采集出了问题,不能单看一个数字宣布根治。

在这种任务里,日志和用户输入还可能夹带秘密或无关个人信息。排障所需的字段要经过筛选,测试用合成样本表达故障条件。把整包生产事件原样塞进提示词、报告或测试夹具,不会自动让排查更准确。

发布:检查用户真正拿到的产物

开头那次图片故障,发生在代码之外的一段连接上:正文引用正确、HTML 能生成,但部署包没有对应资源。检查范围停在构建退出码,错误就被放过了。

后来补上的检查分成两层。构建后,遍历生成页面的本地图片引用,确认部署目录里有文件;部署后,再在预览页面里验证图片确实能够加载、解码。两层检查回答不同的问题:文件有没有被打包,以及服务端最终有没有把正确资源交给浏览器。

一个发布 Skill 可以把这类约定组织起来:先读取项目的构建命令、产物目录、环境配置与关键路径,再选择验收项目。对内容网站,可能是正文、图片、跳转和站点地图;对服务端接口,可能是一个受控请求的状态码、响应内容与相关副作用。

版本也必须对得上。刚测试过的提交,若又增加了代码,旧的绿色结果不能自动覆盖新改动。实际部署了哪个版本、使用哪些配置、检查的是哪个环境,都应进入记录。

如果发布同时包含数据库结构变化,还需要考虑新旧应用是否能与结构变更兼容,以及失败后怎样恢复。回滚应用镜像不必然撤销数据变化。对可逆性有限的操作,Skill 应先取得恢复安排和所需授权,再由受控工具执行,不能把“失败就回滚”当作已经解决的问题。

必须满足的发布条件,应成为项目流水线或审批机制的一部分;Skill 则指导 Agent 准备输入、理解失败和整理证据。运行环境里的权限限制仍要独立生效。SKILL.md 中的一句“只读”,无法自动改变数据库连接或发布凭证的权限。

用工程产物衡量 Skill 的价值

这些实践不需要塞进同一份巨型 Skill。前端性能、数据库检查、事件排查和发布验收,可以共享项目入口,但各自维护有边界的参考资料与脚本。

能否持续复用,要看项目改变后是否仍然适用:框架版本换了,旧规则是否还成立;迁移方式改了,脚本是否同步更新;换一个 Agent 接手,能不能找到相关资料和上一次检查对应的版本。

原文整理了 Matt 对交付证据的重视。这个要求还需要落到不同的工程对象上:前端看请求和交互,数据库看计划与结果,排障看复现和回归,发布看真实环境中的产物。一个测试全部通过的记录,只有连同输入、范围和版本,才便于后来的人判断它说明了什么。

比较 Skill 修改前后的效果时,也应固定一组代表性任务,记录模型、工具和代码版本,区分选错技能、漏读依据、工具失败和验收未通过。少量成功可以提供下一轮改进的线索,不足以证明普遍可靠。

Skills 的复用价值,取决于执行条件和验收证据能否随项目一起维护。 下一次换一个模型、更新一套依赖,技能包里的经验仍然可以提供方向,但旧的通过记录需要重新确认。值得留下的是能找到依据、复现问题、核对结果的工程知识;项目要对自己的交付作出判断。

原文:The Pragmatic Engineer,《AI Skills with Matt Pocock》。点击阅读原文。