OpenHands技术架构解析 + 本地部署复刻指南:从原理到跑通一个Bug修复

OpenHands 在 GitHub 上已经攒到了 78,597 颗星。

这个数字说明它不是一个玩具项目。但翻了一圈中文内容,发现大多数停留在"安装教程"或者"功能演示"层面。很少有人认真拆解过它为什么这样设计、架构上做了哪些取舍、实际跑起来到底是什么效果。

这篇文章试图补上这块。我会从架构拆解入手,然后在本地完整部署并实测一个真实 Bug 修复,最后聊聊这套设计背后的得与失。

所有代码和配置都会在文内给出,你可以跟着复刻。

项目背景

OpenHands 的前身是 2024 年 3 月启动的 OpenDevin 项目,同年 7 月更名。背后的公司 All Hands AI 在 2025 年 11 月完成了 1880 万美元的 A 轮融资,由 Madrona 领投。

核心团队三个人值得记住:

  • Robert Brennan,CEO,之前做过 LucyBot
  • Graham Neubig,首席科学家,CMU 教授,项目学术发起人
  • Xingyao Wang,首席 AI 官,CodeAct 论文一作

项目定位是"AI-Driven Development 开源平台",MIT 协议(enterprise/ 目录除外)。

整体架构

图:OpenHands 的核心不是“自动写代码”,而是把事件流、工具调用和安全沙箱串成可追踪工作台。

图:OpenHands 的核心不是“自动写代码”,而是把事件流、工具调用和安全沙箱串成可追踪工作台。

OpenHands 的架构可以分成五层:

用户接口层 (Web UI / SDK / CLI)
      ↓
Agent 核心 (事件循环 + LLM 调度)
      ↓
工具系统 (文件编辑 / 终端 / 浏览器 / 自定义)
      ↓
执行环境 (Docker 沙箱 / 远程容器 / 本地)
      ↓
状态管理 (事件溯源 + 确定性重放)

下面逐个拆解关键设计决策。

设计决策 1:事件溯源

这是 OpenHands 最核心的架构选择。

每个 Agent 的动作——LLM 调用、工具执行、用户输入——都被记录为不可变事件。这意味着你可以精确重放任何一次 Agent 运行,看到它每一步做了什么、为什么这样做。

SDK 论文(arxiv:2511.03690)给了一个数据:V1 架构(基于事件溯源)相比 V0 减少了 61% 的系统归因故障。论文说事件溯源本身的开销"可忽略不计"。

这个设计的好处是调试极其友好。Agent 出了问题,你不需要猜——直接回看事件流,每一步都有记录。坏处是高频交互场景下事件量会很大,虽然论文说开销可忽略,但在极端场景下可能不是这样。

设计决策 2:工作空间抽象

同一套 Agent 代码可以在本地、Docker 容器、远程服务器上运行,改动最小。

关键接口是 LocalWorkspaceRemoteWorkspace。开发的时候用本地工作空间方便调试,生产环境切到远程沙箱,Agent 逻辑本身不需要改。

这个设计很实用。它解决了"在我机器上能跑"的问题——开发环境和生产环境用的是同一套抽象。

设计决策 3:类型化工具系统

工具不是字符串拼接,而是有类型定义的接口。每个工具有明确的输入/输出 schema。

内置工具包括:

  • file_editor:读取、编辑、创建文件
  • terminal:执行 shell 命令
  • browser:浏览器操作(可选)

可以通过插件扩展自定义工具。类型化的好处是减少 LLM 幻觉导致的工具调用错误——模型看到的是结构化的参数定义,不是自由文本。

设计决策 4:安全沙箱

默认在 Docker 容器中执行代码。网络隔离、文件系统隔离、资源限制,Agent 不会意外破坏宿主环境。

这是生产环境的基本要求。你不想让一个 AI Agent 有权限删你系统文件。

核心组件详解

Agent 事件循环

Agent 的核心是一个事件驱动的循环:

1. 接收任务描述 → 生成初始事件

2. LLM 根据当前事件历史决定下一步动作

3. 执行工具调用 → 产生新事件

4. 重复直到任务完成或达到限制

关键类是 AgentEventStreamActionObservation。每次 LLM 的输出是一个 Action(比如"读取文件 X"),执行结果是一个 Observation(文件内容),然后 LLM 再根据这个 Observation 决定下一步。

LLM 调度层

模型无关设计。通过 LiteLLM 统一接口,支持 100+ 提供商。切换模型只需要改配置,不需要改 Agent 代码。

这次实测我用的是 qwen3.7-plus,通过自定义 API 端点调用。

工具系统的 ACI 设计

这里要提一下 SWE-agent 论文(arxiv:2405.15793)的影响。SWE-agent 提出了 Agent-Computer Interface(ACI)的概念——AI Agent 是一类新的"终端用户",需要专门设计的界面。

OpenHands 的工具系统吸收了类似理念。file_editor 不是简单的 sed 包装,而是提供了结构化的编辑接口(指定文件名、要替换的内容、替换后的内容),降低 LLM 犯错的概率。

本地部署全流程

环境准备

  • 系统:Linux / macOS
  • Python:3.11+
  • Docker:推荐安装(用于沙箱执行)

安装 SDK

pip install openhands-ai==1.8.0

编写运行脚本

这次实测用的是 SDK 方式。核心脚本如下:

from openhands import Agent, LLMConfig

# 配置 LLM
config = LLMConfig(
    model="qwen3.7-plus",
    api_key="your-api-key",
    base_url="your-api-base-url"
)

# 创建 Agent
agent = Agent(config=config)

# 运行任务
result = agent.run(
    task="Fix the bug in calculator.py. Run the tests to verify.",
    workspace="./test-project/"
)

