首页
/ OpenHands Agent Canvas:自托管编码 Agent 控制中心的安装、运行与架构解析

OpenHands Agent Canvas:自托管编码 Agent 控制中心的安装、运行与架构解析

2026-09-04 11:03:15作者:冯梦姬Eddie

OpenHands Agent Canvas 是一个自托管的开发者控制中心,用于在同一界面上启动、切换和自动化多个编码 Agent(OpenHands、Claude Code、Codex、Gemini 等),支持本地、Docker 沙箱与云端后端的灵活部署。本文基于仓库根目录 README.md 展开,覆盖三种安装方式的完整命令、CLI 参数与环境变量、Docker 镜像的内部服务路由,并结合源码给出端口、版本与调用链的实现证据。读完后可独立完成从笔记本快速试用到 VM 上长期运行的完整部署。

定位:把编码 Agent 变成常驻工程团队

Agent Canvas 的核心价值在于把分散的编码 Agent 收敛到一个自托管的控制中心:

  • 开箱即运行开源的 OpenHands Agent,也可驱动任意第三方 Agent(Claude Code、Codex、Gemini CLI 等任何兼容 ACP 协议的 Agent);
  • 默认在本地机器上运行,但可连接多个「Agent 后端」(agent backend),例如把 Agent 放进 Docker 容器、虚拟机或公司自有基础设施中执行;
  • 支持创建自动化(automations),例如定时生成报告并发布到 Slack,或把 GitHub Issue 自动拆解为任务;
  • 支持「自带模型」(bring your own model)与跨后端切换,本地、远程、云后端可在同一前端间无缝切换。

这一能力在 package.json 中也有体现:npm 包名为 @openhands/agent-canvas(当前版本 1.16.0),同时暴露了 agent-canvas 可执行入口(bin/agent-canvas.mjs)、独立应用构建产物,以及 browser、conversation、files、settings、sidebar、terminal、i18n 等库式入口,说明它既可作为独立应用自托管,也可作为组件嵌入其他宿主应用(对应 docs/architecture.md 中的「Runtime modes / Packaging」部分)。

快速开始:三种安装方式

README 给出三种等价的部署路径,分别对应不同安全边界。选择的核心判据是:是否允许 Agent 直接访问宿主机文件系统。

方式一:无沙箱直跑(npm 全局安装)

注意:该模式让 agent-server 直接运行在安装目标机器上,Agent 将获得对文件系统的完全访问权限,仅在可信环境使用。

前置条件:Node.js 22.12.x 或更高版本(package.jsonengines.node 要求 >=22.12.0),以及 uv(用于通过 uvx 拉取 Python 侧的 agent-server)。

npm install -g @openhands/agent-canvas
agent-canvas

agent-canvas 命令默认启动完整本地栈。如果希望把各部分拆开单独运行:

agent-canvas --frontend-only  # 仅静态前端 + ingress 代理
agent-canvas --backend-only   # 仅 agent server + automation backend + ingress 代理

方式二:Docker 沙箱(推荐用于个人机器)

前置条件:

  • Docker:macOS/Windows 用 Docker Desktop,Linux 用 Docker Engine/Docker Desktop;
  • 一个作为 PROJECTS_PATH 的宿主机目录,存放希望 Agent 访问的项目文件夹,需在启动容器前创建。

macOS / Linux:

export PROJECTS_PATH="$HOME/projects"  # 存放项目文件夹的目录
mkdir -p "$PROJECTS_PATH" "$HOME/.openhands"

docker run -it --rm \
  -p 8000:8000 \
  -v "$HOME/.openhands:/home/openhands/.openhands" \
  -v "${PROJECTS_PATH}:/projects" \
  ghcr.io/openhands/agent-canvas:1.16.0

Windows(PowerShell)等价命令见 README.windows.md,要点是 docker pull 后使用 Join-Path 构造路径,并以反引号续行执行同样的 docker run

