把 Codex CLI 接到 CCSub 之后,最常见的体感问题不是报错,而是「不报错但没写完」:模型讲到一半停住、返回的 JSON 少一个右括号、让它重写一个长文件只改了前 30 行。这类现象统称输出被截断,但根因往往完全不同,盲目改参数只会浪费时间。下面按「先定位在哪一层、再对症下药」的顺序讲清楚。
先分清三种截断表现
同样是没写完,落在不同层时特征差别很大,先对号入座能省掉一半排查时间。
- 请求侧 max_tokens 太小:回答在句中断掉,通常没有完整的结尾标点,日志里
finish_reason是length;换一个更短的问题能正常回答完。 - 上下文压缩裁掉了历史:模型答非所问或反复问你要文件内容,输出本身是完整的,但基于的信息已经缺失;同一轮对话第一次问没事,聊到第 10 轮开始出问题。
- 传输层提前中断:输出突然消失、CLI 报连接类错误或超时,重试同一请求有时又成功;这类通常伴随
connect_error、upstream_unavailable之类的错误记录。
第一步:确认 CCSub 侧的接入方式正确
Codex CLI 走的是 Responses 接口,base URL 用 https://ccsub.xyz/openai,客户端会自动请求 /responses。这是 Codex 原生调用方式,不要和 OpenAI 兼容的 /v1/chat/completions 混用。
# ~/.codex/config.toml
model = "gpt-5.6-sol"
model_provider = "ccsub"
[model_providers.ccsub]
name = "CCSub"
base_url = "https://ccsub.xyz/openai"
wire_api = "responses"
env_key = "CCSUB_API_KEY"
如果你用的是 Claude Code,那边是另一套:ANTHROPIC_BASE_URL=https://ccsub.xyz/api,客户端自动请求 /v1/messages。两种配置不要互相套用,否则会因为接口语义不一致出现各种奇怪的截断。
可用模型列表随时可以通过 GET https://ccsub.xyz/v1/models 查询,确认你写的 model id 真实存在。
第二步:用 curl 做最小复现,判断问题在哪一层
这一步是整个排查的核心。绕开 Codex CLI,直接请求 CCSub 的 OpenAI 兼容端点,看纯接口层面能不能正常返回完整内容。如果能,说明问题在 CLI;如果不能,说明在参数或传输层。
curl https://ccsub.xyz/v1/chat/completions \
-H "Authorization: Bearer sk-你的CCSub密钥" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"messages": [{"role": "user", "content": "输出一段 800 字左右的说明文字,不要中断"}],
"max_tokens": 2048
}'
观察返回里的两个字段:
finish_reason为length:输出确实被 token 上限砍掉了,问题在请求侧。finish_reason为stop但正文依然很短:请求侧正常,问题大概率在 CLI 的上下文管理。- curl 直接报连接错误或中途断开:属于传输层,和 CLI 无关,优先检查网络与重试。
想进一步看参数支持范围,可以参考站内 API 参数与推理能力,里面列出了 Chat、Responses、Messages 三类接口各自支持的字段。
根因一:max_tokens 设置过小
Codex CLI 默认的 max_tokens 对「写一个完整文件」来说经常不够。让它生成 300 行代码、或者输出一个嵌套较深的 JSON,很容易撞上上限。
在 config.toml 里显式提高上限:
model = "gpt-5.6-sol"
max_tokens = 8192
推理类接口里这个字段也可能叫 max_output_tokens,两个名字指的都是「这次调用最多生成多少 token」。注意两点:
- 它不是越大越好。设置得远超实际需要,会让长输出更容易在传输过程中被中断。
- 输出 token 是要计费的。CCSub 上
gpt-5.6-sol的定价是输入 56、输出 168(单位按站内价目表口径),长输出任务成本涨得比你想的快,建议按任务类型分档设置。
根因二:Codex CLI 的上下文压缩裁掉了关键信息
Codex CLI 为了控制上下文长度,会在对话变长时自动压缩历史。压缩本身是合理的,但它可能把你几分钟前贴进去的文件内容、或者当前的编辑约束裁掉,于是模型「忘」了要改哪个文件,输出的内容自然看起来像被截断。
判断方法:
- 同一任务在第一轮就失败 → 不像压缩问题。
- 聊了十几轮、或者连续读了好几个大文件之后才开始失败 → 高度怀疑是压缩。
- 把关键约束重新贴一遍就能正常完成 → 基本可以确认。
缓解手段:把大文件拆成小任务逐个处理;在每个任务开头重新声明「修改哪个文件、保持什么风格」;不要在一轮对话里既让它读全文又让它改全文。这一条和站内关于 token 消耗异常的文章是同一类问题,可以配合阅读。
根因三:传输层提前中断
如果你在 curl 直连时也遇到中断,就属于这一类。长输出请求在传输中被打断,客户端只能拿到半截内容,前端看起来就是「写一半停了」。服务端偶发的 connect_error、upstream_unavailable 都会产生这种表现。
处理建议:
- 开启客户端自动重试,但把重试次数限制在 2–3 次,避免长任务反复计费。
- 把「一次生成 2000 行」拆成「分三次生成 700 行」,单次请求越短越稳。
- 如果连续多次中断,先按站内 故障排查 里的按症状速查表走一遍,再判断是不是本地网络出口的问题。
一个实用习惯:把失败的请求原样保留下来,先用 curl 打一遍。能在 curl 复现的问题不要改 CLI 配置,反之亦然。
完整排查清单
- 确认 Codex 用的是
https://ccsub.xyz/openai+wire_api = "responses",没有和其他接口混用。 - 用 curl 请求
https://ccsub.xyz/v1/chat/completions做最小复现,记录finish_reason。 finish_reason = length→ 提高max_tokens/max_output_tokens。finish_reason = stop但内容异常 → 检查是否上下文压缩导致信息缺失,拆任务重试。- curl 也中断 → 属于传输层,开启有限重试并缩短单次请求长度。
- 确认 model id 在
GET https://ccsub.xyz/v1/models里真实存在。
关于成本的一点提醒
截断问题经常和「不知不觉花了很多」同时出现。长输出任务被中途打断后重试,前面的输出 token 已经计费。排查阶段建议先用低价模型跑通流程,确认配置无误后再换回主力模型。充值前可以先看 注册与充值 了解计费口径,用 入门使用手册 里的 Token 明细对照实际消耗。
如果你还没完成接入,从 安装配置 开始,把 Codex 指向 CCSub 之后,再按本文的顺序排查输出截断问题,基本能在十分钟内定位到具体是哪一层出了状况。