返回文章列表
/更新于

GEM:从 Agent Skill 到 Gen-AI Expertise Module

如果说 agent skill 解决的是单点任务经验复用,那么 GEM 要解决的是更完整的 AI 能力模块化问题:输入输出契约、模块协作关系,以及面向 UI 的适配定义。

  • AI
  • Agent
  • Architecture
  • Workflow
  • UI

很多人现在说到 AI 能力沉淀,第一反应还是 prompt 或 skill。

这当然没错,但如果你想把 AI 能力真正变成一个可复用、可协作、可产品化的系统单元,只有 prompt 或 agent skill 还不够。

我更倾向于用一个更完整的概念来描述它:

GEM,Gen-AI Expertise Module。

如果一句话概括:

GEM 可以理解为 agent skill 的扩展版本。

它不只是“告诉 agent 该怎么做”,而是进一步把一项 AI 能力沉淀成一个可以被系统调用、被多个模块配合、并且能被 UI 承接的能力模块。

一、为什么 agent skill 还不够

agent skill 很有价值,因为它能把经验、规则、步骤、边界条件和最小命令清单固化下来。

但它主要解决的是一个问题:

  • agent 在执行某类任务时,应该怎么做

这还不等于一个完整的能力模块。

因为一旦你希望这项能力进入真实产品或复杂工作流,你很快就会遇到另外三类问题:

  • 它到底接受什么输入,产出什么输出?
  • 它和其他模块之间怎么配合?
  • 它在 UI 上应该如何被触发、展示和交互?

除此之外,现有 skill 体系还有一个很实际的缺陷:

它通常不支持良好的参数注入。

这点在简单任务里不一定明显,但一旦进入真实项目协作,很快就会暴露出来。

比如我们要求一个前端项目,在工作过程中需要查看另一个“契约项目”的内容。

问题在于:

  • 这个契约项目具体在哪
  • 它的仓库路径是什么
  • 它的接口文档入口是什么
  • 它的 OpenAPI 文件放在哪里

这些信息在不同前端项目里并不一样。

也就是说,这不是一个能被写死在 skill 里的常量,而是一个必须根据当前项目环境动态注入的参数。

再举一个更具体的例子。

假设有一个前端项目里的 skill,要求在分析页面实现时,顺便读取对应后端项目的代码,用来检查:

  • 前后端接口 contract 是否一致
  • 字段命名是否对齐
  • 错误处理和状态语义是否一致

如果这是传统 skill,很容易被写成默认假设:

  • 后端项目就在 ../backend
  • OpenAPI 文件就在某个固定目录
  • 服务代码就在某个固定路径下

但现实里,不同前端项目对应的后端项目路径往往并不一致:

  • 有的前后端在同一个 monorepo
  • 有的是两个独立 repo
  • 有的后端目录叫 server
  • 有的叫 api
  • 有的还需要通过配置文件才能定位

所以这里真正稳定的,不是“后端路径是什么”,而是:

  • 这个能力需要一个“对应后端项目位置”的参数
  • 这个参数必须随项目动态注入

也就是说,这类能力不应该被定义成“去读 ../backend”,而应该被定义成“给我当前项目对应的后端代码位置,我再继续分析”。

如果没有参数化注入能力,skill 往往就会陷入两个问题:

  • 要么把路径、仓库名、接口地址硬编码进去,结果一换项目就失效
  • 要么把说明写得很抽象,真正执行时还是得靠人临场补上下文

这说明很多时候,skill 只能表达“通用经验”,却很难稳定表达“带项目实例参数的可执行模块”。

如果这些都没有定义,那这个能力往往还是停留在“会用的人自己会用”的阶段,而不是系统意义上的可复用模块。

所以,skill 很重要,但很多时候还只是第一层。

GEM 想补上的,正是后面这些系统层定义。

二、什么是 GEM

GEM,Gen-AI Expertise Module,本质上是在 skill 之上再补三层能力定义:

  1. 输入输出定义
  2. 模块之间的协作定义
  3. 适配 UI 的定义

也就是说,GEM 不是只描述“怎么做”,而是同时描述:

  • 这个模块处理什么问题
  • 它需要什么上下文和输入材料
  • 它输出什么结构化结果
  • 它怎么和别的模块衔接
  • 它在产品界面里如何被人使用

这样一来,AI 能力才不再只是一个 prompt 片段或者一段 skill 文本,而是一个可以稳定接入系统的模块。

三、第一层:输入输出定义

这是 GEM 最基础的一层。

如果输入输出没定义清楚,再强的模型、再好的 prompt,最后也很容易变成“看起来做了很多,实际上系统没法稳定接住”。

