Claude Code Agent Harness入门:从Skills、Session到Memory说起

如果你想学的是 agent harness,而不是“怎么写一段更会哄模型的 prompt”,那你真正该研究的不是一句话提示词,而是 AI 助手背后的执行骨架。

最近我专门翻了一遍一份公开暴露出来、被认为和 Claude Code 有关的仓库。先说结论:我不把它当成“可以直接代表官方完整源码”的东西来看,而是把它当成一份很有研究价值的harness 解剖样本

为什么这么说?

因为这个仓库最有价值的部分,不是某个具体业务功能,而是它把一个 agent 系统拆成了几块非常清晰的能力:

  • skills:让 agent 知道“什么时候该用哪套工作流”
  • session:让 agent 能在多轮对话里保持状态
  • memory:让 agent 不只是记住眼前几句话,而是能带着长期指令和上下文工作

如果你能看懂这三块,基本就算摸到了 agent harness 的门框。


一、先别急着看模型,先理解 harness 是什么

很多人学 AI agent,会先盯着模型本身:

  • 用的是哪个模型
  • 上下文多大
  • 推理强不强
  • 写代码厉不厉害

这些当然重要,但真正让一个 agent “像个系统”而不只是“像个聊天框”的,往往不是模型,而是 harness。

你可以把 harness 理解成 AI 助手的操作系统外壳。它至少要解决几个问题:

  1. 用户说了一句话,系统怎么判断该走哪条执行路径?
  2. 这条路径里能调用哪些工具?权限是什么?
  3. 多轮对话进行到一半,状态怎么保存?
  4. 上下文太长了怎么办?怎么压缩?
  5. 仓库规则、团队规范、历史偏好这些长期信息,怎么持续影响后续回答?

这几个问题合起来,就是 agent harness。

而这份仓库最值得看的,就是它没有把这些东西糊成一团,而是分成了清楚的模块。


二、这个仓库到底暴露了什么

这份仓库本身其实分成两条线:

1. Python 线:偏“镜像”和研究样机

Python 侧更像一个 clean-room rewrite,也就是重新搭了一个外壳,用来镜像命令、工具、session、runtime 这些结构。

它有几个很典型的入口:

  • src/main.py:CLI 入口,暴露 summarymanifestcommandstoolsroutebootstrapturn-loop 等命令
  • src/query_engine.py:一层轻量的多轮消息引擎
  • src/runtime.py:把 prompt 路由到 command/tool,再生成一次“会话报告”

但要注意,Python 侧很多地方还不是“真实执行逻辑”,而是“镜像表面”。比如命令和工具大多来自快照文件,执行时只会告诉你:

1
Mirrored command 'xxx' would handle prompt '...'

也就是说,它更适合拿来学习结构,不适合拿来当生产实现。

2. Rust 线:更像真正的 harness 实现

Rust 侧就有意思多了。

它已经把很多关键机制真的做进 CLI 里了,比如:

  • prompt
  • repl
  • resume
  • /compact
  • /memory
  • /session
  • /export
  • 权限模式切换
  • system prompt 装配
  • instruction file 发现

换句话说,Python 侧帮你看清“长什么样”,Rust 侧开始告诉你“它准备怎么跑”。


三、Skills 是什么:不是提示词合集,而是工作流入口

很多人第一次看到 skills,会以为它就是一堆 prompt 模板。

这理解只对了一半。

从这份仓库暴露出来的信息看,skills 更像是一组可装配的任务套路

在 Python 侧的快照里,skills 这个子系统对应了 20 个模块,样例文件包括:

1
2
3
4
5
6
skills/bundled/remember.ts
skills/bundled/verify.ts
skills/bundled/stuck.ts
skills/bundled/skillify.ts
skills/loadSkillsDir.ts
skills/mcpSkillBuilders.ts

光看这些名字,其实已经很能说明问题了。

1. skill 不是“知识点”,而是“遇到某类问题时的处理套路”

