Harness 即库:子智能体与会话存储


文档摘要

Harness 即库:子智能体与会话存储 本节摘要:原始 LLM API 一次调用只给你一次往返;生产 Agent 需要的远不止——工具执行、MCP 服务器、生命周期钩子、子智能体派生、会话持久化、跨进程追踪传播。把这套「外壳(Harness)」从零写出来是巨大的工程量,而 Anthropic 的回答是:Claude Agent SDK 把 Claude Code 用的那套 Harness 当成一个可 import 的库发出来了——内置工具、子智能体(subagent)做上下文隔离与并行、生命周期钩子、W3C 追踪传播、会话存储,一个 import 全到位。

Harness 即库:子智能体与会话存储

本节摘要:原始 LLM API 一次调用只给你一次往返;生产 Agent 需要的远不止——工具执行、MCP 服务器、生命周期钩子、子智能体派生、会话持久化、跨进程追踪传播。把这套「外壳(Harness)」从零写出来是巨大的工程量,而 Anthropic 的回答是:Claude Agent SDK 把 Claude Code 用的那套 Harness 当成一个可 import 的库发出来了——内置工具、子智能体(subagent)做上下文隔离与并行、生命周期钩子、W3C 追踪传播、会话存储,一个 import 全到位。本节先厘清 Client SDK(裸 Messages API,你自己拥有循环)与 Agent SDK(Harness 形状)的区别,再吃透子智能体的两大用途(并行化、上下文隔离——派生 20 个子智能体去找 20 个模块的测试文件,编排者的上下文窗口不被污染)、会话存储的五方法面(append/load/list_sessions/delete/list_subkeys)与 --session-mirror、六类生命周期钩子,以及云端托管的 Claude Managed Agents(长时异步、内置缓存与压缩,用控制权换托管基建)。读完本节,你应能用标准库实现一个带内置工具、子智能体派生、隔离上下文、生命周期钩子与会话存储的 Harness,并识别三种失败模式:子智能体过度派生、钩子蠕变、会话膨胀。

对应原课程:Phase 14 · Lesson 17 · claude-agent-sdk(原英文 phases/14-agent-engineering/17-claude-agent-sdk/docs/en.md)。前置:第 01 节(Agent 循环)、第 10 节(技能库)。

学习目标

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

  1. 区分 Anthropic Client SDK(裸 API)Claude Agent SDK(Harness 形状)
  2. 描述子智能体(subagent)——并行化与上下文隔离——以及何时该用。
  3. 说出 Python SDK 的会话存储面(appendloadlist_sessionsdeletelist_subkeys)及 --session-mirror 的作用。
  4. 列出六类生命周期钩子及各自触发时机。
  5. 解释 W3C 追踪上下文如何让多进程追踪汇成一条。
  6. 用标准库实现一个带内置工具、子智能体派生(隔离上下文)、生命周期钩子、会话存储的 Harness。

一、问题与直觉

一个裸 LLM API 调用,给你的是一次往返:发提示、收响应。但生产 Agent 需要的是:

  • 工具执行——读文件、跑 shell、查数据库,失败要重试、要校验。
  • MCP 服务器——外部工具与资源的标准接口(第 14 章工具与协议)。
  • 生命周期钩子——工具调用前要审计、会话结束要清理。
  • 子智能体派生——把一块工作丢给一个独立上下文的子 Agent,只把结果收回来。
  • 会话持久化——跨轮次、跨进程地存对话历史。
  • 跨进程追踪传播——CLI 子进程发的 span 要挂到调用方的 trace 上。

把这些从零写出来,是 Claude Code 这个产品本身大部分的工程量。Claude Agent SDK 的洞见是:这套 Harness 本身就是产品——把它作为库暴露出来,自定义 Agent 直接 import,不必重造轮子。

Client SDK vs Agent SDK

  • Client SDK(anthropic) —— 裸 Messages API。你自己拥有循环、工具、状态。适合:你已经有一套 Harness,只需一个稳定的 API 客户端。
  • Agent SDK(claude-agent-sdk) —— 内置工具执行、MCP 连接、钩子、子智能体派生、会话存储。Claude Code 的循环,作为库。适合:你想直接拿到生产级 Harness,把精力放在业务逻辑上。

内置工具

