跳至正文
来两杯美式
返回

Agent Skill 是快照,快照会腐烂:我把业务流程全部搬到了服务端

By 来两杯美式
发布于

上一篇里,我讲过把存量系统交给 Agent 时,API、Skill、MCP 三层各是什么角色:API 是系统的能力面,MCP 把能力面标准化给 Agent 调用,而 Skill 承载的是「怎么用」——人脑里那套使用方法。

这一篇钻进 Skill 这一层,讲一个我们踩了很久才想明白的问题:

Skill 的默认形态是一份快照,而快照会腐烂。

我们的解法是把 Skill 拆成三部分:一个只有 51 行的「薄壳启动包」、一个服务端能力目录、一份按会话动态下发的领域协议。业务流程一行都不写在 Skill 里。

Agent Skill 薄壳化总结:快照腐烂的三种方式、薄壳-能力目录-领域协议三层架构、三条会话规则与腐烂方式的对应关系

Skill 的默认形态是快照

主流的 Agent Skill(Claude Code 的 SKILL.md、各家 Agent 平台的 Skill / Agent File)大概长这样:

---
name: daily-report
description: 当用户需要记录工作、生成日报时使用……
---

# 日报助手

## 流程

1. 先调用 xxx 工具查询今天的工作素材;
2. 按「背景-动作-结果」结构整理成草稿;
3. 调用 xxx 工具提交,状态为 PENDING 时轮询结果;
4. ……

## 注意事项

- 素材分「工作」和「计划」两类,混合内容要拆分;
- 删除素材前必须向用户确认;
- ……

触发词、流程步骤、工具用法、注意事项,全部打包在一个文件里,安装时落到用户机器上。这个形态对个人工具没问题——你自己写的 prompt,烂了你自己知道。

但当你开始做一个面向一堆用户的 Agent 平台,Skill 由平台维护、装在用户的 Agent 宿主(Claude Code、Codex、公司内部的 Agent 客户端)里运行时,快照形态的问题会一个一个冒出来。

快照腐烂的三种方式

1. 改一次流程,就要所有用户重装一次

日报的生成规则变了、工具的参数 schema 变了、加了一个新的确认步骤——对服务端来说就是改几行代码的事。但流程写在 Skill 里意味着这些知识不在服务端,而在几百个用户机器上的几百份副本里。

你要么发新版 Skill 让所有用户重装(运维成本高、总有人不更新),要么忍受新逻辑和旧副本并存。快照没有「热更新」这个选项。

2. LLM 会「凭记忆」执行旧流程

更隐蔽的问题是第二份副本:Agent 的记忆

Agent 宿主普遍有长期记忆机制(MEMORY.md、CLAUDE.md、自动总结的会话记忆)。用户用了一次日报功能,流程很容易被总结进记忆。下次用户再说「帮我记一下今天的工作」,Agent 大概率不再读 Skill 全文,而是直接按记忆里的流程走——

而记忆里的流程是旧的。你上周改了提交步骤,Agent 记忆里还是上周的。

这不是理论风险。我们在实践里反复观察到:只要协议全文在客户端出现过一次,它就会在你看不见的地方被缓存、被摘要、被复用。LLM 没有「这段指令过期了」的概念。

3. 旧副本等于绕过新权限模型

第三种腐烂最致命。假设你后来收紧了权限:某个写操作现在需要用户确认、某个工具从「所有用户可用」改成了「按角色可见」。服务端工具层的校验当然是新的,但旧协议副本里白纸黑字写着「直接调用 xxx 工具提交」——

Agent 会拿着过期的说明书,去敲新版的门。多数时候会被服务端拦下来(这没问题),但更糟的情况是:旧流程里描述的交互方式(不确认、不询问)和新权限模型对用户的承诺不一致。用户以为删除前会弹确认,Agent 按旧协议直接删了。

把这三条放在一起看,结论其实只有一个:

凡是会被 LLM 当作指令来读的东西,都必须有服务端的单一事实源。

客户端可以有副本,但副本必须短命到不值得缓存——这是我们整个设计的第一性原则。

拆成三层

顺着这个原则,我们把原来「一个大 Skill」拆成了三层:

┌─────────────────────────────────────────────┐
│  薄壳启动包(SKILL.md,51 行)                 │
│  只做能力路由:怎么找能力、怎么拉协议、失败怎么办   │
│  —— 不含任何业务流程                           │
└───────────────┬─────────────────────────────┘
                │ yi_list_capabilities

┌─────────────────────────────────────────────┐
│  服务端能力目录(Capability Catalog)           │
│  能力元数据 + 按当前身份过滤后的可见能力列表      │
│  「你是谁」由 MCP 凭据决定,客户端不用声明        │
└───────────────┬─────────────────────────────┘
                │ yi_get_capability_protocol

