如果把 agent memory 拆开看,其实有两条不同的主线。

第一条是 personal memory:agent 如何更懂你,理解用户偏好、长期上下文、隐含约束和历史决策。这类问题更接近 long-context QA,评估的重点往往是“它是否记得、是否理解、是否能在正确场景下调用用户相关信息”。

第二条是 procedural memory:agent 如何避免重复犯错,如何从过去的成功与失败中总结出可复用经验,如何越跑越好、越用越强。它更关心的是 agentic benchmark 上的任务成功率、工具调用效率、错误率下降、 token的成本下降,以及在真实环境中是否能形成工程复利。

这篇文章主要讨论第二条路线。

今天很多 agent-harness, Claude Code、Hermes-agent、OpenClaw等,在长期使用后都会积累大量 trajectory这些轨迹实际上记录了 agent 和环境交互中最宝贵的东西。

但问题是,人类对这些 trajectory 的利用率尚且不足。大多数时候,trajectory 被当成日志、debug 记录,或者最多作为检索材料塞回上下文。一个 agent-harness 跑了半年,可能积累了成千上万条任务轨迹,但下次遇到相似问题时,agent 仍然可能从零开始探索,重复踩同样的坑。

引出了一个核心问题:

trajectory 到底如何才能变成 skill?

以 Hermes-agent 这类系统为例,用久了之后会发现 skills 可能越来越多。但真正有效的 skills 有多少?

本文将借最近几篇相关工作,讨论一个正在变得重要的问题:如何从大量 agent trajectories 中,自动挖掘、总结、验证并优化可以被未来任务复用的 agent skills。

以hermes-agent 作为入口

Hermes-agent 有一个很有意思的定位:一个会随着使用而变强的 agent。也就是把过去的经验沉淀为可以被未来复用的外部记忆。这里的外部记忆大致可以分成两类:

第一类是 declarative memory,也就是关于用户、项目、环境和偏好的事实记忆,具体形式是 USER.md 和MEMORY.md, 这类 memory 解决的是“agent 如何更懂你”的问题。

第二类是 procedural memory,也就是 skills。具体形式是写入到state.db 中的 sessions/messages,以及被总结成 md 的skills。

更具体地说,Hermes-agent 中的 skill 自动学习,更接近一种 prompt-driven 的自我沉淀机制。在其prompt 中给 agent 一个触发规则:当完成复杂任务、经历多次工具调用、修复 tricky error,或者发现一个非平凡 workflow 时,应该把这套 approach 保存成 skill;如果使用已有 skill 时发现它过时、不完整或错误,则应该立即 patch,而不是等用户提醒。

SKILLS_GUIDANCE = (
    "After completing a complex task (5+ tool calls), fixing a tricky error, "
    "or discovering a non-trivial workflow, save the approach as a "
    "skill with skill_manage so you can reuse it next time.\n"
    "When using a skill and finding it outdated, incomplete, or wrong, "
    "patch it immediately with skill_manage(action='patch') — don't wait to be asked. "
    "Skills that aren't maintained become liabilities."
)

真正落盘则由 skill_manage 工具完成。并提供几个基本动作:create 创建新的 SKILL.md,patch 对已有 skill 做局部替换,edit 做完整重写,write_file 添加 supporting files,delete 删除不再需要的 skill。

优点是简单、直接、可解释, 但它也很粗糙。

  • 主要依赖模型自己的判断来决定什么经验值得变成 skill

  • 更像单次任务后的经验沉淀,而不是从多条成功/失败轨迹中归纳共性规律

  • 没有 evaluation ,是否真的提升任务成功率?skills是否真实有效?

  • 用久之后 skills 会越来越多,但哪些 skill 仍然有效、哪些已经过时未知

其展示了最朴素的一种闭环——agent 在工作中发现 workflow,然后把 workflow 写成 skill,也暴露了后续研究真正要解决的问题:如何从大量 trajectories 中自动归纳 skill,如何验证 skill,如何合并 skill,如何优化 skill,以及如何避免 skill bank变成垃圾场。

