1. WSL Ubuntu 里跑 Codex CLI 到底卡在哪:401 与 local proxy failed 的真实场景
很多人第一次在 Windows 上折腾 Codex CLI,路径基本一致:装 WSL、装 Ubuntu、装 Node.js、npm install -g @openai/codex,然后codex一敲,终端要么甩一个401 Unauthorized,要么来一句local proxy failed,接着就是无限转圈。你以为是网络问题,重启 WSL 没用;你以为是 Key 填错,反复粘贴还是 401。问题往往不在“能不能连”,而在 Codex CLI 的配置结构和你填的字段对不上。
Codex CLI 这个工具本质是一个跑在终端里的编码 Agent,它能读你的项目文件、按AGENTS.md的约定改代码、进 Plan mode 先规划再动手。它适合谁?适合习惯命令行、想让 AI 直接在自己仓库里干活的后端和全栈开发者。它不适合只想在网页里聊天的人,因为它的价值在于“读写本地文件 + 执行命令”这条链路。
在 WSL Ubuntu 下,这条链路有三个容易断的点。第一,Node.js 版本太老,Codex CLI 依赖较新的运行时,nvm没装好就会在全局安装时静默失败。第二,~/.codex/config.toml里的model_provider和base_url没对齐,CLI 拿着默认的 OpenAI 地址去请求,自然 401。第三,auth.json的字段名写错,比如写成api_key而不是OPENAI_API_KEY,CLI 读不到凭证,就会报代理层失败。
我试过最典型的一次:config.toml 里base_url写成了带/v1/结尾又重复拼了一次,结果请求打到.../v1/v1/responses,返回 404,CLI 把它包装成local proxy failed。所以这篇不聊虚的,直接把 WSL Ubuntu 下 Node.js 环境、Codex CLI 安装、config.toml 与 auth.json 的可复制片段、以及验证 DeepSeek 模型调用的完整命令走一遍,顺带把 401 和 local proxy failed 的排查表给你。
先明确一个概念:Codex CLI 通过model_providers声明“我要用哪个兼容 OpenAI 协议的服务”。TaoToken 提供的就是这种兼容层,你只要把base_url指向https://taotoken.net/api,再把专用 Key 填进auth.json,CLI 就会把请求发到 TaoToken,由它转发到 DeepSeek 等模型。理解这一点,后面所有配置都是围绕“声明 provider + 提供凭证”这两件事展开的。
2. 前置准备:WSL Ubuntu 装 Node.js 与 Codex CLI 的完整链路
这一节把地基打牢。WSL 的安装网上教程很多,核心就三步:管理员 CMD 里wsl --install -d Ubuntu,装完wsl --set-default-version 2确保是 WSL2,然后wsl进系统。这里不展开,重点放在进 Ubuntu 之后的 Node.js 环境,因为 Codex CLI 的报错有一半来自运行时。
进 Ubuntu 后先别急着apt install nodejs,系统源里的版本通常偏旧。用nvm管理版本最稳。先装 nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash source ~/.bashrc command -v nvmcommand -v nvm能打印出nvm就说明装好了。如果没输出,检查~/.bashrc末尾有没有 nvm 的加载脚本,没有就手动补上再source。接着装一个较新的 LTS 版本,比如 22:
nvm install 22 nvm use 22 nvm alias default 22 node -v npm -vnode -v应该输出v22.x.x,npm -v输出10.x以上。这里有个坑:如果你之前用apt装过 node,which node可能指向/usr/bin/node,和 nvm 的路径冲突。用which node确认它指向~/.nvm/versions/node/...,不是就nvm use 22重新切。
Node.js 就绪后装 Codex CLI:
npm install -g @openai/codex@latest codex --versioncodex --version能打印版本号就说明 CLI 本体没问题。如果这一步报EACCES权限错误,说明 npm 全局目录权限不对,别用sudo npm install -g,那会把文件装到 root 下,后面codex命令可能找不到。正确做法是给 npm 配一个用户级全局目录:
mkdir -p ~/.npm-global npm config set prefix ~/.npm-global echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc source ~/.bashrc npm install -g @openai/codex@latest装完确认~/.codex目录存在,不存在就mkdir -p ~/.codex。这个目录是 Codex CLI 读配置和凭证的地方,后面所有文件都放这里。到这一步,环境层面就干净了,剩下的全是配置对齐问题。
3. 可复制配置:config.toml 与 auth.json 接入 TaoToken 的完整片段
这一节是全文核心,直接给可复制的片段。Codex CLI 读两个文件:~/.codex/config.toml声明模型和 provider,~/.codex/auth.json放凭证。两个文件缺一不可,字段名必须完全一致。
先写config.toml。用cat覆盖写入,注意<< 'EOF'的单引号,它能防止 shell 变量被提前展开:
cat > ~/.codex/config.toml << 'EOF' model_provider = "taotoken" model = "deepseek-chat" model_reasoning_effort = "medium" network_access = "enabled" disable_response_storage = true [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" wire_api = "responses" requires_openai_auth = true EOF逐字段说明。model_provider = "taotoken"必须和下面[model_providers.taotoken]的段名一致,这是最常见的 401 来源之一——上面写taotoken,下面写duckcoding,CLI 找不到 provider 就用默认地址。model = "deepseek-chat"是你要调用的模型 ID,换成 DeepSeek 的其他模型就改这里。base_url指向https://taotoken.net/api,注意不要自己再拼/v1,wire_api = "responses"会处理路径。requires_openai_auth = true表示需要凭证,CLI 会去读auth.json。
再写auth.json:
cat > ~/.codex/auth.json << 'EOF' { "OPENAI_API_KEY": "你的TaoToken专用Key" } EOF字段名是OPENAI_API_KEY,不是api_key,也不是token。Codex CLI 沿用了 OpenAI 的凭证字段名,写错就报 401。Key 从 TaoToken 控制台的 API Keys 页面生成,生成后立刻复制,页面刷新后可能不再完整显示。把你的TaoToken专用Key替换成真实 Key,注意保留双引号。
两个文件写完后,用cat检查一遍:
cat ~/.codex/config.toml cat ~/.codex/auth.json确认base_url没有多余斜杠、model_provider和段名一致、auth.json是合法 JSON(可以用python3 -m json.tool ~/.codex/auth.json校验)。JSON 里多一个逗号、少一个引号,CLI 都会读失败,然后报一个和凭证无关的错,让你误以为是网络问题。
如果你同时想保留多个 provider,比如一个直连、一个走 TaoToken,可以在config.toml里写多个[model_providers.xxx]段,然后用model_provider切换当前用哪个。但auth.json只有一个OPENAI_API_KEY,多 provider 场景下要确认当前 provider 用的就是这把 Key。对大多数只接 TaoToken 的人来说,单 provider 最省心。
4. 验证请求:用 Codex CLI 调用 DeepSeek 并确认预期输出
配置写完,先别急着进项目。在任意目录下敲:
codex第一次启动会进交互界面。如果配置正确,你会看到 CLI 加载了taotokenprovider 和deepseek-chat模型,光标停在输入框等待你说话。这时候输入一句最简单的测试:
用一句话说明你当前使用的模型名称。预期输出是模型返回一句中文,里面提到 DeepSeek 或 deepseek-chat。如果它回的是 GPT 相关的内容,说明model字段没生效,CLI 还在用默认模型,回去检查config.toml的model行有没有拼错。
想更直接地验证,用非交互模式跑一条命令:
codex exec "输出当前工作目录下的文件数量"codex exec是 Codex CLI 的一次性执行模式,适合脚本化验证。预期它会读取当前目录、返回文件数量,并在终端打印执行过程。如果这一步成功,说明从 WSL 到 TaoToken 再到 DeepSeek 的整条链路是通的。
再验证一次带文件读写的场景。在空目录里建一个hello.js:
mkdir -p ~/codex-test && cd ~/codex-test echo 'console.log("hi")' > hello.js codex exec "把 hello.js 里的输出改成 Hello Codex,并加上中文注释"预期 Codex 会修改hello.js,把输出改成Hello Codex,并加一行中文注释。改完cat hello.js能看到变化。这一步验证的是 Agent 的读写能力,比单纯对话更能说明问题。
如果你在交互模式里想切换 Plan mode,按shift+tab。Plan mode 下 Codex 不直接改代码,而是先分析项目、提澄清问题、给实施方案。验证阶段建议先用普通模式确认链路通,再进 Plan mode 做真实需求。
验证通过后,建议在项目根目录放一个AGENTS.md,把项目概述、技术栈、约定和禁止事项写进去。Codex 每次新对话会读它,相当于给 Agent 一份长期记忆。比如约定“新增代码必须加中文注释”“文件行尾用 CRLF”“不要自动更新 AGENTS.md”,这些规则写进去后,Agent 的行为会稳定很多。
5. 本篇常见错排查:401、local proxy failed 与 reading choices 对照表
这一节按真实报错来。你遇到的错误信息基本逃不出下面几种,对照着查。
401 Unauthorized。最常见的原因是auth.json字段名写错,或者 Key 本身无效。先确认字段是OPENAI_API_KEY,再确认 Key 是从 TaoToken 控制台新生成的、没有多余空格。用python3 -m json.tool ~/.codex/auth.json校验 JSON 合法性。如果 Key 没问题,检查config.toml里requires_openai_auth是不是true,写成false时 CLI 不会带凭证,也会 401。
local proxy failed。这个报错通常不是网络断,而是请求路径拼错或 provider 配置不一致。检查base_url是不是https://taotoken.net/api,有没有多写/v1或结尾斜杠。再检查model_provider的值和[model_providers.xxx]的段名是否完全一致,大小写也要对。如果wire_api写成chat而服务端按responses处理,也会触发这个错。
reading choices 相关报错。这类错误说明请求发出去了、也拿到了响应,但 CLI 解析响应结构时对不上。常见于wire_api和实际返回格式不匹配。确认wire_api = "responses",如果换成chat后报错变化,说明服务端返回的是另一种格式,按实际调整。
OAuth 相关报错。Codex CLI 某些版本会尝试走 OAuth 流程,如果你用的是 API Key 模式,确保requires_openai_auth = true且auth.json存在。如果 CLI 提示登录,检查是不是装成了需要账号登录的版本,用codex --version确认版本,必要时回退到稳定版。
命令找不到 codex。npm install -g后codex命令不存在,多半是 npm 全局目录不在 PATH 里。按第 2 节的用户级全局目录方案重配,或者nvm use 22后重装。
版本回退。如果新版本行为异常,先看历史版本:
npm view @openai/codex versions --json然后装指定版本:
npm install -g @openai/codex@0.x.x把0.x.x换成列表里的版本号。回退后重新codex --version确认。
排查时有个通用顺序:先cat两个配置文件确认内容,再codex --version确认 CLI 正常,然后codex exec跑一条最简命令看报错。报错信息里的关键词直接对应上面的条目,别一上来就重装 WSL,那是最没必要的操作。
6. 长期编码与 Agent 场景:把 Codex CLI 用顺的几个实用习惯
链路通了之后,真正决定效率的是使用习惯。Codex CLI 不是一次性问答工具,它是能长期待在你仓库里的 Agent,所以配置和约定要一次做对。
第一,AGENTS.md要当项目文件维护。每次新增功能测试通过后,让 Codex 把变更同步进去,但明确告诉它“不要自己更新 AGENTS.md”,由你确认后再手动或显式让它更新。这样避免 Agent 在你不注意时改掉约定。
第二,Plan mode 用在需求模糊的时候。按shift+tab进入后,Codex 会先给方案再动手,适合重构、加模块这类影响面大的改动。小改动直接普通模式更快。
第三,模型 ID 按需切换。config.toml里的model字段改成 DeepSeek 的其他模型就能换,不用改base_url。如果你有多个 provider,用model_provider切换,但记得auth.json的 Key 要对应。
第四,凭证和配置分离。config.toml可以进版本库(不含敏感信息),auth.json绝对不要提交。Key 泄露了就去 TaoToken 控制台吊销重发。
如果你打算把 Codex CLI 用在日常编码和 Agent 任务上,长期跑的话可以了解下 Coding Plan,它更适合高频调用场景。需要生成和管理 Key 就去 API Keys 页面,接入细节看接入文档。想先验证模型对话效果,模型对话页面可以直接试。把这些配好,WSL Ubuntu 下的 Codex CLI 就是一个能读你代码、按你约定干活的终端搭档,401 和 local proxy failed 也会变成可查可解的普通配置问题。