Eigent 开源 Cowork 桌面技术全景
- [一、产品定位与效果:从对话助手走向 Agentic Workspace](#一、产品定位与效果:从对话助手走向 Agentic Workspace)
-
- [1.1 Eigent 解决的是"让 Agent 在项目上下文中完成工作"](#1.1 Eigent 解决的是“让 Agent 在项目上下文中完成工作”)
- [1.2 Single Agent 与 Workforce 不是同一个界面的两种皮肤](#1.2 Single Agent 与 Workforce 不是同一个界面的两种皮肤)
- [二、系统架构与核心数据流:桌面端、Brain 与本地服务如何协作](#二、系统架构与核心数据流:桌面端、Brain 与本地服务如何协作)
-
- [2.1 技术分层、运行拓扑与源码目录](#2.1 技术分层、运行拓扑与源码目录)
- [2.2 一次任务从 `/chat` 到桌面事件与固定工作目录](#2.2 一次任务从
/chat到桌面事件与固定工作目录) - [2.3 Trigger:Celery 负责调度,在线桌面负责真正执行 Agent](#2.3 Trigger:Celery 负责调度,在线桌面负责真正执行 Agent)
- [三、Agent 与 Workforce 内核:规划、分配、执行、失败和记忆](#三、Agent 与 Workforce 内核:规划、分配、执行、失败和记忆)
-
- [3.1 Workforce:Eigent 包装 CAMEL,而不是重写一套调度器](#3.1 Workforce:Eigent 包装 CAMEL,而不是重写一套调度器)
- [3.2 Single Agent:跳过 Workforce,但仍然是带工具的执行器](#3.2 Single Agent:跳过 Workforce,但仍然是带工具的执行器)
- [3.3 Remote Sub Agent:受策略约束的委派工具,不自动继承本地工作区](#3.3 Remote Sub Agent:受策略约束的委派工具,不自动继承本地工作区)
- [3.4 项目记忆是本地结构化上下文,不是默认向量 RAG](#3.4 项目记忆是本地结构化上下文,不是默认向量 RAG)
- [四、模型、工具、MCP 与安全边界:Agent 到底能做什么](#四、模型、工具、MCP 与安全边界:Agent 到底能做什么)
-
- [4.1 模型层统一了入口,没有抹平模型差异](#4.1 模型层统一了入口,没有抹平模型差异)
- [4.2 工具暴露分为预置 Toolkit、MCP、Skills 和人工交互](#4.2 工具暴露分为预置 Toolkit、MCP、Skills 和人工交互)
- [4.3 Hands/Sandbox 与两套后端的认证边界](#4.3 Hands/Sandbox 与两套后端的认证边界)
- 五、安装与部署:从快速体验到完全本地
-
- [5.1 从源码启动桌面端:默认连接 Eigent 云服务](#5.1 从源码启动桌面端:默认连接 Eigent 云服务)
- [5.2 完全本地:先启动控制面,再让桌面指向它](#5.2 完全本地:先启动控制面,再让桌面指向它)
- [5.3 跑通第一个可验证任务](#5.3 跑通第一个可验证任务)
- [5.4 生产前必须改掉示例配置](#5.4 生产前必须改掉示例配置)
- 六、工程边界、适用场景与落地建议
-
- [6.1 运行状态、认证、数据出网与并发边界](#6.1 运行状态、认证、数据出网与并发边界)
- [6.2 适用场景与落地顺序](#6.2 适用场景与落地顺序)
- 参考资料
Eigent 是一个开源 Cowork 桌面应用,将项目文件、模型、浏览器、终端、MCP 与 Skills 组织进可持续工作的 Agentic Workspace,把"选择工作目录---理解上下文---拆分任务---分配专业 Agent---调用浏览器/终端/文件/MCP---产出文件---继续下一轮"放进桌面工作台。本文基于固定提交,拆解 Single Agent 与 Workforce、CAMEL 调度、Trigger 桌面执行链、Remote Sub Agent、工具暴露、本地记忆和双后端部署,并说明"无人值守""本地运行"和"沙箱"的真实边界。
GitHub仓库:https://github.com/cmyk-labs/eigent.git(如果这个仓库对你有帮助,欢迎在 GitHub 上点一个 Star ⭐ 支持一下。)
官方GitHub仓库:https://github.com/eigent-ai/eigent
一、产品定位与效果:从对话助手走向 Agentic Workspace
1.1 Eigent 解决的是"让 Agent 在项目上下文中完成工作"
传统对话产品的上下文主要来自当前聊天;Eigent 则要求先选择 Space 或本地项目目录,让文件、运行记录、产物和工具成为任务的一部分。一次较完整的工作过程可以概括为:
text
选择本地文件夹或空白 Space
→ 创建 Project 与本次 Run
→ 输入目标、添加附件、选择执行模式
→ Single Agent 直接执行,或 Workforce 先规划任务
→ Agent 使用文件、终端、浏览器、搜索、MCP、Skills
→ 桌面端实时展示任务、工具调用、终端和产物
→ 结果与项目上下文留给后续 Run 使用

围绕这条链路,Eigent 当前主要包含以下能力:
| 功能域 | 用户看到的能力 | 源码中的主要承载层 |
|---|---|---|
| 工作空间 | Space、本地文件夹、Project、Run、附件与输出文件 | React/Electron、workspace_resolver.py、Space overlay |
| 执行模式 | Single Agent 与多智能体 Workforce | single_agent_service.py、chat_service.py、CAMEL Workforce |
| 专业角色 | Developer、Browser、Document、Multi-Modal、自定义 Worker | backend/app/agent/factory/ |
| 工具扩展 | 文件、终端、浏览器、搜索、MCP、Skills、人工问询 | Eigent Toolkit 包装层与 CAMEL Toolkits |
| 模型 | Eigent Cloud、BYOK、OpenAI 兼容接口与本地模型 | CAMEL ModelFactory、Provider 配置 |
| 自动化 | 定时任务、Webhook/Slack 等触发入口 | server/、Celery Worker/Beat、Trigger 服务 |
| 连续上下文 | 项目级对话、摘要、事实、产物与 Run 状态 | ~/.eigent/memory、PostgreSQL 聊天元数据 |
这里有两个需要先说清的边界。第一,开源桌面、云服务和企业功能不是同一个部署面;例如 SSO、组织级访问控制和定制能力不能因为官网提到 Enterprise 就视为社区源码的默认能力。第二,"本地部署"表示应用、工作区和自建服务可以运行在自己的环境中,不代表数据必然不出网:只要使用云模型、远程 MCP、搜索服务或其他 Connector,相应请求仍会发往外部服务。
1.2 Single Agent 与 Workforce 不是同一个界面的两种皮肤
两种模式共享模型与工具底座,但执行路径不同:
| 对比项 | Single Agent | Workforce |
|---|---|---|
| 适合任务 | 目标集中、连续迭代、协调成本不值得 | 多步骤、多专业角色、可并行子任务 |
| 规划阶段 | 不创建 Workforce 任务树 | 规划器先分解,前端展示并允许调整任务 |
| 执行主体 | 一个 CAMEL Agent | 协调器、任务规划器和多个 Worker Node |
| 上下文特点 | 同一 Agent 延续当前 Project 的多轮上下文 | 协调器持有规划视图,具体任务交给不同 Worker |
| 工具 | 文件、浏览器、终端、Skills、MCP 等 | 每个预置或自定义 Worker 获得自己的工具集合 |
| 代价 | 路径短、模型调用较少 | 规划、分配、执行、检查与汇总会增加 Token 和时延 |
图片来源:Eigent 官方 Workforce 文档。

因此,简单文件修改不需要为了"多智能体"而强行拆分;研究、编码、资料整理和报告生成能够形成相对独立的工作包时,Workforce 才更有价值。并行不是目标本身,可验证的任务边界和清晰依赖关系才是。
二、系统架构与核心数据流:桌面端、Brain 与本地服务如何协作
2.1 技术分层、运行拓扑与源码目录
Eigent 仓库不是单一 Web 服务,而是由三个自有层组成:
text
React + TypeScript UI
└─ Electron 主进程:桌面窗口、更新、文件/终端桥接、启动 Brain
└─ backend/ Brain:FastAPI + Uvicorn,端口默认从 5001~5050 选择
├─ 任务会话、Workforce/Single Agent、工具、浏览器、工作区、本地记忆
└─ CAMEL + 模型 API + MCP Server + 本机终端/浏览器
server/ 本地控制面:FastAPI + PostgreSQL + Redis + Celery
├─ 用户、Provider、配置、聊天历史、MCP 管理
└─ 定时/事件触发和远程控制相关服务
| 层次 | 主要实现 | 关键职责 |
|---|---|---|
| 渲染层 | React、TypeScript、src/ |
项目、任务树、Agent 活动、终端和产物预览 |
| 桌面宿主层 | Electron Main/Preload | 窗口与 IPC、Brain 生命周期、文件和 CDP 浏览器资源 |
| Brain 执行层 | FastAPI、CAMEL、backend/app |
Run 状态、Single Agent/Workforce、工具、记忆与流式事件 |
| 本地控制面 | server/、PostgreSQL、Redis、Celery |
用户、模型/MCP 配置、Space、历史和 Trigger 调度 |
| 外部能力 | 模型 API、MCP Server、Connector、本机浏览器与终端 | 提供 Eigent 自身之外的推理和业务操作能力 |
| 构建交付层 | npm、uv、Electron Builder、Docker Compose | 管理两套 Python 环境、桌面打包和控制面部署 |
text
eigent/
├── src/ # React/TypeScript 渲染进程
│ ├── components/ # 页面与执行过程组件
│ ├── hooks/ # Trigger 等桌面桥接逻辑
│ ├── service/ # 前端服务调用
│ └── store/ # 项目、任务与界面状态
├── electron/
│ ├── main/ # 窗口、IPC、Brain 与浏览器进程管理
│ └── preload/ # 受控 Electron API 暴露
├── backend/
│ ├── main.py # Brain 启动入口
│ └── app/
│ ├── agent/ # Agent 工厂与 Toolkit
│ ├── hands/ # 部署能力探测与资源门控
│ ├── memory/ # 本地项目记忆
│ ├── remote_sub_agent/ # 远端 Agent Provider 与会话
│ └── run_context/ # Run 工作目录与状态快照
├── server/
│ ├── app/domains/ # 用户、模型、MCP、Space、Trigger 等领域
│ └── docker-compose.yml # PostgreSQL、Redis、API、Worker 与 Beat
├── package.json # 桌面端依赖与脚本
├── electron-builder.json # 桌面打包配置
└── LICENSE # Apache-2.0 许可证文件
这套目录说明了为什么"完全本地"不等于只启动一个后端:Electron 管理宿主资源,Brain 承担实时 Agent 执行,server/ 保存账户、配置并调度自动任务。三者可以协作,但运行状态、认证方式和扩展边界并不相同。
Electron 在开发和桌面运行时启动 backend/main.py 的 Uvicorn,并把实际 Brain 端口通知渲染进程。Brain 才是一次 Agent 任务的执行引擎;server/ 更像本地账户、配置、历史与自动化控制面。完全本地部署需要同时理解这两套后端,不能只启动 PostgreSQL 容器就认为 Agent 执行链已经就绪。
外部依赖也必须与 Eigent 自有代码分开:
- 多智能体核心
BaseWorkforce、TaskChannel、Agent、模型工厂和大量基础 Toolkit 来自 CAMEL;Brain 依赖固定为camel-ai[eigent]==0.2.91a5。 - Eigent 自己实现了桌面交互、任务锁与 SSE 协议、Agent 工厂、工具事件包装、能力门控、浏览器资源池、工作目录、Space overlay、本地 Project 记忆和控制面集成。
- 云模型、本地 OpenAI 兼容推理服务、远程 MCP 及第三方 Connector 是外部系统,其内部限流、权限、可用性和数据策略不由 Eigent 源码保证。
图片来源:Eigent 官方 Workforce 文档。

这张图只描述 Brain 内部由 CAMEL 提供的 Workforce 子系统,不包含 Electron 宿主、Brain API、server/ 控制面以及外部模型和 Connector;全系统关系应以上面的运行拓扑和源码目录为准。
2.2 一次任务从 /chat 到桌面事件与固定工作目录
前端向 Brain 的 POST /chat 发送 Chat 配置,其中包含 Project/Task/Run、问题、附件、执行模式、模型平台、模型名称、API 地址、MCP、CDP 浏览器和工作区信息。后端并不是在这个请求函数内一直同步执行,而是先冻结本次 Run 的目录和上下文,再把动作送进任务队列:
text
POST /chat
→ get_or_create_task_lock(project_id)
→ freeze_task_directories() 固定工作目录、产物目录和快照
→ 准备 CDP 浏览器与 RunContext
→ MemoryService.on_run_start() 记录用户问题和 Run 状态
→ ActionImproveData 进入 asyncio.Queue
→ step_solve() 消费动作并执行
→ create_agent / task_state / terminal / write_file / ask / end 等事件
→ StreamingResponse(text/event-stream)
→ React 状态仓库更新任务树、Agent、工具活动和预览区
TaskLock 是这条链的会话枢纽:它保存动作队列、人工回复等待者、后台任务、当前状态、RunContext、工作目录、当前进程内的会话历史和 Agent 内存快照。暂停、恢复、停止、增加 Worker、编辑任务和人工回复并不是另起一套 RPC,而是转成不同 Action 写入同一队列。SSE 负责"及时看到发生了什么",不等于任务本身成为无状态请求。
这种设计很适合单机桌面,但也带来扩展边界:当前运行中的 task_locks 和 asyncio.Queue 位于 Brain 进程内。源码没有展示把执行状态放入 Redis 或跨 Brain 进程协调的完整实现。因此不能仅凭 Uvicorn/FastAPI 就宣称可以无状态横向扩展;如果自行部署多个 Brain Worker,需要额外设计会话粘性、任务状态外置和浏览器/终端资源归属。
启动 Run 时,workspace_resolver 会根据 Space、Project 与 workdir_mode 决定实际工作目录。当前模型包含 worktree、copy、direct-write 和 artifact-only 等模式;随后把源目录、任务输出目录、快照和绑定来源冻结到 RunContext。工具写入时,FileToolkit 还会把落在工作目录内的变更登记到 Space overlay,以便后续审阅或应用。
这比让所有 Agent 直接在用户原目录随意修改更容易追踪,但不是所有模式都天然安全:direct-write 就意味着直接修改源目录;终端命令也可能绕过高层文件写入包装。对重要仓库,应先提交或备份现有修改,优先使用隔离工作目录,确认产物后再合并。
2.3 Trigger:Celery 负责调度,在线桌面负责真正执行 Agent
官方的 v0.0.86 发布说明展示了定时与外部事件触发能力,Slack → Odoo CRM 示例则展示了实际业务效果。不过,从固定提交源码看,开源版 Trigger 不是一套完全在服务器后台运行的 Agent Worker,而是"控制面调度 + Redis 事件投递 + 桌面端执行"的组合:
text
Celery Beat
→ poll_trigger_schedules 扫描到期 Cron
→ PostgreSQL 创建 pending TriggerExecution
→ Redis Pub/Sub 发布 execution_created
→ 在线桌面的 WebSocket 收到事件并立即 ACK
→ useTriggerTaskExecutor 将任务写入目标 Project 的 queuedMessages
→ useBackgroundTaskProcessor 调用 startTask
→ 本地 Brain 走正常 /chat + SSE + Agent/Workforce 执行链
→ 桌面端把 running / completed / failed 回写控制面
trigger_schedule_task.py中的 Celery 任务负责轮询到期计划和检查超时;trigger_schedule_service.py创建执行记录、推进下一次 Cron 时间,再向 Redis 发布事件。该文件明确保留了"实际任务队列尚待接入、当前发送给客户端执行"的 TODO。因此 Redis 在这里承担通知和跨进程分发,不是运行 LLM、浏览器或终端工具的执行器。
Webhook 走同一边界。webhook_controller.py先校验触发器、频率和单次执行约束,再落一条 pending 记录;若用户存在活动 WebSocket,会发布事件并等待最多 10 秒确认。没有活动会话时接口仍然成功接收 Webhook,但返回 delivered: false 与 reason: no_active_sessions。这里所谓"queued"是控制面保存了待执行事实,不等于服务器稍后会自行启动 Agent。
桌面端的订阅 Hook收到 execution_created 后发送 ACK;TriggerTaskExecutor负责创建或恢复 Project 并加入消息队列;BackgroundTaskProcessor每 2 秒扫描一次队列、把执行状态改为 running,再调用普通聊天任务入口。当前实现会避免同一 Project 同时跑多个后台任务,不同 Project 的已启动任务则可以并存。
这也解释了两个运维数字:默认 pending 超过 60 秒未被桌面接管会标记为 missed,running 超过 600 秒没有完成回报会标记为 failed;连续失败达到 Trigger 配置阈值后还会自动停用。它们是源码默认值,可以通过环境变量或配置改变,不是产品 SLA。要实现真正"无人值守",至少要保证桌面应用、WebSocket、本地 Brain、模型和所需浏览器/Connector 长期在线;若希望只部署服务端就持续执行,则还需要补齐服务端 Agent Worker、任务领取、租约、幂等、重试和资源隔离,而不能只增加 Celery 并发。
三、Agent 与 Workforce 内核:规划、分配、执行、失败和记忆
3.1 Workforce:Eigent 包装 CAMEL,而不是重写一套调度器
复杂任务进入 Workforce 后,construct_workforce() 会并行创建以下对象:
- 协调 Agent:根据 Worker 描述和任务状态做分配;
- 任务规划 Agent:把主任务拆为带依赖的子任务;
- 新 Worker Agent:需要时辅助生成定制 Worker;
- Developer、Browser、Document、Multi-Modal 四类预置专业 Worker;
- MCP 搜索/安装相关 Agent;
- 用户另外配置的自定义 Worker。
这里"并行创建 Agent"使用 asyncio.gather() 与 asyncio.to_thread(),优化的是启动等待时间;真正的子任务发布、Worker 监听、结果回传和依赖处理来自 CAMEL 的 Workforce 与 TaskChannel。Eigent 的 Workforce 子类主要增加了 UI 事件、流式分解、失败兜底、超时、清理和本地上下文接入。
一次复杂任务的执行分为两个明显阶段:
text
阶段 A:规划
question_confirm 判断是否复杂
→ eigent_make_sub_tasks()
→ task_agent 流式生成子任务
→ 更新依赖并通过 SSE 展示
→ 用户可增删改任务
阶段 B:执行
用户确认 Start
→ eigent_start() 把编辑后的任务放入 pending deque
→ CAMEL Workforce 分配给 Worker Node
→ Worker 调模型并调用工具
→ 结果回到 TaskChannel,依赖任务继续
→ Eigent 同步任务状态、结果、失败与最终汇总
这个"先规划、可人工调整、再执行"的停顿非常重要:规划器输出不是不可更改的真理。对于会写文件、发消息、修改外部数据或调用高成本模型的任务,执行前检查任务拆分、Worker 和工具范围,通常比事后补救更便宜。
当前包装层为单个返回任务设置 3600 秒等待超时,并启用 CAMEL 的 retry、replan 失败策略;_analyze_task() 在结构化输出无效时最多重试三次,仍失败则按场景终止或接受已有结果。这里的数字是代码配置,不是 SLA。模型供应商超时、浏览器卡住、工具副作用和外部服务幂等仍需单独治理。
3.2 Single Agent:跳过 Workforce,但仍然是带工具的执行器
当 session_mode == "single-agent" 时,step_solve() 直接进入 single_agent_solve(),不会创建协调器、规划器和任务树。Agent 通过 astep() 处理当前目标,工具调用和模型输出仍会转成 SSE 事件。默认工具装配包括人工交互、文件、Web 预览、截图、Skills、Todo、搜索、浏览器、终端、Web Fetch、Planning Worktree、MCP 和有限深度的 Agent 委派,实际可用项还要经过部署能力与用户配置过滤。
单 Agent 默认委派深度为 1:根 Agent 可以创建一层子 Agent,子 Agent 不再继续递归。它避免无限生成 Agent,但不代表每个模型都能稳定完成委派;工具调用能力、提示词遵循和上下文容量仍由所选模型决定。
选择原则可以很简单:
- 修改一个明确文件、运行一组测试、连续追问同一问题:优先 Single Agent;
- 调研资料、实现代码、生成文档和检查效果能够拆成不同工作包:考虑 Workforce;
- 包含外部写操作:无论哪种模式,都先减少工具权限并保留人工确认点。
3.3 Remote Sub Agent:受策略约束的委派工具,不自动继承本地工作区
官方的 Gemini Managed Agents 用例展示了本地编排与远端 Agent 之间的两层协作。源码中的实现方式不是再创建一个本地 CAMEL Worker;在启用且 Provider 配置完整时,各类 Agent 工厂会调用 attach_remote_sub_agent_if_enabled(),给 Developer、Browser、Document、Multi-Modal、Social、MCP、新建 Worker 和自定义 Worker 追加 run_remote_sub_agent FunctionTool。模型仍由原 Workforce/Agent 决定何时委派,远端结果再作为工具返回值进入本地推理链。
当前固定提交注册的 Provider 只有 Gemini Agents API。RemoteSubAgentRuntime先检查启用状态、Provider 白名单和最长运行时间,再流式消费 Provider 事件;Gemini 适配器把请求发送到 /interactions,并可用 previous_interaction_id 与远端 environment_id 延续会话。
会话复用并不等于持久化记忆。session_store.py用 project_id + provider + remote_agent_name 组成默认键,把交互 ID 和环境 ID 保存在带锁的进程内字典中。它可以让同一 Brain 进程内的后续委派继续远端上下文,但 Brain 重启后会丢失,也没有展示多进程共享存储;因此不能把它等同于下一节介绍的项目级本地记忆。
Remote Sub Agent 的数据边界尤其重要:
| 边界 | 固定提交中的行为 |
|---|---|
| 默认状态 | 关闭;只有 enabled 且 Provider 的 API Key、Base URL、Agent Name 完整时才暴露工具 |
| Provider | 当前注册表只有 gemini_agents,并检查允许列表 |
| 运行时间 | 默认最长 600 秒,可由 Provider 配置调整 |
| 本地文件 | 不自动上传,也不能直接读取本地工作目录;必须把必要文本放进 instruction,或提供远端可访问的 HTTP(S) URL |
| Skills | 远端环境不能读取本地 SKILL.md;需要由调用方筛选后通过 skill_context 明确传入 |
| 会话 | 可复用 interaction/environment,但状态只保存在当前 Brain 进程内 |
| 快照 | 当前配置路径禁止下载,不存在自动回传本地文件的能力 |
RemoteSubAgentToolkit的公开工具参数只有 instruction、远端 Agent 名称、系统指令、是否复用会话和 skill_context,没有本地文件上传参数。虽然Policy还定义了工作目录约束、50 MB 快照上限,以及 .env、.ssh、私钥、token、secret、credential 等拒绝模式,但当前工具调用链没有启用快照下载,也没有调用文件范围检查完成自动同步。更准确的理解是:这些字段为文件/快照能力预留了安全规则,不代表本地工作区已经安全地镜像到远端。
因此,适合交给远端的是边界清楚、可以仅靠提示文本或公开 URL 完成的研究、日志分析和隔离计算;涉及未提交源码、客户附件、密钥、内部 URL 或本地 Skill 时,应先做最小化、脱敏和可访问性设计。远端 Agent 返回的结论也仍是外部结果,涉及本地文件写入或业务副作用时,应回到本地受控工具执行,而不是把"远端运行"误解为自动获得了本机权限。
3.4 项目记忆是本地结构化上下文,不是默认向量 RAG
Eigent 当前的项目记忆采用以下本地目录结构:
text
~/.eigent/memory/
users/<canonical_user_id>/
spaces/<space_id>/
projects/<project_id>/
project.json
conversation.jsonl
summary.md
facts.json
artifacts.json
runs/<run_id>/
run.json
status.json
tool_events.jsonl
Run 开始时写入用户问题和运行状态,结束时写入最终回答、摘要和状态;ProjectContextBuilder 从项目摘要、最近对话、事实和可用于上下文的产物中组装提示词。默认预算约 8000 Token,以"约 4 字符/Token"做粗略分配,最近对话最多读取 24 条,并让最近对话占主要预算。写入是 best-effort:记忆文件失败会记录日志,但不会让聊天任务失败。
需要注意三层边界:
- 这是本地 JSON/JSONL/Markdown 存储和预算化提示词拼装,不是自动对全部项目文件建立向量索引。
RAGToolkit确实存在,但它是可给自定义 Worker 选择的工具,封装 CAMEL Retrieval、OpenAI Embedding 与本地 Qdrant;它不是每次 Eigent 对话必经的核心链路。- 当前
workforce_worker的专属上下文渲染仍较窄,源码注释也把更完整的按角色记忆拆分列为后续工作。因此不能宣称所有 Worker 自动共享同一份完整长期记忆。
对话上下文、项目文件和 RAG 是三件不同的事:前者解决跨 Run 连续性,第二类是 Agent 当前可读取的事实源,第三类才是按查询召回候选。需要知识库效果时,应明确建立索引、定义数据更新和评测,而不是把"选择了文件夹"直接等同于 RAG。
四、模型、工具、MCP 与安全边界:Agent 到底能做什么
4.1 模型层统一了入口,没有抹平模型差异
agent_model() 将前端提供的 model_platform、model_type、api_key、api_url、额外参数和每个自定义 Worker 的专属配置交给 CAMEL ModelFactory.create()。上层 Agent 因而可以接 Eigent Cloud、BYOK、OpenAI 兼容端点或本地推理服务;官方文档列出的本地方案包括 Ollama、vLLM、SGLang、LM Studio 和 LLaMA.cpp。
图片来源:Eigent 官方 Self-hosting 文档。

源码还对不同角色和平台做了少量适配:任务规划 Agent 强制流式输出;OpenAI 家族的 Browser Agent 默认关闭并行工具调用;Anthropic/Bedrock 设置缓存控制;OpenAI 使用 Project ID 作为 Prompt Cache Key;订阅运行时会刷新凭据并控制存储/流式参数。
但"模型无关"应理解为统一接入层,而不是无成本替换。换模型时至少要验证:
- 是否可靠支持 Function/Tool Calling;
- 上下文长度与结构化输出稳定性;
- 图片、音频等多模态能力;
- 流式格式、Token 统计和超时参数;
- 本地端点是否真正兼容所需 OpenAI API;
- 速度、费用、并发配额和数据合规。
能完成普通聊天的模型,不一定能稳定驱动多 Agent 任务分解和工具循环。更稳妥的做法是先用 Single Agent 完成一组可复现任务,再启用 Workforce 做相同任务的回归比较。
4.2 工具暴露分为预置 Toolkit、MCP、Skills 和人工交互
Eigent 的工具层不是一个全局"工具箱"直接塞给所有模型:
| 类型 | Eigent 自有逻辑 | 外部依赖逻辑 | 暴露范围 |
|---|---|---|---|
| 预置 Toolkit | 为工具增加任务 ID、工作目录、SSE 事件和清理 | 文件、终端、浏览器等基础实现多来自 CAMEL | 按 Agent 工厂和部署能力装配 |
| 自定义 Worker 工具 | 根据用户选择创建 Toolkit | FunctionTool 调用循环由 CAMEL Agent 执行 | 仅当前 Worker 的选择范围 |
| MCP | 过滤 Server、补充认证目录、连接与收集工具 | MCP 协议和客户端来自 CAMEL | Single Agent 为配置中允许的 Server;自定义 Worker 为显式选择的 Server |
| Skills | 读取用户配置、按 Agent 范围过滤 Skill | Skill 的发现、读取与调用由 CAMEL SkillToolkit 承担 |
全局或指定 Agent |
| Human Toolkit | 把问题写入任务队列并等待 GUI 回复 | 无 | 需要澄清、凭据或决定时暂停 |
浏览器工具还有一条桌面专有装配链。Electron Main 在主进程入口管理 CDP Browser Pool、端口、独立 Profile 和健康检查,Preload 通过受控 IPC 将浏览器池能力交给渲染进程;一次 Chat/Run 再把 CDP Endpoint 冻结进 RunContext,Brain 的 toolkit_assembler.py据此创建 HybridBrowserToolkit。这解决了 Agent 与真实桌面浏览器协作的问题,但 Profile 隔离和端口管理不能被解释为强安全沙箱。
对 Single Agent 而言,installed_mcp 中通过 Hands 过滤的 Server 会被连接,Server 返回的工具集合整体加入该 Agent;当前代码没有在工具装配前按本次问题再做向量 Top-K 路由。对自定义 Worker,MCP 范围来自该 Worker 的 mcp_tools。因此应按任务域拆分 Connector,避免把大量相似或高风险工具同时暴露给一个模型。
Skills 也不能被当作无害文本。官方文档支持上传 SKILL.md 或包含它的 ZIP;Skill 可以带脚本、模板和操作流程。只从可信来源安装,检查其文件、命令、网络目标和密钥读取方式,再限定到确实需要的 Agent。
4.3 Hands/Sandbox 与两套后端的认证边界
Brain 启动时通过 BrainCapabilities 判断部署环境:
| 环境 | 文件系统意图 | 终端 | 浏览器 | MCP |
|---|---|---|---|---|
| 本机/Electron | full |
检测本机 Shell | CDP 可用时开启 | 默认全部 |
| Docker/Sandbox | workspace_only |
容器存在 Shell 时仍可能开启 | 默认关闭 | 默认全部,可配置 allowlist |
| RemoteHands | 由远端集群能力决定 | 远端能力 | 远端能力 | 远端能力 |
工具装配阶段会实际依据 Hands 过滤 Terminal、Browser 和 MCP。can_access_filesystem() 的调用点主要用于 workspace 绑定路径校验的回退,并未贯穿所有文件与终端工具路径;文件 API 自己使用 resolve_under_base() 防止路径逃逸,文件 Toolkit 依靠工作目录与 CAMEL 基类,终端则以 safe_mode=True 调用 CAMEL TerminalToolkit,没有在 Eigent 代码里传入明确 allowed_commands。
所以最准确的结论是:Eigent 已有部署感知的能力清单、工作区路径校验和工具级门控,但类名 SandboxHands、workspace_only 或 safe_mode 本身不能证明强隔离。若任务会运行不可信命令或处理敏感数据,仍需使用容器/虚拟机、非特权用户、只读挂载、网络出口策略、CPU/内存/时间限制和一次性凭据。模型生成的命令始终应视为不可信输入。
server/ 控制面实现了本地用户、JWT、Token 黑名单、资源所有权检查,并对远程控制等敏感接口设置 Redis 限流。Brain 的非健康路由虽然统一挂上了认证依赖接口,但默认实现是 NoneAuth,会信任请求并给出固定 local/default 身份;run_standalone() 默认还绑定 0.0.0.0。
桌面 Electron 启动 Brain 时默认只在本机端口工作,这个信任模型尚可理解;独立部署时则不能把 5001 直接暴露到公网。应至少绑定 127.0.0.1、通过受认证的反向代理访问,或实现并启用真正的 Brain Auth Provider。不要把 server/ 已登录误认为 Brain 的每个执行 API 已自动拥有同等身份校验。
五、安装与部署:从快速体验到完全本地
5.1 从源码启动桌面端:默认连接 Eigent 云服务
官方根 README 给出的开发启动方式需要 Node.js 18~22:
bash
git clone https://github.com/eigent-ai/eigent.git
cd eigent
npm install
npm run dev
这条路径会启动 Electron/React,并准备 Brain 依赖,但默认连接 Eigent 云服务且需要账户。第一次启动可能下载 Python、前端和浏览器相关依赖,耗时明显长于普通 Vite 项目。拉取新代码后,如果两个依赖锁都变化,应同时更新:
bash
npm install
cd backend
uv sync
Brain 的 backend/pyproject.toml 当前要求 Python >=3.11,<3.12;Electron 会管理对应环境。不要因为 server/ 使用 Python 3.12 就让两套 Python 环境混用。
5.2 完全本地:先启动控制面,再让桌面指向它
官方 server/README_EN.md 的本地部署由 PostgreSQL、Redis、API、Celery Worker 和 Celery Beat 组成。server/ 当前要求 Python >=3.12,<3.13,但 Docker 镜像已经包含该环境。先复制环境配置并启动:
bash
cd server
cp .env.example .env
docker compose up --build -d
然后在仓库根目录的 .env.development 确认:
dotenv
VITE_BASE_URL=/api
VITE_USE_LOCAL_PROXY=true
VITE_PROXY_URL=http://localhost:3001
再启动桌面开发应用:
bash
cd ..
npm install
npm run dev
当前 Compose 端口关系为:API 3001 → 5678、PostgreSQL 5432 → 5432、Redis 6379 → 6379;数据库保存在 Compose 的 postgres_data 卷。基础验证命令:
bash
docker compose -f server/docker-compose.yml ps
curl http://localhost:3001/health
浏览器打开 http://localhost:3001/docs 可查看本地控制面 Swagger。进入 Eigent 后,还要在 Agents → Models 配置一个可用 Provider;"服务都健康"并不代表已有可执行模型。完全离线还需只使用本地模型和本地 MCP,关闭云 Provider、远程 Connector 及其他外部请求。
5.3 跑通第一个可验证任务
服务健康只说明入口可访问,不能证明 Agent 已经拥有模型、目录和工具。第一次使用建议建立一个小而可复核的闭环:
- 在 Agents → Models 配置一个可用 Provider,并先完成普通对话测试;
- 新建测试 Space,选择一个专用本地目录,避免直接对重要仓库使用
direct-write; - 使用 Single Agent 执行"读取两个文本文件并在
output/summary.md生成摘要"一类结果明确的任务; - 对照任务树、终端/工具事件和文件预览,确认产物真实写入本次 Run 的目录;
- 再用 Workforce 执行同类可拆分任务,检查规划、Worker 分配与最终文件是否比 Single Agent 更合理;
- 接入 MCP 或外部 Connector 时先执行只读操作,核对它只出现在被授权的 Agent 范围。
成功判据不是界面出现一段回答,而是目标文件真实落盘、内容能够人工复核、工具事件与目录一致,停止或重新打开任务后仍能定位本次 Run。若其中任一项失败,应先检查模型工具调用兼容性、工作目录模式和 Brain 事件,再讨论多 Agent 效果。
5.4 生产前必须改掉示例配置
仓库 Compose 更接近可复现的本地环境,不是开箱即用的公网生产基线。至少完成以下处理:
- 将 PostgreSQL 示例密码
123456、secret_key=postgres、聊天分享密钥和 Salt 全部替换为高强度随机值; - 不向公网发布 5432 和 6379,Redis 默认 Compose 没有配置认证;
- API 前置 HTTPS 反向代理,严格配置 CORS、Webhook 域名和可信代理;
- Brain 只监听本地/私网,并补充真实认证;
- 模型、MCP、Slack 等密钥使用专用 Secret 管理,不写入 Git、日志或截图;
- 备份 PostgreSQL 卷、用户配置、工作目录与
~/.eigent/memory,并实际演练恢复; - 固定发布标签或提交,不让生产环境无测试地跟随
main; - 对外部写操作建立人工确认、幂等键、超时、重试上限和审计记录。
源码根 LICENSE 与 README 声明 Apache License 2.0,但 package.json 的 license 字段仍写为 MIT。分发修改版或商业集成前应以完整许可证文件为基础,并向上游确认元数据差异,不要只读取包字段做合规判断。
六、工程边界、适用场景与落地建议
6.1 运行状态、认证、数据出网与并发边界
Brain 当前把运行中的 TaskLock、动作队列和 Agent 内存保存在进程内;Trigger 虽由 server/ 的 Celery Beat 调度,真正执行仍依赖在线桌面接收事件。这意味着"可以同时看到多个任务"不等于已经具备无状态横向扩容。容量还会受模型配额、浏览器 Profile、本机终端、目录 I/O 和 Connector 上游限额共同影响。
当前公开源码没有给出可复现的吞吐、P95 时延或稳定并发报告。生产评估应使用自己的任务组合记录 Run 创建、首个事件、工具耗时、人工等待、产物成功率和失败恢复;若要部署多个 Brain,还需补会话粘性、状态外置以及浏览器和终端资源归属。
server/ 的 JWT 和资源检查不能自动覆盖默认使用 NoneAuth 的 Brain。Hands 提供部署感知的能力门控,但不是容器或虚拟机隔离证明;云模型、远程 MCP 和 Connector 还可能把项目内容发送到外部服务。公网部署必须收紧 Brain 监听与认证,把密钥放入专用 Secret 管理,并对文件写入、终端、浏览器和外部写操作应用最小权限与人工确认。
6.2 适用场景与落地顺序
Eigent 适合以下场景:围绕本地代码库持续开发与测试;同时需要网页调研、数据整理、报告/PPT/表格产出的复合任务;希望用 MCP 接入日历、文档、协作平台或内部服务;希望保留项目文件、Run 和产物,而不是每次从空白聊天开始。
它不天然解决所有企业平台问题。本地模型质量和工具调用兼容性差异很大,跨地域高可用、复杂 RBAC、集中审计、数据防泄漏和大规模任务队列仍需要额外架构。
建议按下面顺序落地:
- 先选一个输入、产物和验收标准都清晰的项目;
- 用 Single Agent 验证工作目录、模型、文件/终端和最终产物;
- 建立任务集,记录成功率、人工介入、Token、耗时和副作用;
- 只有任务确实可拆分时再使用 Workforce,并检查规划结果后启动;
- MCP 与 Skills 从最小集合开始,外部写操作单独授权;
- 最后补齐认证、容器隔离、网络策略、密钥、备份、监控和回滚。
从源码看,Eigent 的价值并不是发明了新的多智能体算法,而是把 CAMEL Workforce、模型与工具能力组织成一个能选择项目目录、看见执行过程、管理 Run 和接收真实产物的桌面工作环境。它把 Agent 从"回答问题"推进到"在上下文和工具边界内完成任务";真正决定生产可用性的,则是任务设计、模型评测、最小权限和可靠运维。
参考资料
- Eigent GitHub 仓库:https://github.com/cmyk-labs/eigent
- Eigent 官方 GitHub 仓库:https://github.com/eigent-ai/eigent
- Eigent 官方文档:https://www.eigent.ai/docs/