技能库与终身学习:Voyager


文档摘要

技能库与终身学习:Voyager 本节摘要:每次会话都从零重建所有能力的 Agent 有三宗错:每个任务都重新 eliciting 同样的推理,浪费 token;会话 A 学到的修正传不到会话 B,进步丢失;复杂任务需要能力层次,一次性提示表达不出。Voyager(Wang 等人, TMLR 2024)的回答是——把每个可复用能力当作一块命名的代码存进库,可按相似度检索、可与其他技能组合、可被执行反馈精炼。它的三个组件是:自动课程(好奇心驱动的任务提议器)、技能库(成功时写入、按描述相似度检索)、迭代提示机制(失败时把错误与环境反馈回灌精炼)。关键设计是动作空间 = 代码——Agent 不发原始命令,而是发可组合的 JavaScript 函数。

技能库与终身学习:Voyager

本节摘要:每次会话都从零重建所有能力的 Agent 有三宗错:每个任务都重新 eliciting 同样的推理,浪费 token;会话 A 学到的修正传不到会话 B,进步丢失;复杂任务需要能力层次,一次性提示表达不出。Voyager(Wang 等人, TMLR 2024)的回答是——把每个可复用能力当作一块命名的代码存进库,可按相似度检索、可与其他技能组合、可被执行反馈精炼。它的三个组件是:自动课程(好奇心驱动的任务提议器)、技能库(成功时写入、按描述相似度检索)、迭代提示机制(失败时把错误与环境反馈回灌精炼)。关键设计是动作空间 = 代码——Agent 不发原始命令,而是发可组合的 JavaScript 函数。本节吃透 Voyager 三组件、为什么用代码做动作、技能的检索与组合、失败驱动的精炼循环,并用标准库从零实现一个带注册/检索/组合/精炼的技能库。读完本节,你应理解 2026 年 Claude Agent SDK 技能与 skillkit 生态背后的同一个 Voyager 骨架。

对应原课程:Phase 14 · Lesson 10 · skill-libraries-voyager(原英文 phases/14-agent-engineering/10-skill-libraries-voyager/docs/en.md)。

学习目标

阅读完本节,你应当能够:

  1. 说出 Voyager 的三个组件——自动课程、技能库、迭代提示——以及各自的作用。
  2. 解释为什么 Voyager 把动作空间设为代码,而不是原始命令。
  3. 用标准库实现一个技能库:注册、检索、组合、失败驱动的精炼。
  4. 把 Voyager 模式映射到 2026 年 Claude Agent SDK 技能与 skillkit 生态。
  5. 诊断技能库腐烂、组合技能漂移、检索质量退化三大反模式。

一、问题与直觉

每次从零开始的 Agent 有三宗错

  1. 浪费 token —— 每个任务都重新 eliciting 同样的推理。
  2. 进步丢失 —— 会话 A 学到的修正,传不到会话 B。
  3. 长程组合失败 —— 复杂任务需要能力层次,一次性提示表达不出。

Voyager 的回答:把每个可复用能力当作一块命名的代码存进库,可按相似度检索、可与其他技能组合、可被执行反馈精炼。

三个组件

Voyager(arXiv:2305.16291)把一个 Agent 围绕三件事组织:

  1. 自动课程(Automatic Curriculum) —— 一个好奇心驱动的提议器,根据 Agent 当前技能集与环境状态挑下一个任务。探索是自底向上的。
  2. 技能库(Skill Library) —— 每个技能是可执行代码。任务成功时新增技能。技能按「查询到描述」的相似度检索。
  3. 迭代提示机制(Iterative Prompting Mechanism) —— 失败时,Agent 收到执行错误、环境反馈、自验证输出,据此精炼技能。

Minecraft 评测(Wang 等人, 2024):独特物品多 3.3 倍、石制工具快 8.5 倍、铁制工具快 6.4 倍、地图穿行长 2.3 倍。数字是 Minecraft 特定的,但模式可迁移。

动作空间 = 代码

大多数 Agent 发原始命令。Voyager 发JavaScript 函数。一个技能长这样:

async function craftIronPickaxe(bot) { await mineIron(bot, 3); await mineStick(bot, 2); await placeCraftingTable(bot); await craft(bot, 'iron_pickaxe'); }

由子技能组合而成。按键为描述与嵌入存储。作为程序而非提示被检索

