课题四:Agent 执行沙箱与 Harness 工程
状态: Layer 1 认知层 — 调研完成 ✅ (2026-05-30) 优先级:P1 — Agent 执行层的基础设施,决定能力边界和安全基线
调研结论速览
推荐方案:分层渐进式沙箱架构
| 阶段 | 方案 | 周期 | 依赖 | 覆盖工具 |
|---|---|---|---|---|
| Phase 1 | Python 级安全包装(路径白名单 + rlimit + 超时 + 审计日志) | 1-2 天 | 零额外依赖 | code_run, file_read/write/patch |
| Phase 2 | macOS sandbox-exec 加固 | 2-3 天 | macOS 原生 (sandbox-exec) | 全工具 |
| Phase 3 | Docker 容器化(可选) | 2-3 天 | Docker Desktop/OrbStack | code_run + browser |
核心结论:短期 subprocess+sandbox-exec(4-5 天,零额外依赖),Docker 化时机为多实例/浏览器隔离需要时。
9 原子工具风险分类
| # | 工具 | 风险 | 说明 |
|---|---|---|---|
| 1 | code_run | 🔥 高危 | subprocess.Popen 直接执行任意 Python/bash,无限制 |
| 2 | web_execute_js | 🔥 高危 | 通过 CDP 执行任意 JS,可读写浏览器数据 |
| 3 | file_write | 🔥 高危 | 写任意路径文件,无路径白名单 |
| 4 | file_patch | 🔥 高危 | 修改任意文件内容 |
| 5 | file_read | ⚠️ 中危 | 读任意路径文件,可数据外泄 |
| 6 | web_scan | ⚠️ 中危 | 获取浏览器页面内容 + 标签页 |
| 7-9 | ask_user/checkpoint/no_tool | ✅ 低危 | 无副作用 |
Docker vs subprocess+seccomp 对比矩阵
| 维度 | Docker | subprocess+seccomp |
|---|---|---|
| 隔离强度 | ★★★★★ 内核级命名空间 | ★★★ 进程+文件级 |
| 性能损耗 | ~5-8%(macOS Docker Desktop) | ~0-2%(native) |
| 启动延迟 | 0.5-5s | 1-50µs |
| 文件 I/O | 差(macOS VM 桥接层) | 好(原生) |
| 系统调用控制 | ✅ seccomp 精确到每个 syscall | ⚠️ macOS sandbox-exec 粗粒度 |
| 资源限制 | ✅ 硬件级(—cpus/—memory) | ⚠️ 用户态(rlimit,可被绕过) |
| 网络隔离 | ✅ iptables/nftables | ⚠️ sandbox-exec 粗粒度 |
| 实现成本 | 7-11 天 | 4-5 天(macOS)/ 6-8 天(含 Linux) |
| 维护成本 | 中(Docker Desktop 更新) | 低(系统自带) |
| macOS 支持 | ⚠️ 需 Docker Desktop/OrbStack | ✅ 原生 sandbox-exec |
Harness 工程架构设计
class ToolHarness:
"""统一工具执行层 —— 策略模式"""
def execute(self, tool_name, args):
validated = self._validate(tool_name, args)
self._check_permission(tool_name, validated)
self._check_quota(tool_name)
result = self._sandbox_execute(tool_name, validated)
filtered = self._filter_output(result)
self._audit_log(tool_name, validated, filtered)
return filtered
def _sandbox_execute(self, tool_name, args):
strategy = self._sandbox_strategy(tool_name)
if strategy == 'native': # Phase 1
return self._exec_native(...)
elif strategy == 'sandbox_exec': # Phase 2
return self._exec_with_sandbox(...)
elif strategy == 'docker': # Phase 3
return self._exec_in_container(...)关键决策
| # | 决策 | 推荐 | 理由 |
|---|---|---|---|
| 1 | 初始沙箱方案 | subprocess + sandbox-exec | 零依赖、低延迟、改造量小 |
| 2 | Docker 化时机 | 多实例/浏览器隔离需要时 | 当前单 Agent 开发阶段无需容器 |
| 3 | Phase 1 与 Docker 接口一致性 | 策略模式 | Phase 1 包装层与 Docker 化不冲突 |
| 4 | macOS 方案 | sandbox-exec (Seatbelt) | 系统内置,无需额外安装 |
实施路径
Week 1: 路径白名单 + 命令白名单 + resource limits + 基础审计日志
Week 2: macOS sandbox-exec profile + 逃逸测试
Week 3 (可选): Dockerfile + docker-py SDK + 容器生命周期管理
核心改动范围: ga.py 的 _get_abs_path + code_run 包装层 + sandbox profile
研究方向
1. 执行环境架构
- 进程级沙箱 — subprocess + seccomp / landlock 限制系统调用
- 容器级沙箱 — Docker / Podman 每个 agent 实例独立容器
- 函数即服务 — 每个工具调用作为 serverless function 执行
- 混合模型 — 轻量操作本地执行,高风险操作沙箱隔离
2. 安全执行
- 代码执行沙箱:Python eval / JavaScript / shell 的安全限制
- 文件系统隔离:每个 agent 的读写范围限定
- 网络策略:允许访问的域名/IP 白名单
- 资源限制:CPU 时间、内存上限、磁盘配额、并发数
- 超时控制:工具调用的超时、重试、熔断
3. 工具执行管线
Agent 请求 → 参数校验 → 权限检查 → 资源配额检查 → 执行 → 输出过滤 → 结果返回
↓ 失败
拒绝/降级 ← 告警 → 审计日志
- 参数校验:防止注入攻击(shell 注入、路径穿越)
- 权限检查:操作是否在当前 agent 的权限范围内
- 审计日志:每个工具调用的完整因果链
- 输出过滤:敏感信息脱敏、结果大小限制
4. 工具通信协议(MCP)
- MCP(Model Context Protocol) 集成方案 — 将现有工具封装为标准 MCP 工具
- 工具发现 — Agent 如何知道有哪些工具可用、怎么用
- 工具描述格式 — OpenAPI / JSON Schema / MCP Tool 定义的对比与选型
- 统一协议适配层 — 支持同时接入 MCP、Function Calling 等多种协议
- 调用结果反馈 — 成功/失败、部分结果、进度更新的标准化返回格式
- 错误传播 — 工具内部错误如何带着上下文回到 Agent
- 现有 9 个原子工具的 MCP 迁移顺序与兼容方案
5. 浏览器/GUI 操作 Harness
浏览器是 Agent 最复杂的外部工具——它涉及可视化的感知-决策-操作闭环、反检测策略、以及多实例隔离。GenericAgent 的 TMWebDriver.py 是核心实验场。
5a. 浏览器实例生命周期
- 每个 Agent 实例关联独立的浏览器 profile/会话,互不干扰
- 浏览器实例随 Agent 生命周期自动创建和回收:Agent 启动 → 按需启动浏览器 → 空闲休眠释放 → 回收时清理缓存/profile
- 浏览器复用策略:同一 Agent 的短期间隔操作复用已有会话,避免重复登录开销
5b. 浏览器 Harness 集成架构
- TMWebDriver.py 的 CDP(Chrome DevTools Protocol)层封装到统一 harness,通过策略模式选择执行后端:CDP 直连(当前) vs Playwright 封装 vs Browserless 远程
- 统一接口规范:
wait_for_element → 导航/操作 → 截图 → 页面状态分析 → 结果验证 - Harness 为浏览器操作提供与文件/代码操作一致的:权限检查、超时控制、审计日志、输出过滤
5c. 视觉感知-操作闭环
截图 → LLM 分析页面 → 确定下一步操作 → CDP 执行 → 截图验证效果 → 直到目标达成
- 截图策略:全页面 vs 视口 vs 元素级,按操作类型选择。长流程用关键帧截图(非每一步都截)
- 操作抽象:click/input/select/scroll/hover/navigate,参数化定义,方便 LLM 调用
- 验证机制:操作后自动截图,LLM 对比操作前后判断是否达到预期。失败时自动重试或报告降级
- 反检测策略:User-Agent 伪装、WebDriver 特征隐藏、窗口尺寸随机化、操作间隔抖动
5d. 浏览器操作的安全与隔离
- 页面导航白名单:限制 Agent 只能访问允许的域名
- 敏感操作审批:文件下载、表单提交、支付等操作需用户确认
- Cookie/Storage 隔离:不同 Agent 的登录状态不交叉
- 资源限制:同时打开的标签页数上限、内存上限、操作频率上限
- 与课题十一(安全边界)的联动:浏览器是 Agent 最容易造成实际影响的外部接口,安全策略在此细化落地
6. 会话与状态管理
Agent 从启动到回收的全生命周期管理,以及执行状态的持久化与恢复。
6a. Agent 实例生命周期
启动 → 授权 → 工作(循环执行工具调用)
→ 空闲 → 休眠(释放资源但保留上下文)
→ 唤醒 → 继续工作
→ 回收(清理资源、归档日志)
- 四种状态:活跃(正在执行)、空闲(等待用户输入/下一个任务)、休眠(上下文持久化到磁盘、释放进程资源)、终止(清理退出)
- 状态转换触发条件:超时空闲 → 休眠,新任务到达 → 唤醒,用户主动终止 / 系统 shutdown → 回收
- 每个实例有唯一 session ID,所有日志/状态/授权绑定到 session
6b. 状态持久化与 Checkpoint
- Checkpoint 触发时机:工具调用前后、步骤完成、用户确认、长时间运行定期
- 序列化内容:Agent 内部状态(变量/堆栈/对话上下文)、已执行的工具调用及其结果、授权 token 和安全上下文
- 存储策略:近期 checkpoint 全量保留,历史 checkpoint 增量压缩,过期自动清理
- 重启恢复流程:检测崩溃 → 加载最新 checkpoint → 干运行验证外部状态一致性 → 继续执行未完成步骤
- 职责边界:本课题只负责 checkpoint 的序列化/存储/加载机制,触发策略和恢复决策由课题二十二(自我验证)定义
- 与课题二十二的联动:checkpoint 为故障恢复提供还原点,恢复策略(重试/回滚/降级)在此决策
6c. 长连接与实时通信管理
- WebSocket / SSE 连接的保活策略:心跳间隔、自动重连、指数退避
- 连接断开时的缓冲区设计:离线期间的消息暂存,重连后按序重放
- 同一 Agent 跨多个 bot 接口(TG/微信/钉钉)的连接复用与会话路由
6d. 资源生命周期
- 关联临时资源(临时文件、浏览器实例、数据库连接)随 Agent 生命周期自动清理
- 资源泄漏检测:Agent 持有的资源在回收时未释放 → 告警 + 强制清理
- 配额管理:每个 Agent 实例的资源上限(CPU/内存/并发数/临时磁盘)
7. 可观测性(Observability)
Harness 是 Agent 执行所有工具调用的必经之路,天然适合作为可观测数据的采集点。数据为故障恢复(课题二十二)提供触发信号,为安全审计(课题十一)提供证据链,为评估(课题十)提供原始数据。
7a. 调用级指标(Metrics)
| 指标 | 来源 | 用途 |
|---|---|---|
| 每次工具调用耗时 | harness 计时 | 性能分析、异常检测(突然变慢 → 可能异常) |
| 成功/失败/超时计数 | harness 返回值 | 可靠性统计、告警触发 |
| token 消耗(LLM 工具调用) | LLM 响应头 | 成本追踪、异常突增告警 |
| 资源使用(CPU/内存/磁盘) | 进程级别采集 | 资源泄漏检测、配额预警 |
| 并发工具数 | harness 调度器 | 负载管理、限流决策 |
7b. 链路追踪(Tracing)
- 从用户请求到最终工具执行的完整有向无环图
- 每个 span 记录:工具名、入参摘要、出参摘要、耗时、状态、关联的 agent session
- 错误时自动捕获现场(入参 + 错误堆栈 + 当时的 agent 状态快照)
- 追踪数据同时为以下场景服务:调试(定位哪一步出问题)、审计(谁做了什么)、评估(步骤效率)
- 下游消费:追踪原始数据为本课题产出,为课题十二(可解释性)提供因果链原材料
7c. 告警与自动响应
- 告警规则示例:
- 连续 N 次工具调用失败 → 触发熔断 + 通知
- 某 Agent 资源使用持续超过阈值 → 触发降级
- 敏感操作(文件写/代码执行)频率突增 → 触发安全审核
- Checkpoint 写入失败 → 触发警告(恢复能力受损)
- 响应动作链:告警 → 通知用户 → 自动降级/重路由 → 记录到审计日志 → 触发事后分析
- 与课题二十二的联动:告警是故障恢复的触发入口。可观测性发现异常 → 自我验证确认故障 → 恢复策略执行
7d. 审计日志
- 每条审计日志包含:session ID、时间戳、工具名、入参、出参摘要、结果、耗时
- 日志结构化(JSON Lines),支持按 session/工具/结果/时间范围查询
- 日志保留策略:近期(30 天)全量,历史(90 天)聚合,超过归档
- 审计日志为课题十一(安全边界)提供证据链:谁在什么时候用什么参数调用了什么工具
8. 与 agent_loop.py 的集成
- 当前 9 个原子工具中有哪些需要包装 / 迁移到 harness
- 最小侵入方案:先包装现有工具,再加执行策略
- 向后兼容:现有的 bot 接口(TG/微信等)不受影响
产出形式
- 执行环境架构方案(沙箱选型 + 隔离模型)
- Harness API 设计(工具注册、执行、监控接口)
- 安全策略配置格式
- 与现有 agent_loop.py 的集成方案
关联课题
- agent-safety-boundary — 安全策略在此落地
- agent-memory-system — 记忆读写需要经过 harness 的权限控制
- agent-collaboration-communication — MCP 等通信协议在 Harness 层落地
- agent-tool-learning — 工具学习新增的工具需要注册到 harness
- agent-evaluation-framework — 评估需要在 harness 内执行
- self-verification — 可观测性为故障恢复提供触发信号,checkpoint 为恢复提供还原点
参考资料
- Docker / Podman 容器安全最佳实践
- gVisor / Firecracker 微 VM 方案
- OpenAI Code Interpreter 的沙箱设计公开资料
- Modal / Fly Machines 的 serverless 执行架构
- seccomp / AppArmor / SELinux 等内核安全机制
- OpenHands(前 OpenDevin)— 自动化软件工程 Agent 平台(72K stars)
- 1jehuang/jcode — Rust 写的高性能 Agent 执行 harness
- LangGraph — 图编排 agent 框架(24K stars),87% 任务成功率