1. 背景
本次目标是在 macOS 上让 OpenAI Codex CLI 使用 Ollama 本地模型,例如:
qwen2.5-coder:7bqwen3:8bdeepseek-r1:8b-0528-qwen3-q4_K_Mgemma4:latestglm-4.7-flash:latestllama3.2:latestgpt-oss:20b
最终目标是让 Codex 作为真正的本地 coding agent 使用,即能够:
- 读取项目文件
- 执行 shell 命令
- 修改文件
- 跑测试
- 总结执行结果
而不是只做普通聊天或代码解释。
2. 环境信息
2.1 初始版本
codex --version
# codex-cli 0.130.0
ollama --version
# ollama 0.24.0
2.2 更新后版本
codex --version
# codex-cli 0.135.0
2.3 硬件环境
从 Ollama 日志可见:
system memory total="24.0 GiB"
gpu memory available="15.5 GiB"
GPU name: Apple M4
机器内存为 24GB,GPU 为 Apple M4,适合运行中等规模本地模型,但对 20B 模型和大上下文仍需要谨慎控制。
3. 最终可用方案概览
最终跑通的方案是:
Codex CLI 0.135.0
↓
自定义 Codex profile
↓
Ollama /v1/responses
↓
gpt-oss-codex:20b
↓
Ollama 派生模型,num_ctx = 16384
最终启动命令:
codex --profile ollama-local
最终成功标志:
• Ran pwd && ls -la
这说明 Codex 已经真正调用了本地 shell 工具,而不是普通聊天回复。
4. 关键问题总结
本次问题不是单一问题,而是多个问题叠加。
4.1 问题一:部分模型不支持 Codex 所需的 tools
例如:
codex --oss -m deepseek-r1:8b-0528-qwen3-q4_K_M
返回:
does not support tools
结论:
该 deepseek-r1 本地模型可以用于普通推理聊天,但不能作为 Codex agent 使用。
Codex 需要模型支持工具调用,例如:
- shell
- 文件读取
- 文件修改
- 测试运行
如果模型不支持 tools,就无法作为 Codex agent。
4.2 问题二:部分模型会伪造工具调用 JSON
例如:
codex --oss -m qwen2.5-coder:7b
执行:
执行 pwd,然后执行 ls -la。不要修改文件。
模型返回类似:
{
"name": "send_input",
"arguments": {
"target": "explorer1",
"message": "Please use the shell command..."
}
}
这不是 Codex 真正执行工具,而是模型把工具调用格式当成普通文本输出。
结论:
qwen2.5-coder:7b 可以用于代码问答,但当前不适合作为 Codex agent。
4.3 问题三:部分模型只会解释命令,不会执行命令
例如:
codex --oss -m llama3.2:latest
输入:
执行 pwd,然后执行 ls -la。不要修改文件。
模型返回:
pwd 是 print working directory
ls -la 是列出文件
它没有真正执行命令。
结论:
llama3.2:latest 在该场景下只是普通聊天模型,不适合作为 Codex agent。
4.4 问题四:ollama launch codex 会写入旧格式配置
执行:
ollama launch codex
会自动写入:
[profiles.ollama-launch]
openai_base_url = "http://127.0.0.1:11434/v1/"
model_provider = "ollama-launch"
forced_login_method = "api"
[model_providers.ollama-launch]
name = "Ollama"
base_url = "http://127.0.0.1:11434/v1/"
wire_api = "responses"
但 Codex 0.134+ 不再接受这种旧式 profile 写法。
报错:
--profile `ollama-launch` cannot be used while ~/.codex/config.toml contains legacy `profile = "ollama-launch"` or `[profiles.ollama-launch]`
结论:
当前不要使用 ollama launch codex。
应该改为手动创建独立 profile 文件。
4.5 问题五:wire_api = "chat" 已不再支持
尝试创建:
wire_api = "chat"
Codex 0.135.0 直接报错:
wire_api = "chat" is no longer supported.
How to fix: set wire_api = "responses"
结论:
Codex 0.135.0 只能使用 wire_api = "responses"。
因此不能通过 Chat Completions API 回退,只能解决 /v1/responses 的兼容问题。
4.6 问题六:本地模型简单 function_call 成功,但 Codex 真实请求失败
多个模型通过手写 curl 测试可以返回 function_call,例如:
curl http://localhost:11434/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-oss:20b",
"input": "执行 pwd",
"tools": [
{
"type": "function",
"name": "shell",
"description": "Run a shell command",
"parameters": {
"type": "object",
"properties": {
"command": {
"type": "string"
}
},
"required": ["command"]
}
}
],
"tool_choice": "auto"
}'
返回:
{
"type": "function_call",
"name": "shell",
"arguments": "{\"command\":\"pwd\"}"
}
这说明模型本身支持基础 tools。
但 Codex 真实运行时仍然返回:
502 Bad Gateway
url: http://localhost:11434/v1/responses
原因是:
Codex 真实 agent 请求比手写 curl 请求复杂得多。
Codex 会发送:
- 系统提示词
- agent 规则
- sandbox 规则
- 工具 schema
- skill 描述
- 当前项目上下文
- 模型 metadata
- 执行策略
所以简单 curl 成功,并不代表 Codex 一定能跑通。
5. 最终根因
通过查看 Ollama 日志,定位到核心问题:
truncating input prompt limit=4096 prompt=5664 keep=4 new=4096
[GIN] ... | 500 | 10.00s | POST "/v1/responses"
同时日志中还有:
KvSize:4096
这说明:
Ollama 当前给 gpt-oss:20b 开的上下文窗口只有 4096。
而 Codex 发来的真实 prompt 长度大约为:
5664 tokens
超出了 4096,于是被截断。
被截断之后,Ollama /v1/responses 无法正常完成 Codex 的 agent 请求,最终返回 500,Codex 侧表现为:
502 Bad Gateway
因此最终根因是:
Codex 真实 agent prompt 超过 Ollama 模型默认 4096 上下文窗口,导致 prompt 被截断,进而引发 /v1/responses 500/502。
6. 最终解决方案
6.1 创建大上下文 Ollama 派生模型
创建 gpt-oss-codex:20b:
cat > /tmp/Modelfile.gpt-oss-codex <<'EOF'
FROM gpt-oss:20b
PARAMETER num_ctx 16384
EOF
ollama create gpt-oss-codex:20b -f /tmp/Modelfile.gpt-oss-codex
这里的关键是:
PARAMETER num_ctx 8192
它把上下文从默认 4096 提升到 8192。
6.2 保持主配置干净
文件:
~/.codex/config.toml
内容:
approval_policy = "on-request"
sandbox_mode = "workspace-write"
oss_provider = "ollama"
[projects."/Users/an/.codex"]
trust_level = "trusted"
[tui.model_availability_nux]
"gpt-5.5" = 1
注意不要在主配置里放:
[profiles.ollama-launch]
也不要放:
profile = "ollama-launch"
否则 Codex 0.135.0 会报 legacy profile 错误。
6.3 创建独立 Codex profile
文件:
~/.codex/ollama-local.config.toml
内容:
model = "gpt-oss-codex:20b"
model_provider = "ollama-local"
model_context_window = 8192
model_max_output_tokens = 2048
[model_providers.ollama-local]
name = "Ollama Local"
base_url = "http://localhost:11434/v1"
wire_api = "responses"
requires_openai_auth = false
关键点:
model = "gpt-oss-codex:20b"
model_context_window = 8192
wire_api = "responses"
requires_openai_auth = false
不要加:
forced_login_method = "api"
因为它会强制 Codex 使用 OpenAI API Key 登录,不适合本地 Ollama provider。
6.4 启动 Codex
codex --profile ollama-local
测试:
执行 pwd,然后执行 ls -la。不要修改文件。
成功结果:
• Ran pwd && ls -la
这说明 Codex 已经真正执行 shell 工具。
7. 模型测试结果汇总
| 模型 | 测试结果 | 结论 |
|---|---|---|
qwen2.5-coder:7b |
输出伪 tool JSON | 不适合作为 Codex agent |
qwen3:8b |
简单 tools curl 成功,但 Codex 502 | 可能受上下文限制影响,可后续用大上下文再测 |
deepseek-r1:8b-0528-qwen3-q4_K_M |
明确 does not support tools |
不能作为 Codex agent |
gemma4:latest |
Codex 502 | 当前不建议继续 |
glm-4.7-flash:latest |
简单 tools curl 成功,但 Codex 502 | 可能受上下文限制影响,可后续用大上下文再测 |
llama3.2:latest |
只解释命令,不执行 | 不适合作为 Codex agent |
gpt-oss:20b |
简单 tools curl 成功,但默认 4096 上下文导致 Codex 502 | 需要派生为大上下文模型 |
gpt-oss-codex:20b |
成功执行 pwd && ls -la |
当前推荐方案 |
8. 为什么一开始 gpt-oss:20b 也失败
一开始直接运行:
codex --oss -m gpt-oss:20b
报:
502 Bad Gateway
原因不是 gpt-oss:20b 不支持 tools,而是:
默认上下文窗口是 4096。
Codex 真实 prompt 是 5664。
prompt 被截断。
截断后 /v1/responses 返回 500。
Codex 侧显示 502。
所以正确做法不是换模型,而是:
创建 num_ctx 更大的派生模型。
9. 关于两个警告
9.1 Model metadata not found
启动时出现:
Model metadata for `gpt-oss-codex:20b` not found. Defaulting to fallback metadata.
这是正常的。
原因:
gpt-oss-codex:20b 是通过 ollama create 创建的派生模型。
Codex 没有内置它的 metadata。
只要能执行工具,这个警告可以先忽略。
9.2 Skill descriptions were shortened
出现:
Skill descriptions were shortened to fit the 2% skills context budget.
这不是错误。
它表示:
Codex 为了控制上下文,把部分 skill 描述压缩了。
这和之前的 4096 截断不同。
之前是整个 prompt 超出模型上下文,导致 /v1/responses 500。
现在是 Codex 自己压缩 skill 描述,仍然可以正常执行工具。
10.3 使用时尽量从项目目录启动
不要总是在:
~/.codex
里启动。
应该进入你的实际项目目录,例如:
cd ~/Documents/Project/your-project
codex --profile ollama-local
这样 Codex 的工作目录就是当前项目,执行命令和读取文件才有意义。
10.4 不要再使用 ollama launch codex
当前不建议使用:
ollama launch codex
原因:
它会自动写入旧格式 [profiles.ollama-launch]。
Codex 0.135.0 会因此报 legacy profile 错误。
推荐统一使用:
codex --profile ollama-local
11. 推荐日常启动命令
可以在 ~/.zshrc 中加 alias:
alias codex-local='codex --profile ollama-local'
加载配置:
source ~/.zshrc
以后在项目目录中直接执行:
codex-local
12. 推荐验证流程
每次换模型或改配置后,按以下顺序测试:
12.1 基础工具测试
执行 pwd,然后执行 ls -la。不要修改文件。
成功标志:
• Ran pwd && ls -la
12.2 文件读取测试
阅读当前目录的 README.md 或 config.toml,总结内容。不要修改文件。
成功标志:
Codex 能读取真实文件内容并总结。
12.3 文件写入测试
创建一个 test_codex_local.txt,写入 hello codex local,然后读取文件确认内容。
成功标志:
Codex 能创建文件并读取确认。
12.4 项目级测试
阅读当前项目结构,告诉我主要模块。不要修改文件。
成功标志:
Codex 能调用 find / ls 等命令,并基于真实项目文件总结。
13. 常见故障排查
13.1 仍然出现 502
查看 Ollama 日志:
tail -80 /opt/homebrew/var/log/ollama.log
重点搜索:
tail -100 /opt/homebrew/var/log/ollama.log | grep -iE "error|panic|unsupported|tool|schema|responses|500|502|truncating|invalid|fail"
如果看到:
truncating input prompt limit=8192 prompt=xxxx
说明 8192 仍然不够,需要提升到 16384。
13.2 出现 legacy profile 报错
检查:
grep -R "profile\|profiles" ~/.codex
如果看到:
[profiles.ollama-launch]
从 ~/.codex/config.toml 中删除。
Codex 0.134+ 不应再把 profile 写在主配置中,应该使用:
~/.codex/<profile-name>.config.toml
13.3 出现 API key login is required
检查 profile 中是否有:
forced_login_method = "api"
如果有,删除。
本地 Ollama provider 应该使用:
requires_openai_auth = false
13.4 出现 wire_api = chat 不支持
不要使用:
wire_api = "chat"
Codex 0.135.0 已经不支持。
应该使用:
wire_api = "responses"
14. 最终推荐配置备份
14.1 主配置
cat > ~/.codex/config.toml <<'EOF'
approval_policy = "on-request"
sandbox_mode = "workspace-write"
oss_provider = "ollama"
[tui.model_availability_nux]
"gpt-5.5" = 1
EOF
如果你需要信任某个项目目录,可以在 Codex 中选择信任,或者手动添加:
[projects."/path/to/project"]
trust_level = "trusted"
14.2 本地 Ollama profile
cat > ~/.codex/ollama-local.config.toml <<'EOF'
model = "gpt-oss-codex:20b"
model_provider = "ollama-local"
model_context_window = 8192
model_max_output_tokens = 2048
[model_providers.ollama-local]
name = "Ollama Local"
base_url = "http://localhost:11434/v1"
wire_api = "responses"
requires_openai_auth = false
EOF
14.3 Ollama 派生模型
cat > /tmp/Modelfile.gpt-oss-codex <<'EOF'
FROM gpt-oss:20b
PARAMETER num_ctx 8192
EOF
ollama create gpt-oss-codex:20b -f /tmp/Modelfile.gpt-oss-codex
14.4 启动命令
codex --profile ollama-local
15. 最终结论
本次问题的最终根因不是:
Codex 没装好
Ollama 没启动
gpt-oss 不支持 tools
模型不会调用工具
真正根因是:
Codex 真实 agent prompt 超过了 Ollama 默认 4096 上下文窗口。
Ollama 将 prompt 从 5664 截断到 4096。
截断后 /v1/responses 返回 500。
Codex 侧表现为 502 Bad Gateway。
最终解决方式是:
基于 gpt-oss:20b 创建 num_ctx=8192 的派生模型 gpt-oss-codex:20b,
并通过 Codex 独立 profile 使用该模型。
最终命令:
codex --profile ollama-local
最终成功标志:
• Ran pwd && ls -la
这表示 Codex 已经成功通过 Ollama 本地模型执行 shell 工具,说明本地 Codex agent 链路已经跑通。