☰
让 Claude Code、Codex 稳定跑一整晚:把 endpoint 改到 TaoToken 的工作流拆解
2026/10/18 10:05:37 网站建设 项目流程

1. 夜间批量任务为什么总在凌晨断掉

如果你把 Claude Code 或 Codex 挂在终端里跑批量重构,第二天早上大概率会看到两种结果:一种是任务确实跑完了,但中间某几次请求返回了 502;另一种更常见——进程还在,但日志停在凌晨两点,后面全是重试超时。很多人第一反应是模型不行、上下文太长、任务太复杂,但把日志翻出来逐行看,真正卡住的位置往往跟模型推理无关,而是请求在链路上被掐断了。

我试过把同一个重构任务分别跑在直连和固定 endpoint 两种配置下,直连那晚在 3 小时 17 分左右开始出现ECONNRESET,之后每 5 分钟重试一次,直到早上都没恢复;换成固定 endpoint 后,同样的任务连续跑了 6 小时 40 分,中间只有两次正常的 429 限流退避,没有一次因为通道问题中断。差别不在模型,在于请求出口是否稳定。

夜间批量任务的特殊性在于:它没有人盯着,没有交互式重试,一旦某次请求失败且客户端没有正确退避,整个 Agent 循环就会卡死在一个状态上。Claude Code 的 agentic loop 和 Codex 的 exec 模式都会在请求失败后进入等待,如果失败原因是网络层而不是模型层,等待时间会非常长。所以让它们稳定跑一整晚,核心动作只有一个:把 endpoint 固定到一个可控的入口,让请求失败的原因收敛到「限流」和「业务错误」这两类可处理的情况,而不是「通道抖动」这种没法处理的情况。

这篇文章拆的就是这个工作流:怎么改 endpoint、auth.json 里哪些字段必须对齐、连续跑 6 小时要看哪些日志、以及最常见的几个报错怎么排。适合已经在用 Claude Code 或 Codex 做自动化、但被夜间中断折磨过的人。

2. 把 endpoint 固定到 TaoToken 的前置准备

在改配置之前,先把三件套对齐:Base URL、API Key、Model ID。这三者任何一个不匹配,夜间任务都会以 401 或 404 的形式断掉,而且断得毫无规律,因为有些客户端只在第一次请求时校验,后续请求复用连接就不报错了,等你发现时已经跑了几个小时。

TaoToken 的 API 入口是https://taotoken.net/api,这个地址不带任何查询参数,直接作为 Base URL 使用。注意不要把它和官网地址混用,官网是https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,那是给人看的页面,不是给客户端请求的。客户端只认/api这个路径。

API Key 在控制台的 API Keys 页面生成,生成后只显示一次,复制下来存到环境变量里,不要硬编码进配置文件。Model ID 要跟你实际调用的模型对齐,Claude Code 走 Anthropic 协议时用 Claude 系列模型 ID,Codex 走 OpenAI 兼容协议时用对应的模型 ID,两者不要混。

前置准备清单:

  • 一个可用的 API Key,存到TAOTOKEN_API_KEY环境变量
  • 确认 Base URL 为https://taotoken.net/api
  • 确认要用的 Model ID,写进配置
  • 本地或远程环境能访问该地址(用 curl 测一次)

这里有个容易踩的坑:很多人把 Base URL 写成https://taotoken.net/api/带尾斜杠,某些客户端拼接路径时会变成//v1/messages,服务端返回 404,但错误信息里不会明确说是路径问题,只会说 model not found,误导排查方向。所以 Base URL 结尾不要带斜杠。

另外,夜间任务建议在远程 Linux 主机上跑,本地笔记本合盖休眠会直接杀掉进程,这跟 endpoint 无关,但会伪装成「通道中断」。用 tmux 挂住会话,SSH 断了任务还在。这一步做完,再进入配置环节。

3. 可复制的 endpoint 配置与 auth.json 字段

这一节给三套配置:Claude Code 的 settings、Codex 的 auth.json、以及通用的环境变量方式。三套都基于同一个 Base URL 和同一个 Key,只是客户端读取位置不同。

3.1 Claude Code 的 settings.json

Claude Code 读取~/.claude/settings.json,把 endpoint 和 key 写进去:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的key", "ANTHROPIC_MODEL": "claude-sonnet-4-20250514" }, "permissions": { "allow": [ "Bash(git *)", "Bash(npm *)", "Bash(pytest *)" ] } }

