开发教程

Codex 与 Claude 桌面版如何协同:GUI 注入与 CLI 接力的取舍

编辑部阅读约 6 分钟

同时装着 Codex 和 Claude 桌面版的人,常想让其中一个把 prompt 直接送进另一个的输入框。桌面客户端没有公开的输入接口,模拟键盘又极其脆弱。本文拆开三种协同思路——GUI 注入、CLI 任务接力、跨机协作,给出任务文件、MCP、tmux 的具体做法与检查清单。

同时使用 Codex 和 Claude 的桌面客户端已经很常见:一个擅长改代码,一个擅长读长文档和调用工具。于是自然产生一个念头——能不能让其中一个把整理好的 prompt 直接送进另一个的输入框,点一下就能接力干活?更进一步的诉求是加上 computer use,让模型自己操作界面,人完全不用坐在电脑前。

这个问题看起来是「两个 App 怎么对接」,实际是三个不同层面的需求被混在一起:往界面上写字、让任务流转起来、让某个模型去操作界面。它们的可行性和稳定性差别极大,混着谈很容易在错误的路上耗掉一整天。下面逐层拆开。

先分清三种「协同」

层次 具体形态 稳定性 适用场景
界面输入层 用脚本把文本写进桌面版当前输入框并回车 很低 一次性演示、有人盯着
任务接力层 两个 CLI 通过文件、队列、MCP 交换任务与结果 高 长期自动化、批量处理
界面控制层 一个 agent 用 computer use 操作另一个客户端 中低 对方只有 GUI、没有 CLI 的场景

绝大多数「协同」需求,其实只需要第二层。第一层看起来最直接,恰恰是最不该做基础设施的那一层。

为什么往桌面版输入框里写文本这么难

桌面客户端没有对外暴露「提交一条消息」的接口。窗口层级、输入框控件、发送按钮都不是稳定契约,客户端一次更新就可能全变。所以剩下的路只有模拟输入:

  • macOS 用 osascript 配合 System Events 发键盘事件;
  • Windows 用 PowerShell 调 UI Automation 或 SendKeys;
  • Linux 用 xdotool 之类工具;
  • 再或者直接操作系统级无障碍接口。

这条路能跑通,但几乎集齐了自动化里最麻烦的几类问题:

  • 焦点抢占:脚本必须先激活目标窗口,你正在打字的编辑器就被顶掉了;后台窗口、多显示器、多桌面下经常失效。
  • 时序不确定:界面还没渲染完就发送,文本会丢;发送后无法可靠确认是否真的提交成功。
  • 输入法与快捷键冲突:中文输入法状态、自定义快捷键都会让粘贴和回车行为变形。
  • 与 computer use 打架:同一台机器上两个 agent 同时抢鼠标键盘,结果是双方都做错事。
  • 幂等性差:重试一次就可能在对话框里留下两条重复消息。

所以模拟键盘适合做一次性的、有人在旁边的操作,不适合当长期流水线的主链路。如果目标只是「每天自动跑几十轮」,请直接跳到下一节。

主链路应该建在 CLI 上

两个客户端都提供非交互执行模式:Codex 侧用 codex exec,Claude 侧用 claude -p(print 模式,执行一次并输出结果)。这类模式本身就是为脚本调用设计的,输入输出走标准流,不依赖任何窗口。

一个常见误解是「claude -p 可以往正在运行的桌面会话里塞消息」。不行。print 模式是另起一次独立的、无界面的执行,跟你在 GUI 里那个会话没有关系。它解决的是「让 Claude 干活」,不是「让 Claude 的输入框出现一行字」。

方案一:任务文件 + 轮询

最朴素也最抗造的做法,两个进程通过目录交换任务。

