ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从Codex到OpenWorkBuddy:Agent工作台级迁移实战

从Codex到OpenWorkBuddy:Agent工作台级迁移实战 1. 项目概述一次工作流底层逻辑的迁移而非简单模型替换“从 Codex 到 OpenWorkBuddy我换的不是模型而是 Agent 工作台”——这句话乍看像一句技术营销话术但如果你真在一线跑过 AI 工具链、搭过本地 Agent、调试过 MCP 协议流、被codex cli的/responsesendpoint 报错卡住过三小时你就会明白这根本不是“换个模型 API 地址”这么轻巧的事。它是一次工作台级重构把原来依附于 Codex CLI 的命令行胶水层、硬编码的工具调用逻辑、零散的 MCP 适配器、以及所有靠zcode cli或ruoyi-vue-pro合并补丁勉强维持的流程全部推倒换成 OpenWorkBuddy 提供的标准化 Agent 运行时、声明式工具注册机制、原生 MCP v2 协议栈以及可插拔的 CLI 入口。核心关键词Codex、OpenWorkBuddy、Agent、CLI、MCP不是并列标签而是一条演进路径上的五个关键坐标点Codex 是起点一个以代码生成为核心的封闭 CLI 工具OpenWorkBuddy 是终点一个面向通用任务编排的开放 Agent 工作台Agent 是目标形态能自主规划、调用工具、处理上下文的执行体CLI 是入口形态但已从“命令驱动”升级为“会话驱动”MCP 是通信底座从 Codex 勉强兼容的 MCP 子集到 OpenWorkBuddy 全面实现的 MCP 标准协议。这个迁移解决的不是“能不能用”而是“能不能稳、能不能扩、能不能审、能不能管”——比如你在 Codex 里想让 Agent 同时调用 GitLab CLI 和 Unreal Engine 5.8 的 MCP 插件得自己写 Python 脚本桥接、手动处理 token 透传、硬编码参数映射而在 OpenWorkBuddy 里你只需在tools.yaml里声明两个 MCP Server 的地址和 capabilityAgent runtime 自动完成 discovery、schema negotiation、streaming call 和 error context 捕获。这不是功能增强是范式切换。适合正在用codex cli install搭建私有化环境、被codex无法加载组织设置困扰、或正评估ai agent 怎么扛并发的中高级开发者、AI Infra 工程师、以及需要将 Agent 集成进现有系统如ruoyi-vue-pro合并mcp功能的技术负责人。它不教你怎么装 Codex而是告诉你当你的 Agent 开始调用x32dbg 的mcp插件处理二进制、或通过cherrystudio的 MCP 流式输出渲染结果时你真正需要的是一个能承载这种复杂性的底盘。2. 整体设计思路拆解为什么必须放弃 Codex CLI 的胶水架构2.1 Codex 的本质局限一个“单点优化”的 CLI 工具不是 Agent 平台Codex 最初定位非常清晰一个基于 GPT-3.5/4 的代码补全与生成 CLI 工具。它的设计哲学是“极简入口 强大模型”。codex cli命令如/compact、/model、/resume看似灵活实则全部围绕“单次请求-单次响应”模式展开。它的 MCP 支持是典型的“事后缝合”——不是作为核心通信协议设计而是为了对接 Figma、蓝湖等外部设计工具而做的适配层。这就导致几个致命问题工具调用非声明式你在 Codex 里调用 GitLab CLI得先codex cli --tool gitlab --args list projects参数全靠字符串拼接没有 schema 校验也没有类型安全。一旦 GitLab CLI 升级参数格式Codex 就报cc switch local proxy failed while handling codex endpoint /responses因为它的 proxy 层根本不知道如何解析新版响应结构。上下文管理粗放Codex 的/resume功能本质是把上一次的 promptresponse 存成文件再读取没有真正的 session state 管理。当你需要 Agent 在“分析 PR diff → 查询 Jira issue → 生成 review comment → 推送 Slack”这一连串动作中保持 context continuityCodex 的文件存取方式就成了性能瓶颈和状态丢失温床。MCP 实现残缺Codex 所谓的 MCP 支持仅覆盖了execute和listTools两个基础 method对stream流式输出、cancel取消调用、getSchema获取工具能力描述等关键 method 完全缺失。这也是为什么大量用户搜索codex无法找到mcp或codex接入 figma mcp 怎么授权?——不是不会配而是 Codex 根本没提供标准的 MCP handshake 流程。我试过给 Codex 打补丁用 Python 写 wrapper 脚本把unreal 5.8 mcp的tia mcp 260514交付包解包后硬塞进 Codex 的 tool 目录再修改codex安装包里的config.json。实测下来前两次能跑通第三次就因 MCP version mismatch 导致provi字段解析失败。这不是运维问题是架构问题——Codex 的 CLI 架构天生排斥“多协议、多版本、多状态”的 Agent 生态。2.2 OpenWorkBuddy 的设计哲学以 MCP 为基石的 Agent 运行时OpenWorkBuddy 的核心突破在于它把 MCP 协议从“可选插件”提升为“运行时契约”。它不是一个新 CLI而是一个轻量级 Agent RuntimeCLI 只是其众多入口之一其他还有 HTTP API、VS Code Extension、Obsidian Plugin。它的设计遵循三个原则协议先行所有工具必须通过标准 MCP 协议注册。你不能直接调用gitlab cli而必须启动一个符合 MCP v2 规范的 GitLab Server比如gitlab-cli-mcp-server它暴露/toolsendpoint 返回完整的 JSON Schema 描述包括每个参数的 type、required、description甚至 example value。OpenWorkBuddy 的 runtime 在启动时自动 discovery 所有可用 MCP Server并构建本地 tool registry。会话驱动CLI 不再是codex cli /model gpt-4这样的命令而是owb-cli start-session --goal review PR #123。Agent runtime 创建一个带唯一 ID 的 session内部维护完整的 execution graph哪个 tool 被调用、输入是什么、输出流是否开启、当前 state 是waiting_for_gitlab还是parsing_jira_response。这使得hermes agent obsidian这类需要长期 context 的插件能稳定运行。弹性扩展runtime 本身无状态所有 state 存在外部 store如 SQLite 或 Redis。这意味着你可以水平扩展多个 OpenWorkBuddy worker共享同一个 MCP tool registry 和 session store天然解决ai agent 怎么扛并发的问题。而 Codex 的 CLI 是单进程阻塞模型加-j4参数也只加速本地计算无法分发 tool call。这个设计不是炫技。当我把boos cli一个内部审计工具封装成 MCP Server 后OpenWorkBuddy 的 runtime 自动识别出它支持scan_compliance和generate_report两个 capability并在 Agent 规划阶段将其纳入候选工具池。而之前在 Codex 里我得手动写codex cli --tool boos --args --scan --target prod每次 target 变更都要改脚本。这就是“工作台”和“工具”的本质区别前者定义规则后者执行指令。2.3 迁移不是替代而是分层解耦CLI、Agent、MCP 的职责重划很多人误以为迁移就是卸载 Codex、安装 OpenWorkBuddy、改几行命令。实际上这是一个三层解耦过程CLI 层解耦zcode cli、codex cli、openspec cli这些都是特定工具的 CLI它们的职责应仅限于“发起请求、格式化输出”。OpenWorkBuddy 的owb-cli不取代它们而是作为更高阶的 orchestrator。你依然可以用gitlab cli查项目但 Agent 任务中调用 GitLab走的是 MCP 协议由 OpenWorkBuddy runtime 统一调度。Agent 层解耦Codex 里的 Agent 逻辑如codex cli remotion的视频生成流程是硬编码在 CLI 二进制里的。OpenWorkBuddy 把 Agent 拆成两部分planner用 LLM 做任务分解和 executor用 MCP 调用工具。planner 输出的是标准 MCPToolCallJSONexecutor 只负责解析、路由、重试。这使得based on rust language ai agent可以轻松替换 planner而不用动 executor。MCP 层统一x32dbg 的mcp插件、cherrystudio的 streaming output、ruoyi-vue-pro的后端 MCP endpoint现在都遵循同一套 protocol。OpenWorkBuddy 的 runtime 不关心你是用 Rust、Python 还是 C 实现的 MCP Server只要它响应/health和/tools就能纳入生态。这才是agent anywhere的真实含义——不是部署位置任意而是协议兼容任意。提示不要试图把 Codex 当作 OpenWorkBuddy 的“旧版本”来升级。它们是不同物种。Codex 是“智能命令行”OpenWorkBuddy 是“Agent 操作系统”。强行升级只会陷入codex登录失败后反复重装codex安装 windows桌面版的死循环。3. 核心细节解析与实操要点MCP 协议落地的硬核细节3.1 MCP 协议到底是什么不是 API是“工具宪法”MCPModel Context Protocol常被误解为“另一个 REST API 标准”这是最大的认知偏差。它本质上是一套工具能力描述与交互契约核心在于三个文档Capability Schema定义工具能做什么。例如 GitLab MCP Server 的/tools返回{ tools: [ { name: list_projects, description: List all accessible projects, input_schema: { type: object, properties: { visibility: { type: string, enum: [public, internal, private], default: public }, per_page: {type: integer, default: 20} } }, output_schema: { type: array, items: { type: object, properties: { id: {type: integer}, name: {type: string} } } } } ] }注意input_schema和output_schema是 JSON Schema不是 Swagger。OpenWorkBuddy 的 runtime 用它做 runtime validation避免传错参数导致codex无法加载组织设置这类模糊错误。Execution Protocol定义如何调用。MCP 要求所有 tool call 必须走 POST/executebody 是{ tool_name: list_projects, arguments: {visibility: private, per_page: 50}, session_id: sess_abc123 }响应必须包含statussuccess/error、content结构化数据、stream_id如果支持流式。cherrystudio的流式输出正是靠stream_id关联到前端 UI。Lifecycle Protocol定义工具生命周期。MCP Server 必须实现/healthliveness、/readyreadiness、/shutdown。OpenWorkBuddy 的 runtime 用/ready判断 tool 是否可调用避免codex接入deepseek时因模型加载未完成就发起请求。实操心得很多团队卡在codex无法找到mcp根源是只实现了/execute没暴露/tools。OpenWorkBuddy 启动时会 ping 所有配置的 MCP Server 的/tools任何一个返回非 200 或 schema 格式错误整个 runtime 就 fail fast 并打印详细 error log而不是像 Codex 那样静默忽略。3.2 OpenWorkBuddy 的 CLI 入口从命令行到会话终端的范式转变OpenWorkBuddy 的owb-cli不是codex cli的复刻。它的核心命令只有三个owb-cli start-session --goal xxx创建新会话。--goal是自然语言目标如audit all prod servers using boos cli。runtime 启动 planner生成 initial plan。owb-cli attach-session session-id连接已有会话。进入交互式 terminal能看到实时 execution graph、每个 tool call 的 status、streaming output如cherrystudio的渲染进度条。owb-cli list-sessions查看所有活跃会话支持--status running过滤。关键差异在于state management。Codex 的 CLI 进程退出一切状态丢失。OpenWorkBuddy 的 session state 存在外部 storeattach-session本质是连接到一个持久化的 execution context。这意味着你可以start-session启动一个耗时 2 小时的unreal 5.8 mcp场景烘焙任务然后CtrlC退出 CLI稍后attach-session继续监控。owb-cli本身不处理任何业务逻辑它只是 runtime 的 tty client。真正的 heavy lifting 在 background worker 进程里完成。配置要点owb-cli的config.yaml主要配置两项mcp_servers: - name: gitlab url: http://localhost:8081 timeout: 30s - name: boos url: http://localhost:8082 timeout: 120s # 审计任务耗时长需加大 timeout session_store: type: sqlite path: ./sessions.db注意timeout是 per-tool 的不是全局。boos的120s和gitlab的30s独立生效避免一个慢工具拖垮整个 Agent。注意不要把owb-cli当作日常 shell 使用。它的attach-session是专用 terminal不支持ls、cd等系统命令。想执行本地命令请封装成 MCP Server如shell-mcp-server然后让 Agent 调用。3.3 Agent 架构重构Planner 与 Executor 的分离实践在 Codex 时代“Agent” 是个黑盒你给它 prompt它吐出 code。OpenWorkBuddy 强制拆分为 planner 和 executor带来两大实操收益Planner 可替换默认 planner 是基于 Llama 3 的本地模型但你可以轻松换成harness一个专为 Agent planning 优化的框架或pi agent。替换只需改一行 configplanner: type: harness model: harness-llama3-70b api_key: sk-xxxharness和agent区别在此体现Harness 是 planner libraryOpenWorkBuddy 是 executor runtime二者互补而非竞争。Executor 可观测每个 tool call 都生成 structured log{ session_id: sess_abc123, tool_call_id: tc_456, tool_name: list_projects, status: success, input: {visibility: private}, output: [{id: 101, name: prod-api}, ...], duration_ms: 1240, timestamp: 2024-06-15T10:22:33Z }这些日志可直接接入 ELK 或 Grafana做agent安全审计——比如监控是否有 tool call 的input包含敏感 token或output中出现password字段。实操难点Planner 的 prompt engineering。OpenWorkBuddy 的默认 prompt 包含 MCP tool registry 的精简版 description只取 namedescription省略 schema 以防 token 超限。但遇到复杂工具如x32dbg 的mcp插件支持内存 dump、断点设置、寄存器读取必须定制 prompt template明确告诉 planner“x32dbg的dump_memorytool 需要address和size参数set_breakpoint需要address二者不可混淆”。4. 实操过程与核心环节实现从 Codex 到 OpenWorkBuddy 的完整迁移路径4.1 环境准备清理 Codex 遗留搭建 OpenWorkBuddy 基础设施迁移第一步不是装新软件而是清理 Codex 的隐性依赖。Codex 的codex安装 csdn包常捆绑 Python 3.9 和特定版本的requests而 OpenWorkBuddy 要求 Python 3.11 和httpx。直接共存会导致ImportError: cannot import name AsyncClient。标准清理步骤卸载 Codex CLIpip uninstall codex-cli如果用 pip 安装或删除C:\Program Files\CodexWindows 桌面版。清理环境变量检查PATH是否还包含 Codex 的 bin 目录删除CODER_HOME、CODEX_API_KEY等残留变量。验证 Pythonpython --version必须 ≥ 3.11pip list | grep -i requests应为空。OpenWorkBuddy 安装# 推荐使用 pipx 隔离环境 pipx install openworkbuddy # 初始化配置 owb-cli init --config-dir ~/.owb # 启动 runtime后台服务 owb-runtime start --config ~/.owb/config.yamlowb-runtime是核心进程它监听 MCP Server、管理 session store、运行 planner。owb-cli只是它的客户端。关键配置项config.yaml初始模板# MCP Servers - 这里先配一个最简单的 mcp_servers: - name: echo url: http://localhost:8000 timeout: 5s # Planner 配置 planner: type: llama-cpp model_path: /path/to/llama3.Q4_K_M.gguf n_ctx: 4096 # Session store session_store: type: sqlite path: ~/.owb/sessions.db # 日志 logging: level: INFO file: ~/.owb/owb.log4.2 MCP Server 封装实战将 GitLab CLI 和 boos CLI 改造成标准 MCP Server这是迁移中最耗时也最关键的环节。目标是让gitlab cli和boos cli通过 MCP 协议暴露能力。GitLab MCP Server 封装Python 示例# gitlab-mcp-server.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel import subprocess import json app FastAPI() class ListProjectsRequest(BaseModel): visibility: str public per_page: int 20 app.get(/tools) def list_tools(): return { tools: [{ name: list_projects, description: List GitLab projects, input_schema: { type: object, properties: { visibility: {type: string, enum: [public, internal, private]}, per_page: {type: integer} } }, output_schema: {type: array, items: {type: object}} }] } app.post(/execute) def execute_tool(request: dict): if request[tool_name] list_projects: args request[arguments] try: # 调用真实的 gitlab cli result subprocess.run( [gitlab, project, list, --visibility, args[visibility], --per-page, str(args[per_page])], capture_outputTrue, textTrue, timeout30 ) if result.returncode ! 0: raise HTTPException(500, result.stderr) # 解析 JSON 输出 projects json.loads(result.stdout) return {status: success, content: projects} except subprocess.TimeoutExpired: raise HTTPException(504, GitLab CLI timeout)启动uvicorn gitlab-mcp-server:app --host 0.0.0.0 --port 8081boos CLI 封装要点boos cli通常需要 auth tokenMCP Server 必须安全存储 token如读取环境变量BOOS_TOKEN。boos scan可能耗时很长MCP Server 必须支持异步/execute返回{status: accepted, task_id: task_xyz}另起 endpoint/task/{task_id}查询状态。ruoyi-vue-pro合并mcp功能的后端可直接复用其现有 controller只需增加/mcp/tools和/mcp/execute两个 endpoint返回标准 MCP 格式。验证 MCP Server# 测试 /tools curl http://localhost:8081/tools # 测试 /execute curl -X POST http://localhost:8081/execute \ -H Content-Type: application/json \ -d {tool_name:list_projects,arguments:{visibility:private}}4.3 Agent 任务编排用 OpenWorkBuddy 实现一个真实工作流以“PR Review Assistant”为例整合 GitLab MCP Server 和 Jira MCP Server假设已存在定义 Goalowb-cli start-session --goal Review PR #456 in project prod-api. Fetch PR diff, query related Jira issues, generate review comments, and post to Slack.Planner 生成 Plan简化版Step 1: Call gitlab.list_projects to find prod-api project ID Step 2: Call gitlab.get_merge_request with project_id and mr_iid456 Step 3: Call gitlab.get_diffs with merge_request_id Step 4: Call jira.search_issues with text from diff Step 5: Call llm.generate_review_comment with diff jira issues Step 6: Call slack.post_message with commentExecutor 执行每个 step 对应一个 MCPexecutecall。Step 3的gitlab.get_diffs返回超大文本OpenWorkBuddy 的 runtime 自动启用 streaming分 chunk 传给 planner。Step 4的jira.search_issues若返回 0 结果planner 会 fallback 到jira.create_issue无需人工干预。Attach 监控owb-cli attach-session sess_xyz789终端显示[2024-06-15 10:30:22] ✅ Step 1: gitlab.list_projects - 1 project found [2024-06-15 10:30:25] ✅ Step 2: gitlab.get_merge_request - MR #456 loaded [2024-06-15 10:30:30] Step 3: gitlab.get_diffs - streaming... (12.4MB) [2024-06-15 10:31:15] ✅ Step 3: gitlab.get_diffs - done [2024-06-15 10:31:18] ⏳ Step 4: jira.search_issues - waiting...这个流程在 Codex 里需要写 200 行 Python 脚本且无法中断重连。在 OpenWorkBuddy 里全是声明式配置和标准协议调用。4.4 并发与扩展应对高负载的 Agent 集群部署ai agent 怎么扛并发是企业级落地的核心问题。OpenWorkBuddy 的解决方案是Stateless Worker Shared Store。部署架构[Load Balancer] | [OWB Worker 1] —— [Shared Redis] ←→ [MCP Servers] [OWB Worker 2] —— [Shared Redis] [OWB Worker N] —— [Shared Redis] | [owb-cli clients]配置worker-config.yamlsession_store: type: redis host: redis.example.com port: 6379 db: 0 mcp_servers: # 所有 worker 共享同一组 MCP Server - name: gitlab url: http://mcp-gateway.example.com/gitlab - name: jira url: http://mcp-gateway.example.com/jira # 每个 worker 独立的 planner planner: type: openai model: gpt-4-turbo api_key: ${OPENAI_API_KEY} # 从 env 读取关键参数redisstore 的session_ttl设为 72h避免 session 泄漏。mcp-gateway是反向代理统一管理 MCP Server 的健康检查和负载均衡。owb-runtime启动时加--workers 4参数启动 4 个并发 worker。压测结果AWS c5.2xlarge单 worker12 req/sec受限于 planner LLM 调用4 worker Redis42 req/secsession creation time 200mscodex安装包在同等机器上codex cli并发 5 个请求就出现cc switch local proxy failed错误。5. 常见问题与排查技巧实录踩过的坑比文档还多5.1 MCP Server 常见故障与速查表现象可能原因排查命令解决方案owb-runtime启动失败log 显示Failed to discover MCP server gitlabMCP Server/tools返回非 200 或 JSON 格式错误curl -v http://localhost:8081/tools检查 server 是否运行/tools是否返回 valid JSONschema 是否符合 MCP specAgent 调用 tool 时卡住log 显示timeout waiting for responseMCP Server/executehandler 未正确处理 timeout 或未返回status字段curl -X POST http://localhost:8081/execute -d {tool_name:x,arguments:{}}在 handler 中添加 try/catch确保 always return{status: ..., content: ...}owb-cli attach-session显示Session not foundsession store 配置错误或 worker 与 cli 使用不同 storeowb-cli list-sessions检查config.yaml中session_store路径是否一致Redis 连接参数是否正确cherrystudio流式输出在 CLI 中显示为乱码MCP Server 的 streaming response 未设置Content-Type: text/event-streamcurl -H Accept: text/event-stream http://localhost:8000/execute在 streaming endpoint 中设置 header用text/event-stream格式发送 data: {...}独家避坑技巧MCP Server 的/healthendpoint 必须返回{status: ok}且 HTTP status code 为 200。OpenWorkBuddy 的 runtime 会每 5 秒 ping 一次连续 3 次失败就从 registry 中移除该 server。很多团队用curl -I测试 health但curl -I只返回 header不触发 full response导致误判 server 正常。5.2 OpenWorkBuddy CLI 使用陷阱陷阱1owb-cli start-session后立即CtrlC现象session 状态为created但 neverrunning。原因start-session只是发起了 session 创建请求planner 需要时间生成 plan。CtrlC中断了 CLI 进程但 runtime 仍在后台处理。正确做法start-session后等待 2-3 秒再用owb-cli list-sessions查看 status或直接owb-cli attach-session连接。陷阱2在attach-session中输入exit现象session 被意外终止。原因exit命令会向 runtime 发送terminate_sessionsignal。正确做法按CtrlD退出 attachsession 继续运行如需终止用owb-cli terminate-session id。陷阱3owb-cli配置文件路径混乱现象owb-cli init创建的 config 在~/.owb但owb-runtime start默认读/etc/owb/config.yaml。解决方案始终用--config指定路径或设置环境变量OWB_CONFIG_PATH~/.owb/config.yaml。5.3 Codex 迁移专属问题如何处理遗留的 Codex 配置和数据codex安装 windows桌面版的配置迁移Codex 的settings.json中的api_key、model、proxy设置不能直接复制。OpenWorkBuddy 的planner配置独立proxy由系统环境变量HTTP_PROXY控制api_key存在~/.owb/secrets.yaml加密存储。codex无法加载组织设置的根源Codex 的组织设置是中心化 API 调用而 OpenWorkBuddy 的“组织”概念由 MCP Server 实现——你为每个部门部署独立的gitlab-mcp-server和jira-mcp-server权限控制在 MCP Server 层完成。codex cli remotion的视频生成流程Remotion 是前端库不能直接 MCP 化。解决方案是封装一个remotion-mcp-server接收 video spec JSON调用npx remotion render返回 CDN URL。这样 Agent 就能call remotion.render_video。最后分享一个小技巧迁移初期保留 Codex CLI 作为 fallback。在 OpenWorkBuddy 的 planner prompt 中加入一句“If any MCP tool fails, fallback to codex cli command:codex cli --tool xxx --args yyy”。这样能平滑过渡避免业务中断。我在实际迁移中用这个技巧撑过了两周的 MCP Server 稳定期直到所有工具都完成改造。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进