比如:

  • remember:说明 skill 可以把某些信息沉淀成后续可复用的上下文
  • verify:说明 skill 可以把“做完以后验证一下”固化成步骤
  • stuck:说明 skill 不只是顺风执行,也考虑到 agent 卡住怎么办
  • loadSkillsDir:说明 skill 支持从目录动态加载
  • mcpSkillBuilders:说明 skill 甚至可能和 MCP 工具生态联动生成

这意味着什么?

意味着 skill 的本质不是静态文档,而是对某种任务路径的编码

你可以把它理解成:

“当用户触发某类意图时,不要只把原始请求塞给模型,而是附带一整套这个任务常用的工作方法、边界条件和工具偏好。”

这就是 skill 对 agent harness 的价值。

2. 为什么 skill 对 agent 很重要

如果没有 skills,一个 agent 往往每次都要从零开始想:

  • 这个问题该先查什么?
  • 该用哪些工具?
  • 是先分析还是先改代码?
  • 做完后要不要验证?

这会导致两件事:

  • 输出不稳定
  • 每次都要重复消耗上下文和推理预算

而有了 skills,本质上就是把“高频任务的最佳实践”提前编排好。

所以从 harness 角度看,skill 的作用不是让模型更聪明,而是让系统更稳定。


四、Session 是什么:多轮对话真正的“状态容器”

如果没有 session,AI 助手其实就是一次性问答机。

你问一句,它答一句;下一句再来,它只能重新猜上下文。

这份仓库里,session 的设计非常值得新手看。

1. Python 侧的 session:轻量但清楚

Python 里有两个关键文件:

  • src/transcript.py
  • src/session_store.py

前者负责暂存会话里的消息列表,后者负责把 session 存成 JSON 文件。

大概逻辑可以概括成这样:

1
2
3
4
5
append(message)
compact(keep_last=N)
flush()
save_session(session_id, messages, token_usage)
load_session(session_id)

虽然不复杂,但它已经把会话系统最核心的骨架搭出来了:

  • 会话有唯一 id
  • 会话有消息历史
  • 会话可以压缩
  • 会话可以持久化
  • 会话可以恢复

对于入门学习者来说,这比一上来研究复杂的 event loop 更有价值,因为它先告诉你:session 首先是状态管理问题,不是模型问题

2. Rust 侧的 session:更接近真实运行时

Rust 里的 Session 结构更完整。它保存的是一组 ConversationMessage,而消息又由 ContentBlock 组成。

这里有几个特别值得学习的点。

第一,消息角色是显式建模的

消息不是只有 user 和 assistant,还包括:

  • System
  • User
  • Assistant
  • Tool

这非常重要。

因为一旦 agent 能调用工具,会话历史就不只是“人和模型的聊天记录”,而是:

  • 用户说了什么
  • 模型决定调用什么工具
  • 工具返回了什么结果
  • 模型如何基于结果继续推理

所以会话不是文本流,而是结构化事件流

第二,消息内容不是只有文本

ContentBlock 里除了文本,还有:

  • ToolUse
  • ToolResult

这说明 session 天然承担了“执行轨迹”的职责。

你以后自己做 agent,如果会话里只记纯文本,很快就会遇到问题:

  • 工具是谁调用的?
  • 输入参数是什么?
  • 工具结果有没有报错?
  • 后续回答是基于哪次工具调用生成的?

结构化消息就是为了解决这些问题。


五、Memory 是什么:不是“记住聊天内容”,而是“加载长期规则”

很多人一说 memory,第一反应是“跨会话记忆”。

但这份仓库让我觉得更值得学的一点是:

memory 并不只是“把以前聊过的话再拿回来”,更重要的是“把长期有效的指令和规则稳定注入系统”。

从 Rust 侧的实现看,memory 的入口不是某个向量库,而是 instruction files,也就是一组约定位置的规则文件。

它会沿着当前工作目录一路向上找这些文件:

  • CLAUDE.md
  • CLAUDE.local.md
  • .claude/CLAUDE.md
  • .claude/instructions.md

