1. Codex 长会话报 context window 满了,先别急着 codex clear
你大概率是在一个跑了很久的 Codex 会话里,突然看到这么一行:
Codex ran out of room in the model's context window. Start a new conversation or clear earlier history before retrying.第一反应通常是敲codex clear,或者干脆重开一个会话。但如果你已经试过这两招还是不行,那说明问题不在「当前这一轮对话」,而在 Codex 落盘的会话历史文件里。Codex 会把每一轮交互按天写进~/.codex/sessions/下的 jsonl 文件,一个会话跑久了,单个 jsonl 涨到十几 MB 很常见,我见过 18M 的。context window 报错本质上是「喂给模型的 token 超了」,而 Codex 在恢复会话时会把这些历史重新拼进上下文,所以哪怕你codex clear了当前屏幕,底层 jsonl 还在,重新进入会话照样爆。
这篇就按「先定位、再决定清不清」的顺序走一遍:怎么找到 sessions 目录、怎么读 jsonl 判断占用来源、codex clear和新建会话到底差在哪、以及把 endpoint 切到 TaoToken 之后怎么用一次可复现的请求验证配置真的生效。适合已经在用 Codex CLI、被长会话卡住、又不想无脑删库的人。
核心检索词先摆出来:Codex context window 报错排查、codex sessions jsonl 清理、codex clear 与新建会话区别。这三个词基本覆盖了你从报错到解决的完整路径。
先说结论方向,免得你中途跑偏:codex clear清的是当前会话的上下文视图,新建会话是换一条干净的上下文线,而真正占空间的历史躺在 jsonl 里。三者不是一回事,混着用就会觉得「怎么清都没用」。下面一步步来。
2. 定位 ~/.codex/sessions 与 jsonl 占用来源
Codex 的会话数据默认落在用户主目录下的.codex里。不同系统路径略有差异,但结构一致:
# macOS / Linux ls -la ~/.codex/ # Windows PowerShell Get-ChildItem $env:USERPROFILE\.codex你会看到类似这样的目录结构:
~/.codex/ ├── sessions/ │ └── 2025/ │ └── 09/ │ └── 23/ │ ├── 0f3a1c2e-....jsonl │ └── 7b9d4a10-....jsonl ├── config.toml └── auth.jsonsessions下面按年/月/日分层,每天一个目录,每个会话一个session-id.jsonl。文件名就是会话 ID,方便你对照。先看哪个文件大:
# 找出 sessions 下最大的 10 个 jsonl find ~/.codex/sessions -name "*.jsonl" -type f -exec du -h {} + | sort -rh | head -n 10Windows 上用 PowerShell:
Get-ChildItem -Path $env:USERPROFILE\.codex\sessions -Recurse -Filter *.jsonl | Sort-Object Length -Descending | Select-Object -First 10 FullName, @{N='MB';E={[math]::Round($_.Length/1MB,2)}}跑完你就能看到那个 18M 的元凶。接下来别急着删,先读一下它,判断占用到底来自哪。jsonl 是「一行一个 JSON 对象」,每行通常带type、role、content之类的字段。用jq统计一下每行的类型分布:
# 统计各 type 出现次数(先装 jq:brew install jq / apt install jq) jq -r '.type // "unknown"' ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl | sort | uniq -c | sort -rn如果没装 jq,用 Python 一行也能看:
python3 -c " import json,collections,sys c=collections.Counter() for line in open(sys.argv[1]): line=line.strip() if not line: continue try: c[json.loads(line).get('type','unknown')]+=1 except: c['parse_error']+=1 print(c.most_common()) " ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl典型输出会告诉你大头在哪。常见占用来源有三类:一是超长的工具调用返回(比如你让它读了一个大文件,整段内容被塞进历史);二是反复的失败重试,同一段报错被记了很多遍;三是会话本身轮次太多,累积起来自然大。看清来源再决定是「删早期行」还是「整段丢弃」。
注意:jsonl 是纯文本,删之前先备份一份,
cp xxx.jsonl xxx.jsonl.bak,改坏了还能回滚。
这一步的目标不是马上清理,而是让你心里有数:到底是哪几行把上下文撑爆的。定位准了,后面codex clear还是新建会话,你都能选对。
3. 可复制配置:把 endpoint 切到 TaoToken 并控制上下文
排查完历史,另一个容易被忽略的点是 endpoint 和模型配置。Codex 默认走官方 endpoint,如果你想让长会话更稳、或者单纯想换个入口,可以把 base URL 指到 TaoToken。先拿 Key:打开 https://taotoken.net/api-keys 生成一个 API Key,然后编辑~/.codex/config.toml。
Codex 的配置是 TOML 格式,路径固定为~/.codex/config.toml。一个可复制的最小片段如下:
# ~/.codex/config.toml model = "gpt-5-codex" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "responses"这里三件套要写全,缺一个都会连不上:
- Base URL:
https://taotoken.net/api - API Key:通过环境变量
TAOTOKEN_API_KEY注入,别硬编码进文件 - Model ID:
model字段,比如gpt-5-codex,按你实际要用的填
环境变量这样设:
# macOS / Linux,写进 ~/.zshrc 或 ~/.bashrc export TAOTOKEN_API_KEY="sk-你的key" # Windows PowerShell(当前会话) $env:TAOTOKEN_API_KEY="sk-你的key"如果你用的是auth.json那套(部分 Codex 版本会读~/.codex/auth.json),结构长这样:
{ "OPENAI_API_KEY": "sk-你的key", "OPENAI_BASE_URL": "https://taotoken.net/api" }提示:
config.toml和auth.json二选一即可,别同时配两套互相打架。改完重启 Codex 进程,配置才会重新加载。
关于上下文控制,Codex 本身没有「一键压缩」的开关,但你可以通过配置减少历史回灌。比如把model_provider指到 TaoToken 后,配合更短的会话策略使用。真正压上下文还是靠第 4 步的清理动作。配置这块先保证 endpoint 通、Key 对、Model ID 存在,这是后面验证的前提。
如果你更习惯用 Coding Plan 做长期编码任务,可以在 https://taotoken.net/coding-plan 看套餐,长会话场景下按量或包月自己权衡。接入文档在 https://taotoken.net/doc ,配置字段有疑问对着查。
4. 验证请求:一次可复现的清理前后对照
配置改完,先做一次最小验证,确认 endpoint 真的通了。用 curl 打一发:
curl https://taotoken.net/api/v1/models \ -H "Authorization: Bearer $TAOTOKEN_API_KEY"返回里能看到模型列表就说明 Key 和 Base URL 没问题。接着回到 Codex 里跑一句最简单的:
codex "print hello"如果这一步就报401或local proxy failed,先回第 5 步排错,别往下走。
现在做清理前后的对照。假设你锁定了那个 18M 的 jsonl,先记录清理前的状态:
# 清理前:文件大小 + 行数 ls -lh ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl wc -l ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl然后备份并删掉早期历史。思路是保留最近 N 行,把前面的丢掉:
# 备份 cp ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl \ ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl.bak # 只保留最后 200 行(按需调整) tail -n 200 ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl.bak \ > ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl再对比一次:
ls -lh ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl wc -l ~/.codex/sessions/2025/09/23/0f3a1c2e-....jsonl文件从 18M 掉到几百 KB,行数从几万掉到 200,这就是可复现的对照。然后重新进入这个会话,再发一条消息,看 context window 报错是否消失。如果消失,说明占用确实来自被删的早期历史;如果还在,说明当前会话的活跃上下文本身就超了,那就得新建会话。
codex clear和新建会话的取舍在这里就清楚了:codex clear只清当前视图,jsonl 不动,适合「当前屏幕太乱但历史还想留」;新建会话是彻底换一条上下文线,适合「这个会话已经没救、历史也不需要」。而手动裁剪 jsonl 是介于两者之间——保留会话 ID,只砍掉撑爆的部分。
验证动作建议固定成一套:改配置 → curl 测 models → codex 跑 hello → 裁剪 jsonl → 重进会话发消息。每次排查都走一遍,出问题能快速定位在哪一环。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
排错这块按真实报错对照,别凭感觉猜。
401 Unauthorized:Key 没生效。先确认环境变量在当前 shell 里真的存在,echo $TAOTOKEN_API_KEY看有没有值。如果为空,说明export没写进启动文件,或者你开的是新终端没 source。Windows 上注意$env:只在当前会话有效,要持久化得用setx。另外检查config.toml里的env_key名字和实际环境变量名是否一致,大小写敏感。
local proxy failed:Codex 尝试走本地代理但没起来。检查config.toml里base_url是不是写成了http://localhost:xxxx之类,正常应该直连https://taotoken.net/api。如果你之前配过别的 provider,残留的 proxy 字段要删掉。
reading choices相关报错:通常是响应体格式和wire_api不匹配。Codex 的wire_api有responses和chat两种,填错会解析失败。用 TaoToken 时按文档填responses,如果报错就换成chat试。这个字段在[model_providers.taotoken]段里。
OAuth报错:说明 Codex 还在走官方登录态,没切到 API Key 模式。检查auth.json里是不是还留着旧的 OAuth token,清掉,改用OPENAI_API_KEY+OPENAI_BASE_URL那套。或者确认config.toml的model_provider指向了taotoken而不是默认 provider。
还有一个高频坑:改了config.toml但没重启 Codex。配置是启动时读的,热改不生效。每次改完pkill codex再重开。
对照表方便你快速定位:
| 报错 | 大概率原因 | 处理 |
|---|---|---|
| 401 | Key 未注入 / 名字不符 | 检查环境变量与 env_key |
| local proxy failed | base_url 指向本地 | 改为 https://taotoken.net/api |
| reading choices | wire_api 填错 | responses / chat 互换 |
| OAuth | 仍走官方登录态 | 清 auth.json,改用 API Key |
排错时优先看 Codex 的启动日志,它会打印实际加载的 provider 和 base_url,比猜快得多。
6. 长会话继续用:把清理和接入固定成习惯
走到这里,你应该已经能自己定位那个撑爆 context window 的 jsonl 了。我的习惯是:每次长会话结束前,先du -h看一眼当天 jsonl 大小,超过 5M 就顺手tail -n 300裁一下,备份留着。这样下次进会话不会一上来就爆。
endpoint 切到 TaoToken 之后,配置就固定成config.toml里那三件套,Key 走环境变量,别写死。需要换模型时只改model字段,provider 段不动。验证动作保持那套固定流程,出问题按第 5 步的报错表对号入座。
如果你要长期跑编码或 Agent 任务,长会话是常态,与其每次爆了再救,不如把「定期裁 jsonl + 固定 endpoint 配置」变成肌肉记忆。接入细节对着 https://taotoken.net/doc 查,模型对话想先试效果可以去 https://taotoken.net/chat ,Key 在 https://taotoken.net/api-keys 生成。配置改完记得重启 Codex,这一步别省。