一个合格的 GEM,至少要把这些事情说清楚:

  • 输入字段是什么
  • 哪些输入是必需的,哪些是可选的
  • 允许接收什么类型的附件、上下文或外部资源
  • 哪些参数需要在运行时按项目注入
  • 输入的粒度是什么,是一句问题、一个文件、一个目录、还是一个 worklist
  • 输出结构是什么
  • 输出里哪些字段是给机器消费的,哪些字段是给人阅读的
  • 如果失败、阻塞或置信度不足,应该怎么返回

也就是说,GEM 需要像 API 契约一样思考自己。

这里“参数注入”非常关键。

还是以前端项目依赖契约项目为例,一个更合理的 GEM 不应该只写:

  • 去查看契约项目内容

而应该把输入显式定义成类似这样:

  • contract_repo_path
  • openapi_spec_path
  • contract_docs_entry
  • frontend_project_path

这样,模块才能在不同项目里复用,而不是每换一个项目就要重写一版 skill。

如果一个模块负责“审查文档结构”,那它不能只说“我会帮你检查文档”,而应该进一步定义:

  • 输入是文档根目录、目标路径、检查范围、验收标准
  • 输出是问题列表、严重级别、定位信息、修复建议、是否通过

只有这样,模块才真正能被其他 agent、其他模块或 UI 稳定消费。

四、第二层:模块之间怎么配合

skill 往往是单模块视角。

换句话说,传统 skill 更像是在提供一个相对独立的能力单元。

这当然有价值,但现实里的复杂任务,往往并不是一组彼此独立的 skill 拼在一起就结束了。

现实是,多个 skill 经常需要相互配合:

  • 一个 skill 的输出,是另一个 skill 的输入
  • 上游 skill 决定下游 skill 有没有足够上下文可用
  • 中间产物的结构,直接决定后续模块能不能稳定消费

也就是说,这些能力很多时候根本无法完全按“独立单元”来设计。

这点很关键:skill 本身也不能被孤立设计。

复杂任务通常不是一步完成的,而是一组多步骤工序:

  • 有前置准备
  • 有中间产物
  • 有多个阶段性输出
  • 有最终交付物
  • 还有过程中需要人确认、系统校验或其他工具补齐的节点

所以真正需要设计的,不只是“某个 skill 怎么写”,而是整个任务链路里:

  • 哪一步应该由 skill 负责
  • 哪一步应该由传统程序负责
  • 哪些中间产物必须结构化交付
  • 哪些判断应该交给 agent,哪些判断应该交给确定性代码
  • 哪些输入输出需要成为跨模块契约

如果不先从整体工序和交付关系出发,只孤立地设计一个个 skill,很容易出现两个问题:一是 skill 之间边界重叠,二是 agent 被迫用自然语言临场解释本该由程序、数据结构或 UI 明确承接的东西。

如果上游输出没有定义清楚,下游就只能靠临场猜测。

如果中间产物没有稳定结构,模块之间就很难真正形成可编排链路。

所以问题不只是“我有没有很多 skill”,而是:

这些 skill 之间有没有被定义成稳定的输入输出关系。

但现实里的复杂任务,通常不是一个模块独立完成的,而是多个模块协作完成的。

所以 GEM 需要显式回答一个问题:

它和其他 GEM 之间到底怎么配合。

这类定义至少应该包括:

  • 自己负责什么,不负责什么
  • 上游模块应该先产出什么给我
  • 我的结果应该交给哪个下游模块
  • 哪些步骤适合串行,哪些步骤适合并行
  • 如果上下游输出不满足要求,应该在哪一层 fail-fast
  • 冲突、缺失或信息不一致时,谁负责收口
  • 多个 agent 共同工作时,每个 agent 对哪些文件、目录或模块有修改权限

最后这一点尤其重要。

如果多个 agent 同时工作,系统必须防止它们修改同一个文件。否则表面上是在并行提效,实际上很容易制造冲突:一个 agent 刚完成的结构调整,可能被另一个 agent 覆盖;一个 agent 依据旧上下文做出的修改,可能和另一个 agent 的新产物互相打架。

所以多 agent 协作不能只定义“谁负责什么任务”,还必须定义“谁可以改什么范围”。

一个 agent 应该只对自己的范围有修改权限。其他 agent 的产出可以作为只读输入、接口契约或下游依赖来消费,但不能随手改。需要跨范围修改时,要么回到统筹层重新分配 ownership,要么通过明确的交接点让对应 owner 处理。

