Harness Engineering 架构设计(三):记忆系统、工具设计与沙箱隔离
约 13 分钟3727 字1 次阅读

Harness Engineering 架构设计(三):记忆系统、工具设计与沙箱隔离
引言
第二篇我们深入了 Harness 的技术原理,理解了 Feedforward/Feedback 双轨控制和六层架构。
这一篇从系统设计角度,讲解生产级 Harness 的核心架构——三层记忆系统如何运转、工具系统如何设计、沙箱隔离怎么做、以及多 Agent 怎么编排。
一、三层记忆系统:Filesystem + RAM + Context Window
1.1 为什么是三层?
Harness 管理状态面临一个根本矛盾:
- Context Window 是有硬限制的(当前模型通常 128K-200K tokens)
- 但任务状态需要跨长会话持久化
- 同时每次请求都需要快速读写
三层记忆架构解决这个矛盾:
Filesystem(持久层)←→ RAM(工作层)←→ Context Window(感知层)
长期状态 会话状态 模型实际看到
1.2 Filesystem:长期记忆
作用:跨会话持久化的长期状态
典型内容:
- progress files(任务进度文件)
- feature lists(功能列表)
- git history(git 历史)
- session transcripts(会话记录)
- AGENTS.md 和约定文档
为什么不用向量数据库?
LangChain 的分析指出:每个生产级 Harness 都用文件系统作为主要状态机制。没有花哨的向量数据库,就是磁盘文件。
原因:
- 简单可靠:文件系统是经过几十年验证的
- Git 友好:版本控制天然集成
- Agent 友好:Agent 天生擅长文件操作
- 成本低:不需要额外的数据库基础设施
Anthropic 的实践:
在他们的 Long-Running Agent Pattern 中:
- 初始化 Agent 创建 progress file 和 feature list
- 编码 Agent 每轮读取 git logs 和 progress files
- 每轮结束时更新 progress file
- 没有数据库,只有文件系统
1.3 RAM:工作记忆
作用:当前会话内的快速状态
典型内容:
- 对话历史(完整原始记录)
- 工具调用结果(JSON 格式)
- 中间推理状态
- 当前任务上下文
特点:
- 快速读写
- 会话结束或 Context Reset 后丢弃
- 需要定期"冲刷"到 Filesystem 持久化
1.4 Context Window:感知记忆
作用:模型实际看到的、决定它行为的一切
约束:
- 硬限制(128K-200K tokens)
- 超过 40% 质量急剧下降
- 是三层中的最短板,决定系统吞吐量
核心操作:
| 操作 | 含义 |
|---|---|
| Load | 从 Filesystem 加载相关状态到 RAM |
| Assemble | 从 RAM 选择内容组装进 Context Window |
| Compact | 压缩冗长内容为摘要 |
| Flush | 将关键状态持久化到 Filesystem |
OpenClaw 的不变量:状态在从 Context 丢弃之前,必须先 Flush 到磁盘。Rehydration(再水化)被当作一个工具形动作——Agent 搜索然后检索特定数据,而不是把一切都塞进上下文。
二、工具系统设计
2.1 工具的分类
| 类型 | 作用 | 例子 |
|---|---|---|
| Bash | 通用命令执行 | 测试、构建、脚本 |
| Filesystem | 安全文件操作 | 读、写、编辑、搜索 |
| State Management | 会话内任务追踪 | Todo、进度队列 |
| Orchestration | 派生子 Agent | task tool、agent tool |
| MCP Servers | 外部系统集成 | GitHub、Slack、数据库 |
| Web Search | 实时信息获取 | 查库版本、API 变更 |
2.2 Bash:通用但需保护
Bash 是最强力的工具——Agent 可以运行任何 shell 命令,包括 rm -rf /。
设计原则:
- 工作目录限制:Agent 只能在指定目录内操作
- 危险命令拦截:删除系统文件、解密凭证等高危操作需要确认
- 超时控制:防止 Agent 陷入长时间运行的进程
2.3 Filesystem:安全文件操作
通过专用工具而非 Bash 做文件操作,优势在于:
- 路径验证:防止 Path Traversal 攻击
- 行数限制:防止读取超大文件撑爆上下文
- 编辑唯一性校验:确保替换目标唯一
- 原子操作:写入失败不回滚到错误状态
// Filesystem 工具的典型保护
ReadTool:
- 强制绝对路径
- 默认行数限制 500 行
- 大文件自动截断
EditTool:
- replacement string 必须唯一
- 超出上下文范围的编辑被拒绝
2.4 State Management:让 Agent 记住自己在做什么
OpenCode 有 TodoAdd / TodoRead 工具——Agent 可以往一个队列里加任务、读取任务状态。
这解决了 Agent 在长任务中"做到哪了"的问题。
2.5 反馈回路是工具设计的核心
Boris Cherny(Claude Code 创始人)的关键洞察:给模型验证自己工作的方式,质量提升 2-3 倍。
工具不只让 Agent 行动,还让 Agent 观察行动的结果。
好工具的例子:
- LSP 集成:实时代码诊断,未定义变量、类型错误立即反馈
- Test Runner:运行测试并解析输出,让 Agent 知道是否通过
- CI Status:读取 CI 流水线状态
2.6 工具访问控制
OpenCode 的设计:规划 Agent 不能调用 Edit 工具。
这防止探索 Agent 意外修改代码——规划者只管想,执行者只管改。
三、沙箱隔离策略
3.1 为什么需要沙箱
Agent 执行代码,代码可能:
- 运行失败
- Crash
- 删除你的文件
- 恶意行为(提示注入、窃取数据)
沙箱隔离确保 Agent 的失败不影响宿主机或其他 Agent。
3.2 硬沙箱 vs 软沙箱
| 策略 | 例子 | 优势 | 劣势 |
|---|---|---|---|
| 硬沙箱 | Codex 云容器 | 最大安全、完全隔离 | 不能访问宿主机文件系统 |
| 软沙箱 | OpenClaw 本地 | 最大能力、完全访问 | 风险更高 |
| 中间路线 | Docker 容器 | 平衡安全和能力 | 需要配置管理 |
Codex 的硬沙箱:
每个任务在隔离的云容器中运行,预加载了仓库。Agent 只能操作容器内文件,不能触碰宿主机。任务结束后,结果被提取,容器销毁。
OpenClaw 的软沙箱:
工作区就是默认工作目录。Agent 有完整的文件系统访问权限。OpenClaw 故意不选硬沙箱,以保留完整能力。
3.3 沙箱 + 水平扩展
沙箱的额外价值:水平扩展。
因为每个容器都是独立的,可以同时跑多个 Agent 处理不同任务。
Stripe 的 Devbox:AWS EC2 预装源码和服务的预热池,分配一个启动约 10 秒。用完释放回池,"牲口不是宠物"原则。
四、多 Agent 编排
4.1 何时需要多 Agent
Mitchell Hashimoto 的建议:
"我坚持一次只跑一个 Agent,保持深度参与。我不打算跑多个 Agent,也不想跑。"
但现实中有时候确实需要多 Agent:
| 场景 | 方案 |
|---|---|
| 任务太复杂,单 Agent 上下文不够 | 任务分解 + 结果聚合 |
| 需要不同专业能力 | 专业化 Agent 分工 |
| 需要并行加速 | 多 Agent 并行处理 |
一个反直觉的发现(Decoding AI):
"我一开始建了 5 个专业 Agent,每个处理一步。后来发现一个带记忆和智能上下文工程的单 Agent 表现超过了整个 Agent 群。"
建议:先用一个配得好的单 Agent,再考虑多 Agent。
4.2 Orchestrator-Worker 模式
当多 Agent 必要时,标准模式是:
Orchestrator(编排者)
→ 分解任务
→ 分配给专门的 Worker(工作者)
→ Worker 各自在独立上下文运行
→ Orchestrator 聚合结果
OpenCode 的 task tool:
- 派生带独立会话、上下文窗口、工具子集的子 Agent
- 任务结果通过 Event Bus 实时广播
- 主会话通过 lane-aware FIFO 队列管理
Claude Code 的 Ralph Loops:
当 Agent 试图用完上下文时,Harness 拦截退出意图,在干净上下文窗口中重新注入原始提示,用文件系统持久化的状态继续。
4.3 Carlini 的 16 Agent 并行实验
Nicholas Carlini 用 16 个 Claude Opus 实例并行,约 2000 个 Claude Code 会话,写出了一个 GCC torture test 通过率 99% 的 C 编译器。
他的设计细节:
- 日志不打印只写文件:用 grep 友好的单行格式
ERROR: [reason],主动控制上下文污染 - 测试子采样:每个 Agent 只跑随机 1-10% 的测试子集,但子采样对单次运行是确定性的,跨 VM 是随机的——集体覆盖全部测试,单 Agent 不会在测试里打转
- Agent 角色专业化:去重(去除重复实现)、性能优化、代码质量、文档
五、安全与权限控制
5.1 工具白名单
只允许 Agent 调用明确列入白名单的工具。
allowed_tools:
- Read
- Edit
- Bash(test)
- Bash(build)
- TodoAdd
- TodoRead
denied_tools:
- rm # 除非在特定目录
- curl # 网络访问受控
5.2 提示注入防护
CVE-2026-25253:OpenClaw 93.4% 的暴露实例曾受影响。
攻击原理:攻击者通过构造特殊文本,诱使 Agent 执行未授权操作。
防护措施:
- 输入验证:外部内容(用户上传、网页抓取)经过清洗再进上下文
- 工具调用审计:所有工具调用记录日志
- 最小权限原则:Agent 只应访问完成任务所需的最少资源
5.3 数据隔离
多租户场景下,确保一个租户的数据不被其他租户的 Agent 访问:
- 沙箱级别的租户隔离
- 工具调用按租户鉴权
- 审计日志覆盖所有数据访问
总结
生产级 Harness 的架构核心是三层记忆的精心管理:
Filesystem 是真相之源——所有重要状态必须持久化到这里
Context Window 是硬约束——40% 阈值、重置优于压缩
工具是 Agent 的四肢——安全设计、反馈优先、白名单控制
沙箱是安全边界——根据信任级别选择硬/软沙箱
多 Agent 是最后手段——先用配得好的单 Agent,再考虑编排
标签:#AI #Agent #HarnessEngineering #MemorySystem #Sandbox #MultiAgent