Agent 工程对照
← 返回框架对照

结构 · 第 3 章

内核与扩展边界

哪些能力属于内核,哪些必须做成扩展?

内核从厚到薄:openJiuwen 是完整单体,Pi 只留循环和四个工具,DeepSeek 连循环都可替换。

内核有多厚

  1. 完整单体
  2. openJiuwen
  3. Codex
  4. Pi
  5. DeepSeek
  6. 连循环都可替换

定性示意:只表示先后,间距没有数值含义。

场景建议

编辑判断

按你的需求,倾向哪种做法

借鉴的是那一家的设计,不等于选用那个框架。

场景

要能替换任何一个部件

它没有特权内核,模型适配器、工具注册表、会话日志和 Agent 循环都是插件,可由分层配置替换。

场景

同一套逻辑服务多个界面

codex-core 本身就是供各个 Rust 界面复用的库,扩展通过 12 种 contributor trait 接入。

场景

内核越小越好

内核只有循环和四个工具,文档明确列出不内置的能力,交给扩展、技能与包。

容易踩的坑

  • 边界切在哪里都有代价:内核越薄越需要文档与测试来钉住「谁负责什么」,否则功能会在两层之间静默丢失。

四家怎么做

差异与源码

openJiuwen

core 提供单体 ReAct 与挂载点,harness 的 DeepAgent 包在外面

包结构就是边界:openjiuwen/core 放基础设施、单体 ReActAgent、会话与上下文引擎,以及挂载点的事件枚举;openjiuwen/harness 放 DeepAgent——它把一个内层 ReActAgent 包起来,在外面加任务循环、rails、子代理运行时、技能与工作区。边界的代价写在这三组常量里:每个挂载点事件必须明确路由到内层还是外层的回调命名空间。harness/rails/AGENTS.md 专门警告,新增事件漏了路由不会报错,只会让 rail 静默失效,所以另有单测断言三个集合恰好覆盖全部事件、互不相交。

适合
想先用一个完整的单体 Agent,再按需叠加 Harness 能力的团队。
代价
两层 Agent 之间的事件路由、状态传递要靠约定与单测维护。

此后的变化

  • 2026-W36 →

    自我演化落在 harness/rails/evolution/ 扩展层而非内核,可由 dynamic_graph_enabled 整体关闭,异常时回退静态规划——「稳定内核 + Rails」路线的又一例证。

  • 2026-W35 →

    「模板与插件的创建、加载与执行」由 W34 的 feat 转为同名 fix,插件机制进入修补期;是否构成内核边界迁移仍需继续观察。

  • 2026-W34 →

    feat(harness) 支持模板与插件的创建/加载/执行,内核与扩展的边界可能正在移动。

Codex

codex-core 是可嵌入的库,功能正按「贡献类型」往 ext/ 外迁

codex-core 的 README 开宗明义:它实现 Codex 的业务逻辑,供各个 Rust 写的界面复用。整个 codex-rs 工作区有 135 个 crate,其中 ext/ 目录下的 14 个是扩展:记忆、技能、目标、网页搜索、图像生成、MCP、连接器等。它们通过 extension-api 定义的 12 种 contributor trait 接入内核——上下文、工具、回合生命周期、回合输入、配置、token 用量、审批复核等。这份设计笔记把每个功能拆成它需要的贡献类型,例如记忆是「上下文 + 工具 + 输出」,技能是「上下文 + 回合」,并预留了「将来的沙箱大概是 请求 + 运行时」。

适合
要把同一套业务逻辑嵌入多个前端(命令行、桌面、服务端)的产品。
代价
工作区规模大(135 个 crate),功能外迁到 ext/ 仍在进行中。
DeepSeek Harness

没有特权内核:运行中的 Harness 是按层配置组装出的插件树

整个产品建在 Cordis 插件框架上,模型适配器、工具注册表、会话日志乃至 Agent 循环本身都是插件,都能靠配置替换;扩展的方式是在旁边挂一个插件,插件卸载时它注册的一切随之撤销。运行时的样子由 profile 决定:按顺序叠加 bundle、profile 的补丁、home 目录的补丁和命令行 --patch,任何一行都能被上层补丁替换,dsh --dump-config 可以打印出本机实际启动的整棵树。packages 目录下还有一个 extensions 包,允许模型在运行时检查、挂载和卸载自己写的插件。

适合
需要按部署场景重新组装整个 Harness,甚至替换 Agent 循环本身。
代价
要先学会插件框架与分层配置,排查问题时得先弄清本机实际启动了哪棵树。

此后的变化

  • 2026-W37 →

    公开包清单收窄:DshManifest 删除 dsh.categories(其自身注释即写明是自由发现标签、不影响插件加载),README 与架构说明同步移除,桌面端未被调用的插件分类查询一并删除。本格描述的「配置生成的插件树」在声明面上少了一层没有执行方的分类元数据。

Pi

内核刻意小:MCP、子代理、权限弹窗、计划模式一律不内置

包的分层就是边界:pi-ai 统一各家模型 API,pi-agent-core 提供带工具调用与状态管理的运行时,pi-coding-agent 是命令行编码 Agent,pi-tui 是终端界面库。使用文档把原则写成一句话:内核保持小,工作流相关的行为推到扩展、技能、提示词模板和包里;并点名不内置 MCP、子代理、权限弹窗、计划模式、待办和后台 bash——需要的话自己写扩展,或交给容器、tmux 这类外部工具。内核工具只有读、写、编辑、bash 四个(见「工具定义方式」一行)。

适合
想要一个能完整读懂、按需自己加功能的最小内核。
代价
MCP、子代理、权限确认这些常用能力都要自己写扩展或另找包。

此后的变化

  • 2026-W40 →

    内核新增通用机制:工具暴露级别、prepareLoadout() 与经过校验和钩子的嵌套调用 ctx.executeTool();codemode、tool_search、MCP 以内置扩展形式提供。「内核不内置 MCP」仍成立,但默认发行版已经带上它。

横向读这一行

四家的「内核」从厚到薄排成一条线:openJiuwen 的 core 提供完整的单体 Agent,harness 包在外面;Codex 的 codex-core 是一个大库,正按贡献类型把功能往 ext/ 外迁;Pi 的内核只有循环和四个工具,其余一律交给扩展;DeepSeek 干脆没有特权内核,连 Agent 循环都是可替换的插件。内核越薄,替换越自由,但「一个功能到底由谁负责」就越需要靠文档和测试来钉住——openJiuwen 为事件路由写单测、Codex 写贡献类型设计笔记,都是在为边界付账。

这个问题为什么存在

第 3 章

Harness 是什么

围绕模型的编排框架:它编码了「模型独立完成不了什么」