比如一个完整的内容生产工作流,可能会拆成:

  • 一个 GEM 负责选题展开
  • 一个 GEM 负责结构设计
  • 一个 GEM 负责事实核对或一致性检查
  • 一个 GEM 负责格式化与发布适配

如果没有协作定义,这些模块很容易互相覆盖、互相漏接,最后只能靠人临场兜底。

但如果协作关系写清楚,整个系统就会稳定很多。你不再只是“有很多 skill”,而是开始拥有一个可编排的能力网络。

五、第三层:适配 UI 的定义

这是很多 AI 能力沉淀里最容易被忽略的一层,但它其实非常重要。

因为一项能力要真正成为产品能力,最终往往都要进入 UI。

一旦进入 UI,就不能只停留在“后台 agent 知道怎么做”,而必须进一步定义:

  • 用户从哪里触发这个模块
  • 需要用户补哪些输入
  • 哪些参数适合做成表单,哪些适合预设选项
  • 运行过程中要不要展示进度、状态和中间结果
  • 输出结果在界面里怎么展示
  • 哪些结果允许用户修改、确认、回退或重跑
  • 哪些错误要直接暴露给用户,哪些应该被系统内部吸收

换句话说,GEM 不只是 agent 能理解的模块,也应该是 UI 能承接的模块。

例如,一个“生成内容提纲”的 GEM,如果只写成 skill,可能只是:

  • 给定主题,输出结构化提纲

但如果按 GEM 设计,它还应该继续往下定义:

  • UI 上是否有主题输入框、受众选择、风格选择、长度选择
  • 输出是树形提纲、卡片列表还是可编辑文档
  • 用户能否点击某一节继续展开
  • 用户修改后的内容,是覆盖原结果还是作为二次输入继续迭代

这层一旦缺失,AI 能力就很难真正接到产品里,最后往往只能停留在命令行或聊天框里。

现在很多 skill 把一个文件夹当作 workspace,再通过聊天文本、CLI 命令和人交互来完成任务。这种形态当然有它的价值,尤其适合快速实现和低成本复用。

但这并不等于它就是最好的产品设计。

很多时候它只是因为实现简单:文件系统天然可读写,CLI 天然可组合,聊天窗口天然能接收自然语言。但对复杂任务来说,这种交互形态并不总是高效,也不总是足够可理解。

如果任务本身包含多阶段状态、多个中间产物、可视化差异、审批节点、参数选择或回滚重跑,那么针对性设计 UI 往往会显著提高效率:

  • 用表单减少参数歧义
  • 用结构化视图展示中间产物
  • 用状态流展示任务进度和阻塞点
  • 用差异视图辅助人做确认
  • 用明确按钮承接确认、回退、重跑和发布

所以 GEM 里的 UI 定义不应该只是“给这个 skill 包一层界面”,而应该回到任务本身,重新思考什么交互形态最适合人和 AI 一起完成这件事。

六、GEM 的价值,不是更复杂,而是更完整

GEM 不是为了发明一个新名词,而是为了补齐 skill 在系统化落地时的缺口。

skill 更偏向:

  • 经验固化
  • 执行约束
  • 工作流指导

而 GEM 更偏向:

  • 能力模块化
  • 契约化输入输出
  • 多模块编排
  • UI 接入与产品承接

所以可以把两者理解成这样一种关系:

  • skill 是 GEM 的核心组成部分之一
  • GEM 是把 skill 往系统层、产品层再推进一步

也就是说,GEM 并不是要替代 skill,而是把 skill 从“agent 的经验包”升级成“系统可用的能力模块”。

七、真正值得沉淀的,不只是 prompt,而是完整能力单元

很多团队做 AI 沉淀时,最容易卡在一个问题上:

沉淀了很多 prompt,也写了不少 skill,但能力还是难以复用,难以组合,难以接到产品里。

根因通常不是模型不够强,而是沉淀粒度不对。

如果你沉淀的是零散 prompt,那你得到的是零散经验。

如果你沉淀的是 skill,你开始拥有更稳定的 agent 行为。

如果你沉淀的是 GEM,你才真正开始拥有:

  • 可调用的能力契约
  • 可编排的模块协作
  • 可承接的 UI 入口

这时候,AI 能力才更像软件系统的一部分,而不是一堆依赖高手经验才能驾驭的隐性知识。

结语

所以我会把 GEM 理解成这样一个方向:

它是 agent skill 的扩展版本。

它要求我们不只思考“怎么让 agent 做对”,还要继续往前想:

  • 输入输出怎么定义
  • 模块之间怎么配合
  • UI 怎么接住这项能力

当这些层都补齐之后,AI 才不只是会做事,而是开始变成一个真正可复用、可组合、可产品化的能力模块。