CodexAgentDelegator:从省token到多Agent协作

最早只是觉得Codex额度和上下文越来越不抗用。把日志、网页和目录扫描交给 WorkBuddy 后,主会话不用再把上下文耗在材料整理上,可以把精力(马内)留给后面的判断。
把材料处理和技术判断分开
一开始没想做”多智能体平台”:很多任务有价值,但不值得让 Codex 全程亲自处理。读日志、扫文件、整理长网页、找线索这类脏活既吃上下文,又把 Codex 拖进材料清洗里;材料全塞进会话,Codex 既要翻日志又要下判断,噪声就跟着涨。所以 CodexAgentDelegator 只把压缩、筛选这类前处理交给 WorkBuddy,判断、修改和答复仍由 Codex 自己完成。
一次实际使用记录

下面是几次WorkBuddy CLI调用的实际积分消耗记录。


Skill不再无条件介入
这个项目后来做过一次重要调整:不再追求无边界的skill激活。
如果一个skill总是无条件介入,很容易从“帮手”变成“噪声源”。每次任务稍微复杂一点,它都想拆、想派、想总结,最后用户和主Agent要花更多精力管理,且会浪费更多的token,适得其反。
这个坑踩得很实。早期版本里触发条件写得太宽,一个 Codex 自己三分钟就能改完的小问题,它也要先拆成子任务、派给 WorkBuddy、再汇总回来,三步的事硬是变成七步。
后来想明白一件事:skill 的价值不在于“能介入”,而在于“知道什么时候不介入”。
更倾向于把它放在明确场景里使用:
- 日志太长,主Agent没必要完整吞进去;
- 仓库候选文件太多,需要先粗筛;
- 较大的检查可以拆成多个边界清楚的委托任务,再由主Agent分别复核;
- 长材料需要压缩成便于主Agent继续处理的短结果;
- 想让辅助Agent(WorkBuddy)只做计划或只读分析,不直接改代码。
当前的配置允许Codex根据任务隐式选择,但 SKILL.md 限制了适用范围:日志压缩、目录扫描、候选查找、长上下文摘要、分类和信息提取可以交出去;最终判断、代码修改和用户答复仍然不能默认交出去。
也就是说,不是默认接管Codex工作流,是在“上下文明显太重”或“任务天然可拆”的时候再出现,设计目标是避免无条件、无边界地介入。
技术实现:MCP、skill 和结构化任务
项目以 Codex 插件形式发布,仓库结构如下:
1 | codex-agent-delegator/ |
整体由两层组成:MCP Server 负责工具暴露和调用链路,Skill 约束层负责定义委托边界。
第一部分:MCP Server 是怎么实现的
先说句写这段的初衷:不是要教人如何从零手搓 MCP,而是想借这个小工具,让人看懂 MCP 到底是怎么把两个 AI 串起来的。没多高端,本质就是一套”谁来喊、喊什么、怎么回”的约定。
MCP(Model Context Protocol)可以理解成一块“标准转换插头”:Codex 是电器,WorkBuddy 是电源,MCP Server 就是中间那块插头。只要插头符合标准,Codex 不需要懂 WorkBuddy 内部怎么工作,插上就能调。这块“插头”是一个纯 Python 脚本,只用基础的标准库。
整个调用链就七步,用大白话过一遍:
- 登记启动方式:
.mcp.json告诉 Codex,“想用这个服务,就去跑python ./scripts/workbuddy_mcp_server.py”。Codex 把它拉起来之后,双方通过 stdin/stdout 互发 JSON 消息。 - 进入消息循环:Server 跑起来后就是一个死循环,读一条消息、处理、回一条,如此反复。消息格式兼容两种(按行分隔的 JSON 和 Content-Length 分帧),首次读取时自动探测。
- 握手自报家门:Codex 先发一个
initialize,Server 回协议版本、名字和一段 instructions。它告诉 Codex“我这有哪些工具、什么时候该用、什么时候别用”。 - 返回工具列表:Codex 问
tools/list,Server 返回四个工具:ask_workbuddy(委托辅助分析)、summarize_for_codex(压缩本地上下文)、fetch_url(抓网页)、summarize_url_for_codex(抓完网页再让 WorkBuddy 摘要)。 - 按名分单:Codex 调
tools/call时带上工具名,Server 按名路由。fetch_url自己处理,不启动WorkBuddy;其余三个会去启动 WorkBuddy CLI。 - 跑 CLI:
run_workbuddy()干三件事——先找到 CLI 在哪(环境变量“WORKBUDDY_BIN” → 系统PATH →~/.local/bin,找不到就报错),再组装参数,最后subprocess.run()同步等它跑完。 - 取结果:优先读 stdout;拿不到就去翻最近的 JSONL 会话记录,从最后一条 assistant 消息里把文本捞出来;还拿不到,就返回诊断信息。
最小的启动配置长这样:
1 | { |
完整版里还有 startup_timeout_sec、tool_timeout_sec 两个超时配置,防止 Server 卡死把 Codex 也拖住。
所谓 MCP 集成,说穿了就是一个“读消息、分发、回消息”的循环,加上一个帮你跑命令行的子进程。
前置条件:本机需安装 WorkBuddy并完成认证(登录或 API Key),
python需在PATH中。如果自动发现找不到 CLI,设置环境变量WORKBUDDY_BIN指向完整CLI路径。
当前版本仅是一条 Codex → MCP Server → 单个 WorkBuddy CLI 的主辅链路,暂时没有并行调度和多 Agent 编排。
第二部分:Skill 层使用约束
Skill 文件(SKILL.md)不执行任务,只约束”何时适合委托”:
- ✅ 适合委托:总结大文件/目录/日志/调用链/网页、查找候选文件/符号/配置项、分类/分组/去重/信息提取、准备简短交接材料
- ❌ 不可委托:最终代码评审、安全判断、破坏性操作、产品决策、存在歧义的取舍、需要审批的修改
权限升级红线:如果任务本应只读但 WorkBuddy 报缺 Bash 等工具,不自动扩大权限,而是缩小提示词范围或由 Codex 直接检查。WorkBuddy 的输出永远只是支持性证据,不是最终结论。
查看当前 SKILL.md
1 | --- |
提交日志里的两个坑

实际测试下来,最折腾的反而是两个环境问题。
第一个坑:stdout 是空的。
WorkBuddy跑完就读 stdout。结果在桌面端 Agent 场景下,CLI 压根不把最终结果写到 stdout,上游拿到一个空串,就以为任务失败了。这个PR就是为了这事——Improve WorkBuddy MCP response recovery and desktop-agent compatibility。解法就是上面第 7 步说的三级策略:stdout 拿不到,就去翻最近的 JSONL transcript,再拿不到就返回诊断信息。
第二个坑:路径换台机器就挂。
一开始工作目录的解析依赖插件的安装位置,本机跑得好好的,换个目录、换台机器,WorkBuddy就找不到在哪启动了。7月5日的 fix: make workbuddy cwd portable 修的就是这个:绝对路径直接用,相对路径丢到 WORKBUDDY_MCP_WORKDIR 下面解析,再加一层 WORKBUDDY_MCP_ALLOWED_WORKDIRS 白名单校验。
后续设想
在当前实现之外,还考虑增加用一份结构化清单(manifest)描述任务和并发限制。
目前它离“多Agent编排”还很远,但本质上还是Codex主导、WorkBuddy做辅助。实际用下来反而感觉这也是比较舒服的状态,不是为了多Agent而多Agent,什么时候委托、什么时候不委托,比多接个Agent更重要。
如果你也在用 Agent 搭自己的小工具,欢迎在评论区聊聊你踩过的坑。



