真实项目很少只存在于一台机器上。前端可能在本机运行浏览器,后端需要公司内网,编译任务需要更大的内存,发布验证又要放在一台长期在线的机器上。传统做法是频繁切换窗口、重复 SSH、复制日志,再把上下文手工搬到另一个终端。
当多个 Codex Task 可以被统一查看和调度时,问题就变成了一个路由问题:什么任务应该放在哪个项目、哪个工作树和哪台主机上?什么时候只需要给另一条会话发消息,什么时候必须迁移整个执行位置?本文围绕这些边界展开,不把跨主机协作写成“自动拥有所有权限”,而是把环境、权限和责任分别说明。
一、先把四个执行概念分开
Local:直接使用当前工作树
Local 适合需要复用当前开发环境的工作,例如打开已经运行的 dev server、使用本地浏览器、查看现有未提交改动,或者与人实时协作。它的优点是反馈快,缺点是多个写任务共享同一份目录,互相能看到未提交文件。
同一个 Local 工作树不适合同时承载多个互不知情的写入任务。除非你明确知道它们修改的文件不重叠,并且会在执行前后检查 diff,否则应该使用 Worktree 或串行执行。
Worktree:隔离同一仓库的并行改动
Worktree 是 Git 仓库的独立工作树。它适合多方案竞赛、同一仓库的并行修复和需要独立测试的候选实现。每个候选拥有自己的文件树和分支,结果可以分别查看 diff、运行测试,再决定是否合并。
Worktree 解决的是文件隔离,不解决服务依赖。例如两个 Worktree 仍然可能争用同一个本地端口、数据库或缓存目录。需要额外配置端口和测试数据,不能因为文件隔离就认为运行环境完全隔离。
SSH Host:使用另一台机器的能力
SSH Host 适合本机不具备的环境:内网访问、特定系统依赖、大内存编译器、专用测试设备或持续运行的服务。Task 的 shell、文件和工具环境都在远端,因此派工时必须把工作目录、分支和凭据可用性说明清楚。
SSH 连接本身不等于权限已经具备。Agent 仍然只能使用连接用户能够访问的目录和服务;敏感操作、生产环境和对外发送数据应继续保留显式确认。
Handoff:执行位置迁移,不是责任交接
Handoff 容易被误解为“把任务交给另一个 Agent”。更准确的理解是:同一个 Task、同一段历史和同一个责任主体,执行位置从一个 Host 迁移到另一个 Host。它适合本机无法继续编译、需要切换到内网或需要使用另一套依赖的场景。
如果是“调研 Agent 把结论交给实现 Agent”,这属于语义层的责任交接,需要自己打包目标、已完成项、未完成项、产物和限制,再发送给目标会话。不要把这两种 Handoff 混在一起。
二、按主机能力设计路由表
在多主机环境中,建议先写一张简单路由表。它不必绑定具体机器名,可以先按能力描述:
| 任务类型 | 首选环境 | 原因 | 交接前检查 |
|---|---|---|---|
| UI、浏览器和人工验收 | Local | 需要现有浏览器和可视化反馈 | dev server、端口、当前工作树 |
| 内网接口和服务联调 | SSH 内网开发机 | 具备内网访问条件 | 网络、凭据、服务地址 |
| 大型编译和集成测试 | 高内存或高核数主机 | 降低资源争用 | 编译器、缓存、磁盘空间 |
| 长时间发布验证 | 常在线主机 | 不依赖个人电脑保持开启 | 任务日志、超时、回滚路径 |
| 同仓库多方案实现 | Worktree | 隔离文件和 Git 状态 | 分支、端口、测试数据 |
路由决策应该基于任务前置条件,而不是基于 Agent 名字。例如“前端 Agent”如果只是修改组件代码,不一定要在本机;只有需要打开浏览器、查看视觉结果时才需要 Local。反过来,一个“后端 Agent”如果需要访问内网服务,就必须进入满足网络条件的 Host。
三、跨项目协作时先传递契约
跨项目交付最容易出错的地方不是派工,而是接口理解不一致。后端、前端、SDK、测试和文档各自派一个 Agent,如果每个 Agent 都从自己的角度解释需求,最后往往会得到多份互相矛盾的契约。
更可靠的流程是先让探索者并行收集事实,再由一个架构角色输出唯一契约:
后端探索者:列出现有接口、错误码和兼容约束
前端探索者:列出调用方、状态处理和展示假设
SDK 探索者:列出公共类型、版本和生成代码影响
-> Architect 汇总为 contract.md
-> 各项目 Agent 只按 contract.md 实现
-> 集成任务在统一环境运行跨项目测试
契约文档应该包含版本、字段类型、错误处理、兼容窗口、迁移顺序和验证命令。它不是“建议”,而是下游任务共同读取的输入。如果契约发生变化,应创建新版本或记录变更,不要在多个会话中分别修改同一份解释。
四、一个跨主机联调的完整例子
假设后端 Task 运行在公司开发机上,已经修改了接口;前端 dev server 和浏览器运行在 Local。目标不是把后端 Task 整个搬回来,而是让本机会话执行浏览器验证,再把结果反馈给后端会话。
步骤可以这样设计:
- 后端 Task 产出接口变更摘要、启动方式和测试前置条件;
- 后端 Task 找到负责本地 UI 验证的 Task;
- 通过 Codex App 的跨会话消息能力发送结构化联调请求;
- 本地 Task 检查 dev server、接口地址和浏览器状态;
- 本地 Task 执行验证,记录浏览器现象、网络请求和控制台错误;
- 将结果回传,并注明成功路径和未覆盖的情况;
- 后端 Task 根据失败证据定点修复,不重复让本地 Agent猜原因。
消息不应只写“帮我测一下”。建议包含:
目标:验证登录过期后前端是否正确跳转到登录页。
前置条件:后端接口 /api/session 已部署到测试地址,测试账号为预先配置的非生产账号。
步骤:登录、等待会话过期或使用测试开关、刷新页面、观察跳转和网络请求。
输出:页面结果、请求状态、控制台错误、截图或日志路径、未覆盖项。
禁止:不要修改前端代码,不要使用生产账号,不要清理共享数据库。
这条链路只传递工作,不传递不必要的权限。需要浏览器的 Task 使用 Local,需要内网的 Task 留在 SSH Host;只有执行环境本身必须变化时才使用位置 Handoff。
五、跨仓库迁移的路由顺序
修改一个被多个仓库消费的 API 时,推荐采用“先扫、再定、后改”的顺序。
第一步:并行扫描生产者和消费者
不同仓库的 Explorer 只读分析真实调用路径、版本约束和测试入口,输出统一格式。每份结果都要标明仓库、分支、文件位置和证据日期,避免把旧分支上的结果当成当前事实。
第二步:生成一份契约产物
Architect 读取所有扫描结果,解决冲突,输出唯一的迁移契约。它需要明确哪些消费者必须同步升级,哪些可以通过兼容层过渡,哪些变更需要人工确认。
第三步:按仓库和 Worktree 并行实现
每个仓库使用自己的工作树和分支。仓库内部再由 Worker 实现、Reviewer 检查,避免多个 Agent 直接写同一目录。所有实现都引用同一版本的契约产物。
第四步:统一集成验证
集成测试应放在具备完整依赖的主机上运行。单仓库测试全绿不代表跨仓库契约正确,因此要增加版本组合、错误路径和回滚路径的验证。
第五步:发布任务接收结构化结果
发布 Task 只接收已完成的仓库列表、构建产物、测试摘要、迁移顺序和回滚条件。它不应该在发布阶段才重新阅读每个仓库的全部上下文。
六、位置迁移前后的检查清单
迁移前
- 当前工作树是否有未提交改动?
- 分支和 Worktree 是否明确?
- 目标 Host 是否有相同的运行时、依赖和工具?
- 需要的文件、缓存、服务和凭据是否可用?
- 当前任务是否会占用端口、数据库或共享资源?
- 迁移后如何验证 Git 状态和产物完整性?
迁移后
- 当前目录和仓库是否是预期项目?
git status是否显示预期的分支和改动?- 依赖版本、环境变量和服务地址是否正确?
- 最小测试是否能够运行?
- 日志是否写入了目标位置?
- 失败时能否回到原 Host 或恢复之前的工作树?
迁移后的第一步不应是直接跑完整构建,而是执行低成本的环境检查。先确认路径、分支、运行时和最小命令,再进入耗时任务,可以避免在错误主机上浪费一小时。
七、安全边界不能由编排自动推断
多主机协作会扩大可见范围,因此要把权限和数据边界写进任务描述。至少注意以下问题:
- 不要把生产密钥、个人 Token 或客户数据放入跨会话消息;
- 不要因为远端拥有访问权限,就默认 Agent可以修改生产资源;
- 不要在多个 Worktree 之间共享未脱敏的真实数据库;
- 对删除、发布、发送外部消息和修改基础设施等操作保留确认点;
- 把远端日志、截图和构建产物存放在有权限控制的目录中;
- 任务结束后清理临时凭据、临时端口和测试数据。
主机路由解决的是“在哪里执行”,不是“可以做什么”。权限、审批和数据分类仍需要单独设计。
八、如何验证路由是否带来收益
可以选一条跨项目任务做对比,不要只看 Agent 是否成功返回。记录以下指标:
上下文搬运次数:是否还需要手工复制日志和说明
环境切换次数:是否把任务放到了正确的主机
等待时间:任务是否被不必要的串行步骤拖慢
失败定位时间:能否从证据直接定位到项目或节点
重复执行次数:是否在错误环境中反复重跑
权限异常:是否出现跨主机访问不该访问的资源
如果跨主机编排让消息更多、环境检查更复杂,却没有减少上下文丢失和重复执行,就说明路由粒度太细。优先合并相邻步骤,只有在环境能力确实不同的时候才增加一个新 Host 或新 Task。
结语
跨项目跨主机协作的关键,是把 Project、Host、Worktree 和 Task 的职责分开:Project定义工作域,Host提供执行能力,Worktree隔离并行改动,Task保存持续上下文。Handoff只处理执行位置迁移,责任交接则需要用结构化产物完成。
先建立一张按能力划分的路由表,再用一个真实联调任务验证。只要每次交接都带着目标、前置条件、证据要求和禁止事项,多个环境就不会只是更多窗口,而会变成可以统一观察和调度的执行节点。