Vue中文社区

AI 总跑偏?你写的 Skill 太人话了

我看过不少公司的 Skill 长这样:

markdown

# 处理工单

收到工单后判断类型,分给对应的人,必要时升级。

字面看好像没毛病,但你给 Agent 用,Agent 会一脸懵。

什么叫"判断类型"?类型有哪些?标准是什么?

什么叫"分给对应的人"?分配规则在哪?查谁来定?

什么叫"必要时升级"?什么是"必要时"?升级到哪?

这就是大量企业内部 Skill 的真实状态:写得像给人看的备忘,不是给 Agent 用的程序化指令。

我研究 Hermes Agent 的 Skill 系统、再结合自己看到的企业实践,越来越觉得:Skill 的设计规范,是 Skill Hub 一切治理动作的起点。结构立不住,版本评估、正确率回归、灰度上线,全都没法做。

这一篇我就把"一个可上线的企业级 Skill 应该长什么样"讲透。

Skill 文档 vs 给人看的文档

这张图我一开始还想过用流程图,但其实最直观的就是这种对比:左边是给人看的散文式备忘,右边是给 Agent 用的结构化操作手册。两边写的可能是同一件事,但能不能"被 Agent 稳定执行",差别巨大。

第一原则:Skill 是"给 Agent 用的程序"

我先说一句听起来有点抽象但很重要的判断:

Skill 不是文档,是程序。

你写文档的时候,可以模糊、可以省略、可以靠"读者自己脑补"。比如你写"发版前别忘了同步运营",作者脑子里其实有一整套语境,读者大概能补上。

但 Skill 不一样。Agent 不会脑补。

Agent 会逐字读 Skill,按 Skill 写的步骤执行,按 Skill 写的判断条件分支,按 Skill 写的失败处理方式 fallback。

任何一处含糊,要么 Agent 跳过这一步,要么 Agent 自己编一套,要么 Agent 直接卡住问你。

所以企业级 Skill 的第一原则是:

写 Skill 的时候,要假设这个 Skill 之后会被一个不熟悉业务的实习生 Agent 反复执行。

每一步都得明确。每个判断都得有依据。每个失败都得有 fallback。

一个可上线 Skill 的最小骨架

我把企业级 Skill 的结构沉淀成八块。少一块就会有事故。

markdown

---
name: kebab-case-name
version: 1.0.0
owner: team-or-person
status: active | deprecated | experimental
last_updated: 2026-04-30
tags: [domain, scenario]
required_tools: [git, kubectl, jira-mcp]
required_permissions: [read:repo, write:branch]
---

## When to use
## Do not use when
## Inputs
## Steps
## Verification
## Failure handling
## Pitfalls
## Examples

听起来 8 块挺多,其实每一块都对应一个"如果不写就会出事"的场景。

我一块一块解释。

▎1. 元数据 frontmatter:让 Skill 进入治理体系

很多人写 Skill 直接从内容开始,没有 frontmatter。这意味着 Skill Hub 拿不到任何结构化信息:版本未知、owner 未知、是不是废弃未知、需要什么工具未知。

最低限度,frontmatter 必须包含:

▸name:稳定标识,不允许重名,建议 kebab-case
▸version:语义化版本(后面专门讲版本管理)
▸owner:到具体人或团队,不要写 "platform-team" 这种模糊词
▸status:active / deprecated / experimental,方便检索
▸last_updated:超过 90 天没更新自动告警
▸tags:检索用,比如 release、incident、db
▸required_tools:声明需要哪些 tool / MCP
▸required_permissions:声明需要的权限范围

required_tools 和 required_permissions 是企业里最容易被忽视的两块。但它们直接决定一个 Skill 能不能在生产环境跑:没有声明的工具会导致执行失败,没有声明的权限会被治理层直接拦截。

Skill frontmatter 字段解剖

每个字段都有它对应的治理动作:name 关联检索、version 关联升级路径、owner 关联通知、required_permissions 关联运行时拦截。少写一个字段,对应的那条治理通道就断了。

▎2. When to use:让 Agent 知道什么时候用

这一节最容易被写成"使用场景"。但你看 Hermes 的官方 Skill 模板,会发现它强调的不是"使用场景",而是 触发条件。

差别在哪?

"使用场景"是给人看的,比如:"这个 Skill 用于处理紧急线上故障。"

"触发条件"是给 Agent 用的,比如:

markdown

## When to use

Use this skill when ALL of the following conditions are met:
- The user is reporting a production incident
- The incident has been confirmed in monitoring (not a user-side issue)
- The affected service is one of: payment, checkout, order
- The current on-call engineer is the user themselves