mkdir -p bridge/{inbox,outbox,logs}
#!/usr/bin/env bash
# 轮询 inbox,逐个交给 claude 执行,结果落到 outbox
while true; do
  for f in bridge/inbox/*.json; do
    [ -e "$f" ] || continue
    id=$(basename "$f" .json)
    claude -p "$(cat "$f")" > "bridge/outbox/$id.md" 2> "bridge/logs/$id.err"
    mv "$f" "bridge/inbox/.done-$id"
  done
  sleep 5
done

反方向同理,把 claude -p 换成 codex exec,或者让一侧的产出文件成为另一侧的输入。要点是先定义任务格式:谁写、字段有哪些、失败怎么标记、结果写到哪。格式定死了,后面换实现都不心疼。

方案二:用 MCP 做中间层

把一侧的能力封装成一个 MCP 服务(比如「执行一次代码任务」「读取某个仓库的变更」),另一侧作为客户端调用。相比文件轮询,MCP 的好处是有明确的工具描述和参数校验,模型自己就能判断该调哪个;代价是要多维护一个进程,调试链路长一些。适合工具数量多、需要模型自主选择的场景。

方案三:同一台机器用 tmux 托管

tmux 会长期保持一个终端会话,比任何 GUI 注入都可靠:

tmux new -s pair -d
tmux send-keys -t pair 'codex' Enter
tmux send-keys -t pair '把 src/api.ts 里的重试逻辑抽成独立函数' Enter
tmux capture-pane -p -t pair > snapshot.txt

send-keys 是往终端程序的标准输入写,capture-pane 把当前屏幕内容抓出来当结果。断线、关闭终端都不影响会话继续跑。缺点是基于屏幕文本解析,输出格式变化时要跟着调整。

关于各种 Agent 协议

社区里提到过用 ACP 一类的 agent 通信协议把多方接起来,也提到过某些客户端对这类协议的支持情况。这类信息时效性很强,各家的支持范围和字段定义随时在变,落地前请以官方文档和仓库的最新说明为准,不要照抄半年前的博客。

两台机器怎么办:SSH 只解决「执行」,不解决「注入」

如果两个客户端跑在不同的电脑上,SSH 是自然的连接方式,但要分清它到底提供了什么:

  • SSH 能让你在 B 机上执行命令、跑 codex exec、接 tmux 会话;
  • SSH 不能让文本出现在 B 机某个桌面应用的输入框里。

所以跨机方案依旧是 CLI 接力,只是把执行位置换到远端:ssh host-b 'tmux send-keys -t pair ...',或者把任务文件放到共享目录。有人用手机端 App 代替 SSH 下发指令,本质一样,只是换了通道。

真正需要远程操作图形界面时,才轮到远程桌面或 computer use。这时建议只保留一个操作者:一台机器做「手」,其余机器只做纯文本计算,否则两边的鼠标键盘操作会互相打断。

另外,如果协调链路要跨地域、还要连续跑几个小时甚至通宵,本地机器的休眠、断网、风扇降频都会直接打断代理。一种可选做法是把其中一台换成长期在线的远程 Mac——例如整台 Mac mini 放在新加坡机房、按月租用、远程连接使用,网络环境相对稳定,适合长期挂着 Claude Code 这类 CLI 工具。它解决的是「机器不睡、网络不抖」,并不解决桌面版输入框的问题,两件事不要混为一谈。

落地检查清单

  1. 先跑通单向单步:手动触发一次,确认输入、输出、退出码都对,再谈循环。
  2. 固定任务格式:任务 ID、来源、指令、约束、期望产出,缺一项后面就会出歧义。
  3. 加超时与重试上限:模型调用可能长时间无响应,必须有上限并记录日志。
  4. 做幂等:同一个任务 ID 重复消费时不得产生两份副作用。
  5. 禁止并发写同一资源:两个 agent 同时改一个文件或一个工作区,冲突排查成本极高。
  6. 关键动作留人工确认:提交代码、发消息、删文件这类不可逆操作,加一道闸。
  7. 日志可回放:保存每次调用的完整输入输出,出问题时能复现,而不是靠猜。

注意事项

  • 账号与调用方式要合规。各自使用官方订阅或官方 API,不要共用账号、不要购买来源不明的账号或中转服务。这类做法除了违反服务条款、可能被封禁之外,还意味着你的 prompt 和代码要经过别人的通道,数据风险远大于省下的成本。
  • 不要把模拟键盘当生产链路。它可以当临时脚本,但每次客户端更新都可能导致失效,而且失败时往往没有明显报错。
  • computer use 的可复现性差。界面像素、加载速度、弹窗都会影响结果,适合「有兜底、可中断」的任务,不适合无人值守的批处理。
  • 协议与子命令随时会变。codex exec、claude -p、MCP 工具的参数都请以当前官方文档为准。

小结

在这个需求上,最省事的答案往往也是对的:让两个客户端都退到 CLI,用一个定义清楚的任务格式把它们串起来,单步跑通之后再谈并发和多机。往桌面版输入框里注入文本技术上做得到,但它依赖模拟键盘、抢焦点、无法确认结果,只适合临时演示。computer use 留作兜底手段,而不是主干。把界面这一层从架构里去掉之后,协同反而变得简单可控。

ClaudeCodextmux多智能体协同CLI 自动化