注意ANTHROPIC_BASE_URL不要带/v1,Claude Code 会自己拼/v1/messages。如果你写成https://taotoken.net/api/v1,最终请求会变成/api/v1/v1/messages,直接 404。这是夜间任务最常见的配置错误之一。

permissions.allow里把夜间任务需要的命令放开,避免 Agent 在凌晨卡在权限确认上。但只放开任务必需的,不要用Bash(*)全放开。

3.2 Codex 的 auth.json

Codex 读取~/.codex/auth.json,字段名跟 Claude Code 不同:

{ "OPENAI_BASE_URL": "https://taotoken.net/api", "OPENAI_API_KEY": "sk-你的key", "OPENAI_MODEL": "gpt-5-codex", "provider": "openai" }

Codex 的OPENAI_BASE_URL同样不带/v1,它会拼/v1/chat/completions或/v1/responses,取决于模型。如果你用的是 Codex 的 exec 模式跑批量任务,还要在~/.codex/config.toml里确认model_provider指向正确的 provider:

model_provider = "openai" model = "gpt-5-codex" [model_providers.openai] base_url = "https://taotoken.net/api" env_key = "OPENAI_API_KEY"

TOML 和 JSON 两处都要对齐,只改一处会出现「auth.json 读到了但 config.toml 还在用默认地址」的情况,表现为部分请求走旧地址、部分走新地址,日志里看起来像随机中断。

3.3 环境变量方式(通用)

如果你不想改配置文件,或者要在 CI 里跑,用环境变量:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的key" export OPENAI_BASE_URL="https://taotoken.net/api" export OPENAI_API_KEY="sk-你的key"

环境变量的优先级通常高于配置文件,但不同客户端行为不一致,建议只保留一种方式,避免排查时搞不清哪个生效了。

3.4 三件套对照表

客户端Base URL 字段Key 字段Model 字段配置文件路径
Claude CodeANTHROPIC_BASE_URLANTHROPIC_API_KEYANTHROPIC_MODEL~/.claude/settings.json
CodexOPENAI_BASE_URLOPENAI_API_KEYOPENAI_MODEL~/.codex/auth.json
Codex TOMLbase_urlenv_keymodel~/.codex/config.toml

三件套必须同时对齐,缺一个都会在夜间任务里以不同形式爆出来。改完配置后,先别急着跑长任务,用下一节的验证请求确认一次。

4. 验证请求与连续 6 小时日志观察

配置改完,先用一条最小请求确认链路通。Claude Code 用:

curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "reply with ok"}] }'

返回里如果有content字段且stop_reason是end_turn,说明 Base URL、Key、Model 三件套都对。如果返回 401,是 Key 问题;返回 404,大概率是 Base URL 带了多余路径;返回 400 且提示 model 不存在,是 Model ID 写错。

Codex 用:

curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -H "content-type: application/json" \ -d '{ "model": "gpt-5-codex", "messages": [{"role": "user", "content": "reply with ok"}], "max_tokens": 64 }'

两条都通了,再挂夜间任务。挂的时候把日志重定向到文件,方便第二天分析:

tmux new -s night-agent claude --dangerously-skip-permissions -p "按 TASK.md 执行重构任务" 2>&1 | tee -a ~/logs/night-$(date +%F).log

--dangerously-skip-permissions只在隔离环境用,配合前面 settings.json 里的 allow 列表,避免凌晨卡权限确认。

连续跑 6 小时后,看日志里这几个指标:

第一,请求成功率。用 grep 统计:

grep -c "HTTP 200" ~/logs/night-2025-01-01.log grep -c "ECONNRESET\|ETIMEDOUT\|502\|503" ~/logs/night-2025-01-01.log

如果 502/503 出现次数为 0,说明通道稳定;如果出现但后面跟着成功的重试,说明退避逻辑生效了,可以接受;如果出现后没有恢复,说明客户端退避策略有问题,需要调max_retries。

第二,请求间隔。正常 agentic loop 的请求间隔在几秒到几十秒,如果日志里出现超过 5 分钟的空白,说明卡住了。用 awk 算时间差:

awk '/timestamp/ {print $1}' ~/logs/night-2025-01-01.log | \ awk 'NR>1 {print $1-prev} {prev=$1}' | sort -rn | head

第三,token 消耗曲线。如果某段时间 token 消耗突然归零,说明请求没发出去。这个要结合客户端自己的 usage 日志看。