你会发现写法完全不一样。Agent 看到这种写法,会逐条对照当前上下文是否满足,再决定要不要用这个 Skill。

▎3. Do not use when:明确的边界比触发条件更重要

我看过太多事故是这样的:Skill 写了"什么时候用",但没写"什么时候绝对不能用"。Agent 在边缘场景上自由发挥,结果跑出问题。

所以企业级 Skill 一定要有明确的"反向触发条件"。比如:

markdown

## Do not use when
- The user is in a sandbox or test environment but asks for prod-level checks
- The action would touch the payment flow without explicit user confirmation
- The on-call schedule shows another engineer is actively handling the incident

这一节本质上是 Skill 的"禁飞区"。Hub 里所有涉及生产数据、支付、用户隐私、批量改动的 Skill,必须显式声明禁飞区。

▎4. Inputs:把模糊的"上下文"变成显式参数

很多 Skill 不写 Inputs,导致同一个 Skill 在不同调用方身上表现完全不同。

比如一个"代码评审 Skill",A 团队默认要看安全漏洞,B 团队默认要看性能。如果不显式写 Inputs,Agent 只能靠对话上下文猜,猜错了就翻车。

正确写法是把上下文显式参数化:

markdown

## Inputs
- repo_path (required): absolute path to the local repo
- review_focus (optional, default="general"):
  - "general" – correctness, readability
  - "security" – vulnerability scan
  - "performance" – hot path analysis
- target_branch (optional, default="main")

显式 Inputs 还有一个隐藏好处:未来 Skill Hub 做评估时,可以直接拿 Inputs 当测试参数。

▎5. Steps:可执行、可检查、可失败的步骤

这是 Skill 的核心。我看过的"差 Skill"几乎都死在 Steps 上。

差的写法:

markdown

1. 拉代码
2. 跑测试
3. 部署

好的写法(每一步都是可执行单元):

markdown

1. **Pull latest code**
   - Run `git pull --rebase origin main`
   - If rebase has conflicts, abort and notify the user
   - Verify HEAD matches remote with `git status`

2. **Install dependencies if lockfile changed**
   - Compare current lockfile hash with last successful build
   - If different, run `pnpm install --frozen-lockfile`

3. **Run quality gates in this order**
   - `pnpm lint` – must pass
   - `pnpm typecheck` – must pass
   - `pnpm test` – must pass
   - `pnpm build` – must pass
   - If any step fails, stop and report which step failed

每一步要满足三个条件:

  1. 可执行
    :写明确的命令或工具调用,不要写"做某事"
  2. 可检查
    :写清楚成功/失败的判断条件
  3. 可失败
    :失败之后明确该做什么,是停止、跳过还是 fallback
Skill Steps 的三要素

我特别强调"可失败",因为这是新手最容易忽略的。Agent 一旦在中间一步出错,没有失败处理就会瞎补救,最后越补越糟。

▎6. Verification:怎么知道这次执行真的成功了

Verification 是一个被严重低估的部分。

很多 Skill 写完 Steps 就完了。Agent 把命令跑完一遍,然后宣布"完成"。

但"命令成功执行" ≠ "任务真的完成"。

举几个反例:

▸pnpm test exit 0,但其实跳过了一半测试
▸git push 成功,但 push 到了错的分支
▸kubectl apply 成功,但 Pod 还没真正起来
▸curl 200,但返回的是缓存页面

所以企业级 Skill 必须显式写 Verification。比如:

markdown

## Verification

After completing all steps, verify:
- `git log -1` shows the expected commit hash
- The CI run on the new commit is green within 5 minutes
- The deployed pod count matches replicas declared in manifest
- The health check endpoint returns 200 with the new build hash

If any of these fail, do NOT report success.

Verification 是 Skill 走出"我跑完了"和"我做对了"的分水岭。

▎7. Failure handling:失败之后该干嘛

每一个企业级 Skill 都必须假设:"这一步是会失败的。"

失败处理至少要回答三件事:

  1. 哪一步失败的?
  2. 已经做到什么状态?
  3. 接下来该做什么(重试 / 回滚 / 通知人)?

markdown

## Failure handling

If any step fails:
1. Capture the failed step name and error message
2. Snapshot current state:
   - Current git HEAD
   - Local uncommitted changes
   - Last 50 lines of relevant logs
3. Decide recovery action:
   - lint/typecheck/test failure → report and stop, do not deploy
   - build failure → check if cache is stale, retry once with clean cache
   - deploy failure → run `kubectl rollout undo` and notify on-call
4. Always leave the working tree in a recoverable state

这一段非常关键。后面我们讲 Skill 稳定性评估和回滚机制时,全都依赖 Skill 自己有"知道怎么收拾烂摊子"的能力。