然后把这些文件读出来,作为 system prompt 的一部分装进去。

1. 这是一种非常工程化的 memory 设计

它的优点是:

  • 可读:人能直接打开文件看规则
  • 可控:版本可追踪,能跟仓库一起管理
  • 可叠加:父目录、项目目录、本地目录的规则可以组合
  • 可审计:不会变成黑盒记忆

这跟很多人想象中的“AI 自己默默记住所有事情”完全不同。

它更像:

把团队规范、项目约束、工作习惯写成一组长期生效的可组合指令文件。

2. /memory 命令做的也很实在

在 Rust CLI 里,/memory 命令不会神神叨叨地说“我记得你喜欢什么”,而是老老实实列出:

  • 当前工作目录
  • 发现了多少 instruction files
  • 每个文件的路径
  • 文件的行数
  • 文件开头的预览内容

这很像一个成熟工具应有的风格:

  • 让 memory 可见
  • 让 memory 可检查
  • 让 memory 能解释

这比“我有记忆能力”这句宣传语有用得多。


六、上下文太长怎么办?这就是 compact 的意义

当 agent 真的跑起来,多轮以后一定会遇到一个问题:上下文不够用了。

仓库里给出的答案不是简单粗暴地裁掉前文,而是做 compaction。

Rust 侧的 compact_session() 很有代表性:

  1. 先判断当前会话是不是已经超过阈值
  2. 保留最近几条消息
  3. 把更早的消息总结成一段 resumable system summary
  4. 把这段 summary 作为新的 system message 放回会话头部

这件事的本质是:

不要把旧上下文直接丢掉,而是把它压成更便宜但仍可继续工作的状态。

这对 agent harness 来说是必修课。

因为 agent 一旦开始做复杂任务,比如改代码、跑工具、反复验证,你不可能永远把所有历史消息原封不动地带着。

所以 session 和 memory 中间,还需要一个“压缩层”。


七、把三件事连起来,你就理解了 agent harness 的骨架

如果把这篇文章压成一句话,我会这样总结:

1
2
3
Skills 决定“怎么做”
Session 决定“做到哪了”
Memory 决定“做事时要遵守什么长期规则”

它们分别对应:

  • Skills:任务工作流模板
  • Session:执行中的短期状态
  • Memory:长期约束与持久指令

再加上工具系统、权限系统和 compaction,一个真正的 agent harness 才算长出来。


八、如果你也想自己做 agent,最值得抄什么

如果你不是在做研究,而是想自己搭一个 agent 系统,我最建议你先抄这几件事:

1. 不要把所有逻辑塞进一个 prompt

把它拆成:

  • command surface
  • tool surface
  • session store
  • memory loader
  • compact strategy

先拆清楚,再谈模型。

2. skill 要设计成工作流,不是话术片段

一个好的 skill,至少应该回答:

  • 什么时候触发
  • 先做什么
  • 后做什么
  • 用哪些工具
  • 什么叫完成

3. session 一开始就做成结构化

别只存纯文本。至少要区分:

  • user
  • assistant
  • tool_use
  • tool_result

以后你做回放、导出、恢复、审计时会感谢自己。

4. memory 优先用“文件化规则”

在很多工程场景里,CLAUDE.md 这种 instruction file 比“神秘的长期记忆黑盒”更实用。

因为它:

  • 好调试
  • 好版本管理
  • 好协作
  • 好解释

九、最后一句判断

这份仓库最值得学习的,不是“Claude Code 到底写了哪一行神秘代码”,而是它暴露出了一种非常明确的工程观:

一个 agent 系统要可靠,靠的不是一次回答有多惊艳,而是 skills、session、memory、tools、permissions、compaction 这些基础设施能不能互相咬合。

如果你想学 agent harness,这正是最该盯住的地方。

下一篇我会更进一步,不再讲概念,而是直接拆这份仓库里 skills / session / memory 的实现骨架,看看一个工程化的 agent 系统到底是怎么把这些模块接起来的。

延伸阅读