> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Claude Code 与 Codex 交接：哪些状态搬得过去，哪些搬不过去
- URL: https://www.hubwiz.com/blog/claude-code-codex-session-handoff/
- Published: 2026-10-25T05:17:56.000Z
- Updated: 2026-10-25T05:18:37.000Z
- Description: 会话是本地文件，能增量搬；系统提示、权限批准、没落盘的推理搬不过去。搬不动的部分，只能靠交接件重述。
- Author: admin
- Tags: Claude Code, Codex, AI 编程, 多 Agent

**一句话结论**：会话**不是**黑盒——Claude Code 的每一次会话就是 `~/.claude/projects/` 下的一个 JSONL 文件，Codex 可以走它自己的 app-server 读，所以**"把任务搬到另一侧"是可以做成增量的**，不需要你重讲背景。但**能搬的只是"消息 + 压缩后的工具痕迹"**；系统提示、权限批准、MCP 连接状态、以及模型没落盘的那段推理，**永远搬不过去**。所以正确姿势是两段式：**能搬的用游标搬，搬不动的用交接件重述。**

**披露**：本文编译五篇 2026-10 的一手文章与一份备考资料，作者立场各有不同（见文末）。`ccx` 的实现细节来自其作者自述，我们**没有在 macOS 上跑过它**；其余方案（half-clone、Stop hook、子 agent 边界）同样未独立复现。

---

## 一、先认清：会话是一堆状态，不是一段对话

原文作者的切换理由很朴素：**一侧额度用完了**（Claude Code 有 5 小时窗口和周上限，Codex 也有），或者**换模型查 bug**（一个模型在原地打转，另一个一遍过）。

两种情况下，新的一侧都是"冷的"：不知道项目是什么、做到哪、哪些方案已经排除、现在坏在哪。**把 transcript 粘过去也不行**——工具调用加输出动辄几万词，粘过去直接撑爆上下文。

于是问题变成：**到底有哪些状态，各自存在哪，能不能搬。**