启动后 Agent 可访问 PROJECTS_PATH 下的任意项目。这里的两个卷挂载与 Dockerfile 完全对应:docker/Dockerfile 声明了 VOLUME ["/home/openhands/.openhands", "/projects"],并注释说明前者持久化「设置、密钥、会话、自动化数据库」,后者是「Agent 可读写用户代码」;镜像预创建了 /home/openhands/.openhands/agent-canvas/conversationsbash_eventsautomation 等子目录并 chown 给 openhands 用户,因此宿主机挂载点建议是空目录或已存在的用户目录。

方式三:从源码运行

同样是「agent-server 直跑」模式,Agent 对宿主机文件系统有完全访问权限。

前置条件:Node.js 22.12.x+、npmuv(用于通过 uvx 运行 agent server)。

git clone https://github.com/OpenHands/OpenHands.git
cd OpenHands
npm install
npm run dev

访问入口与后端管理

启动完成后:

  • npm / 源码启动方式访问 http://localhost:8000
  • Docker 镜像访问 http://localhost:8000/canvas(镜像构建时通过 VITE_BASE_PATH=/canvas 把前端烘到子路径下,见 docker/Dockerfile)。

额外后端可以直接在 UI 中添加。README 强调的一点是「多后端」:可以把同一个 Agent Server 共享给团队做代码评审和依赖更新,同时保留笔记本上的个人 Agent,在同一 Agent Canvas 前端之间切换而不中断上下文。

CLI 参数与环境变量:来自源码的完整说明

上面只列了 README 出现的两个拆分参数。完整的参数面可从 CLI 入口 bin/agent-canvas.mjs--help 输出处确认,该文件是 agent-canvas 命令的入口,默认以「生产等价模式」运行:通过 uvx 拉起 agent-server 与 automation backend,并服务预构建的静态前端(即 npm run dev 的产物化等价物)。

参数

参数 作用
-p, --port <port> ingress 代理端口,默认 8000
--public 启用 public 模式:API key 不再注入前端,用户首次打开 UI 需手动粘贴 LOCAL_BACKEND_API_KEY;要求设置该环境变量
--frontend-only 仅启动 ingress 后的静态前端
--backend-only 仅启动 agent-server + automation backend(与 --frontend-only--public 互斥,入口代码中有显式校验并报错退出)
-v, --version 输出版本号
--info 输出默认栈版本、兼容下限与各服务端口
-h, --help 帮助信息

环境变量

变量 说明
LOCAL_BACKEND_API_KEY 服务端 API key。非 public 模式下可省略(自动生成并在重启间持久化);public 模式下必填
OH_SECRET_KEY 用于加密设置的密钥
OH_AGENT_SERVER_GIT_REF agent-server 的 Git 引用
OH_AGENT_SERVER_LOCAL_PATH 本地 software-agent-sdk checkout 路径,用于开发(优先级最高:会从本地源码重建 agent-server 并以 editable 方式安装 SDK 组件)
OH_AGENT_SERVER_VERSION 指定 agent-server 的 PyPI 版本

帮助文本还明确了一点常被问到的问题:LLM 配置通过 Web UI 的设置页完成,而不是环境变量

从入口实现看,agent-canvas 最终调用 scripts/dev-with-automation.mjsmain(),传入 staticMode: true 与构建目录 build/;该脚本头部的注释也完整画出了 ingress 的路由拓扑:/api/automation/* 路由到 Automation Backend(:18001),/api/*/sockets 路由到 Agent Server(:18000),其余路径路由到 Vite 开发服务器或静态服务。

默认版本与端口

所有 npm 与 Docker 安装路径共享的「单一事实来源」是 config/defaults.jsonagent-canvas --info 读取的就是它:

  • 版本钉定:agent-server 1.44.0、agent-canvas 1.16.0、automation 1.9.0;agent-server 兼容下限 1.28.0
  • 端口:ingress 8000、agent-server 18000、automation 18001、内置编辑器(vscode)8001
  • 路径:状态子目录 agent-canvas/、会话目录、bash 事件目录、automation 数据库 automation/automations.db、Canvas 基路径 /canvas、编辑器基路径 /vscode

