如果你同时用 Claude Code 和 Codex,大概经历过这种场面:左边终端跑 Codex,右边 Claude Code 等权限确认,下面还有个 OpenCode 不知道卡在哪。额度用完要换工具,任务交接靠复制粘贴。手机想看进度,要么没客户端,要么各家 App 各管各的。
Paseo 想解决的就是这件事。它目前在 GitHub 上有 18700+ Star,支持 Claude Code、Codex、OpenCode、Pi 等 Agent 工具。但它最值得聊的地方,不是“又一个 Agent”,而是它的定位:Paseo 不提供模型,不内置 AI 能力,只给已有的 Agent 做一层统一的管理和调度界面。
换句话说,你原来的账号、配置、开发环境、Skill、MCP 插件,全都留在本地。Paseo 只是在上面加了一层控制平面:启动 Agent、查看状态、发送指令、管理权限、分配 Git worktree,然后让你在桌面、手机、Web 或命令行里把这一堆活管起来。
这篇文章就把它背后的核心功能和原理讲清楚。
一、Paseo 到底在管什么?
先看功能层。Paseo 的界面左侧会列出所有正在执行任务的 Agent。谁在干活、谁空闲、谁卡在权限确认,一眼能看清。新建任务时,你可以选择项目、Agent 和模型,直接把消息发出去。不同任务可以分给不同工具,不必反复切终端。
它还有几个关键能力:
跨 Agent 协作:通过 /paseo-handoff、/paseo-advisor、/paseo-committee 等技能,让 Claude 规划、Codex 实现、另一个 Agent 审查。
手机远程:iOS 和 Android 客户端配对后,看到的是电脑上同一份 Agent 列表。支持语音输入,语音识别可本机运行。
Git worktree 隔离:每个 Agent 可以单独建一个 worktree,在独立目录和分支里干活,避免互相覆盖文件。
多端一致:桌面端、Web 端、命令行连的都是电脑上同一个本地服务。
但这些功能只是表象。真正让它跑起来的,是下面这套架构。
二、架构总览:本地 daemon 是唯一控制平面
Paseo 采用的是 daemon-client 模式。
你的电脑上运行着一个本地 daemon 进程。它负责管理所有 Agent 进程、工作区、终端和调度任务。桌面端、手机端、Web 端和 CLI 都只是连接这个 daemon 的客户端。所有操作最终都汇聚到 daemon,再由 daemon 去启动和管理具体的 Agent。
这解释了一个关键问题:为什么手机能看到电脑上的 Agent?因为手机连的不是某个 Agent 的官方客户端,而是你电脑上的 Paseo daemon。daemon 手里握着所有 Agent 的会话,手机只是换了个显示终端。
三、Provider 适配层:Paseo 怎么做到同时管多家 Agent
Paseo 不制造 Agent,它启动并监管你本机已经装好的 CLI 工具。为了同时管理 Codex、Claude、OpenCode 等不同工具,它做了一层 Provider 适配器。
这套适配层有两个核心接口:
AgentClient:Provider 级别接口,负责创建会话、恢复会话、获取模型目录、检查可用性。Codex 的 AgentClient 知道怎么启动 codex app-server 并完成协议握手;Claude 的 AgentClient 知道怎么通过 Agent SDK 启动 claude 进程。
AgentSession:会话级别接口,抽象了与单个 Agent 的活跃通信,包括发送 prompt、流式接收事件、处理权限请求、中断和关闭会话。
Paseo 的 AgentManager 通过这两个接口统一管理所有 Agent,维护活跃 Agent 注册表,协调生命周期状态转换,并向订阅的会话广播事件。
不同 Provider 的原生输出格式不一样。Paseo 为每个 Provider 写了工具调用映射器,把原生格式翻译成统一的 ToolCallTimelineItem。不管底层是 Codex 的 shell 工具还是 Claude 的 BashTool,在 Paseo 时间线里都呈现为同一种 tool_call 事件。
这是它能统一界面的基础。
四、对 Codex 来说,Agent 是什么?
要理解 Paseo 怎么调用 Codex,得先知道 Codex 里的 Agent 到底是什么。
对 OpenAI Codex 来说,一个 Agent 的具体形态是一个 Thread(对话线程)。
Codex 的核心是一个智能体循环,协调用户、模型和工具之间的交互。而 Codex App Server 是这个循环的对外接口:它是一个长期运行的进程,托管 Codex 核心对话线程。App Server 既是客户端与服务器之间的 JSON-RPC 协议,也是托管对话线程的进程本身。
一个 Thread 就是一个独立的 Agent 实例。Thread 里面包含多个 Turn(轮次),每个 Turn 通常以用户消息开始,以 Agent 回复结束。Thread 有自己的生命周期:可以创建(thread/start)、恢复(thread/resume)、分叉(thread/fork)。
所以当 Paseo 启动一个 Codex Agent 时,本质上是在 Codex App Server 里创建了一个 Thread,并通过 Turn 向它发送任务。
Paseo 对 Codex 的调用路径大致是:
daemon 通过 ProviderRegistry 发现本机安装了 Codex CLI。
执行类似 codex app-server 的命令,把 Codex 作为普通子进程启动。
通过 stdio 完成 JSON-RPC 2.0 握手:Paseo 发送 initialize,Codex 返回 initialized。
调用 thread/start 创建新对话线程。
通过 turn/start 把用户任务作为 Turn 发送进去。
Codex 在推理过程中,通过 stdio 把消息、工具调用、审批请求流式推回。
Paseo 把 Codex 原生工具调用翻译成统一时间线事件,再通过 WebSocket 广播给所有客户端。
权限方面,Codex App Server 支持服务端发起的审批请求。Codex 需要执行某个操作时,会向 Paseo 发送 JSON-RPC 请求要求确认。Paseo 把它转成界面上的权限弹窗,用户确认后再回传给 Codex 子进程。
五、对 Claude Code 来说,Agent 是什么?
Claude Code 的 Agent 形态和 Codex 不太一样。
Claude Code 的核心是 QueryEngine,也就是 SDK/headless 模式的生命周期引擎。QueryEngine 暴露的接口是 submitMessage(prompt),返回一个 AsyncGenerator,流式地把结果推回给调用方。它内部编排了完整生命周期:系统提示词组装、斜杠命令解析、主 Agent 循环、JSONL 持久化。
一个 Claude Agent 会话,本质上就是 QueryEngine 的一次 submitMessage 调用链路。它可以是单次问答,也可以是长生命周期的流式会话,通过 streaming input 模式接受排队消息,支持 interrupt() 等中途控制。
Claude Code 的 Agent 循环内部还有一个 StreamingToolExecutor,会把模型请求的工具分成“并发安全”和“串行”两类:只读工具并行执行,写操作串行执行以避免冲突。
Paseo 对 Claude 的集成方式,对应源码中的 providers/claude/agent.ts,它集成的是 @anthropic-ai/claude-agent-sdk。这个 SDK 本质上是对 Claude Code CLI 的封装:SDK 会启动 claude 进程作为子进程,通过 stdin/stdout 上的双向 JSON 流通信。
启动时,SDK 会以 --output-format stream-json --print 非交互模式启动 claude。Paseo 的输入通过 stdin 以 NDJSON(换行分隔 JSON) 格式写入,从 stdout 读取流式响应。
权限方面,Claude 的 headless/SDK 模式没有交互式权限提示,工具权限完全由 permissionMode 决定。Paseo 在启动 Claude 时会设置自己的模式预设,让 Claude 以 Paseo 的 bypassPermissions 模式启动,Paseo 自己在更上层做权限管控。
六、Codex 和 Claude 的 Agent 模型差异
两者都支持持久化和恢复,但 Codex 的 Thread 模型更接近“一个 Agent 一个对话线程”,Claude Code 更接近“一个编程接口驱动 Agent 循环”。
七、跨 Provider 协作是怎么实现的?
这是 Paseo 真正有意思的地方。
原生子 Agent 只能属于同一个 Provider:Claude Code 只能启动 Claude Code 的子 Agent,Codex 只能启动 Codex 的子 Agent。它们之间没有共同的调度层。
Paseo 的子 Agent 可以跨 Provider 边界。Claude Code 可以启动 Codex 的子 Agent,Codex 也可以启动其他 Provider 的 Agent。一个模型规划、另一个实现、第三个审查,这种分工在 Paseo 里是原生支持的。
原理并不复杂:Paseo 子 Agent 不是由 Codex 或 Claude 原生创建的,而是由 Paseo daemon 直接管理的完整 Agent 会话。
当 Claude Code 通过 /paseo-handoff 交接任务时,实际发生的是:Claude 通过 Paseo 提供的工具接口向 daemon 发送一个 create_agent 请求,指定 provider 为 codex/gpt-5.5,携带当前任务上下文。daemon 收到请求后,走的是和手动创建 Codex Agent 完全相同的路径:启动 Codex 子进程、完成 JSON-RPC 握手、创建 Thread、把上下文作为 Turn 发送进去。
从 daemon 的视角看,不存在“Claude 启动 Codex”这种特殊操作。所有 Agent 创建都是同一条路:daemon 作为唯一控制平面,根据请求中的 provider 字段,调用对应 Provider 的 AgentClient,启动子进程并管理会话生命周期。
跨 Provider 能力之所以成立,是因为 daemon 同时管理着所有 Provider 的 Agent,它可以在任意两个 Agent 之间搬运上下文和任务。而原生子 Agent 做不到,是因为它们只在各自进程内部生效。
八、Claude 为什么会调用 Paseo 的接口?
这是很多人会疑惑的点。Claude 并不是“知道” Paseo 的存在,而是 Paseo 通过技能(Skills)和 MCP 工具两种机制,把调用能力直接“喂”到了 Claude 的上下文里。
第一层是技能。Paseo 提供了一套编排技能,本质上是一些 Markdown 文件,里面写好了如何用 Paseo 启动其他 Agent 的完整流程、命令示例和上下文模板。安装方式:
npx skillsaddgetpaseo/paseo这会把技能文件写入 ~/.agents/skills/,并为每个 Agent 建立符号链接。安装后,Claude Code 对话里就多出 /paseo-handoff、/paseo-advisor、/paseo-committee 等斜杠命令。当你在 Claude 里输入这些命令时,Claude 读取到的是一份预置好的工作流指令,它只是照着执行。
第二层是 MCP 工具。Paseo 的 daemon 内置 MCP Server,把编排能力暴露成标准化的 MCP 工具,比如 list agents、create agent、send prompt。Paseo 启动 Claude Code 时,会把自己的 MCP Server 配置注入到 Claude 的运行环境中。从 Claude 的视角看,这些工具和它自带的 Bash、Read、Write 没有区别,都是可调用的外部能力。
完整链路是这样的:
用户在 Claude 对话里说:“把认证修复交接给 Codex”。
Claude 识别到“交接”意图,看到已安装的 /paseo-handoff 技能,决定使用它。
Claude 按照技能指令,调用 Paseo 的 MCP 工具,传入任务描述和上下文。
Paseo daemon 收到工具调用,走正常 Agent 创建流程:启动 Codex 子进程、完成握手、创建 Thread、发送任务。
Codex 开始干活,Paseo 把输出流式回传给 Claude,Claude 在对话里展示交接结果。
Claude 并不知道 Codex 子进程怎么启动,也不需要知道。它只是在调用一个 MCP 工具,而工具背后是 Paseo daemon 在干活。
九、Paseo 的适用场景
Paseo 适合那种电脑里不止一个 Agent、又经常并行跑任务的人。如果你只用一家,也不怎么开多个窗口,可能感知没那么强。但如果你同时用两三家命令行 Agent,天天在终端里切来切去,Paseo 这种统一入口就值得试。
它不造新 Agent,只做管理这一层,还能通过插件接入新 Agent。以后再多装一个,只要 Paseo 支持,就不用多开一个窗口、多装一个 App。
Agent 只会越来越多,各家都想把人留在自己的 App 里。统一入口这件事,可能真得靠第三方来做。Paseo 选的这条路,至少从架构上看,是成立的。