
在第 15 节的 Mock Responses WebSocket Server 能验证 Tool Call 循环但响应是写死的验不了真实模型行为。要让源码构建出的 codex 二进制观察真实 Agent Turn我把模型服务接到 TaoToken官网落地页是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 。本文接着原文的调试主线只做一件事在~/.codex/config.toml里把model_provider指到 TaoToken用https://taotoken.net/api作为 Base URL再用RUST_LOGcodex_coredebug跑一次exec最后用just log确认调用进了 SQLite。调试环境里最怕的不是代码错而是不知道错在哪一层。Mock 把模型层完全摘掉剩下的是纯本地代码问题一旦切回真实模型认证、请求路由、模型 ID、响应格式全都会参与进来这些恰恰是 Agent 卡住的高发原因。TaoToken 在这里的角色是一个统一 API 通道把多模型接入收窄成一个 Key、一个 Base URL、一个模型 ID。1. 从 Mock 到真实模型调试环境缺的不是代码是模型服务1.1 Mock Responses WebSocket Server 验证了什么原文章节 15.2 的脚本scripts/mock_responses_websocket_server.py做的事情很巧妙第一次模型请求返回 Shell Tool Callcodex 执行工具后发送第二次请求Mock Server 再返回最终 Agent Message。它让本地代码不依赖外部服务就能跑完“模型、工具、模型”的完整调度循环。排障时先用它可以确认协议层、工具执行层、Turn 循环本身没有断裂。但 Mock 的边界也很清楚它不会根据ls的输出决定下一步读取哪个文件也不会在 Agent 走偏时表现出真实模型的任意性。你看到的是一个固定的脚本响应不是模型真实推理的产物。更重要的是真实模型请求涉及的认证Key 是否有效、Base URL请求是否被路由到能处理的网关、模型 ID是否真实存在于模型广场这三件事Mock 全部绕过了。1.2 真实模型请求的三件套真实 Turn 循环只需要三样东西一个有效的 API Key一个 codex 能识别并接受请求的 Base URL一个存在于模型列表里的模型 ID。对于从源码构建出的 codex这三样统一从~/.codex/config.toml的model_providers配置读取不需要改一行 Rust 代码。这也是源码调试环境里最值得先确认的一点你构建出的二进制和官方发布版走的是同一条配置读取路径。接下来把模型服务这一层切到 TaoToken就是改配置不是改代码。2. 把 codex 的模型供应商指到 TaoToken2.1 先拿 Key再谈调试打开 TaoToken 注册进入控制台创建 API Key。创建后你会得到一把类似YOUR_API_KEY的密钥。注意这个 Key 通常只完整显示一次复制后直接放进环境变量不要提交进 Git也不要写进任何会同步到外部的配置文件。使用 TaoToken 的原因很实际codex 源码构建出的二进制需要一个统一接入不同模型的 API 通道。你只需要一个 Key 和一个 Base URL之后想换模型就换模型 ID认证与请求转发由通道处理。它解决的是“多服务商、多 Key、多 Base URL”切来切去的问题而不是绕过任何平台的限制。2.2 修改 ~/.codex/config.tomlCodex CLI 从~/.codex/config.toml读取模型供应商配置。如果目录还不存在先创建mkdir -p ~/.codex然后在~/.codex/config.toml中加入model 从TaoToken模型广场复制的模型ID model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api responses逐项解释model模型 ID 不猜、不复制别人博客里的旧 ID。去 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的模型广场看当时的列表复制一个真实存在的 ID。model_provider指定使用下面哪个model_providers配置块这里命名成taotoken。base_url填https://taotoken.net/api。特别注意末尾不要加/v1。很多兼容接口的文档要求/v1结尾但 TaoToken 的接口路径就是/api结尾多加一层路径会返回 404。env_key告诉 codex 从哪个环境变量读取 Key这里用TAOTOKEN_API_KEY。wire_api按模型类型选responses或chat。以模型广场对应模型支持的类型为准不确定就先用responses试如果日志里出现协议解析错误再改回chat。接着在 shell 里设置环境变量export TAOTOKEN_API_KEYYOUR_API_KEYYOUR_API_KEY是从前一步创建的真实 Key不是字面量。不同版本的 codex 对model_providers的字段名严格程度不同如果某个版本的配置解析报 “unknown field”去codex-rs对应 crate 里搜base_url的 serde 定义字段名以你源码版本为准。2.3 先验证 Key 和模型 ID再验证 codex 配置不要急着跑完整对话。先在 TaoToken 模型对话 里用同一把 Key 发一条消息。这样可以拆开两层问题Key 和模型 ID 是否有效属于账号层codex 能不能正确组请求属于本地代码层。模型对话能通再回 codex 调模型对话也报错那就先去控制台重新创建 Key或者换模型广场里的另一个模型 ID。模型对话验证通过后再确认本地配置被读到cd codex-rs ./target/debug/codex --version如果 config.toml 有 TOML 语法错误codex 启动时会直接报出来如果model_provider指向的配置块不存在也会在加载阶段失败。这两类问题在进入网络请求前就会被拦截是成本最低的检查。3. 用 RUST_LOG 跑通第一次真实 Turn3.1 用 exec 模式不用 TUITUI 适合人机交互但调试时会把日志和界面混在一起。exec 模式更适合第一次验证一个 Prompt一个退出码日志干净。从源码构建出的二进制直接执行cd codex-rs RUST_LOGcodex_coredebug \ ./target/debug/codex exec 只回复 READY为什么要设RUST_LOGcodex_coredebug原文已经提到按 Target 设置级别不要一开始就全局 trace。codex_core是 Agent Session 所在 crateTurn 循环的调度、模型请求、工具调用都从这一层经过。debug 级别能看到请求是否发出、响应是否收到、工具结果是否回填。如果第一次调用日志很少先确认环境变量在同一个 shell 里、TAOTOKEN_API_KEY真的被导出、config.toml 里env_key的名字和实际环境变量名一致。Codex 读的是TAOTOKEN_API_KEY不是OPENAI_API_KEY。3.2 debug 日志里应该出现什么一次正常的真实 Turn日志大致会经过这几个阶段模型请求发出能看到模型 ID 和请求体摘要。模型返回文本或 Tool Call。工具执行如果有Shell Tool 的 stdout 和 stderr 被收集回来。第二次模型请求带回工具结果。最终 Agent Message 生成exec 结束。实际调试时最常见的问题不是日志没有而是日志里直接出现401 Unauthorized或404 Not Found。401 说明 Key 没被正确读取或 Key 无效404 说明 Base URL 或模型 ID 不对。这两个报错在下一节展开。3.3 用 just log 确认调用进了 SQLitecodex 会把结构化日志写入本地 SQLite。原始文章里提到根目录的just log配方跑完 exec 后执行just log它启动 codex-state 的logs_client按时间、Thread、级别查看结构化日志。这次 exec 应该能看到Turn 开始、模型请求、工具调用、Turn 结束这几条记录。至此源码调试环境才算真正通不再依赖 Mock 的固定响应而是通过https://taotoken.net/api发真实请求又能从 SQLite 日志还原整个过程。如果 exec 第一次就报 401 或 404又不想反复改 codex 配置可以先用 TaoToken 的 CLI 单独验一次通道npm install -g taotoken/taotoken taotoken cc -k YOUR_API_KEY -u https://taotoken.net/api -m YOUR_MODEL_ID这条命令用同一个 Base URL、同一把 Key、同一个模型 ID 发一次直连请求。它能正常返回说明问题在 codex 本地配置它也报 401/404说明 Key、Base URL 或模型 ID 至少有一个不对。这个办法能把“通道问题”和“本地 codex 配置问题”快速切开。4. 接入真实模型后401、404、无日志各查各的层4.1 401Key 没被读到或 Key 无效现象debug 日志里出现401 Unauthorized。排查步骤执行echo $TAOTOKEN_API_KEY确认环境变量真的存在且不是空字符串。检查~/.codex/config.toml的env_key TAOTOKEN_API_KEY和实际环境变量名完全一致。如果配置是在 codex 进程启动后改的需要重新启动进程。CLI 每次执行都读新配置不用太担心缓存但 App Server 等常驻模式必须重启。去官网控制台确认 Key 没有被删除或停用。你还可以在模型对话里用同一把 Key 发一条消息模型对话能通问题就在 codex 侧读取 Key 的方式模型对话也报 401直接重新创建 Key。4.2 404多余的 /v1或模型 ID 不在列表里现象日志里出现404 Not Found。404 有两个高发来源。第一个是 Base URL 尾部多了/v1。如果你填成https://taotoken.net/api/v1请求会被路由到不存在的路径返回 404。删掉末尾的/v1只保留https://taotoken.net/api。第二个是模型 ID 不存在或已下架。codex 会把 config.toml 里的model原样放进请求体TaoToken 再按模型广场的列表路由。模型广场改过列表或者你从旧文章复制了一个已经下架的 ID就会 404。去 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的模型广场复制当时列表里的 ID不要用记忆里的 ID。4.3 请求发出但一直转圈debug 日志几乎没有输出如果RUST_LOGcodex_coredebug下没有任何请求日志先确认跑的是不是 exec 而不是 TUI。TUI 会启动 App Server日志写入 TUI 自己的路径和 exec 的 stdout/stderr 不一致。调试早期统一用codex exec等 exec 通了再回 TUI。如果 exec 模式下也没有日志检查RUST_LOG的 target 名。codex_core对应 crate 名大小写要一致。可以在源码里搜tracing::debug!所在的模块路径确认 target 到底是什么。4.4 认证和路由都通了但响应空白或一直调用工具能走到这一步说明 Key、Base URL、模型 ID 三件套都正常。剩下的问题是模型行为差异有的模型在 Agent 场景里倾向于频繁调用工具有的模型会一口气返回长文本。这属于模型选择差异不是配置错误。回模型广场换一个模型 ID再跑一次exec 只回复 READY用最短响应判断模型是否适合当前调试任务。调试源码时优先选响应快、工具调用稳定的模型而不是能力最强的模型。源码调试需要的是可重复、可观察一次回答多惊艳并不重要。5. 把 Mock 和真实模型放进同一套调试流程5.1 两个工具的分工Mock Responses WebSocket Server 不要废弃。它和 TaoToken 负责的是不同阶段改 Rust 代码怀疑协议或工具调度有问题用 Mock。固定响应、不依赖网络、不消耗任何真实请求。怀疑模型适配层、认证流程、Turn 循环行为用真实模型走 TaoToken。调试时先 Mock 后真实成本最低。Mock 跑通说明本地代码基本可用切真实模型后所有新报错大概率落在 Key、Base URL、模型 ID 这三项里。这个排查顺序和原文章节 15 讲“隔离问题”的思路一致只是把“模型服务”从 Mock 替换成了真实通道。5.2 对应原文练习补一个真实模型验证练习原文章节 17 有五个练习这里补一个第六个练习专门验证真实模型接入第一步进入 Cargo Workspace 并确认构建产物存在cd codex-rs cargo build -p codex-cli --bin codex第二步先用 Mock 跑一次最小 exec确认本地 Tool Call 循环正常。按原文方式启动 Mock 脚本把模型地址指向 Mock Server。第三步切到真实模型export TAOTOKEN_API_KEYYOUR_API_KEY RUST_LOGcodex_coredebug ./target/debug/codex exec 只回复 READY第四步查 SQLite 日志just log对比两次日志你能看到 Mock 响应和真实模型响应在 Turn 循环上的差别Mock 的 Tool Call 是脚本写死的真实模型会根据工具结果决定是否继续调用工具。这个差别就是“隔离模型依赖”和“观察真实 Agent 行为”之间的分界线。验证跑通后建议去 TaoToken 模型对话 里再用同一把 Key 发一条消息比对模型对话返回和 codex exec 返回是否一致。如果一致说明 codex 发出的请求和模型对话页面走的是同一套认证和路由逻辑。长期写代码可以看 Coding Plan 是否覆盖调用量Key 不够时在 控制台 API Keys 创建。TaoToken 的接口 Base URL 固定是https://taotoken.net/api官网落地页仍是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 一个管配置一个管账号与用量别混。真实模型请求跑通后你手里的源码调试环境已经能观察完整 Turn 循环认证、请求路由、模型响应、工具调用、结构化日志落库每一层都可审计。下一步进入codex-rs/cli/src/main.rs时看到的就不再是静态代码而是每一段都可以用这套环境实测的运行时行为。