print(result)

你需要替换 api_keybase_url 为你自己的 LLM API 配置。我用的是 aifatepilot 的 API 代理,你也可以直接用 OpenAI、Anthropic 或其他兼容端点。

使用 Docker 方式(替代方案)

如果不想用 SDK,也可以直接跑 Docker:

docker run -it openhands/openhands

然后访问 http://localhost:3000 使用 Web UI。

常见问题

  • Docker 权限问题:确保当前用户在 docker 组
  • API 连接超时:检查 base_url 和代理设置
  • 模型不支持工具调用:确认模型支持 function calling
  • 工作目录权限:确保 Agent 有读写权限

实测复现:让 OpenHands 修复一个真实 Bug

测试项目

我准备了一个简单的 Python 计算器项目:

test-project/
├── calculator.py      # 4个函数:add, subtract, multiply, divide
└── test_calculator.py # 6个单元测试

预埋的 Bug:divide() 函数写成了 return a,而不是 return a / b

测试覆盖包括正常除法、除以1、浮点除法、除以负数等场景。

运行结果

启动脚本后,Agent 的执行过程如下:

1. 读取项目文件列表(ls

2. 读取测试文件,理解预期行为(file_editor: read test_calculator.py

3. 运行测试,确认哪个失败了(terminal: pytest)→ test_divide 失败

4. 读取 calculator.py,定位 Bug(file_editor: read calculator.py

5. 修改代码(file_editor: editreturn areturn a / b

6. 重新运行全部测试(terminal: pytest)→ 6/6 通过

7. 报告完成

总耗时 61.9 秒。模型 qwen3.7-plus。

行为链分析

几个值得注意的点:

Agent 没有"猜"答案。它通过运行测试确认了 Bug 的存在,修改后又跑了一遍测试确认修复成功。这是一个完整的"假设→验证"循环。

工具使用合理。先读后改,改完验证。没有多余操作。

61.9 秒里大部分时间是 LLM 推理耗时,工具执行本身很快。API 延迟会显著影响总时间。

架构设计的得与失

优势

  • 事件溯源让调试变得简单,每次运行都可以精确回放
  • 工作空间抽象让开发和生产环境一致
  • 类型化工具减少了 LLM 的工具调用错误
  • 安全沙箱是生产环境的基本保障

代价

  • Docker 依赖增加了部署复杂度,不是所有环境都能跑
  • Agent 能力高度依赖底层 LLM——架构再好,模型不行也白搭
  • SWE-bench-Live 上只有约 20% 的新 Issue 解决率,说明模型能力才是真正的瓶颈

与 SWE-agent 的对比

简单说一下两者的定位差异。

OpenHands 走的是生产路线:完整架构、Docker 沙箱、插件生态、远程执行。适合需要稳定运行的场景。

SWE-agent 走的是研究路线:最小实现、文本优先、专注 ACI 设计。适合做论文基线和学术研究。

CodeSOTA 有句话说得挺准:"If you are writing a paper, use SWE-agent. If you are shipping a product, use OpenHands."

两者不是竞争关系,是不同场景的最优解。

注意事项

几个需要提醒的点:

1. 这次实测只是一个简单的单文件 Bug 修复。复杂项目(多文件、跨模块、需要架构设计)的表现差距很大。SWE-bench-Live 的 19% 解决率才是更接近真实世界的数字。

2. 模型选择对结果影响很大。我用的是 qwen3.7-plus,一个中等能力的模型。用 Claude Sonnet 或 Opus 级别的模型,Agent 的行为链可能更高效。

3. API 成本。Agent 一次任务会进行多次 LLM 调用(读文件、分析、修改、验证),token 消耗比单次对话高很多。跑复杂任务之前要有成本预期。

4. 架构细节基于 openhands-ai v1.8.0(2026年6月版本)。SDK 迭代很快,后续版本可能有 API 变化。

5. 不存在所谓的"OpenHands 和 SWE-agent 联合论文"。两个项目分别由 All Hands AI 和 Princeton NLP 维护,各自发布独立论文。

总结

OpenHands 的架构设计代表了当前 AI Agent 工程的一个不错的参考:事件溯源、沙箱执行、类型化工具、工作空间抽象。这些不是花哨的概念,而是从 18 个月开源开发中提炼出来的实战经验。

但架构不是万能的。SWE-bench-Live 的 20% 解决率说明,模型能力才是真正的瓶颈。框架做得再好,底层 LLM 理解不了复杂需求,Agent 也帮不上忙。

对于想复刻的开发者:本地部署并不复杂,pip install 加一个脚本就能跑起来。关键是选对模型、设计好任务描述。任务拆得越细,Agent 表现越好。

延伸方向可以考虑:多 Agent 协作、自定义工具开发、与 CI/CD 集成。这些是 OpenHands SDK 已经支持但大多数人还没用起来的场景。


参考资料

  • OpenHands GitHub: https://github.com/OpenHands/OpenHands
  • OpenHands SDK 论文: https://arxiv.org/abs/2511.03690
  • SWE-agent 论文: https://arxiv.org/abs/2405.15793
  • OpenHands 平台论文: https://arxiv.org/abs/2407.16741
  • SWE-bench 官方: https://www.swebench.com/
  • SWE-bench-Live 数据: localaimaster.com/blog/openhands-vs-swe-agent
  • CodeSOTA 对比: codesota.com/agentic/openhands-vs-swe-agent

*实测环境:openhands-ai v1.8.0, qwen3.7-plus, 2026-06-29*

Last modification:June 29, 2026
如果觉得我的文章对你有用,请随意赞赏