此外,该文件还包含一个值得注意的约束:agent-client-protocol 被临时钉在 <0.11(acp 0.11.0 重排了 prompt() 参数,会破坏 SDK 的 ACP 客户端),这解释了本地启动脚本为什么需要对 uvx 安装命令做约束处理(从源码结构看,约束由 scripts/dev-safe.mjs 消费)。

架构:Agent Canvas、Agent Server 与 Automation Server

README 的 Architecture 部分给出了三层结构,docs/architecture.md 进一步明确了系统边界:

  1. Agent Canvas(本仓库):React + TypeScript 前端,直接对接 OpenHands Agent Server。它负责渲染会话、终端、浏览器、文件、设置与自动化 UI,管理前端状态,并把 UI 操作翻译成 Agent Server API 调用;它不负责执行 Agent 动作、提供沙箱隔离、托管 LLM 凭证,也不在没有 automation 后端时运行定时/事件触发的自动化。
  2. OpenHands Agent Server:一个「在单机上运行多个 Agent」的 REST API。每个 Agent Server 监听单一 host/port;Agent Canvas 可同时连接多个 Agent Server 并在 UI 中切换。Agent Server 可以跑在任何地方:笔记本(谨慎)、专用机器(Mac Mini 等)、云上虚拟机、OpenHands Cloud。
  3. Automation Server(可选配套):负责「什么时候跑」——按调度或事件(webhook)把会话派发给 Agent Server/SDK 执行;Agent Canvas 前端中的自动化功能即对接它。

关于仓库分工,README 的「Repository boundaries」表格明确了多仓库边界,变更应提交到拥有该行为的仓库:

仓库 职责
OpenHands/OpenHands(本仓库) Agent Canvas 前端、用户控制中心、后端选择、本地栈编排
OpenHands/software-agent-sdk Python SDK、Agent Server、Agent、工具、会话、工作区、事件与规范服务端 API
OpenHands/typescript-client 浏览器可用的 Agent Server API TypeScript 客户端
OpenHands/automation 自动化定义、调度、webhook、运行历史与派发

本仓库前端最重要的源码区域(见 docs/architecture.md):src/api/(Agent Server、云、设置、git、skills、automations、backend registry 的服务适配器)、src/components/(会话、聊天、浏览器、文件、设置、后端、自动化等路由与功能 UI)、src/hooks/(React Query 与状态 hooks)、src/stores/(Zustand 状态)、src/mocks/(MSW 处理器)、以及 bin/scripts/(CLI 与开发栈启动器)。

单端口 ingress:Docker 镜像内部路由

Docker 镜像把三个服务合并进一个镜像(docker/Dockerfile 头部注释):

  • Agent Server 基于上游 SDK 镜像 ghcr.io/openhands/agent-server
  • Automation 通过 pip 安装 openhands-automation(钉定版本);
  • 前端为预构建静态产物,由 Node 静态服务器提供。

入口 docker/entrypoint.sh 启动全部服务与一个 ingress 代理,统一在 8000 端口暴露,路由规则为:

