闫志恒 / Codex GPT-5.6-Sol 没有终端工具,我是这样修好的

Created Wed, 29 Jul 2026 21:30:00 +0800 Modified Wed, 29 Jul 2026 14:39:04 +0000

最近给 Codex 配置 gpt-5.6-sol 时,我遇到了一个有点奇怪的问题:同一台电脑、同一个 Codex,其他模型都能正常调用终端,只有这个模型一直提示“当前会话未提供终端调用工具”。

一开始我怀疑过 PowerShell、环境变量,甚至重新检查了 shell_type。最后才发现,问题并不在终端本身,而是在自定义模型 catalog 里。

这篇文章记录的是自定义模型 catalog 和中继服务环境下的实测结果。tool_modeuse_responses_lite 等字段并不是 Codex 公开配置文档承诺的稳定接口,不同供应端或版本的行为可能不同。

问题出在哪里

当时 gpt-5.6-sol 的配置里同时存在下面几个字段:

{
  "shell_type": "shell_command",
  "tool_mode": "code_mode_only",
  "use_responses_lite": true
}

虽然已经声明了 shell_type,实际请求仍然进入了没有注入本地终端工具的路径。我的处理方式是保留 shell_type,关闭 lite 请求,并删除 tool_mode

{
  "shell_type": "shell_command",
  "use_responses_lite": false
}

修改后还需要新建一个 Codex 任务。已有任务的工具列表不会随 catalog 文件动态刷新。

找到当前生效的 catalog

Codex 的个人配置通常在:

%USERPROFILE%\.codex\config.toml

自定义 catalog 的路径由 model_catalog_json 指定。不要根据文件名猜,也不要照搬别人电脑上的完整路径,可以直接从配置中读取:

$codexHome = Join-Path $HOME '.codex'
$config = Join-Path $codexHome 'config.toml'

$match = Select-String `
  -Path $config `
  -Pattern '^model_catalog_json\s*=\s*"([^"]+)"$'

if (-not $match) {
  throw 'config.toml 中没有找到 model_catalog_json'
}

$catalogRelative = $match.Matches[0].Groups[1].Value
$catalog = Join-Path $codexHome $catalogRelative
$catalog

官方配置文档也将 model_catalog_json 描述为启动时加载的可选模型目录覆盖项。因为配置是在启动时读取的,所以改完后新建任务是很重要的一步。

先检查,不要直接修改

找到文件后,先看看目标模型当前有哪些字段:

$json = Get-Content -Raw -LiteralPath $catalog | ConvertFrom-Json

$json.models |
  Where-Object { $_.slug -eq 'gpt-5.6-sol' } |
  Select-Object slug, shell_type, tool_mode, use_responses_lite

我当时看到的是:

slug               : gpt-5.6-sol
shell_type         : shell_command
tool_mode          : code_mode_only
use_responses_lite : True

这也解释了为什么单纯补上 shell_type 没有解决问题。

备份并修复

下面这段脚本只修改 gpt-5.6-sol 对象,并在原目录生成一份带时间戳的备份:

$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$backup = "$catalog.bak-5.6sol-terminal-$timestamp"
Copy-Item -LiteralPath $catalog -Destination $backup

$json = Get-Content -Raw -LiteralPath $catalog | ConvertFrom-Json
$model = $json.models |
  Where-Object { $_.slug -eq 'gpt-5.6-sol' } |
  Select-Object -First 1

if (-not $model) {
  throw "没有在 $catalog 中找到 gpt-5.6-sol"
}

$model | Add-Member `
  -NotePropertyName shell_type `
  -NotePropertyValue shell_command `
  -Force

$model | Add-Member `
  -NotePropertyName use_responses_lite `
  -NotePropertyValue $false `
  -Force

$model.PSObject.Properties.Remove('tool_mode')

$json |
  ConvertTo-Json -Depth 100 |
  Set-Content -LiteralPath $catalog -Encoding UTF8

Write-Host "已修复:$catalog"
Write-Host "备份位置:$backup"

ConvertTo-Json 会重新排版整个文件,但不会改变 JSON 的数据结构。如果很在意原文件格式,也可以只手工修改目标模型对象。

验证修改结果

先确认 JSON 仍能正常解析,再查看目标字段:

$verified = Get-Content -Raw -LiteralPath $catalog | ConvertFrom-Json

$verified.models |
  Where-Object { $_.slug -eq 'gpt-5.6-sol' } |
  Select-Object slug, shell_type, tool_mode, use_responses_lite

预期结果是:

shell_type         : shell_command
tool_mode          :
use_responses_lite : False

一定要用新任务实测

关闭旧任务,新建一个使用 gpt-5.6-sol 的任务,然后发送:

请调用终端运行 Get-Location,然后只返回终端输出。

也可以用 CLI 单独验证:

codex exec -m gpt-5.6-sol --skip-git-repo-check `
  "请调用终端运行 Get-Location,然后只返回终端输出。"

成功时,日志中应该能看到类似内容:

model: gpt-5.6-sol
exec
pwsh.exe -Command Get-Location
succeeded

如果 codex.exe 命中了 WindowsApps 入口并提示拒绝访问,可以先检查自己的配置是否记录了实际 CLI 路径,再使用那个完整路径执行命令。

为什么旧任务还是不能用

这是这次排障里最容易让人误判的一点。

模型 catalog 在任务启动时读取,可用工具也在那时确定。修改文件只能影响之后创建的任务,不能给已经存在的任务动态补上 shell_command

因此可以这样判断:

  1. CLI 新会话能调用终端,说明 catalog 修改已经生效。
  2. 旧任务仍然提示没有终端工具,并不代表修复失败。
  3. 新建任务后恢复正常,问题就算真正解决了。

如果以后再次出现

Codex 更新、中继服务或 catalog 同步程序都可能重新生成模型目录。问题复发时,我会按下面的顺序检查:

  1. 重新读取 config.toml 中当前生效的 model_catalog_json
  2. 检查 gpt-5.6-solshell_typetool_modeuse_responses_lite
  3. 修复后新建任务,不在旧任务里反复测试。
  4. 最后做一次真实的终端调用,而不只是检查 JSON。

如果修改后引发了其他问题,直接把之前生成的备份复制回原 catalog 即可。回滚之后同样需要新建任务。

最后

这次问题最迷惑的地方,是配置里明明已经有 shell_type = shell_command,看起来终端能力应该存在。真正影响行为的却是另外两个不太显眼的字段。

所以遇到“某个模型没有终端工具”时,不必先重装 PowerShell 或 Codex。先确认问题是否只发生在单个模型,再检查当前实际生效的 catalog,通常能少走不少弯路。

参考:Codex Configuration Reference