┌─────────────────────────────────────────────┐
│  领域协议(服务端 Markdown / 结构化渲染)        │
│  工作汇报怎么做、自动化怎么配——完整流程          │
│  每个会话动态拉取,用完即弃                     │
└─────────────────────────────────────────────┘

一次完整的会话流程是:

  1. 用户说「帮我记一下今天的工作」,宿主按触发词激活薄壳 Skill;
  2. Skill 指示 Agent 调用 yi_list_capabilities,拿到当前身份有权使用的能力目录;
  3. Agent 按目录条目的 whenToUse 选中「工作汇报」能力,调用 yi_get_capability_protocol 拉取完整协议;
  4. Agent 严格按协议执行,协议不落盘、不进记忆;
  5. 会话结束,客户端什么都不保留。下次从第 2 步重新开始。

注意这个拆分带来的职责变化:

快照依然存在(薄壳也是快照),但我们把变化最快的那部分从快照里抽走了

薄壳里装了什么

脱敏后的启动包如下(去掉了内部产品信息,比实际的 51 行略短):

---
name: yi
description: >
  工作助手。当用户需要记录或总结工作、设置提醒和自动化、管理个人工作信息,
  或不确定该使用哪项工作能力时使用。本启动包通过 MCP 能力目录按需加载领域协议。
  触发词:工作助手、工作记录、工作日志、日报、周报、月报、工作总结、
  记录一下、今天做了什么、后续计划、提醒、定时、自动化、定时任务、Cron……
version: 3.0.1
author: assistant-platform
tools:
  - mcp
---

# 小yi(启动包)

你是用户的工作伙伴,是用户工作辅助的唯一入口。本启动包不承担具体业务流程:
它从 MCP 能力目录选择 capability 并动态拉取领域协议,不内置工作日志、自动化等
领域流程副本,也不安装或激活其它 Skill。

## 会话规则

1. 需要日期、时间等基础信息时,直接使用基础 MCP 工具。
2. 调用 `yi_list_capabilities` 获取当前身份实际可用的能力目录;同一会话中
   目录未变化时可以复用结果。
3.`whenToUse` 选择最匹配的 capability;调用
   `yi_get_capability_protocol({ capabilityId })` 获取完整协议。
4. 获取完整协议后,立即严格按该协议完成任务,不再激活或安装另一个 Skill,
   也不凭记忆执行。
5. 不要把任何领域协议写入记忆、本地文件或调用日志;下次需要时重新拉取。

## 能力路由

- 能力 ID、适用场景和协议入口全部以服务端能力目录为准,不在本启动包中硬编码。
- 用户意图仍无法归类时,简要展示能力目录并询问目标,不要擅自执行写操作。

## 权限与降级

- 能力目录只返回当前身份有权使用的能力;目录中不存在的能力不得尝试调用。
- capability 协议或业务工具缺失时,说明权限不足或服务暂不可用;不要绕过 MCP scope。
- 「能加载协议」不代表可以执行所有写操作,仍须遵守对应工具的 scope、确认和审计规则。

## 失败处理

- 能力目录或协议工具不可用时,告知用户「暂时不可达,请稍后再试」,
  不要猜测流程或工具。

51 行里没有一行业务流程,全部是「元规则」。值得逐条说的是三条核心会话规则,它们分别堵住了前面三种腐烂。

规则 4:「严格按协议执行,不凭记忆」

这条直接对应腐烂方式 2。LLM 拿到一份完整流程文档后,天然的倾向是「我懂了」,然后按自己的理解(混着预训练知识和上次会话的残留)自由发挥。规则 4 把「懂了」和「照做」分开:协议是唯一依据,理解力只用于执行协议内的判断,不用于脑补协议外的步骤。

规则 5:「协议不写入记忆、本地文件、调用日志」

这条对应腐烂方式 2 和 3 的根因,也是整个设计里我最想强调的一行。

只要允许协议进记忆,前面说的「记忆里的旧流程」就会重新出现——你把副本从 Skill 里删了,它又从记忆里长出来。所以动态下发必须配一条禁令:协议的生命周期等于会话的生命周期

我们甚至在服务端做了配套:MCP 调用日志对这两个工具显式设置 skipResultData: true,协议全文不进调用日志。否则日志就成了第二个缓存——既是泄密面,也是旧版本的长存地。

规则 2 的后半句:「同一会话中可以复用」

