【AgentScope】12-HarnessAgent 总结回顾
HarnessAgent 总结回顾恭喜你走到了这里。如果你一路读到了这篇总结说明你已经把 HarnessAgent 的每一个模块都过了一遍。但学完了每个零件不代表理解了整台机器怎么运转。这篇总结只做一件事帮你把所有概念串起来让你产生原来都是连在一起的的感觉。一句话总结HarnessAgent 在裸 ReActAgent 之上通过 Hook 和 Toolkit 两个扩展点装配出一套让 Agent 能够长期、稳定、可靠运行的工程化基础设施。如果把 ReActAgent 比作一辆能跑的车HarnessAgent 不是重新造了一辆车而是给它装上了导航系统工作区上下文、行车记录仪会话持久化、自动变速箱对话压缩和对讲机子 agent 编排让它能跑长途而不出事故。全景图HarnessAgent 的架构分为三层薄包装层、推理内核、共享对象层。详细的三层架构剖析请参阅 02-architecture.md此处只做简要回顾。HarnessAgent薄包装层身份绑定 溢出兜底 └── ReActAgent推理内核reason → act → observe ├── Hook 链按 priority 排序的扩展点 └── Toolkit可调用的工具集合 共享对象层所有模块的协作底座 RuntimeContext身份 WorkspaceManager文件访问 AbstractFilesystem存储后端核心概念回顾概念一句话解释生活类比HarnessAgentReActAgent 的薄包装叠加工程化能力给裸车加装导航、记录仪、对讲机ReActAgent负责推理-行动-观察循环的推理引擎公司的核心业务部门Hook在推理循环的关键节点插入自定义逻辑各部门经理在关键审批节点签字Priority决定 Hook 执行顺序的数字越小越先执行签字的优先级越重要的越先签ToolkitAgent 可调用的工具集合公司的服务窗口每个窗口办不同的事RuntimeContext当次调用的身份信息sessionId、userId访客证记录你是谁、这次来访编号WorkspaceAgent 的家人格、记忆、知识都在这里公司的档案室所有资料统一存放双层记忆日流水账追加 长期记忆重写记者在现场的速记 编辑整理后的文章对话压缩消息超阈值时用 LLM 摘要历史保留尾部书太厚时把旧章节缩成摘要只留最近的原文沙箱Sandbox隔离执行环境文件和命令在容器内运行独立的实验操作间实验不影响大楼子 AgentSubagent主 Agent 委派任务的临时 Agent 实例项目经理把子任务外包给专业团队Skill一份写好的能力包放到工作区就生效买了一个工具箱放在工位上随时用会话持久化call() 结束后状态落盘下次自动恢复下班前保存工作进度明天接着干溢出恢复模型报 context overflow 时强制压缩重试包裹太大被拒收压缩后重新寄出其他实现细节级概念如 NamespaceFactory、MemoryIndex、SandboxExecutionGuard、WorkspaceManager、IsolationScope、SkillBox、EventSource 等请查阅对应章节。一条消息的生命旅程好了概念都列出来了。但这些概念到底怎么配合的让我们跟踪一条用户消息从它进入 HarnessAgent 到最终返回看它经历了什么。第一幕前台接待你是一条用户消息“帮我分析一下最近三天的销售数据。”你来到一栋大楼前门口有个前台就是HarnessAgent。前台做的第一件事不是处理你而是确认你的身份。agent.call(msg,ctx)// ctx 里装着 sessionId 和 userId前台接过你的访客证RuntimeContext开始bindRuntimeContext把你的 sessionId 和 userId 记录下来通知所有部门经理Hook“这次来访的是 session-001 号的 alice 女士”如果 alice 女士上次来过从档案室调出她的工作进度loadIfExists恢复到她的 Memory 里如果是第一次来访呢那就从零开始Memory 是空的。第二幕部门经理们开会你被引到了核心业务部门ReActAgent。在正式工作之前各个部门经理要按照固定顺序priority开个碰头会。这个碰头会就是PreReasoningEvent。第一位发言的是 TraceHookpriority 0“我记录一下本次会议的开始时间。”第二位发言的是 CompactionHookpriority 10“让我检查一下 alice 女士的对话记录……嗯已经积累了 35 条消息超过了 30 条的阈值。我需要先清理一下。”CompactionHook 做了三件事让 LLM 把旧消息提炼成摘要把原始消息归档到.log.jsonl完整的不丢把提炼出的新事实追加到memory/2026-06-01.md今天的流水账只保留最近 10 条消息 摘要其余清掉如果消息没超阈值CompactionHook 就什么都不做直接过。第三位发言的是 SubagentsHookpriority 80“我来告诉系统目前可用的子团队有general-purpose通用助手、data-analyst数据分析师。”它把这些信息注入到 system prompt 里这样主 Agent 在推理时就知道可以委派谁。最后发言的是 WorkspaceContextHookpriority 900“轮到我了。让我从档案室取出 alice 女士的资料……”它从工作区读取了几个关键文件全部塞进 system promptAGENTS.md你是谁、该怎么做事人格MEMORY.md之前沉淀的长期记忆比如 alice 之前说她负责华东区knowledge/KNOWLEDGE.md领域知识比如销售数据的分析规范今天 Session 的上下文信息为什么 WorkspaceContextHook 要最后执行因为它拼的是最终的 system prompt。前面的 Hook 可能修改了上下文它必须等所有人都改完才能拼最终版本。第三幕正式工作——推理循环碰头会开完了ReActAgent 开始进入推理循环reason → act → observe。Reason推理Agent 思考了一下得出结论——“我需要调用 read_file 工具读取销售数据文件然后做分析。但这个任务比较重我应该委派给>第四幕收尾工作——下班前的整理Agent 终于给出了最终回复。但工作还没结束。PostCallEvent触发又一批部门经理出来做收尾TraceHookpriority 0“我记录一下本次会议的结束时间和结果。”MemoryFlushHookpriority 5“对话里有不少有价值的信息比如 alice 说她用的是新版报表系统。让我把这些新事实提取出来。”它把对话交给 LLM 提炼得出新增的 bullet 点追加到memory/2026-06-01.md。然后告诉后台调度器“有空的时候合并一下记忆。”MemoryMaintenanceHookpriority 6“收到我看看能不能触发一次合并。不过如果 30 分钟内已经合并过了就先不急。”SessionPersistenceHookpriority 900“最重要的——让我把这次的状态保存下来。”它把当前 Memory 快照、ToolExecutionContext 等所有 StateModule 序列化写入agents/agentId/context/sessionId/memory.json。这样下次 alice 再来bindRuntimeContext 能直接恢复到这里。第五幕意外情况——溢出恢复如果运气不好模型报了一个 ContextOverflow 错误上下文太长了HarnessAgent 的应急机制启动HarnessAgent.forceCompactAndRetry → 拼一个 triggerMessages1 的临时压缩配置 → 强制压缩清空 Memory → 重新调一次 delegate.call(msg)就像包裹太大被快递拒收前台帮你重新打包压缩后再寄一次。旅程总结用户消息 │ ▼ 前台HarnessAgent验明身份恢复历史 ──────① bindRuntimeContext │ ▼ 碰头会PreReasoningEvent Hooks 按优先级 │ TraceHook: 记日志 │ CompactionHook: 超阈值就压缩 │ SubagentsHook: 注入子 Agent 列表 │ WorkspaceContextHook: 注入人格记忆知识 │ ▼ 推理循环reason → act → observe──────── ② ReAct Loop │ 思考 → 调工具 → 观察结果 → 再思考... │ ▼ 收尾会PostCallEvent Hooks 按优先级 │ TraceHook: 记日志 │ MemoryFlushHook: 提取记忆 归档 │ MemoryMaintenanceHook: 触发后台合并 │ SessionPersistenceHook: 保存状态 │ ▼ 返回最终消息给用户 ────────────────────────③ final Msg 意外路径ContextOverflow → forceCompactAndRetry → 重试设计模式总结HarnessAgent 的架构里藏着好几个经典设计模式的身影。以下是最核心的两种1. 装饰器模式DecoratorHarnessAgent 是 ReActAgent 的装饰器。它不替换 ReActAgent 的推理循环而是在外围叠加能力。HarnessAgent装饰器 └── delegate: ReActAgent被装饰的核心类比给手机套上一个带电池的保护壳。手机本身的功能完全不变但你多了一层电池续航。2. 观察者模式Observer/ 事件驱动ReActAgent 在推理循环的各个节点发布事件PreReasoning、PostReasoning、PreActing、PostActingHook 是事件的订阅者。ReActAgent事件发布者 │ PreCallEvent │ PreReasoningEvent │ PostReasoningEvent │ PreActingEvent │ PostActingEvent │ PostCallEvent │ ErrorEvent │ └──→ Hook们事件订阅者类比公司广播系统。关键节点播报通知相关部门经理听到后各自行动。进阶读者可自行分析责任链模式Hook 按 priority 依次传递、策略模式AbstractFilesystem 可插拔后端、工厂方法模式子 Agent 按声明创建、模板方法模式build() 固定构建流程。知识检验基础题HarnessAgent 和 ReActAgent 是什么关系HarnessAgent 替换了 ReActAgent 的推理循环吗Hook 的 priority 数字越小越先执行还是越大越先执行WorkspaceContextHook 的 priority 是 900为什么它要排在最后双层记忆模型中流水账和策划后长期记忆分别对应哪个文件它们在写入策略上有什么区别追加 vs 重写会话持久化是在哪个 Hook 里完成的它在 PostCallEvent 里的 priority 是多少为什么它要排在最后子 Agent 的声明来源有哪几种文件声明的文件名和agent_id是什么关系思考题HarnessAgent 的设计哲学是薄包装不替换推理循环。如果将来你要设计自己的 Agent 框架你会采用同样的方式吗为什么Hook 之间不持有彼此的引用只通过三个共享对象RuntimeContext、WorkspaceManager、AbstractFilesystem协作。这种松耦合的设计有什么好处在什么场景下可能会成为限制双层记忆模型中流水账只追加、长期记忆整体重写这个设计决策的取舍是什么如果反过来流水账重写、长期记忆追加会有什么问题下一步学完 HarnessAgent 的全貌之后你可以往这些方向深入动手实践从 Quickstart 示例 开始自己跑一遍完整的代码尝试配置不同的 CompactionConfig 参数观察压缩行为的变化在工作区里添加自定义 Skill体验技能的加载和使用编写一个子 Agent 声明文件实现一个简单的多 Agent 协作场景深入原理阅读agentscope-harness的源码特别是HarnessAgent.Builder.build()方法看它是如何一步步组装各个组件的跟踪一次完整的call()调用链路在关键 Hook 处打断点观察研究AbstractFilesystem的类层次结构理解不同后端的实现差异生产落地学习沙箱模式的配置尝试用 Docker 后端实现隔离执行研究分布式场景sandboxDistributed下的 Session 和快照管理了解SandboxExecutionGuard在多副本部署下的并发控制策略拓展视野对比其他 Agent 框架如 LangGraph、CrewAI的设计思路思考 HarnessAgent 的取舍关注 Agent 评估Evaluation和可观测性Observability方向这些是生产环境的关键能力探索多 Agent 编排的更多模式层级式、对等式、市场式思考 HarnessAgent 的子 Agent 模型适合哪些场景