这就是 2026 年 Claude Agent SDK 技能:一块命名、可检索的代码加上说明,Agent 按需加载。

💡 设计要点:为什么是代码不是命令?命令是瞬时的——「挖三块铁」是一次性动作,下次还得重新规划。代码是可复用、可组合、可版本化的——craftIronPickaxe 一旦写好并存库,下次「做钻石镐」就能直接复用 mineIronplaceCraftingTable。代码把 Agent 的学习从「单次推理」升级为「累积的程序库」。这也是为什么技能库是**程序记忆(Procedural Memory)**的最佳载体(对照第 07 节四类记忆)。

技能检索

新任务「做一把钻石镐」。Agent:

  1. 把任务描述嵌入。
  2. 查技能库取 top-k 相似技能。
  3. 检索出 craftIronPickaxemineDiamondplaceCraftingTable 等。
  4. 从检索到的原语 + 新逻辑组合出新技能。

这正是第 13 章 MCP 资源和 Agent SDK 技能实现的模式:在一个知识/代码面上做检索,限定在当前任务范围内。

迭代精炼:自我精炼 + 环境验证

Voyager 的反馈循环:

  1. Agent 写一个技能。
  2. 技能跑向环境。
  3. 三种信号之一返回:successerror(带堆栈)、self-verification failure(自检失败)。
  4. Agent 用这个信号作为上下文重写技能。
  5. 循环直到成功或达到最大轮次。

这是自我精炼(Self-Refine,第 05 节)应用到代码生成,以环境接地验证为准。CRITIC(第 05 节)是同一模式,只是把外部工具当验证器。

课程与探索

Voyager 的课程模块会基于「Agent 有什么、还没做什么」提议任务,如「在湖边建个庇护所」。提议器用环境状态 + 技能清单,挑一个刚好在当前能力之上的任务——探索的甜区。

对生产 Agent,这翻译成一个「缺什么」算子:给定当前技能库与一个领域,我们还缺哪些技能?团队通常把这件事手动做成课程评审。

这个模式在哪里出错

  • 技能库腐烂(Skill Library Rot) —— 同一技能被加 10 次,描述略有不同。对策:写入时去重,检索只返回一份。
  • 组合技能漂移(Composed-Skill Drift) —— 父技能依赖一个被精炼过的子技能。对策:给技能做版本,固定在 v1 的父技能不会神奇地吃下 v3。
  • 检索质量退化(Retrieval Quality) —— 技能描述上的向量检索,在库长到几百以后退化。对策:补标签过滤与硬约束(「只要 category=tooling 的技能」)。

二、从零实现

原课程 code/main.py 用标准库实现一个技能库:

  • Skill —— name、description、code(字符串)、version、tags、dependencies。
  • SkillLibrary —— register、search(token 重叠)、compose(依赖拓扑排序)、refine(更新时版本号 +1)。
  • 一个脚本 Agent:注册三个原语技能、组合出第四个、撞上失败、精炼。

核心骨架如下,用伪代码展示。

Step 1:技能对象

class Skill: def __init__(self, name, description, code, tags=None, deps=None): self.name = name self.description = description # 检索的关键:嵌入的就是它 self.code = code # 可执行代码串 self.version = 1 self.tags = tags or [] self.deps = deps or [] # 依赖的其他技能名

Step 2:技能库(注册 + 检索 + 组合)

class SkillLibrary: def __init__(self): self.skills = {} # name -> Skill def register(self, skill): # 写入去重:描述高度相似则合并 dup = self._find_dup(skill.description) if dup: return f"已存在近似技能 {dup}" self.skills[skill.name] = skill return f"已注册 {skill.name}@v1" def search(self, query, top_k=3): qtok = set(query.lower().split()) scored = [(len(qtok & set(s.description.lower().split())), s) for s in self.skills.values()] scored.sort(reverse=True, key=lambda x: x[0]) return [s for _, s in scored[:top_k] if _ > 0] def compose(self, name, deps, new_code): # 依赖拓扑排序,检测环 order = topo_sort(deps, self.skills) # 有环则抛错 combined = "\n".join(self.skills[d].code for d in order) + "\n" + new_code skill = Skill(name, f"组合自 {deps}", combined, deps=deps) self.register(skill) return skill

Step 3:失败驱动的精炼