注意我们没有走极端。同一会话内目录不会变(权限变更粒度是分钟级的,会话是分钟级的),重复拉取纯属浪费。这条半句划出了缓存的合法边界:会话内可复用,跨会话必须重新拉。即使目录真的因权限变更而过期,风险也只停在目录层——协议工具在每次调用时都会重新鉴权(下一篇展开),旧目录换不来新协议。工程上的正确答案往往不是「绝不缓存」,而是「给缓存找一个够短的生命周期」。

服务端的镜像:双保险

还有一个现实问题:用户没装 Skill、或装了旧版 Skill 怎么办?

我们的做法是在 MCP 服务端的 instructions 字段里写同样的会话规则。MCP 协议在初始化握手时会把 instructions 交给客户端,等于服务端每次连接都重申一遍「先拉目录、再拉协议、严格照做」。

这样规则存在两份镜像:Skill 里一份(覆盖宿主 Agent 的激活与路由),服务端 instructions 一份(覆盖所有已连接客户端)。旧版 Skill 的用户至少会被服务端 instructions 纠正行为;没装 Skill 的客户端,其 Agent 也能按 instructions 摸到能力目录。

代价是两处规则要同步维护——我们把它记进了平台的工程约定:改会话规则时,SKILL.md 和 instructions 必须一起改,并同步升版本号。

这套设计的代价

诚实起见,也说说不好的地方:

  1. 每个会话多两次工具调用。拉目录 + 拉协议,一次几 KB。对内部平台这个开销可以忽略,但对延迟极敏感的场景要想清楚。
  2. 强依赖服务端在线。服务端挂了,Agent 连流程都不知道,只能按失败规则说「暂时不可达」。快照形态至少还能离线跑旧流程——但如前所述,「离线跑旧流程」本身就是我们想消灭的东西。
  3. 触发词仍是快照。description 里的触发词装在用户机器上,加新触发词依然要用户更新 Skill(我们就发过一次 3.0.1 只为加触发词)。这是接受的残余:触发词的变化频率远低于流程。

小结

把这篇的核心论点压缩成三句话:

  1. Skill 是快照,快照会在用户机器、Agent 记忆、调用日志三个地方腐烂,其中记忆最难防;
  2. 解法是把变化最快的「业务流程」从 Skill 里抽走,做成服务端单一事实源 + 按会话下发;
  3. 动态下发要配套「不缓存」的禁令,否则旧副本会换个地方长回来。

到这里,薄壳这一层讲完了。但还有两个关键问题没回答:能力目录到底返回什么结构、身份过滤怎么做?协议本体为什么选 Markdown?user: 前缀的用户自定义能力又是什么?下一篇讲能力目录与协议下发的接口设计。

本系列下一篇:《能力目录与协议下发:把接口设计和控制流一起交给 Agent》


分享这篇文章:
通过邮件分享这篇文章✓ 链接已复制
查看系列全部文章
  1. 01.MCP Server 选型决策树:从语言到审计,六个维度一次说清
  2. 02.当 MCP Server 只是"翻译"现成能力:FastMCP + Mem0 + Redis 的选型逻辑
  3. 03.当 MCP Server 要"嵌进"对外平台:Node.js + 官方 SDK + API Key 的选型逻辑
  4. 04.SSE 已被 MCP 判为 legacy:存量服务怎么迁、新服务怎么选
  5. 05.MCP 权限怎么分级?只读、可操作和高风险动作(附完整源码)
  6. 06.MCP 工具权限码怎么设计?read、write、dangerous 三层模型(附完整源码)
  7. 07.自建 SearXNG + MCP:给 AI 工具接入可控的网页搜索
  8. 08.Agent Skill 是快照,快照会腐烂:我把业务流程全部搬到了服务端
  9. 09.能力目录与协议下发:把接口设计和控制流一起交给 Agent
  10. 10.四套版本号:把 Agent Skill 的版本管理挪回服务端之后
  11. 11.让用户自定义 Agent 能力,而不打开注入的后门
  12. 12.MCP 2026-07-28 改了什么:从有状态会话到无状态核心
  13. 13.Anthropic 发布 Agent Skills:AI Agent 的能力该如何被打包
  14. 14.Agent Skills 设计模式:用文件夹给 Agent 装上专业能力
  15. 15.Agent Skills 最佳实践:从评测、结构拆分到安全审查
  16. 16.MCP Server 升级 2026-07-28:不是换依赖,而是重画协议边界
  17. 17.MCP Client 升级 2026-07-28:服务端能留兼容窗口,我们偏不兼容旧协议
  18. 18.MCP 爆炸之后,Agent 怎么从一堆工具里选对那一个

上一篇
能力目录与协议下发:把接口设计和控制流一起交给 Agent
下一篇
大模型 vs 小模型,以及一场关于电价的算力战争