实测下来,配置正确的情况下,6 小时连续运行只会看到两类日志:正常的请求成功记录,和偶发的 429 限流退避。任何ECONNRESET、ETIMEDOUT、502都不应该出现。如果出现了,按下一节排查。

5. 夜间任务常见报错排查

5.1 401 Unauthorized

日志里出现401且提示invalid api key,先确认环境变量有没有被覆盖。Claude Code 会优先读ANTHROPIC_API_KEY,如果你在 shell 里 export 了一个旧 key,settings.json 里的新 key 就不生效。用env | grep ANTHROPIC确认当前生效的值。

另一个原因是 key 复制时带了空格或换行。把 key 用echo -n "$ANTHROPIC_API_KEY" | wc -c看长度,跟控制台显示的长度对比。

5.2 local proxy failed / connection refused

这个报错说明客户端在尝试连本地代理,而不是直连 Base URL。常见于之前配过代理工具、环境变量里残留了HTTP_PROXY或HTTPS_PROXY。夜间任务里这个报错特别隐蔽,因为白天手动跑可能走的是另一套 shell 配置。

排查:

env | grep -i proxy

如果有输出,在启动夜间任务前 unset:

unset HTTP_PROXY HTTPS_PROXY ALL_PROXY

然后在同一个 tmux 会话里启动任务,确保环境干净。

5.3 reading choices 相关报错

日志里出现error reading choices或unexpected response format,通常是响应体不是预期的 JSON 结构。原因可能是 Base URL 指向了一个返回 HTML 的地址(比如误填了官网地址),或者 Model ID 跟协议不匹配(用 Anthropic 协议调了 OpenAI 模型)。

确认 Base URL 是https://taotoken.net/api,不是官网地址。确认 Claude Code 用 Anthropic 协议、Codex 用 OpenAI 协议,不要交叉。

5.4 OAuth 相关报错

如果日志里出现OAuth token expired或refresh token failed,说明客户端在走 OAuth 流程而不是 API Key。Claude Code 和 Codex 都支持两种认证方式,夜间任务必须用 API Key,OAuth 的 token 有效期短,凌晨过期后无法自动刷新。

检查~/.claude/settings.json里有没有oauth相关字段,有就删掉,只保留ANTHROPIC_API_KEY。Codex 同理,auth.json里只保留OPENAI_API_KEY。

5.5 报错对照表

报错关键词最可能原因排查动作
401 invalid api keykey 被环境变量覆盖或带空格env grep + 长度检查
local proxy failed残留代理环境变量unset HTTP_PROXY
reading choicesBase URL 或协议不匹配确认 /api 路径 + 协议
OAuth token expired用了 OAuth 而非 API Key删掉 oauth 字段
404 model not foundBase URL 带 /v1 或 Model ID 错去掉尾斜杠 + 核对 Model ID

排障时优先看第一条报错,后面的报错往往是第一条的连锁反应。比如 401 之后客户端会重试,重试时可能触发 OAuth 流程,日志里就同时出现 401 和 OAuth 报错,但根因只有一个。

6. 把夜间任务跑成可复用的工作流

配置和排障都过了之后,剩下的就是把整套动作固化成脚本,下次直接跑。我自己的做法是写一个night-run.sh,里面做四件事:检查环境变量、启动 tmux 会话、跑任务、把日志按日期归档。

#!/bin/bash set -e export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="$TAOTOKEN_API_KEY" unset HTTP_PROXY HTTPS_PROXY ALL_PROXY LOG=~/logs/night-$(date +%F).log mkdir -p ~/logs tmux new-session -d -s night "claude --dangerously-skip-permissions -p \"$(cat TASK.md)\" 2>&1 | tee -a $LOG" echo "started, log at $LOG"

第二天早上先看日志尾部的stop_reason,如果是end_turn,说明任务正常结束;如果是max_turns或空,说明中途卡住了,用第 4 节的 awk 命令找时间空白点。

长期跑的话,建议把 API Key 和 Base URL 的管理集中到一处,比如用.env文件配合 direnv,避免每个项目都要重新配。TaoToken 的控制台可以生成多个 Key,给不同项目分配不同的 Key,这样某个 Key 出问题时不会影响其他夜间任务。

最后一点经验:夜间任务不要一次跑太复杂的重构,拆成多个小任务串行跑,每个任务单独提交 Git,这样即使某个任务失败,前面的成果还在。Agent 的稳定性不只取决于 endpoint,也取决于任务粒度。粒度越细,单次失败的影响越小,第二天恢复的成本越低。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询