【Eigent 源码架构与实战】开源 Cowork 桌面、多智能体 Workforce、Trigger 自动化与本地部署

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

官方文档:https://www.eigent.ai/docs/

一、产品定位与效果:从对话助手走向 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:记忆文件失败会记录日志,但不会让聊天任务失败。

需要注意三层边界:

  1. 这是本地 JSON/JSONL/Markdown 存储和预算化提示词拼装,不是自动对全部项目文件建立向量索引。
  2. RAGToolkit 确实存在,但它是可给自定义 Worker 选择的工具,封装 CAMEL Retrieval、OpenAI Embedding 与本地 Qdrant;它不是每次 Eigent 对话必经的核心链路。
  3. 当前 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 已经拥有模型、目录和工具。第一次使用建议建立一个小而可复核的闭环:

  1. 在 Agents → Models 配置一个可用 Provider,并先完成普通对话测试;
  2. 新建测试 Space,选择一个专用本地目录,避免直接对重要仓库使用 direct-write;
  3. 使用 Single Agent 执行"读取两个文本文件并在 output/summary.md 生成摘要"一类结果明确的任务;
  4. 对照任务树、终端/工具事件和文件预览,确认产物真实写入本次 Run 的目录;
  5. 再用 Workforce 执行同类可拆分任务,检查规划、Worker 分配与最终文件是否比 Single Agent 更合理;
  6. 接入 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、集中审计、数据防泄漏和大规模任务队列仍需要额外架构。

建议按下面顺序落地:

  1. 先选一个输入、产物和验收标准都清晰的项目;
  2. 用 Single Agent 验证工作目录、模型、文件/终端和最终产物;
  3. 建立任务集,记录成功率、人工介入、Token、耗时和副作用;
  4. 只有任务确实可拆分时再使用 Workforce,并检查规划结果后启动;
  5. MCP 与 Skills 从最小集合开始,外部写操作单独授权;
  6. 最后补齐认证、容器隔离、网络策略、密钥、备份、监控和回滚。

从源码看,Eigent 的价值并不是发明了新的多智能体算法,而是把 CAMEL Workforce、模型与工具能力组织成一个能选择项目目录、看见执行过程、管理 Run 和接收真实产物的桌面工作环境。它把 Agent 从"回答问题"推进到"在上下文和工具边界内完成任务";真正决定生产可用性的,则是任务设计、模型评测、最小权限和可靠运维。

参考资料

  1. Eigent GitHub 仓库:https://github.com/cmyk-labs/eigent
  2. Eigent 官方 GitHub 仓库:https://github.com/eigent-ai/eigent
  3. Eigent 官方文档:https://www.eigent.ai/docs/
相关推荐
汐ya~1 个月前
【 Kortix开源ChatGPT Work平替】Git 驱动的 AI Management System、OpenCode Agent 与隔离沙箱
github开源·ai管理系统·chatgpt work·开源替代方案
汐ya~1 个月前
【MaxKB 技术全景】开源企业级知识库 RAG、工作流智能体、工具生态与生产部署
github开源·企业级rag知识库·工作流agent·mcp/skills/工具
汐ya~1 个月前
【PageEyes Agent 跨端 UI 自动化】开源Pydantic AI、OmniParser 多源感知的UI 自动化Agent
计算机视觉·agent·ui自动化·github开源