![状态四类分桶：逐字搬（消息）、压缩后搬（工具痕迹、todo、图片路径）、按引用搬（git status、完整 transcript）、搬不动（系统提示、权限批准、MCP 连接状态、未落盘推理、被压缩掉的文本）](https://www.hubwiz.com/blog/content/images/2026/10/fig-crosses-boundary.jpg)

图：把"会话"拆成四类状态，决定了你能自动化到哪一步。（编者据源文绘制）

| 状态             | 存在哪                         | 能不能搬       | 怎么搬                        |
| -------------- | --------------------------- | ---------- | -------------------------- |
| 用户消息、助手回复      | Claude：JSONL 一行一个事件         | ✅          | **逐字**                     |
| 工具调用与结果        | 同上                          | ⚠️ 能搬但不能原样 | **压缩**：调了什么、作用于什么、大约返回什么   |
| todo / plan    | 会话内（Claude todo、Codex plan） | ✅          | 取最新一份带上                    |
| 是否停在半步         | 会话内                         | ✅          | 标注"上一侧是中断的"                |
| 粘贴的图片          | 应用自己的缓存副本                   | ⚠️         | 只搬**缓存副本的路径**              |
| git status     | 仓库                          | ✅          | 现取现带（代码本来就在盘上）             |
| 系统提示 / 项目指令    | 各工具自己拼                      | ❌          | 只能是"重述"，不是"迁移"             |
| 权限批准、MCP 连接状态  | 运行时                         | ❌          | 到另一侧要重新批准/重新连              |
| 未落盘的推理、被压缩掉的原文 | 上下文里                        | ❌（半救）      | 压缩掉的部分用 read\_session 分页找回 |

这张表的用处：**看到 ❌ 的那几行，就知道"全自动交接"不可能做满**。它们不是工程没做好，是设计上就不该跨进程搬（权限尤其：搬过去等于绕过批准）。

## 二、Claude 侧：整段历史就是一个 JSONL

这是整套方案的地基，也是很多人不知道的一点：

```
~/.claude/projects/<escaped-project-path>/<session-id>.jsonl

```

一个会话一个文件，**一行一个事件**：用户消息、助手回复、工具调用、工具结果、todo 更新。所以**不需要任何 API 就能读完整段会话**。

（顺便：另一个源文给了同一件事的路径规则——项目路径里的 `/` 变成 `-`，例如 `/Users/yk/Desktop/projects/claude-code-tips` 对应 `~/.claude/projects/-Users-yk-Desktop-projects-claude-code-tips/`。这也解释了"老对话去哪了"：一直在你自己的机器上。）

作者说，难的不是读，是**决定读多少**：

- 工具结果可能巨大（整份文件读取、完整跑一遍测试）；
- 所以压缩：**消息逐字保留**，每个工具调用降维成"调了什么 / 作用于什么 / 大约返回什么"，再附上当前 todo 和 `git status`。

这三行 bash 就够你自己翻历史（需要 `jq`）：

```bash
# 哪些会话提过某个词
grep -l -i "reddit" ~/.claude/projects/-Users-you-project/*.jsonl

# 今天的会话里搜关键词
find ~/.claude/projects/-Users-you-project/*.jsonl -mtime 0 -exec grep -l -i "keyword" {} \;

# 只抽用户消息
cat ~/.claude/projects/.../<session>.jsonl | jq -r 'select(.type=="user") | .message.content'

```

## 三、Codex 侧：走它自己的 app-server，别解析内部文件

Codex 也在本地存会话记录，但原文作者**刻意不去解析**：

> 只使用 Codex 自带的 app-server：建 thread、往里发消息、读回来。这样 Codex 某次更新换了文件格式也不会把我的东西搞坏，而且写入走的是官方路径。

具体用到的三个能力：`thread/list`、`thread/read`、`session import`。

这个选择值得单独记一笔：**"读别人的私有存储"是最容易在某次升级后静默坏掉的东西**。一边是你的解析器，一边是别人的内部格式——没有契约。能用官方接口就别省这一步。

额度检查同理：Codex 有 `account/rateLimits/read`，直接读。

## 四、增量同步：配对 + 游标 + 只投递一次

作者的第一版是**一次性导出**：Claude 写一份 `HANDOFF.md`，Codex 读。这版能用，但有个明显缺陷——**切回来的时候，Claude 不知道 Codex 改了什么**，于是你又得导一次。手动，就回到原点了。

现在这版是双向的：

![双向游标同步：Claude 会话（JSONL）与 Codex thread（app-server）配对，pairs.json 存两条游标；发送时 UserPromptSubmit hook 把对方的新进展前置到这条消息，然后移动游标](https://www.hubwiz.com/blog/content/images/2026/10/fig-cursor-sync.jpg)

图：配对 + 双向游标 + 一次性投递。（编者据源文绘制）

四个环节：

1. **配对**：Claude 会话 A 与 Codex 线程 T 在 `~/.ccx/pairs.json` 里构成一对，**每侧记一个游标**——"对方已经收到哪了"。
2. **只发增量**：切换时只发游标之后、压缩过的进展。
3. **投递**：你在 A 里发消息时，`UserPromptSubmit` hook 把 T 的新进展**前置**到这条消息里，然后移动游标。**同一份内容不会送两次，hook 也绝不阻塞你的输入。**
4. **兜底**：如果某段内容被压缩掉了，模型可以用 `read_session` 工具**分页翻回来**。

原文的形容很准：**"这些内容作为上下文到达模型，而不是变成新的聊天气泡。"** 每次更新通常几千 token；没有新内容时再点一次，什么也不会发生。

结果就是：**两侧在同一个任务上工作，而不是两个互不相关的对话。**

## 五、什么时候该切：盯额度，但别绕过额度

大多数切换是因为额度。所以 `ccx` 在**任一侧 5 小时窗口超过 90%**、以及**用完**时，菜单栏各提醒一次，并给你"用对方继续"的入口。

这里有个不对称，很能说明"哪些状态搬不过去"：

- **Codex**：额度从 app-server 的 `account/rateLimits/read` 读，**内置**。
- **Claude**：**本地没有任何达标前的信号**。所以它只能去读你已经在装的那些工具的**文档化输出**（CodexBar、Claude Code Usage Monitor、`ccusage`、`abtop`、`claude-hud`、`ccstatusline` 等），装了哪个用哪个，不需要额外配置。

作者也明确了两条边界：**不绕过任何额度**（各用各的套餐），**不上传任何东西**（同步全在本地，只有安装和检查更新时才连 GitHub）。

## 六、同一个问题，四条路：清、压、写、切

第二篇源文把"上下文快满了怎么办"整理成四级阶梯，从"交出控制权"到"自己动手"，这个排序比工具本身更有用。

| 手段                         | 留下什么              | 什么时候用        | 代价          |
| -------------------------- | ----------------- | ------------ | ----------- |
| /clear \+ 新会话              | 什么都不留             | 换到不相关的任务     | 上下文全丢       |
| /compact                   | **模型自己写的摘要**      | 急需腾空间、细节不太重要 | 摘要不知道什么对你重要 |
| HANDOFF.md                 | **你审过的交接文件**      | 长任务、有死胡同值得记  | 要人多看一眼      |
| /branch、\--fork-session    | 分叉点之前**完整**对话     | 想在某个点试另一条路   | 会话数变多       |
| half-clone / quarter-clone | **后半段（或后四分之一）逐字** | 长对话、最近状态最重要  | 丢掉开头        |

三条值得抄的实践：

**1）把自动压缩关掉。** 理由不是"压缩不好"，而是**自动摘要不知道什么对你重要**——它可能留下一个已经定论的争论，却丢掉你只提过一次的小约束。关了不等于不压缩，而是**你挑时机**（通常在某个里程碑之后）**并挑留下什么**。

**2）交接文件比摘要强，因为你能读它。** 原文给了一个具体例子：让 Claude 把剩下的计划写进 `HANDOFF.md`，说明"试过什么、什么成了、什么没成"，让"一个有干净上下文的 agent 只读这一个文件就能接着干"——产出是 **129 行**，开头是目标（"把 Claude Code 的系统提示压掉约 45%（现在 11%，还差约 34%）"），后面是进展和已经写好的脚本。

然后关键的一步是：**别文件一落地就开新会话**。先扫一眼，缺什么就问（比如"你有没有写清楚要迭代测试，而不是想一次做完？"）——这个问题常常能省掉下一个会话的整个下午。确认之后再开新会话，**只贴路径**：

```text
> experiments/system-prompt-extraction/HANDOFF.md

```

之后每次都让 agent 更新同一个文件，留给下一个接手的人。（源文附了一个 `/handoff` skill 把这套流程自动化。）

**3）half-clone 不做摘要。** 它把超长对话复制成"只保留后半段"的副本，你和 Claude 的消息**逐字保留**，只是丢掉较早的部分；副本第一条消息带 `[HALF-CLONE Jan 7 14:30]` 标记，让你知道自己在哪个版本里。嫌多还有 `--quarter`。和压缩的区别很清楚：**压缩会重新解释，half-clone 只做截断。**

再往前一步是自动化：一个 `Stop` hook（`check-context.sh`）在每次回复后检查上下文占用，**超过 85% 就不让 Claude 停**，让它去跑 `/half-clone` 生成一个只带后半段的新会话，让新 agent 在那里继续。**前提条件写死：必须关掉 Auto-compact**，否则 Claude Code 可能在 hook 生效前先自己压了。

原作者的一句话总结很到位：**如果只养成一个习惯，就养成交接文件。** 它迫使你和 agent 把"现在到底到哪了"讲清楚——而这正好是干净上下文最需要的东西。

## 七、更窄的边界：子 agent 只拿到 prompt

如果你把"交接"缩小到**同一个 agent 内部派活**，能过的状态更少。一份备考资料把边界列得很干脆：

| 方向    | 能过去的东西                                                      |
| ----- | ----------------------------------------------------------- |
| 父 → 子 | **只有 Agent 工具（原 Task 工具）的 prompt 字符串**                      |
| 不继承   | 父对话历史、工具结果、系统提示；skills 里没列出的技能内容也不会自动带过去                    |
| 子 → 父 | **只有最终消息**；中间的工具调用留在子 agent 内部                              |
| 例外    | fork（/subtask 或 subagent\_type: "fork"）会复制整段对话              |
| 配置    | AgentDefinition 必填 description \+ prompt；同名时**程序化定义覆盖文件定义** |

所以"发现、约束、质量标准"必须**写进那句 prompt**——你不能指望它从父上下文里"感受到"。作者给的实践是：**上下文用结构化记录传（内容与元数据分开），并要求结构化最终报告**。否则协调者拿不回来源。

还有一个容易误读的字段：`allowed_tools` 是"**免批准**"，不是"**权限边界**"——它让 Agent 不问你直接跑，不代表它跑不了别的。

## 八、团队级：共享会话与"可执行的流程"

第三篇介绍的 Agent Relay 把这件事推到团队层（Apache-2.0，v14.0.0，2026-10-13 发布，约 900 star），四件套：

- **Messaging**：agent 之间用频道、线程、DM、文件、搜索、实时事件通信，可以跨机器共享工作区（像给 agent 用的 Slack 原语）。
- **Integrations 当虚拟文件系统**：GitHub、Linear、Notion、Slack 以 `ls`/`cat`/`grep`/写文件的方式暴露，用来替代"每个工具接一个 MCP server"。
- **Shared Sessions**：捕获会话，供队友和他们的 agent 搜索"之前做过什么、为什么这么定"；通过 plugin 或 `agent-relay mcp --sessions-only` 访问（文档提到要云登录）。
- **Flows**：用 TypeScript 定义多步流程，带确定性检查、必需步骤和人工闸——**把"你希望 agent 遵守的规则"变成"不遵守就过不去的流程"**。

写这篇的介绍者明确说**自己没有跑过它**，并给了一个谨慎的试法：**先拿一个废弃仓库**，让 Claude Code 干一件小事，再让 Codex 读它的会话接着做；**交接能成，再接真仓库**。这条建议本身就值钱——它是"先验证通道，再接生产"。

## 九、三段式：搬状态、搬契约、留在原地

把上面拼起来，判据只有三句话：

| 层       | 适用于                                     | 手段                         | 判据                        |
| ------- | --------------------------------------- | -------------------------- | ------------------------- |
| **搬状态** | 消息、压缩后的工具痕迹、todo、git status             | 游标增量同步（JSONL / app-server） | 切换后**对方不需要你再讲背景**         |
| **搬契约** | revision、命令、预期输出、验收人、未完成项、Do Not Change | HANDOFF.md（可读、可提交、可审）      | 换到**任何**工具都能开工，包括你下周新装的那个 |
| **不搬**  | 权限、系统提示、连接状态、未落盘推理"是否该这么干"的判断           | **留在原 agent 做完**，或人来做      | 搬过去等于绕过批准 / 等于猜           |

第三层最容易被忽略。**"能不能全自动"的真正答案在第三行**：凡是需要重新获得授权的东西（权限、部署、外发消息），都不该被"搬"过去——那正是第 68 篇讲的 staged tools 想在同一个进程里解决的问题。

第四篇源文（团队工作流那篇）把"搬契约"这一层写成了文件名清单，可以直接抄：`PROJECT.md`（目标与约束）、`ARCHITECTURE.md`、`docs/PLAN.md`、`docs/TASKS.md`、`docs/DECISIONS.md`、`docs/WORKLOG.md`、`docs/HANDOFF.md`；`CLAUDE.md` 与 `AGENTS.md` 只当**薄适配层**，指向上面的规范文件，避免两边规则漂移。

它的交接模板里有三个字段值得直接偷：

- **Revision**：branch / base commit / **待评审的 head commit** / 未提交改动（有就列出）；
- **Verification**：命令 × 通过/失败/**未跑** × **在哪个提交上跑的**；
- **Do Not Change**：受保护行为与范围排除项。

最后一条还附了一句提醒：**`Do Not Change` 只是记录约束，不提供强制。** 同一篇文章里还有两句同类的：**分支不是访问控制边界**，**worktree 只是组织改动、不是沙箱**。这三句放在一起，基本把"用文件解决权限问题"的幻想堵住了。

## 十、坑（都是踩过的）

- **平台**：`ccx` 只有 macOS 13+，要 Claude 和/或 Codex 桌面应用；Windows / Linux / 独立 CLI 都还不行。想在 Linux 上用，就得自己照它的思路写。
- **JSONL 会越来越大**：一个会话一个文件，工具结果全在里面。要定期清理或按项目归档，别指望它永远轻。
- **压缩会丢细节**：被压掉的内容只能靠 `read_session` 分页找；如果那一段已经从磁盘上删了（比如你自己清了历史），就真没了。
- **hook 的纪律**：不能阻塞输入、不能往 stdout 打印（打印会进上下文）、必须幂等（同一份只投一次）。这几条和第 68 篇里 Claude 生命周期 hook 的规则是同一套。
- **图片只是路径**：搬过去的是一个缓存副本的路径，换机器就断。
- **自动压缩会让 Stop hook 失效**：想让 `85% → /half-clone` 生效，必须先关 Auto-compact。
- **别拿旧对话当交接**：源文把它列进"常见错误"第一条区——旧会话既没有 revision，也没有验证记录。
- **子 agent 的 `allowed_tools` 不是防火墙**，prompt 也不是访问控制；**审批状态不能搬**（搬了就是绕过批准）。

## 十一、三步落地（每步有判据）

**第 1 步（半天）：先只做"能搬的那半"。** 写个 50 行脚本：读某个会话的 JSONL → 压缩工具结果 → 生成一段"现状摘要"附到新会话开头。判据：**新会话接到任务后，第一轮不再问你"项目是干什么的 / 之前试过什么"**。

**第 2 步（一天）：加游标，做成双向。** 配对表（一个会话 ↔ 一个对方线程）+ 两个游标 + 一次性投递。判据：**来回切三次，没有一次重复投递、没有一次漏掉对方的改动**。

**第 3 步（一天）：把"搬不动"的部分固化成 `HANDOFF.md`。** 字段：revision（含待评审 head）、验证（命令 × 结果 × 提交）、`Do Not Change`、未完成项、验收人。放在源文件旁边写进仓库；**新会话只贴路径**。判据：**换任意一个工具接手都能开工**——包括你下周新装的那个。

团队级共享会话（第 8 节那套）放到这三步之后：先在一个废弃仓库验证"两个 agent 互读会话"，再考虑接真仓库。

## 编者补充：和第 68 篇的关系

- 第 68 篇讲**交接件写什么**（revision / 命令 / 预期输出 / 验收人）与**台账怎么推导状态**；这篇讲**这些状态里哪些根本搬不过去**，所以你才需要那个交接件（见 [多 Agent 交接：把"写条"换成四字段契约与台账](https://www.hubwiz.com/blog/agent-handoff-contract-and-ledger/)）。
- 两篇叠起来的结论：**同步解决"重复叙述"，契约解决"无法开工"，闸门解决"越权"**——三者不能互相替代。
- 与站内 [多 Agent 同机：Git 作者与凭据归属](https://www.hubwiz.com/blog/multiple-coding-agents-identity-git-attribution/) 的关系：那篇讲"谁签的字"，这篇讲"谁记得住"。

## 边界

- 本文为**编译整理**，未在 macOS 上运行 `ccx`，也未实测 half-clone / Stop hook / Agent Relay；所有机制细节来自源文自述。
- **立场披露**：`ccx` 与 Agent Relay 都是各自作者的项目（前者个人开源，后者是 Agent Workforce 的产品，介绍者声明"未运行过"）；`HANDOFF.md`/half-clone 一套来自一份 50 条 tips 的二手整理（原始观点见 YK Sugi 的 `claude-code-tips` 仓库）；子 agent 边界那张表来自一份**备考资料**（非 Anthropic 官方文档，作者声明与 Anthropic 无关）；团队工作流那篇是工具站内容。
- `Agent` 工具名、`--fork-session`、`/autocompact`、hook 事件名等随版本变化，以你本地 `claude --version` 的文档为准。
- 文中"通常几千 token"这类量级是作者在其设置下的观察，不是基准测试。

---

**相关阅读**：[AI 编程 / Vibe Coding 完全指南](https://www.hubwiz.com/blog/vibe-coding-stack/) ｜ [Agent / MCP / 自动化完全指南](https://www.hubwiz.com/blog/agent-stack/) ｜ [多 Agent 交接：四字段契约与台账](https://www.hubwiz.com/blog/agent-handoff-contract-and-ledger/) ｜ [多 Agent 写代码：协议才是系统](https://www.hubwiz.com/blog/multi-agent-coding-workflow-identity-isolation-review/) ｜ [子代理交接的三种做法：compaction vs subagent vs fold](https://www.hubwiz.com/blog/subagent-fork-fold-context-handoff/) ｜ [多机并行 coding agent 实战栈](https://www.hubwiz.com/blog/parallel-coding-agents-multi-machine/)

**Sources**

- *How I hand a Claude Code session to Codex (and back) without re-explaining anything*，dev.to，2026-10-21：[https://dev.to/aaron\_w\_ef987250d3531be6d/how-i-hand-a-claude-code-session-to-codex-and-back-without-re-explaining-anything-2poe](https://dev.to/aaron%5Fw%5Fef987250d3531be6d/how-i-hand-a-claude-code-session-to-codex-and-back-without-re-explaining-anything-2poe?ref=hubwiz.com)
- *How Claude Code and Codex store sessions, and how to hand a task from one to the other*，dev.to，2026-10-23：[https://dev.to/aaron\_w\_ef987250d3531be6d/how-claude-code-and-codex-store-sessions-and-how-to-hand-a-task-from-one-to-the-other-m2m](https://dev.to/aaron%5Fw%5Fef987250d3531be6d/how-claude-code-and-codex-store-sessions-and-how-to-hand-a-task-from-one-to-the-other-m2m?ref=hubwiz.com)
- *Claude Code Context Management: Compact, Handoff, and Half-Clone*，camnangai.com，2026-10-24：[https://camnangai.com/en/for/developers/claude-code-tips-context-management](https://camnangai.com/en/for/developers/claude-code-tips-context-management?ref=hubwiz.com)
- *Spawning subagents and passing context*（Claude Certified Architect 备考资料），2026-10-22：[https://www.certifyforce.com/study-guide/claude-certified-architect-foundations/agentic-architecture-and-orchestration/spawning-subagents-and-passing-context](https://www.certifyforce.com/study-guide/claude-certified-architect-foundations/agentic-architecture-and-orchestration/spawning-subagents-and-passing-context?ref=hubwiz.com)
- *Claude Code and Codex shared workflow: A practical setup guide*，agentkit.best，2026-10-13：[https://agentkit.best/blog/claude-code-guides/claude-code-and-codex-shared-workflow-a-practical-setup-guide](https://agentkit.best/blog/claude-code-guides/claude-code-and-codex-shared-workflow-a-practical-setup-guide?ref=hubwiz.com)
- *Agent Relay: Open-Source Messaging, Shared Sessions and Flows*，explainx.ai，2026-10-23：[https://explainx.ai/blog/agent-relay-open-source-shared-sessions-flows-coding-agents-handoff-apache-2026](https://explainx.ai/blog/agent-relay-open-source-shared-sessions-flows-coding-agents-handoff-apache-2026?ref=hubwiz.com)

*本文由 hubwiz 编译整理，转载请注明出处。*

> **这是「AI 编程 / Vibe Coding」专题的一部分。**完整地图见：[AI 编程 / Vibe Coding 完全指南](https://www.hubwiz.com/blog/vibe-coding-stack/)