SDK 开箱带 10+ 工具:文件读写、shell、grep、glob、网页抓取等。自定义工具通过标准工具模式接口注册(第 06 节那套 name+description+JSON Schema)。这意味着一个最小 Agent 几乎零配置就能读写文件、跑命令。

子智能体

Anthropic 文档记录了两大用途:

  1. 并行化(Parallelization) —— 独立工作并发跑。「为这 20 个模块各找对应的测试文件」就是 20 个并行子智能体任务,比串行快近 20 倍。
  2. 上下文隔离(Context isolation) —— 子智能体用自己的上下文窗口;只有结果回到编排者。编排者的预算(上下文窗口)被保护下来,不被 20 份冗长的搜索过程污染。这是第 07 节「主上下文 = RAM」思想在多智能体层的延伸。

Python SDK 近期新增 list_subagents()get_subagent_messages(),用于读取子智能体的对话轨迹——这对审计与调试至关重要。

会话存储

与 TypeScript SDK 协议对齐的五方法面:

  • append(session_id, message) —— 追加一轮。
  • load(session_id) —— 恢复对话。
  • list_sessions() —— 枚举所有会话。
  • delete(session_id) —— 删除,级联到子智能体会话
  • list_subkeys(session_id) —— 列出该会话下的子智能体键。

--session-mirror(CLI 标志)在流转时把对话镜像到外部文件,用于调试——你能实时看到 Agent 在「想」什么。

钩子

可注册的生命周期钩子:

  • PreToolUsePostToolUse —— 门控或审计工具调用(可拒绝、可记录)。
  • SessionStartSessionEnd —— 建立与拆除(如连数据库、清临时文件)。
  • UserPromptSubmit —— 在模型看到用户输入前先动作(如敏感词过滤、注入检测)。
  • PreCompact —— 在上下文压缩前跑(第 08 节的压缩门)。
  • Stop —— Agent 退出时清理。
  • Notification —— 旁路告警(如发 Slack)。

钩子是横切关注点(cross-cutting concern)的落点——专业工作流(pro-workflow)与类似系统靠它加跨切行为,而不必改主循环。

W3C 追踪上下文

调用方活跃的 OTel span,经 W3C trace context 头传播进 CLI 子进程。结果:整个多进程的追踪,在你的后端里显示为一条 trace。这是第 23 节(OTel 约定)与第 24 节(可观测性)能跨进程串起来的工程地基。

Claude Managed Agents

托管的替代方案(beta 头 managed-agents-2026-04-01):长时异步工作、内置提示缓存、内置压缩。用控制权换托管基建——你不再管 Harness 进程,Anthropic 替你管。适合跑几小时的研究型 Agent;不适合需要精确控制执行环境的工作。

⚠️ 三种失败模式:① 子智能体过度派生(Subagent over-spawn)——为 100 个小任务派 100 个子智能体,开销(派生、上下文拷贝、结果汇总)压过收益;应批处理(如每组 5 个)。② 钩子蠕变(Hook creep)——每个团队都加钩子,启动时间膨胀;每季度评审一次钩子清单。③ 会话膨胀(Session bloat)——会话累积、体积增长;用 list_sessions + 过期策略定期清理。

二、从零实现

原课程 code/main.py 用标准库实现了 SDK 的形状:

  • ToolToolRegistry,带内置 read_filewrite_filelist_dir
  • Subagent——私有上下文、隔离运行、返回结果。
  • SessionStore——append、load、list、delete、list_subkeys。
  • Hooks——pre_tool_usepost_tool_usesession_startsession_end
  • 演示:主 Agent 并行派生 3 个子智能体(各自隔离),聚合结果,持久化会话。

Step 1:内置工具注册表

class ToolRegistry: def __init__(self): self.tools = { "read_file": lambda path: open(path).read(), "write_file": lambda path, content: open(path, "w").write(content), "list_dir": lambda path: os.listdir(path), } def call(self, name, **kw): return self.tools[name](**kw)

Step 2:子智能体(隔离上下文)

class Subagent: def __init__(self, instructions, tools): self.context = [] # 私有上下文,与编排者隔离 self.instructions = instructions self.tools = tools def run(self, task): self.context.append({"role": "user", "content": task}) # 在自己的窗口里跑循环,结果摘要返回 result = llm_loop(self.instructions, self.context, self.tools) return result["summary"] # 编排者只收到摘要,过程留在子智能体里

Step 3:会话存储 + 钩子

