1. Windows CJK 用户名下 Codex auth.json 读取失败的真实场景
先说清楚这篇在解决什么问题。Windows 上用中文、日文、韩文用户名(也就是常说的 CJK 用户名)时,Codex CLI 的鉴权文件auth.json经常读不出来,表现是启动后提示未登录、或者报一串乱码路径、或者干脆reading choices之类的解析错误。核心检索词就是 Windows CJK 用户名编码问题修复,它指的是:系统用户名含非 ASCII 字符时,路径在 UTF-8、GBK、UTF-16 之间来回转换,最终落到auth.json的读取环节就崩了。
适合谁看?三类人。第一类,Windows 账户名是中文的开发者,比如C:\Users\张三\,装了 Codex CLI 后一直鉴权失败。第二类,用日文或韩文用户名,遇到auth.json路径乱码但不知道从哪下手。第三类,想把 Codex 的鉴权端点切到 TaoToken 这类兼容 OpenAI 协议的服务,结果发现改完auth.json还是报错,怀疑是配置写错了,其实是编码在作祟。
我先把现象拆开。Codex CLI 在 Windows 上默认把鉴权信息放在%USERPROFILE%\.codex\auth.json。当%USERPROFILE%展开成C:\Users\张三时,这个路径里的中文字符会经历一次「环境变量展开 → 字符串拼接 → 文件系统 API 调用」的链路。问题就出在中间某一步用了错误的编码去解释这段字节。比如某个环节按 GBK 解码了本该是 UTF-8 的字节,路径就变成了C:\Users\寮犱笁这种乱码,文件自然找不到。
更隐蔽的是,有时候文件明明存在,auth.json内容也是对的,但 Codex 读出来的 JSON 里字段名或字符串值出现乱码,导致解析失败。这通常是因为写入时用了 UTF-8,读取时按系统默认代码页(简体中文 Windows 是 936/GBK)去解,中文字符对不上。所以「编码问题」这四个字,在 Windows CJK 场景下既可能是路径编码,也可能是文件内容编码,得分开排查。
这一节先建立判断标准:如果你看到报错里出现C:\Users\后面跟着一串看不懂的字符,或者auth.json明明在却提示找不到,或者 JSON 解析报Unexpected token但文件肉眼看着正常,那基本可以锁定是 CJK 用户名引发的编码问题。接下来我会给出可复制的auth.json配置片段、路径转义写法,以及用最小请求验证鉴权是否恢复的操作步骤。
2. TaoToken 前置准备:拿到 Base URL、Key 和 Model ID
在动手改auth.json之前,得先把要写入的鉴权信息准备好。这里以 TaoToken 为例,因为它兼容 OpenAI 的接口协议,Codex CLI 改起来最省事。你需要三样东西:Base URL、API Key、Model ID。这三件套缺一不可,后面配置片段里会一一对应。
Base URL 用https://taotoken.net/api,注意这个地址不带任何查询参数,直接作为接口根路径。API Key 需要你去控制台生成,入口在 API Keys 页面,登录后创建一个新的 Key,复制出来保存好,它只会完整显示一次。Model ID 取决于你要调用的模型,比如gpt-4o、claude-3-5-sonnet这类,具体以你账号下可用的模型列表为准。
我建议你先把这三样写到一个临时文本里,格式像这样:
Base URL: https://taotoken.net/api API Key: sk-xxxxxxxxxxxxxxxxxxxxxxxx Model ID: gpt-4o为什么要单独列出来?因为auth.json的字段名和嵌套结构容易写错,先把值准备好,写配置时直接粘贴,减少手误。另外提醒一句,API Key 属于敏感信息,别提交到 Git 仓库,也别贴到公开的 issue 里。
如果你还没生成 Key,可以走这个流程:打开控制台,找到 API Keys 菜单,点新建,给它起个能认出来的名字,比如codex-win-cjk,然后复制。生成后如果发现鉴权还是 401,先别急着怀疑编码,回头确认 Key 有没有多余空格、有没有复制完整。
关于模型选择,如果你只是验证鉴权通不通,用最便宜的模型跑一次最小请求就行。等确认链路正常了,再换成你日常用的模型。TaoToken 的接入文档里有各模型的调用示例,遇到字段不确定的时候可以对照着看。
这一节的核心是:把 Base URL、Key、Model ID 三件套备齐,并且明确 Base URL 是https://taotoken.net/api。下一节进入实际配置,我会给出完整的auth.json片段和路径转义写法。
3. 可复制配置:auth.json 片段与路径转义写法
现在进入动手环节。Codex CLI 的鉴权文件默认在%USERPROFILE%\.codex\auth.json。如果你的用户名是中文,这个路径展开后就是C:\Users\张三\.codex\auth.json。我们要做两件事:一是把文件内容写成正确的 JSON 结构,二是确保写入和读取的编码一致。
先看auth.json的配置片段。Codex CLI 的鉴权结构通常包含 API Key 和可选的 Base URL 覆盖。下面是一个可复制的示例,字段名请以你当前 Codex 版本的文档为准,但结构大体一致:
{ "OPENAI_API_KEY": "sk-xxxxxxxxxxxxxxxxxxxxxxxx", "OPENAI_BASE_URL": "https://taotoken.net/api", "model": "gpt-4o" }注意几个点。第一,OPENAI_BASE_URL的值是https://taotoken.net/api,不要在后面加/v1,除非文档明确要求。第二,Key 和 URL 都用双引号,JSON 不允许单引号。第三,如果你用的是需要额外字段的版本,比如带tokens或last_refresh的结构,保留原有字段,只替换 Key 和 URL 的值。
接下来是路径转义。在 Windows 上,反斜杠\在 JSON 字符串里是转义字符,所以如果你要在配置里写路径,必须写成双反斜杠\\。比如:
{ "OPENAI_API_KEY": "sk-xxxxxxxxxxxxxxxxxxxxxxxx", "OPENAI_BASE_URL": "https://taotoken.net/api", "model": "gpt-4o", "log_path": "C:\\Users\\张三\\.codex\\codex.log" }这里的C:\\Users\\张三\\.codex\\codex.log才是合法的 JSON 字符串。如果你只写一个反斜杠,JSON 解析会报错,比如Invalid escape character。这是 CJK 用户名场景下特别容易踩的坑,因为路径里既有中文又有反斜杠,两个问题叠在一起。
那怎么保证文件本身是 UTF-8 编码?用 PowerShell 写入时显式指定编码:
$authPath = Join-Path $env:USERPROFILE ".codex\auth.json" $content = @' { "OPENAI_API_KEY": "sk-xxxxxxxxxxxxxxxxxxxxxxxx", "OPENAI_BASE_URL": "https://taotoken.net/api", "model": "gpt-4o" } '@ [System.IO.File]::WriteAllText($authPath, $content, [System.Text.Encoding]::UTF8)这段脚本的关键是最后一行用了[System.Text.Encoding]::UTF8,确保写入的是无 BOM 的 UTF-8。有些编辑器默认存成 GBK 或者带 BOM 的 UTF-8,Codex 读的时候就可能出问题。写完后你可以用下面命令确认文件存在且路径正确:
Test-Path $authPath Get-Content $authPath -Encoding UTF8如果Test-Path返回True,Get-Content能正常显示中文和 JSON 内容,说明文件层面没问题。如果返回False,那说明%USERPROFILE%展开的路径和你以为的不一样,这时候要检查系统环境变量里的USERPROFILE值。
还有一个细节:Codex CLI 有些版本会优先读环境变量OPENAI_API_KEY和OPENAI_BASE_URL,如果环境变量里设了旧值,会覆盖auth.json。所以改完文件后,顺手检查一下:
Get-ChildItem Env: | Where-Object { $_.Name -like "OPENAI*" }如果有输出,且值和你要用的不一致,就在当前会话里清掉或者改成新值。这一步能排掉很多「文件改了但没生效」的困惑。
4. 验证请求:用最小调用确认鉴权恢复正常
配置写完了,怎么知道鉴权真的通了?别急着跑完整任务,先用一个最小请求验证。最小请求的好处是:如果失败,报错信息干净,容易定位是 Key 问题、URL 问题还是编码问题。
最直接的方式是用curl打一次模型列表或者一次 chat completions。先试模型列表:
curl -s https://taotoken.net/api/models \ -H "Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxx"如果返回一段 JSON,里面有data数组和模型条目,说明 Key 和 Base URL 都对。如果返回401,看响应体里的error.message,通常是 Key 无效或者没带上。如果返回404,检查 Base URL 是不是写成了https://taotoken.net/api/v1这种多加了路径的形式。
再打一次 chat completions,确认模型也能调:
curl -s https://taotoken.net/api/chat/completions \ -H "Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 5 }'正常返回里会有choices数组,第一条的message.content可能是pong或者类似内容。如果这里报reading choices相关的错误,说明响应结构和你预期的不一样,可能是模型名写错了,或者该模型不支持这种调用方式。
curl 通了之后,再回到 Codex CLI 里验证。启动 Codex,让它执行一个最简单的任务,比如:
codex "print hello"观察输出。如果它正常返回结果,没有提示未登录,也没有乱码路径报错,那鉴权就恢复了。如果还是报错,把报错原文记下来,对照下一节的排查表。
这里有个经验:验证顺序一定是「先 curl 后 CLI」。因为 curl 绕过了 Codex 自身的路径和编码处理,能直接确认服务端鉴权是否正常。如果 curl 通了但 CLI 不通,问题就在本地配置或编码;如果 curl 也不通,问题在 Key 或 Base URL,跟 CJK 用户名无关。
另外,验证时尽量用同一个终端会话,避免环境变量在不同窗口里不一致。如果你在 PowerShell 里改了环境变量,记得新开窗口或者重新加载配置。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
这一节把 CJK 用户名场景下最容易撞到的几类报错列出来,对照着查。每一条都给出可能原因和动作。
先看401 Unauthorized。这个最直接,意思是鉴权没通过。可能原因有三个:Key 写错了、Key 过期了、请求没带上 Authorization 头。排查动作:用第 4 节的 curl 命令单独测 Key,确认 Key 本身有效。如果 curl 也 401,去控制台重新生成一个 Key。如果 curl 通了但 Codex 还 401,检查auth.json里的 Key 有没有被环境变量覆盖,或者文件里有没有多余空格。
再看local proxy failed。这个报错通常出现在 Codex 尝试通过本地代理转发请求时。可能原因是 Base URL 配置成了本地地址,或者系统代理设置干扰了请求。排查动作:确认OPENAI_BASE_URL是https://taotoken.net/api,不是http://localhost:xxxx。然后检查系统代理:
netsh winhttp show proxy如果有代理设置且你不需要,可以临时清掉再试。注意,这里说的是系统代理配置检查,不是让你去搭什么通道,只是排除本地网络设置对请求的干扰。
然后是reading choices类错误。这个报错说明 Codex 拿到了响应,但在解析choices字段时失败了。可能原因是响应不是预期的 JSON 结构,比如返回了 HTML 错误页,或者模型名不对导致服务端返回了错误格式。排查动作:用 curl 打一次 chat completions,看原始响应长什么样。如果返回的是{"error": ...},那就是模型名或参数问题。如果返回的是 HTML,那可能是 Base URL 路径不对,请求打到了别的端点。
最后是OAuth相关报错。Codex 某些版本支持 OAuth 登录流程,如果你之前用过 OAuth,auth.json里可能残留了 OAuth 的 token 字段,和 API Key 字段冲突。排查动作:打开auth.json,看有没有tokens、access_token、refresh_token这类字段。如果有,且你现在的目标是走 API Key 鉴权,就把这些字段删掉,只保留 Key 和 Base URL。删之前备份一份,万一要回滚。
为了更清楚,我把这几类报错整理成对照表:
| 报错关键词 | 可能原因 | 排查动作 |
|---|---|---|
| 401 Unauthorized | Key 错误/过期/未携带 | curl 单独测 Key,重新生成 |
| local proxy failed | Base URL 指向本地/系统代理干扰 | 确认 URL 为 taotoken.net/api,检查系统代理 |
| reading choices | 响应结构异常/模型名错误 | curl 看原始响应,核对模型名 |
| OAuth | auth.json 残留 OAuth 字段 | 删除 tokens 相关字段,保留 API Key |
还有一个和 CJK 用户名强相关的报错:路径乱码导致auth.json找不到。表现是报错里出现C:\Users\加乱码字符。排查动作:用echo $env:USERPROFILE确认实际路径,用Test-Path确认文件在不在。如果路径本身乱码,说明环境变量在某个环节被错误解码了,这时候可以临时把auth.json放到一个纯 ASCII 路径下,比如C:\codex-auth\auth.json,然后在配置里指向它,绕过 CJK 路径问题。
6. 把鉴权切到 TaoToken 后的长期使用建议
配置改完、验证通过之后,还有几件事值得做,避免下次升级或者换机器时又踩一遍。
第一,把auth.json的备份放在一个纯 ASCII 路径下。比如C:\codex-backup\auth.json。这样即使系统用户名是中文,恢复配置时也不受路径编码影响。备份时注意别把 Key 明文放到云盘同步目录,本地存一份就行。
第二,如果你经常在多个项目里切换模型,可以考虑用环境变量而不是改文件。在 PowerShell 里临时设置:
$env:OPENAI_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxx" $env:OPENAI_BASE_URL = "https://taotoken.net/api"这样只影响当前会话,不会污染auth.json。适合临时测试不同 Key 或不同模型的场景。但要注意,环境变量的优先级通常高于文件,所以设了之后记得在会话结束时清掉,或者新开窗口。
第三,关注 Codex CLI 的版本更新。有些编码相关的 bug 会在新版本里修掉,也有些新版本会改变auth.json的结构。升级后如果鉴权失效,先看 release notes 有没有提到配置格式变化,再对照本文的排查表走一遍。
第四,如果你在做长期编码或者 Agent 类任务,频繁调用模型,可以了解一下 Coding Plan 这类方案,它适合需要稳定额度和长期使用的场景。入口在 Coding Plan 页面,具体权益以页面说明为准。对于只是偶尔验证鉴权的场景,用按量计费的 API Key 就够了。
第五,养成看原始响应的习惯。不管是 curl 还是 Codex 的日志,遇到报错先看原始返回,别只看封装后的错误提示。原始响应里往往有error.message和error.type,能直接告诉你问题在哪。Codex 的日志路径可以在配置里指定,用第 3 节提到的log_path字段,指向一个纯 ASCII 路径,方便排查。
最后说一个实际经验:Windows CJK 用户名的编码问题,根源往往不在 Codex 本身,而在系统环境变量展开和文件读写的编码假设不一致。所以修复思路不是去改系统用户名(那影响太大),而是在配置层面显式指定编码、用纯 ASCII 路径做中转、用 curl 做独立验证。这三招组合起来,基本能覆盖绝大多数 CJK 场景下的鉴权读取失败。
如果你在排查过程中需要对照接口文档,可以看接入文档;需要生成或管理 Key,去 API Keys 页面;想先手动验证模型对话是否正常,用模型对话页面跑一次最小请求。这几个入口配合本文的步骤,能把「Windows CJK 用户名编码问题修复」这件事从头到尾走通。