/api/automation/*  → automation backend (:18001)
/api/*, /sockets   → agent server      (:18000)
/* (default)       → 静态前端 + SPA fallback

这也是为什么容器只 EXPOSE 8000 一个端口,而 README 中的 docker run 只需 -p 8000:8000

ACP Agent:接入 Claude Code、Codex、Gemini

README 能力表中「Use with any agent」对应的实现细节在 docs/ACP_AGENTS.md:Agent Canvas 并不直接调用 LLM,而是由 Agent Server 以子进程方式拉起 ACP Agent 的 CLI(stdio 上的 JSON-RPC),逐轮转发消息。外部 Agent 自管 LLM、工具与执行,Agent Canvas 只记录「跑哪个 Agent」并渲染返回内容。

内置支持的提供方与默认命令:

提供方 默认命令
Claude Code npx -y @agentclientprotocol/claude-agent-acp
Codex npx -y @agentclientprotocol/codex-acp
Gemini CLI npx -y @google/gemini-cli --acp

认证上有两类方式:订阅登录(provider 自有 CLI 在本地存的登录态,如 macOS Keychain、~/.codex/auth.json~/.gemini/oauth_creds.json)或 API key(ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY)。关键点:登录态优先于 API key——在 Agent Server 与用户同一台机器(本地/自托管后端)时,通常无需配置任何 key;而在干净的云端沙箱中则必须提供 API key。Agent 选择按后端(backend)维度存储,切换后端即可能切换 Agent。提供方清单来自 SDK 注册表并镜像进 @openhands/typescript-client,Canvas 侧仅在 src/constants/acp-providers.ts 补充 UI 元数据。

自托管与安全加固

README 指出「最强大的运行方式是部署在云服务器上」——Agent 可以持续运行,并方便地被 Slack、GitHub、Datadog 等第三方服务触发。完整操作与加固细节在 docs/SELF_HOSTING.md,要点:

  1. 准备一台常开的 Linux/macOS 主机(云 VM 或 Mac Mini、NUC 等专用硬件);
  2. 先加固再启动:默认只允许 SSH(且限源 IP),ingress(:8000)、agent-server(:18000)、automation(:18001)、静态服务(:3001)全部绑定 127.0.0.1,禁止对外可达;
  3. 生成密钥并 public 模式启动:openssl rand -base64 32 生成 key,export LOCAL_BACKEND_API_KEY=<key>npx @openhands/agent-canvas --public。public 模式下 API key 不注入前端,用户需在 UI 首次加载时粘贴;每个 /api/* 调用都必须携带匹配的 X-Session-API-Key 头;
  4. 可选:nginx + Let's Encrypt 提供 TLS,只开放 80/443;
  5. 可选:在本地 Agent Canvas 中把该远程添加为后端,实现「本地前端 + 云端 Agent」组合。

SELF_HOSTING 文档还记录了一个值得注意的安全边界:内置编辑器(OpenVSCode)通过路径前缀(默认 /vscode)复用 Canvas 的浏览器源,路径前缀只做路由不做隔离,编辑器侧的脚本可读 Canvas 的 localStorage(其中保存了该浏览器内所有已注册后端的 SESSION API key)——这正是「单一端口部署」的代价,公网暴露前应知悉。docs/architecture.md 的 Security posture 一节亦呼应此点:本地运行会让 Agent 访问用户工作区,因此推荐笔记本场景使用 Docker 沙箱模式;自托管部署应叠加常规服务器加固、认证、HTTPS、防火墙与谨慎的工作区限定。

运行时模式与开发命令

docs/architecture.md 以表格形式列出了 package.json scripts 对应的运行模式,与 package.json 中的定义一致:

模式 用途
npm run dev 在宿主机直接启动完整本地栈:uvx 拉起 agent-server 与 automation backend、Vite 开发服务器、ingress 代理。Agent 拥有宿主机文件系统访问权,仅用于可信环境
npm run dev:minimal 仅 agent-server + Vite 开发服务器,不含 automation backend
npm run dev:static dev,但服务前端生产构建而非 Vite 开发服务器
npm run dev:mock 前端对接 MSW mock,用于 UI 开发与测试
npm run build 构建独立应用
npm run build:lib 构建用于嵌入的库式入口

配套的质量门(CI):npm run lint(typecheck + ESLint + Prettier)、npm test(单元/组件测试)、npm run buildnpm run build:lib(双构建验证)、npm pack --dry-run(打包校验)。npm 包通过 GitHub Actions 的 trusted publishing 与 provenance 发布,postinstall 脚本还会在全局安装后打印启动提示(agent-canvas,默认 http://localhost:8000)。

延伸阅读

围绕 README 的更多文档均可在当前仓库内查阅:

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384