OPEN SOURCE DEEP DIVE
OpenDuet:主动工作的自托管个人智能体
基于 OpenBot 与 CopilotKit 打造的自托管主动型个人智能体,以独立电脑执行任务,并用审批、审计与网络策略约束每一步。
OpenDuet 是 CopilotKit 开源的主动型个人智能体。它不等用户每次发问,而是每天先整理邮件与日程、提出下一步任务,并在用户离开后继续使用一台独立电脑完成工作。项目目前仍处于早期开发阶段,核心能力建立在 CopilotKit 的 OpenBot 平台之上,采用 MIT 许可证;OpenDuet 自身主要是一套放在 openbot/examples/openduet 目录里的品牌、智能体、渠道、模型与技能配置。
它真正值得研究的并不是“主动”这个宣传词,而是主动工作所需的治理链。一个持续获得邮件、浏览器、文件与命令行权限的智能体,如果没有清晰的动作边界,能力越强,风险越大。OpenDuet 尝试把每次工具调用重新送回服务端网关,先解析目标、判断策略、写入审计,再允许执行。也正是在这条链上,项目展示了主动智能体从演示走向可部署系统时必须回答的问题。
主动工作首先需要一台真正能干活的电脑
普通聊天助手擅长解释问题,却很难在用户离开后继续处理一项跨多个网页、文件和工具的任务。OpenDuet 给每个智能体准备一个独立容器,里面包含 Chromium、持久化浏览器配置、/workspace 目录和 shell。智能体可以打开网站、整理文件、执行命令、保存中间结果,并在下一次对话中继续使用同一工作区。
这种持续环境解决了聊天机器人最常见的断裂:一次对话结束后,页面状态、下载文件和已经完成的步骤不该全部消失。浏览器配置会保留登录状态,工作区会保留产物,于是“帮我查一下、填完、整理好”才有可能成为一条连续任务。用户还可以通过网页、移动端、Slack 或 Microsoft Teams 与同一个智能体对话,OpenBot 负责这些渠道以及登录、团队空间和实时界面。
但持久化电脑也会放大错误。一个模型如果误点按钮、误发邮件或误删文件,后果不再停留在回答文本里。因此 OpenDuet 没有让智能体直接操作整台电脑,而是要求浏览器、文件和 MCP 动作经过服务端网关。电脑提供执行空间,网关保留最终控制权,这两者缺一不可。
一条请求怎样穿过系统
用户在界面中发出任务后,OpenDuet 服务器先确定登录者、所选智能体和对应会话,再把这一轮请求通过 AG-UI 发送给智能体。智能体可以是使用 LangGraph、Mastra、CrewAI、Pydantic AI、Google ADK 构建的端点,也可以由开发者手写;OpenDuet 没有被绑定到单一框架。
智能体需要浏览器或连接器工具时,调用不会直接落到目标资源,而是返回服务端。网关先从服务器保存的页面快照中解析不透明元素引用,确认模型所说的“这个按钮”究竟对应哪个真实目标;随后读取当前策略,决定允许、询问还是移交给用户;每个决定先写入审计记录,只有被允许的动作才会执行。动作执行失败时,系统还会再写一条失败审计。
这条顺序看起来比“模型调用工具”多了几层,但每一层都解决一个具体问题。目标必须由服务端解析,模型不能伪造元素指向;策略必须由部署方控制,提示词不能自我授权;审计必须发生在动作之前,否则一次成功但未记录的操作无法追查。OpenDuet 把审批和记录放在动作前,而不是等出了问题再补日志。
策略引擎失败时默认拒绝
OpenBot 的动作策略使用 CEL 表达式,并能读取工具名、动作意图、智能体身份、当前用户、页面地址、元素角色与名称、按键、命令、文件路径、MCP 服务以及运行发起者等字段。拒绝规则先于允许规则计算;损坏的拒绝规则会拒绝动作,损坏的允许规则不会放行。缺失策略或空策略也不会产生默认许可。
这里有一个容易被文章写错的边界。策略引擎本身失败关闭,但 OpenBot 随项目提供的启动默认策略是显式的 deny: [] 与 allow: ["true"],除非环境变量或管理员保存的策略覆盖它。因此不能笼统宣称“OpenDuet 一启动就默认拒绝全部动作”。准确的说法是:策略表达出现问题时不放行,而实际部署必须检查默认策略是否已经被合适的限制替换。
| 治理层 | 它负责什么 | 为什么不能省略 |
|---|---|---|
| 服务器快照 | 把模型给出的不透明元素引用解析成真实页面目标 | 防止模型用过期页面或伪造引用指向另一个按钮 |
| 动作策略 | 根据工具、页面、文件、命令和运行来源决定是否放行 | 把部署方的规则放在模型提示词之外 |
| 审计记录 | 在动作前记录授权身份、发起者、目标和策略决定 | 让成功、拒绝与失败都能被事后调查 |
| 人工审批 | 对发送、付款、签署、删除等动作暂停并展示具体目标 | 为高风险后果保留明确的人的决定 |
审计还区分“以谁的身份执行”和“是什么启动了这次执行”。例行任务以创建者的权限运行,但发起者是定时任务,而不是当时坐在屏幕前的人。这样管理员才能筛出“无人观看时发生了什么”,而不是只看到某位用户授权过就误以为他当时在场。对于主动智能体,这一区别比普通聊天系统更重要。
审批不是一枚万能开关
OpenDuet 的动作决策按 allow、pre_approved、ask、hand_off 四档处理。普通低风险读取可以直接允许;需要审批的动作会暂停,并向用户展示准确的目标、内容和触发规则,通常提供“拒绝”“允许一次”“始终允许”。凭据操作、安全设置和付款始终移交给人,不会因为模型判断“看起来安全”而自动执行。
预批准也不等于跳过审查。即使某类动作此前已获得授权,系统仍会调用审查器,确认当前请求确实要求的是同一类动作和同一个目标。审查器失败、输出无效或超时都会回到需要人工审批的状态。发给其他人的消息始终需要询问一次,并明确展示收件人与正文。这个设计承认了一个现实:用户批准的是有限情境,不能让模型把一次批准扩展成永久通行证。
敏感输入走另一条隔离路径。网站要求密码时,用户看到的是掩码秘密输入框,密码直接交给网站,不进入模型读取的对话转录。需要保存的凭据会加密存储、只允许写入而不通过 API 读回,并在审计事件中脱敏。系统可以记录“请求过一个秘密”和字符数量,但不记录秘密本身。
遇到验证码或登录墙时,智能体可以请求人工接管。人工控制浏览器期间,机器人动作会被拒绝而不是排队等待,避免用户在操作时智能体同时点击;交还控制权时,系统要求重新取得页面快照。这样既让用户解决真人验证,又避免旧快照成为下一步错误动作的依据。
独立电脑还需要独立网络边界
OpenDuet 的网络策略有四种模式:允许全部、默认规则加允许列表、只允许列表、全部拒绝。无论处于哪一种模式,云元数据地址和链路本地地址都会被拒绝。新电脑启动后,在服务端推送策略之前不能主动外连。这能降低恶意网页诱导智能体访问云凭据端点或内部服务的风险。
网络过滤由浏览器和 shell 继承的代理设置执行,因此它不是完整的内核级隔离。一个程序如果忽略代理变量并直接建立原始套接字,代理层无法阻止它。项目文档明确指出,对于这一层需要依赖 Kubernetes NetworkPolicy。阅读 OpenDuet 的安全声明时,应把代理策略与容器网络策略分开理解,不能把它们当成同一道防线。
计算机容器和 PostgreSQL 也被放在不同网络里。智能体拥有 shell,而 shell 能访问其所在容器的全部网络,所以数据库被单独放入只允许迁移任务进入的网络。如果 API 服务也被放进 Compose,它会成为两个网络之间的连接点,这是部署时需要特别审计的位置。运行在支持 gVisor 的主机上时,还可以把计算机运行时切换为 runsc,进一步收紧隔离。
晨间简报如何变成可信的任务入口
OpenDuet 的第一个具体场景是 Gmail 与 Google Calendar。每位用户连接自己的账户,智能体读取邮件和当天日程,把新邮件分成“需要你处理”和“可以等待”,并为每一封给出简短原因。晨间简报每天第一次打开聊天时生成,汇总需要处理的事项、可以等待的邮件、日程,以及无法检查的部分;即使同时打开多个标签页或设备,也只会发布一次。
邮件分类并非全部交给大模型。规则可以先判断一封邮件是否可能等待,但不确定或可能重要的邮件会交给模型处理。分类失败的邮件不会被静默丢掉,而是出现在“需要你”的区域。晨间简报最多读取五十封邮件,并在超过上限时明确报告还有邮件未处理。这些限制说明项目试图让系统在能力不足时暴露边界,而不是假装整个收件箱已经被完整理解。
简报里的“开始”按钮才会把一封邮件交给智能体处理。任务标签页把工作分成需要用户回答、后台建议、正在执行、待复核和等待输入等状态。后台研究可能生成建议,但建议不会自动开始;即使智能体通过工具一次性创建多张任务卡,也不会有任何一张被自动启动,数量被限制在一到八张之间。
定时例行任务同样不是无限自主。例行任务以创建者身份运行,最小间隔为十五分钟,每个人最多启用二十条;连续失败十次后会被禁用。错过的执行窗口会被跳过,不会在系统恢复后集中补跑。面对一项可能影响外部世界的任务,这些限制能避免延迟恢复造成意外的时间错位。
主动能力背后的普通工程
OpenDuet 的工作不止晨间简报。它支持任务与例程、受治理的 MCP 连接器、Google Drive 与 Notion 等应用、通过对话创建的设计与网页、Slack 和 Teams 渠道,以及用斜杠调用的可复用技能。所谓主动智能体,最终还是由这些普通的持久化、调度、权限和状态管理组件支撑。
会话与记忆存放在 CopilotKit Intelligence,策略、审批、审计与加密凭据存放在 PostgreSQL 和 pgvector 中。默认模型是 gpt-5.6-terra,也可以切换到 Anthropic 或其他外部 AG-UI 智能体。自托管需要 Docker、Bun 1.3 以上、Node、一个模型密钥和一个 CopilotKit Intelligence 项目。Intelligence 不是可选组件,因为它保存线程和记忆,缺少密钥时服务器无法启动;免费开发者计划已经够用。
仓库结构也反映了这一分工。服务器、应用、例程工作进程、计算机容器、Docker 与 Helm 文件都在 openbot/ 中;OpenDuet 真正新增的品牌名、智能体提示词、频道、模型和技能集中在一个租户目录。开发者复制该目录并修改 TENANT_PACKAGE_DIR,就能做另一个助手,同时继续接收底层 OpenBot 的修复。
分类评测能说明什么,不能说明什么
仓库包含一组专门构造的邮件回归样本,用来检查规则与模型在“需要你”和“可以等待”上的分类表现。在一次六十二封邮件的测试中,Claude Sonnet 5.5 达到百分之百的精确率、召回率和准确率;在更早的六十封样本中,GPT-5.6 Terra 达到百分之九十六点二的精确率和百分之百的召回率。纯规则在六十二封邮件中自行决定了十二封,没有观察到错误。
这些数字适合验证代码路径和提示词改动是否破坏已有案例,不能证明真实收件箱中的表现。样本是为了测试而编写的,没有覆盖不同企业的邮件文化、长线程、附件、恶意内容和分布漂移。一个准备部署 OpenDuet 的团队应当使用自己的脱敏邮件集重新评测,并把误报和漏报分别标价:漏掉需要处理的邮件会损害信任,频繁误报则会让人很快忽略整个简报。
适合谁,以及现在还不能承诺什么
OpenDuet 更适合愿意自己运行服务、能够配置模型与 Google OAuth、并且重视审批与审计的开发者或小团队。它适合拿来研究主动智能体如何获得持久电脑、如何把无人值守动作与人工授权连接起来,也适合作为一个可改造的个人工作助手基础。它当前不是一个开箱即用的托管消费产品。
项目的早期状态必须明确看待。OpenDuet 目前没有正式发布镜像或部署指南,Docker 与 Helm 文档部署的是纯 OpenBot,而不是已经带好 OpenDuet 租户层的版本。计算机、网关、审批、凭据和连接器的实质性修改通常属于上游 OpenBot,贡献者被建议先开 issue。任何准备用于真实付款、法律文件或公司敏感数据的人,都还需要自行补充密钥管理、备份、网络策略、合规与事故响应。
从系统设计角度看,OpenDuet 提出了一条清晰主张:主动智能体的可用性不取决于它能否替代用户点击更多按钮,而取决于无人值守执行是否和能力本身受到同等认真对待。独立电脑让它能够持续推进工作,网关让它不能自行扩张权限,审批把不可逆后果交还给人,审计则让“它做过什么”成为可调查的事实。对于一个仍处于早期阶段的开源项目,这比再多自动化入口更值得关注。