class SessionStore: def __init__(self): self.db = {} def append(self, sid, msg): self.db.setdefault(sid, []).append(msg) def load(self, sid): return self.db.get(sid, []) def list_sessions(self): return list(self.db.keys()) def delete(self, sid): self.db.pop(sid, None) # 真实版级联子键 def list_subkeys(self, sid): return [k for k in self.db if k.startswith(f"{sid}.")] class Hooks: def pre_tool_use(self, name, args): ... # 门控/审计 def post_tool_use(self, name, res): ... def session_start(self, sid): ... def session_end(self, sid): ...

Step 4:并行派生 + 聚合

def spawn_parallel(subagent_factory, tasks): results = [subagent_factory().run(t) for t in tasks] # 真实版用线程/进程池 return aggregate(results) # 编排者上下文只增加聚合摘要,非 N 份原始过程

运行 python3 code/main.py 会展示:子智能体的上下文隔离(编排者上下文体积保持有界)、钩子执行、会话持久化。

💡 设计要点:子智能体的价值不在「并行」本身,而在上下文隔离——编排者收的是 N 份摘要而非 N 份冗长过程。这正是 MemGPT(第 07 节)「外部存储」思想在多智能体层的复现:把噪音推出主上下文,只在需要时把结论换页换进来。

三、框架对比

框架/形态 何时选 关键取舍
Claude Agent SDK Claude 优先、想要 Claude Code 的 Harness 形状 Harness 原生化,绑 Anthropic
Claude Managed Agents 托管长时异步工作 用控制权换托管基建
OpenAI Agents SDK(第 16 节) OpenAI 优先 handoff/guardrail 原生
LangGraph + 自定义工具 想要图形状状态机 隔离/钩子/会话存储要自己接
Client SDK(anthropic) 已有 Harness、只要 API 客户端 自己拥有循环与状态

四、可复用产物

原课程 outputs/skill-claude-agent-scaffold.md:脚手架一个 Claude Agent SDK 应用——子智能体、钩子、会话存储、MCP 服务器挂载、W3C 追踪传播。把 Mock LLM 换成真实 Messages API 调用即可投入生产,Harness 的组合逻辑无需改动。

五、练习

  1. (Easy) 加一个子智能体派生器,把 20 个任务按每组 5 个批处理。测量编排者上下文体积 vs 逐个派生。
  2. (Medium) 实现一个 PreToolUse 钩子,对 write_file 限流(每会话每分钟 5 次)。追踪其行为。
  3. (Medium)list_subkeys 接到一个子智能体树渲染器。深度嵌套长什么样?
  4. (Hard) 把玩具移植到真实的 claude-agent-sdk Python 包。工具注册有什么变化?
  5. (Hard) 读 Claude Managed Agents 文档。你何时会从自托管切到托管?

本节要点回顾

  1. Harness 即产品:Client SDK 给裸 API(你拥有循环),Agent SDK 把 Claude Code 的 Harness 当库(工具/MCP/钩子/子智能体/会话存储全到位)。
  2. 子智能体两大用途:并行化(独立工作并发)、上下文隔离(只回结果,编排者预算受保护)。
  3. 会话存储五方法:append/load/list_sessions/delete(级联子键)/list_subkeys;--session-mirror 实时镜像对话用于调试。
  4. 六类钩子:Pre/PostToolUse、SessionStart/End、UserPromptSubmit、PreCompact、Stop、Notification——横切关注点的落点。
  5. W3C 追踪上下文:调用方 span 经 HTTP 头传播进 CLI 子进程,多进程汇成一条 trace。
  6. Claude Managed Agents:托管长时异步、内置缓存与压缩,用控制权换基建。
  7. 三大失败模式:子智能体过度派生(批处理)、钩子蠕变(季度评审)、会话膨胀(过期策略)。
  8. 上下文隔离是核心价值:编排者收摘要而非原始过程——MemGPT「外部存储」在多智能体层的复现。
  9. 选型:Claude 优先用本 SDK,要图形状用 LangGraph,已有 Harness 用 Client SDK。
  10. 跨进程可观测性地基:W3C + OTel 让第 23/24 节的追踪能跨子智能体、跨 CLI 子进程串起来。

下一节,我们看 Agno 与 Mastra 这类生产 Agent 运行时——把会话、记忆、工具、评估、可观测性整合成一个可部署服务的运行时,对比 Harness 即库与运行时即服务两种形态。


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