def refine(library, skill_name, error_signal): skill = library.skills[skill_name] # 用错误信号作为上下文,让 LLM 重写 code new_code = rewrite_with_feedback(skill.code, error_signal) skill.code = new_code skill.version += 1 # 版本号 +1,父技能不会自动跟随 return f"{skill_name}@v{skill.version}"

运行 python3 code/main.py 会展示库写入、检索、组合、一次失败执行、一次 v2 精炼——Voyager 的循环端到端跑通。

💡 设计要点:compose() 的拓扑排序与环检测是承重的。技能依赖构成一个 DAG,一旦出现环(A 依赖 B,B 依赖 A),执行就会无限递归。生产里这步必须显式,而且要在注册时就拦住,不是等运行时崩。

三、框架对比

  • Claude Agent SDK 技能(Anthropic)—— 2026 年参考实现:每个技能有描述、代码、说明,在 Agent 会话中按需加载。
  • skillkit(npm: skillkit)—— 跨 Agent 的技能管理,支持 32+ AI 编程 Agent。
  • 自定义技能库 —— 领域特定(数据 Agent 的 SQL 技能、基础设施 Agent 的 Terraform 技能)。Voyager 模式能向下缩放。
  • OpenAI Agents SDK tools —— 在低端;每个工具是一个轻量技能。
系统 技能形态 组合 版本 适用
Claude Agent SDK 技能 代码 + 说明 通过子 Agent 技能级 通用 Agent
skillkit 跨 Agent 标准 跨 Agent 内置 多 Agent 编程
Voyager 原版 JS 函数 DAG v+1 游戏/探索
OpenAI tools 函数 轻量

四、可复用产物

本节产出一份可复用技能(原课程 outputs/skill-skill-library.md):

  • skill-skill-library.md:给定任意目标运行时,生成一个 Voyager 形状的技能库,内置注册、检索、版本、精炼接线。包含一份技能设计清单(每个技能的描述是否足够独特以利检索?依赖是否构成 DAG?标签是否覆盖领域分类?),以及一份运维清单(多久去重一次?版本如何钉死?检索退化后补什么标签?)。

Python 代码(code/main.py)是独立可运行的技能库骨架,注册/检索/组合/精炼都是运行时无关的;把玩具检索换成真实嵌入、把脚本重写换成真实 LLM 即可投入生产。

五、练习

  1. (Easy)compose()依赖环检测。当技能 A 依赖 B、B 依赖 A 时会发生什么?报错还是警告?
  2. (Medium) 实现按技能的版本钉死。当父技能组合了 crafting@1 时,对 crafting@2 的精炼不能静默升级父技能。
  3. (Medium) 把 token 重叠检索换成 sentence-transformers 嵌入(或标准库 BM25)。在 50 个技能的玩具库上测检索@5。
  4. (Hard) 加一个「课程」Agent:给定当前库与领域描述,提议 5 个缺失技能。每周调一次。
  5. (Hard) 读 Anthropic Claude Agent SDK 技能文档。把玩具库移植到 SDK 的技能模式。可发现性变化在哪?

本节要点回顾

  1. 从零开始的 Agent 三宗错:浪费 token、进步丢失、长程组合失败。
  2. Voyager 三组件:自动课程(任务提议)、技能库(成功写入相似检索)、迭代提示(失败回灌精炼)。
  3. 动作空间 = 代码:发可组合的函数而非原始命令,把学习从「单次推理」升级为「累积程序库」。
  4. 技能检索:任务描述嵌入 → 查库 top-k → 组合原语 + 新逻辑。
  5. 迭代精炼:成功/错误/自检失败三信号回灌,重写技能直到成功——即 Self-Refine(第 05 节)应用到代码。
  6. 课程挑甜区:提议器挑「刚好在当前能力之上」的任务。
  7. 技能库是程序记忆载体:与第 07 节四类记忆中的「怎么做」对应。
  8. 组合是 DAG:拓扑排序 + 环检测必须在注册时就拦。
  9. 三大反模式:库腐烂(写入去重)、组合漂移(版本钉死)、检索退化(补标签与硬约束)。
  10. 2026 映射:Claude Agent SDK 技能、skillkit 跨 Agent 管理,背后都是 Voyager 骨架。

下一节,我们转向规划——HTN(层次任务网络)与进化规划,把「一次性生成完整计划」升级为「在可复用任务模板的层次结构上做搜索」,正是 Voyager 技能组合思想在规划层的对应。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U