▎8. Pitfalls 与 Examples:把踩过的坑写进 Skill

这一节是 Skill 越用越聪明的体现。

每一次 Skill 在线上踩了坑,都应该把坑沉淀回来。比如:

markdown

## Pitfalls

- ❌ Don't run `pnpm install` without `--frozen-lockfile` in CI; it silently bumps versions
- ❌ Don't deploy on Friday after 16:00 unless explicitly approved
- ❌ Don't trust local `pnpm test` if `node_modules` is older than 24h; reinstall first
- ❌ Don't assume the user knows the staging URL; always print it explicitly

Examples 部分则用"对话片段 + 期望行为"的方式给 Agent 一个参照:

markdown

## Examples

### Example 1: 标准发版

User: "帮我发版到 staging"
Agent: 检查工作树 → 跑全套测试 → build → 部署 staging → 提示需要人工 QA 的页面

### Example 2: 发版前发现脏工作树

User: "帮我发版"
Agent: 发现未提交变更 → 列出变更文件 → 询问用户是否要 stash → 不要自动 commit

一个完整 Skill 模板,可以直接拿去用

把上面 8 块串起来,就是一个能立刻在企业里上线的 Skill 模板。

markdown

---
name: frontend-release-check
version: 1.0.0
owner: zhang@team-frontend
status: active
last_updated: 2026-04-30
tags: [release, frontend, ci]
required_tools: [git, pnpm, kubectl, vault-mcp]
required_permissions: [read:repo, write:branch, read:vault]
---

## When to use
Use when ALL conditions are met:
- The user explicitly asks for a frontend release
- The target environment is one of: staging, prod
- The current branch is `main` or a release branch

## Do not use when
- The user is on a feature branch and hasn't merged to main
- The change touches `pages/payment/*` without QA sign-off
- It's after 16:00 on Friday in production environment

## Inputs
- environment (required): staging | prod
- skip_qa_check (optional, default=false)

## Steps
1. **Pull and verify clean tree**
2. **Install deps if lockfile changed**
3. **Run quality gates: lint → typecheck → test → build**
4. **Pull env vars from vault**
5. **Deploy and wait for rollout**
6. **Run smoke tests**

## Verification
- `kubectl rollout status` reports success
- `/healthz` returns 200 with the new commit hash
- All declared smoke tests pass

## Failure handling
- Quality gate failure → stop, report
- Build failure → retry once with clean cache
- Deploy failure → rollout undo, notify on-call
- Smoke test failure → rollout undo, snapshot logs, notify on-call

## Pitfalls
- ❌ Never deploy with uncommitted changes
- ❌ Never deploy if last test run is older than 1h
- ❌ Always verify staging URL before claiming success

## Examples
(略:见 examples 目录)

这个模板看着复杂,但写完一次之后,组织里所有发版动作都可以以它为基线。

怎么判断你的 Skill 是不是"可上线"

我把这个判断浓缩成一份 8 条 checklist:

#
检查项
判断
1
frontmatter 完整且有 owner
Y / N
2
触发条件具体到可对照
Y / N
3
显式声明了禁飞区
Y / N
4
Inputs 有默认值与类型说明
Y / N
5
每一步都可执行、可检查、可失败
Y / N
6
Verification 写明了怎么算成功
Y / N
7
Failure handling 覆盖主要失败场景
Y / N
8
Pitfalls 至少写了 3 条踩过的坑
Y / N

8 条全 Y 才是企业级可上线的 Skill。

少一条都先别进 Hub。

企业级 Skill 8 条上线清单

这张图我建议你截图保存。后面写 Skill 之前对照一遍,能省掉一半的返工。

我的判断

很多人写 Skill 的时候,第一反应是"AI 反正聪明,写糙一点没事"。

但企业里 AI 落地真正的痛,从来不是 AI 不够聪明,而是 AI 不够稳定。

不稳定的根源,往往不在模型,而在 Skill 写得不规范:

▸触发条件含糊,导致 Skill 在不该用的时候被用
▸Steps 没写清判断条件,导致 Agent 自己脑补
▸没有 Verification,导致"看起来成功"
▸没有 Failure handling,导致出事之后越补越糟

把 Skill 当成"程序"来写,而不是当成"备忘"来写,是企业级 AI 系统迈向可治理的第一步。

下一篇我会接着讲:写完 Skill 之后,怎么管它的版本——尤其是 v1 改 v2,如何避免"越改越差"。

▎可进一步阅读

▸Hermes Agent Skills 模板:https://hermes-agent.nousresearch.com/docs/user-guide/features/skills
▸Anthropic:Effective tool use with Claude(关于 schema 和指令明确性的部分)