技能库与终身学习:Voyager 本节摘要:每次会话都从零重建所有能力的 Agent 有三宗错:每个任务都重新 eliciting 同样的推理,浪费 token;会话 A 学到的修正传不到会话 B,进步丢失;复杂任务需要能力层次,一次性提示表达不出。Voyager(Wang 等人, TMLR 2024)的回答是——把每个可复用能力当作一块命名的代码存进库,可按相似度检索、可与其他技能组合、可被执行反馈精炼。它的三个组件是:自动课程(好奇心驱动的任务提议器)、技能库(成功时写入、按描述相似度检索)、迭代提示机制(失败时把错误与环境反馈回灌精炼)。关键设计是动作空间 = 代码——Agent 不发原始命令,而是发可组合的 JavaScript 函数。
本节摘要:每次会话都从零重建所有能力的 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)。
阅读完本节,你应当能够:
Voyager 的回答:把每个可复用能力当作一块命名的代码存进库,可按相似度检索、可与其他技能组合、可被执行反馈精炼。
Voyager(arXiv:2305.16291)把一个 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一旦写好并存库,下次「做钻石镐」就能直接复用mineIron、placeCraftingTable。代码把 Agent 的学习从「单次推理」升级为「累积的程序库」。这也是为什么技能库是**程序记忆(Procedural Memory)**的最佳载体(对照第 07 节四类记忆)。
新任务「做一把钻石镐」。Agent:
craftIronPickaxe、mineDiamond、placeCraftingTable 等。这正是第 13 章 MCP 资源和 Agent SDK 技能实现的模式:在一个知识/代码面上做检索,限定在当前任务范围内。
Voyager 的反馈循环:
success、error(带堆栈)、self-verification failure(自检失败)。这是自我精炼(Self-Refine,第 05 节)应用到代码生成,以环境接地验证为准。CRITIC(第 05 节)是同一模式,只是把外部工具当验证器。
Voyager 的课程模块会基于「Agent 有什么、还没做什么」提议任务,如「在湖边建个庇护所」。提议器用环境状态 + 技能清单,挑一个刚好在当前能力之上的任务——探索的甜区。
对生产 Agent,这翻译成一个「缺什么」算子:给定当前技能库与一个领域,我们还缺哪些技能?团队通常把这件事手动做成课程评审。
category=tooling 的技能」)。原课程 code/main.py 用标准库实现一个技能库:
Skill —— name、description、code(字符串)、version、tags、dependencies。SkillLibrary —— register、search(token 重叠)、compose(依赖拓扑排序)、refine(更新时版本号 +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 [] # 依赖的其他技能名
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
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),执行就会无限递归。生产里这步必须显式,而且要在注册时就拦住,不是等运行时崩。
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 即可投入生产。
compose() 加依赖环检测。当技能 A 依赖 B、B 依赖 A 时会发生什么?报错还是警告?crafting@1 时,对 crafting@2 的精炼不能静默升级父技能。下一节,我们转向规划——HTN(层次任务网络)与进化规划,把「一次性生成完整计划」升级为「在可复用任务模板的层次结构上做搜索」,正是 Voyager 技能组合思想在规划层的对应。