news 2026/9/17 7:24:21

Codex 旧对话报 sub_lxapi not found?TaoToken 这样配统一通道

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Codex 旧对话报 sub_lxapi not found?TaoToken 这样配统一通道

Codex 从 sub_lxapi 切到 custom 后,旧会话一打开就报Model provider 'sub_lxapi' not found。这行报错后面通常还跟着一句“Codex 无法加载 config.toml”,看着像配置文件写坏了,于是不少人反复改 config.toml、删掉让它自动重建、把缓存清一轮,报错一字没变。TaoToken(https://taotoken.net/?utm_source=taotoken_aicg_blog_end)这条统一通道的接法可以把问题从源头掐掉:供应商名只写一次、写死成同一个 ID,之后换模型只在 TaoToken 侧动模型 ID,session 里记录的 provider 再也不变,新旧对话都不会因为“某次切换”翻车。

这篇不从修复脚本开头,而是从来路开头:先弄清 Codex 为什么会记住一个已经不存在的供应商名,再把这套“provider 名锁死”的接法落到config.toml上。

1. sub_lxapi not found 到底是谁在报

1.1 旧对话加载时,Codex 先去找 provider 定义

打开一个历史会话时,Codex 并不是直接读你现在的 config.toml 然后开工,而是先读这条会话自己记下的元信息:这条对话当时用的是哪个 provider。拿到名字以后,再去配置里找对应的 provider 定义,找到才继续加载模型、渲染上下文。

问题就出在这一步。旧会话里记的名字是sub_lxapi,而你在切换时把配置里的定义换成了custom,名字对不上,Codex 找不到对应的 provider 段,于是整条对话串加载失败。它顺手给出的那句“请修复 config.toml 中的问题”具有相当强的误导性——因为 config.toml 本身很可能完全正确,是会话记录和它对不上了。

1.2 provider 名其实记在四个地方

把“供应商名”当成一个值来追踪,会发现它同时落在四个位置,改一个不管用就是因为另外三个还留着旧值:

层级位置记录内容切换供应商后
第 1 层全局config.tomlprovider 定义与默认 provider用户可见,容易改,但单独改不够
第 2 层sessions/*.jsonl每条会话的session_meta里带 provider 名需要逐行修
第 3 层sqlite/state_5.sqlite状态库副本保一致性用,通常不被读
第 4 层根目录state_5.sqlitethreads 表里的 provider 字段关键,Codex 实际读这份

提示:原文里有价值的判断是读取优先级——根目录 SQLite 排在 session_meta 之前,而 config.toml 和环境变量都排在后面。所以“我 config.toml 明明改了”这句话,在这个报错面前没有说服力。

这也解释了为什么删 config.toml 完全无效:它是可再生的,而旧值躺在数据库和会话文件里。同理,清缓存也没用,缓存不负责存 provider 名。

2. 把供应商名固定成同一串,就不会再有残留

2.1 报错的本质是“名字变过一次”

sub_lxapi这个报错之所以出现,是因为过去某次切换时改变了一个长期标识:旧记录写的是 A,新配置写的是 B。凡是把“切换供应商”等同于“改变 provider 名”的用法,都会重复踩一次。

换个思路就简单了:让 Codex 认的 provider 名从第一天起就是固定的一个值,比如taotoken。新会话记taotoken,数据库 threads 表记taotoken,配置文件里定义也是taotoken,三处天然一致。以后你要从 A 模型换到 B 模型,改的是模型 ID,不是 provider 名,session 里的那串字符根本没动过,自然不存在“旧对话找不到 provider”。

2.2 换模型改哪一层:改 TaoToken 侧,不改 session

在这套接法里,需要你手工维护的只有两处:

  • config.toml里的model = "YOUR_MODEL_ID",用来指定当前默认模型;
  • TaoToken 控制台里可用模型的选择,也就是实际被调用的那个模型。

provider 名始终是taotoken[model_providers.taotoken]这一段也始终在。于是不管你是从便宜的模型换到强的模型,还是反过来,Codex 这边只是换了个字符串参数,历史会话记录的 provider 名一直有效,打开即加载。

一句话:把“切供应商”这个动作前置,之后就没有“切换”这回事了。

3. 在 config.toml 里把 Codex 指到 TaoToken 的通道

3.1 先准备两样东西:Key 和模型 ID

第一样是 API Key。打开 TaoToken 注册登录,进控制台创建一把 Key,文中一律用YOUR_API_KEY占位,真实 Key 只放本地,别粘进任何要提交的文件。

第二样是模型 ID。这个必须去模型广场看当时列出来什么就写什么,别照抄别人文章里的日期后缀或者自己拼一个出来——不存在的 ID 会在第一次请求时报错,而且报错信息往往不含“模型不存在”这几个字,容易误判成网络问题。

3.2 写~/.codex/config.toml

文件位置:

  • Windows:C:\Users\用户名\.codex\config.toml
  • macOS / Linux:~/.codex/config.toml

内容按下面这样写,重点是model_provider[model_providers.taotoken]的段落名必须完全一致:

# ~/.codex/config.toml model_provider = "taotoken" model = "YOUR_MODEL_ID" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY"

两个容易写错的地方:

  • base_url一律填https://taotoken.net/api,末尾不要加/v1。多这一层路径,请求会打到不存在的地址上。
  • 这里的地址是给工具用的接口地址,和你在浏览器里打开的落地页不是一回事,别把带查询参数的那串粘进来。注册、建 Key、看用量走落地页;填进工具的一律是https://taotoken.net/api

3.3 环境变量和 auth.json 怎么给 Key

env_key = "TAOTOKEN_API_KEY"的意思是“Key 从这个环境变量里读”,所以你还得把变量导出来:

# macOS / Linux export TAOTOKEN_API_KEY=YOUR_API_KEY # Windows PowerShell(当前窗口有效) $env:TAOTOKEN_API_KEY="YOUR_API_KEY" # Windows CMD(写入用户变量,重开终端后生效) setx TAOTOKEN_API_KEY "YOUR_API_KEY"

Codex 各版本对凭据的处理略有差别,有的版本会走~/.codex/auth.json。如果本地已经生成了这个文件,动它之前先把整个~/.codex目录复制一份备份,然后打开你机器上那份已有的 auth.json,照着它现有的字段结构填同一把 Key,别从别处抄一套字段名进来。改动凭据类文件之前先关掉 Codex,改完再启动。

注意:export只在当前终端窗口有效。关掉窗口再开,变量就没了,表现是“昨天还好好的,今天全部 401”。长期使用请写进 shell 的启动文件,或者用setx

4. 配完之后怎么验证新旧对话都能开

4.1 新会话先跑一条最小请求

重启 Codex,新开一个会话,让它做一件只涉及文本的事:解释一段 SQL 的写法,或者生成一段示例 SQL 供你参考,但不要执行。

这里有一条底线值得写清楚:Codex 这类工具默认不应该去直连你的库、你的生产机器执行操作。让模型生成 SQL、解释 SQL、对照改 SQL 都可以,真正要跑的时候,由你在本地终端或数据库客户端里执行,再把结果或者报错贴回对话里。这样既安全,也更容易定位问题到底出在模型输出还是出在你的环境。

4.2 打开一条切换前创建的老会话

分两种情况,别混着判断:

  • 如果这条老会话当初就是用taotoken这个名字创建的,它现在应该正常打开。
  • 如果它当初记的是sub_lxapi或者别的名字,那它还是会报同样的错,因为库里那条记录的名字没变过。这不是配置没配好,是历史遗留,交给第 5 章处理。

这套接法保证的是“从现在起不再产生新的残留”,而不是凭空把旧名字擦掉。

4.3 去控制台核对这次调用有没有记上

新会话能正常返回之后,打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 看一眼用量和调用记录,确认刚才那一次请求记在了你刚创建的那把 Key 上。这一步顺便把“Key 正确、Key 属于你、Key 有额度”三件事一次验完,比在 Codex 里反复试请求省事得多。

5. 已经踩了 sub_lxapi 的坑,怎么收尾

5.1 先只读检查,别急着改

老会话报错、你又想抢救,第一步是确认残留分布在哪一层,而不是直接替换字符串。先备份整个.codex目录,然后在本地终端里跑只读查询:

# 根目录数据库:Codex 实际读的那份 sqlite3 ~/.codex/state_5.sqlite \ "SELECT COUNT(*) FROM threads WHERE model_provider='sub_lxapi';" # 看看具体是哪几条会话 sqlite3 ~/.codex/state_5.sqlite \ "SELECT id, model_provider FROM threads WHERE model_provider='sub_lxapi' LIMIT 20;" # 会话文件里还有没有引用 grep -rl "sub_lxapi" ~/.codex/sessions | head

Windows 下把路径换成C:\Users\用户名\.codex\state_5.sqlite。这些 SQL 在你自己的终端里执行,不要让 AI 工具替你连库跑;模型可以帮你写 SQL、解释这条 SQL 在查什么,执行权留在你手上。

5.2 把旧值统一成一个稳定名字

思路是:先确认config.toml里已经有[model_providers.taotoken]这段定义,然后把旧记录里的名字统一改成taotoken。数据库两份都要动,根目录那份是关键,子目录那份是为了保持一致:

-- 根目录:Codex 实际读取 UPDATE threads SET model_provider='taotoken' WHERE model_provider='sub_lxapi'; -- 子目录副本:保持一致,避免下次又读出一份旧值 UPDATE threads SET model_provider='taotoken' WHERE model_provider='sub_lxapi';

会话文件要逐行处理,不要做全文替换——JSONL 里其他字段也可能出现同名字符串,全文替换会误伤。

#!/usr/bin/env python3 """把 Codex session 里的旧 provider 名改成统一名字,改前请备份 .codex 目录""" import json import pathlib OLD, NEW = "sub_lxapi", "taotoken" root = pathlib.Path.home() / ".codex" / "sessions" for path in root.rglob("rollout-*.jsonl"): raw = path.read_text(encoding="utf-8") out, changed = [], 0 for line in raw.splitlines(): try: item = json.loads(line) except json.JSONDecodeError: out.append(line) continue payload = item.get("payload") or {} if item.get("type") == "session_meta" and payload.get("model_provider") == OLD: payload["model_provider"] = NEW item["payload"] = payload changed += 1 out.append(json.dumps(item, ensure_ascii=False, separators=(",", ":"))) if changed: (path.parent / (path.name + ".bak")).write_text(raw, encoding="utf-8") path.write_text("\n".join(out) + "\n", encoding="utf-8") print(f"{path} 修改 {changed} 处")

改之前先把 Codex 完全退出。它在运行状态下可能把内存里的旧状态再写回数据库,刚改完就被覆盖,会让人误以为脚本没生效。

5.3 改完把 provider 名锁死,别再改它

清理完之后再打开那条老会话,通常就能正常加载了。接下来真正防止复发的动作只有一个:以后不管换什么模型,model_provider = "taotoken"这行别再动。要换的是model = "YOUR_MODEL_ID",以及 TaoToken 侧实际调用哪个模型。名字不变,sessions 和 state_5.sqlite 就不会再产生新的不一致。

6. 这套配置最容易踩的几个错

6.1 报 provider 找不到,但明明写了

多数时候是名字对不上:model_provider = "taotoken"[model_providers.taotoken]才是合法组合,写成[model_providers.taotoken_api]就会重新触发同款报错,只是名字从sub_lxapi换成了你新起的那个。改完配置一定回头对一遍这两处字符串是否完全一致,大小写也算。

6.2 401 和 404 分别指向不同的地方

401 基本是凭据问题:环境变量没导出、终端窗口重开后丢了、或者 Key 粘贴时带了空格。先在一个新终端里echo $TAOTOKEN_API_KEY(Windows 用echo $env:TAOTOKEN_API_KEY)确认变量真的有值。

404 更常见于路径写错:base_url末尾手滑加了/v1,工具本身又拼一次版本路径,请求就落到不存在的地址上。统一填https://taotoken.net/api即可。

6.3 第一次请求就报模型不存在

先怀疑模型 ID 抄错了。模型广场里的 ID 会变,别用几个月前文章里的字符串,也别自己拼日期后缀。以 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 上模型广场当时列出的名字为准,复制粘贴。

7. 接下来做两件小事

第一件,用同一把 Key 在 模型对话 里发一条消息,确认通道、Key、模型 ID 三样东西在当前状态下都对得上。这一步排掉的是环境问题,比在 Codex 里反复重开会话高效。

第二件,如果你接下来要长时间用 Codex 写代码,可以看一下 Coding Plan 的额度安排;需要新 Key 或者想给不同项目分不同 Key,在 控制台 API Keys 里建,建完记得顺手把环境变量也更新掉。如果你同时在用 Claude Code,环境变量对照可以看 Claude Code 接入文档,把 provider 名固定成同一个的习惯照搬过去,同样能省掉一批“切换后旧会话打不开”的麻烦。

回到那条老会话:名字统一、配置稳定之后,它加载靠的就是数据库里那串再也不会变的字符。真正需要长期维护的,只剩你自己的模型 ID 而已。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 7:20:43

蜂鸟拍摄全攻略:从选址到参数设置的系统方法论

我蹲了整整三个清晨,才拍到第一张蜂鸟翅膀完全定格的画面。那一刻我意识到,这个以“Colibri”命名的观察与拍摄项目,真正难的不是器材,而是理解它每秒扇动几十次翅膀背后的生存逻辑。如果你也对这类飞行速度极快、体型极小、又在花…

作者头像 李华
网站建设 2026/9/17 7:20:21

多智能体系统企业落地:Plan模式与主子Agent协作实战复盘

把多智能体系统真正接到企业业务里,和跑 Demo 是两码事。我们在售后工单自动处理这条链路里,从最初单 Agent 硬撑,到最后切换成 MultiAgent 架构,中间踩的坑比预想多得多。这篇复盘想重点讲两套机制:一套是 Plan 模式&…

作者头像 李华
网站建设 2026/9/17 7:20:10

Win11下解决SQL Server 2016安装0x851A001A错误

先跟遇到同样问题的朋友说一句:这个错误别怕,它比你想象的常见,也比你想象的容易解决。我在Windows 11上给一台新机器部署SQL Server 2016时,装到数据库引擎配置那一步,进度条突然停住,过一会儿弹出一个错误…

作者头像 李华
网站建设 2026/9/17 7:19:34

Windows Docker Desktop 安装与镜像构建全流程指南

Windows 上想跑容器,绕不开 Docker Desktop 这个桌面端工具,而真正让人卡住的往往不是 Docker 本身,而是从"装不上"到"装上了但起不来",再到"起来了却不知道镜像怎么建"。我自己从早期的虚拟化方案…

作者头像 李华