在 Hermes-agent 本体之外,Nous 也单独开了一个 [hermes-agent-self-evolution](https://github.com/NousResearch/hermes-agent-self-evolution) 项目,试图把这种 skill 自我沉淀进一步推向“外部优化器式”的 self-evolution。思路是读取已有 skill、prompt、tool description 或代码,再结合 execution traces,用 DSPy + GEPA 生成候选变体,经过评估、约束检查和人工 review 后,产出更优版本。

# https://github.com/NousResearch/hermes-agent-self-evolution/README.md
Read current skill/prompt/tool ──► Generate eval dataset
                                        │
                                        ▼
                                   GEPA Optimizer ◄── Execution traces
                                        │                    ▲
                                        ▼                    │
                                   Candidate variants ──► Evaluate
                                        │
                                   Constraint gates (tests, size limits, benchmarks)
                                        │
                                        ▼
                                   Best variant ──► PR against hermes-agent

更像一个外部优化器:它把 skill / prompt / tool description 当成可优化对象,用 execution traces 来解释失败原因,再搜索更好的文本变体。不过,这个项目目前还处在比较早期的阶段,大多数功能还处于都还在 planned 状态。

Trace2Skill:批量轨迹归纳

https://arxiv.org/abs/2603.25158

当我们面对的不是单个 skill 或单次任务,而是大量成功/失败 trajectories 时,如何从中自动归纳出可迁移 skill?

面对单次任务,单条 trajectory 很容易带有偶然性。一次任务里的经验,未必是长期有效的规律,如果每次都把局部 lesson 写进 skill bank,最后很容易产生碎片化、重复、冲突和过拟合。

在Trace2Skill 这篇工作的出发点中,先收集一批trajectories,再从整体分布中归纳共性经验。

Trace2Skill 的整体流程可以拆成三步:

Stage 1: Trajectory Generation
  frozen agent + initial skill S0
  → 在 evolution tasks 上 rollout
  → 得到成功轨迹 T+ 和失败轨迹 T-

Stage 2: Parallel Multi-Agent Patch Proposal
  对每条轨迹派一个 analyst sub-agent
  → 成功分析器 A+ 总结成功模式
  → 失败分析器 A- 做 agentic root-cause analysis
  → 每条轨迹产出一个 trajectory-local skill patch

Stage 3: Conflict-Free Patch Consolidation
  所有 patches 分层合并
  → 去重、解决冲突、筛掉偶然经验
  → 抽象成一个统一 skill directory S*

实际上把 from trajectories 2 skill 拆成了三个子问题

  • 经验从哪里来?来自 agent 在任务环境中的真实 rollout

  • 局部经验如何表达?表达为 trajectory-local patch,而不是直接写入最终 skill

  • 多条局部经验如何变成稳定 skill?通过层次化合并、冲突检测和格式校验,归纳出统一 skill directory

不过,Trace2Skill 不是完整的真实环境 self-learning agent,在论文和源码中,基于SpreadsheetBench数据集,能够很好的进行评估,error analyst 能对比 ground truth,并通过最小修复验证 failure cause。

但真实环境中,很多任务没有明确标准答案。一份分析报告是否足够好,一个代码修改是否符合用户意图,都很难用单一 evaluator 判断。

SkillOpt:把 Skill 当成可以被训练的外部参数

https://arxiv.org/abs/2605.23904

skill 还能不能继续被优化?换句话说,skill 是否只是一次性的经验总结?还是可以像模型参数一样,在反馈中持续训练?这正是 SkillOpt 的切入点。

SkillOpt 问的是:给定一个当前 skill, 它在一批任务上的表现如何? 哪些规则应该增加、删除或替换? 这次修改是否真的让 agent 变强? 如果没有变强,是否应该拒绝这次修改?

也就是说 Skills不只是经验总结文档,而是看作一个可以被优化的外部状态。SkillOpt将深度学习中的一些思想迁移到 natural-language skill 的优化上,基本设定是:目标模型不变; 执行 harness 不变; 任务环境不变; 唯一被优化的是外部 skill 文档,用类似深度学习训练的方式进行 text-space optimization。

SkillOpt 的流程可以拆成几个步骤,

当前 skill S_t
  ↓
目标 agent 用 S_t 跑一批任务,得到 scored trajectories
  ↓
optimizer model 分析成功/失败 mini-batches
  ↓
提出 add / delete / replace edits
  ↓
按“文本学习率”限制每次最多改多少
  ↓
在 held-out selection split 上验证
  ↓
提升才接受,否则拒绝并记录为负反馈
  ↓
多 epoch 后导出 best_skill.md

optimizer model 可以提出修改建议,但是否接受,不由模型的自信决定,而由 held-out validation score 决定

具体实现。

Forward pass:目标 agent 跑 rollout batch

让 frozen target agent 带着当前 skill 去执行一批任务,harness 会记录任务 metadata、messages、tool calls、observations、command outputs、final answers、verifier feedback,以及特定 benchmark 的上下文,

这一步类似深度学习里的 forward pass,但输出不是 loss tensor,而是:

scored trajectories:
  task
  current skill
  agent messages
  tool calls
  observations
  final answer
  verifier feedback
  score

这里很关键:SkillOpt 依赖 scored rollout。没有 score,就很难做后面的 validation gate。

Backward pass:minibatch reflection

这些 trajectories 告诉 optimizer 两类信息:

  • 成功轨迹:当前 skill 中哪些规则可能有效,哪些行为应该保留。

  • 失败轨迹:当前 skill 缺少什么指导,哪些规则不够明确,哪些操作需要禁止或替换。

SkillOpt 不会直接把所有 trajectories 一次性塞给 optimizer model,而是把成功和失败轨迹分成 reflection minibatches。

失败 minibatch 负责提出 corrective edits。它要回答:

这些失败轨迹暴露了什么共同问题?
当前 skill 缺少哪些检查步骤?
哪些已有规则太模糊?
哪些行为应该被明确禁止?

成功 minibatch 负责提出 preservation edits。它要回答:

哪些行为让 agent 成功了?
哪些规则应该保留或强调?
哪些有效流程不应该在后续修改中被破坏?

Add / Delete / Replace

optimizer model 最终输出的不是完整重写后的 skill,而是结构化 edits。局部 edit 则让每一步更新都更可控,也更容易审计,而非完整重写 SKILL.md

Textual Learning Rate

把 skill update 限制成受控的文本操作。在模型训练中,有learning rate,SkillOpt 把这个思想迁移到了文本更新上:每一轮最多允许应用多少个 edits。从而解决agent skill 很容易“越学越乱”,其意义在于:skill 的演化应该是连续的,而不是每次都推倒重来。

Validation Gate

每一轮生成 candidate skill 后,SkillOpt 会让同一个 frozen target agent 带着这个 candidate skill,在 held-out selection split 上重新执行任务。只有当 candidate skill 的 score 严格超过当前 skill 时,这次修改才会被接受

Rejected-Edit Buffer

如果 candidate skill 没有通过 validation gate,SkillOpt 不会简单丢掉这次尝试,而是把 rejected edits 记录下来。会告诉后续 optimizer:

哪些修改方向试过但失败了;
哪些规则看似合理但伤害了表现;
哪些 failure pattern 仍然没有被解决;
哪些 edits 导致了 regression。

其实是一种 optimizer memory,但更细的东西:哪些 skill edits 被尝试过,但没有通过验证

最终产物:best_skill.md

当然,SkillOpt 也有明显限制。

首先,它强依赖 scored trajectories。也就是说,任务需要有比较可靠的评分机制。无论是 exact match、unit test、benchmark evaluator,还是 LLM-as-judge,都必须能给出某种可比较的分数。在 benchmark 中比较容易,但在真实环境中很难。

AutoSkill: 在线 Lifelong Skill Lifecycle

https://arxiv.org/abs/2603.01145

skill 应该如何持续产生、维护和复用?

用户在长期使用 agent 的过程中,会不断表达稳定偏好、工作习惯、格式要求、任务约束和操作方式,AutoSkill 试图把这些短暂的 interaction experience 转化为显式、可复用、可维护、可检索的 skills。

真实用户和 agent 的交互,和 benchmark trajectory 有很大不同。

在 benchmark 中,任务边界清楚,输入输出明确,往往还有 evaluator。比如 spreadsheet 任务是否答对,代码是否通过测试,网页任务是否完成,都可以比较直接地打分。

但真实用户交互通常不是这样。用户会反复表达一些不那么“任务化”的需求, 这些内容不像一道题有标准答案,但它们非常重要。

传统 memory 可以保存这些偏好,但 memory 往往只是事实或片段。例如:

用户喜欢正式风格;
用户不喜欢过度技术化;
项目使用 pnpm。

这类 memory 解决的是“知道什么”,但不一定能转化成“以后如何做”。AutoSkill 的目标是把这些重复出现的交互经验进一步抽象成 skill,也就是带有触发条件、行为目标、约束和执行方式的 procedural artifact。

因此,AutoSkill 的基本判断是:用户交互经验不应该只作为 memory 被保存,而应该被抽象成可执行的长期技能。

总体闭环:

用户对话 / agent 轨迹 / 历史 conversation
  ↓
抽取可复用 skill candidate
  ↓
检索相似已有 skill
  ↓
决策:discard / add / merge
  ↓
写入或更新 SkillBank 中的 SKILL.md
  ↓
未来请求时 query rewrite + hybrid retrieval
  ↓
把相关 skill 注入 LLM prompt
  ↓
新反馈继续触发 skill evolution

核心在于两个循环

第一个是 response generation loop。当新请求到来时,AutoSkill 会先根据当前 query 和历史上下文重写检索 query,然后从 SkillBank 中检索相关 skills,并把它们注入 prompt,辅助模型生成回复。

第二个是 skill evolution loop。每轮交互之后,系统会尝试从用户输入和 interaction traces 中抽取 reusable skill candidate,并判断它应该被丢弃、作为新 skill 添加,还是合并进已有 skill。

AutoSkill 的重要点在于:新 candidate 不会直接进入 SkillBank。它会先检索最相似的已有 skill,只把 candidate 和少量近邻 skill 送给 management judge,而不是把整个 skill bank 都塞进 prompt。这样做有两个目的:一是避免重复 skill;二是让管理决策可扩展。

management judge 做三类决策:

discard:候选太泛、低信号、不可迁移、一次性、或已有库能覆盖;
add:候选是一个新的 durable capability;
merge:候选和已有 skill 属于同一能力,应更新已有 skill。

判断时会比较四个维度:

job-to-be-done
deliverable type
hard constraints / success criteria
required tools / workflow

只有去掉实例细节后仍是同一能力,才 merge;否则 add;如果不值得长期保留,则 discard

如果决策是 merge,AutoSkill 会调用 skill merging 模块。非简单拼接文本,而是做 semantic union:

保留原 skill 的能力身份;
加入 candidate 中新的可复用约束、例子、执行细节;
删除重复内容;
去掉过时或无关 topic constraints;
避免 regression,保留原 skill 里的重要检查;
不引入用户没有明确给出的新标准。

合并后 skill 版本号会递增。

AutoSkill 把 skill 作为普通文件持久化,默认布局是:

SkillBank/
  Users/<user_id>/<skill-slug>/SKILL.md
  Common/<skill-slug>/SKILL.md
  vectors/
    <embedding-signature>.meta.json
    <embedding-signature>.ids.txt
    <embedding-signature>.vecs.f32
  index/
    skills-bm25.*
    skill_usage_stats.json

Users/<user_id> 存用户个性化 skill,Common 存共享 skill,vectors 存向量缓存,index 存 BM25 索引和使用统计。

不过AutoSkill的局限

  • 主流程主要依赖 LLM 判断 candidate 是否值得保存、是否应该 merge、如何 merge,而非基于评分验证

  • 更适合偏好、风格、流程和个性化约束的学习。对于复杂工具任务,单纯从用户交互中抽 skill 可能不够

SkillX:层级化 Skill Knowledge Base

https://arxiv.org/abs/2604.04804

SkillX 的核心思路,就是把 agent experience 组织成一个 层级化 Skill Knowledge Base,而不是一个扁平的 skill 列表。或者说,应该被拆成不同粒度、可以组合使用的 skills。

用强 agent 在训练任务中 rollout,收集成功轨迹;把轨迹蒸馏成 planning / functional / atomic 三层 skill;再经过聚类合并、质量过滤、schema 校验和多轮迭代更新,最终构建一个可检索、可注入、可迁移到弱 agent 的 Skill Knowledge Base。

整体流程可以概括为:

训练任务
  ↓
强 backbone agent rollout
  ↓
筛选成功轨迹
  ↓
抽取三层 skills:
    Planning Skills
    Functional Skills
    Atomic Skills
  ↓
聚类 / 合并 / 拆分
  ↓
两阶段过滤:
    general quality filter
    tool schema filter
  ↓
Skill Library update:
    add / modify / keep
  ↓
探索 under-used / failure-prone tools
  ↓
合成新任务、继续 rollout、继续抽 skill
  ↓
形成 plug-and-play SkillKB

其中把 agent 经验拆成三层。

  • Planning Skill 捕捉的是“如何组织一个长程任务”

  • Functional Skill:可复用工具子程序

  • Atomic Skill:工具级使用约束和失败模式

同时SkillX 不是一次性从轨迹中抽 skills 后就结束。它引入了 iterative skills refinement,让 SkillKB 在多轮中持续变好。

从当前 skill library 出发,rollout 训练任务,抽取 multi-level skills,然后应用 refinement operator,包括 Skills Merge 和 Skills Filter,最后通过 add / modify / keep 更新 Skill Library。

SkillX 的价值在于,把 agent experience 从单个 agent 的私有经验变成了可迁移的公共skills,类似于一种非参数化蒸馏:不是把强模型的能力蒸馏进弱模型参数; 而是把强模型的执行经验蒸馏成外部 SkillKB; 弱模型通过检索和注入 SkillKB 获得能力增益。

当然,SkillX 也有明显边界,适合工具环境相对稳定的场景,并主要面向 tool-using agent。

从 RL 角度重新思考

如果从 RL 的角度重新看 Traj2Skill(泛指这一类方法),这件事的本质可能不是“从 trajectory 中总结知识”,而是:

从历史行为分布中提取可复用的 policy 改进单元。

一个 agent 在环境中的行为过程,可以抽象成某个 policy 生成 trajectory,并最大化期望回报:

$$ J(π)=E_{τ∼π}[∑_{t=0}^Tγ^tr_t] $$

其中,trajectory 记录的是 agent 在状态、观察、工具调用、环境反馈之间的完整交互过程。

那么 Traj2Skill 的目标就不只是从 trajectory 里总结出几条人类可读的经验,而是从已有 trajectory 中找到一些结构化行为模式,使得新的 policy $\pi’$ 在未来任务上的期望回报高于原始 policy $\pi$

$$ J(\pi’) > J(\pi) $$

区别在于,Traj2Skill 通常并不直接更新模型参数。它更新的是模型外部的 skill library。

trajectory → experience signal → update external skill library → guide future policy

从这个角度看,skill 不是普通 memory,也不是任务日志的压缩版。它更像一种外部化的 policy prior。

如果将Agentic-RL加入比较,Agentic-RL 更接近 end-to-end policy optimization,优化的是模型本身,而 Traj2Skill 更接近 modular policy improvement,优化的是模型外部的可复用行为模块。

从工程角度看,这也是 skill library 有吸引力的原因。LLM policy 本身训练成本高、更新慢、可解释性弱,也不适合频繁微调,但 skill library 是外部化的、可读的、可编辑的、可检索的、可版本化的。它提供了一种比直接更新模型参数更轻量的 policy improvement 路径。这或许也是 SkillOpt 这类工作的意义:让 skill 本身进入“生成—评估—优化”的闭环。

从另一个角度看,二者也并非替代关系,而是可以互相结合的。这也是SAGE / SkillRL 这些工作在做的方向,将 skill 纳入强化学习或策略优化框架中。

进一步看,Trajectory 太长、太具体、太偶然,真正有价值是从中提取出能跨任务复用的行为结构。那么Traj2Skill 到底更像 offline RL,还是 behavior cloning?

目前很多 Traj2Skill 工作,实际上更接近 behavior cloning,大量 trajectory mining 工作的基本流程是总结出高频模式,压缩,复用;但这里有一个问题:成功轨迹不等于最优轨迹。

这就是 credit assignment 问题。一个长程 agent trajectory 的最终 return,可能只来自少数几个关键决策,而不是整条轨迹中的所有步骤。真正值得沉淀为 skill 的,不一定是最频繁出现的行为片段,而是那些能够稳定提高未来任务 expected return 的行为结构。

这个视角也暴露了 Traj2Skill 最难的问题:reward 从哪里来?在 benchmark 中有标准答案,但真实环境不一样,往往没有简单的 ground truth, 意味着,真实 Traj2Skill 系统的上限,很大程度上取决于 evaluator 的质量。

如果把这些工作放在一起看,会发现它们在解决 trajectory-to-skill pipeline 中的不同环节:

  • Hermes-agent:单条轨迹后的自我沉淀

  • Trace2Skill:多条轨迹中的经验归纳

  • SkillOpt:评测驱动的 skill 优化

  • AutoSkill:长期 skill 生命周期管理

  • SkillX:层级化 skill 组织与强到弱迁移

因此,Traj2Skill 类工作的核心可以拆成两个问题。

第一个是 SkillOps:如何创建、合并、检索、注入、版本化、评估和淘汰 skills,避免 skill bank 变成垃圾场。

第二个是更底层的问题:如何从 trajectory 中做 credit assignment,找到真正能提升 expected return 的行为结构。

前者解决长期运行的问题,后者回答解决究竟是“经验总结”,还是“policy improvement”。