Codex 本地接入排障:进程安静却无产出
作者记录将 Codex CLI 接入本地模型服务时遇到的三个集成缺陷,测试框架看似结束却没有产出。已展示的关键问题是 CLI 不再支持 chat 传输,需要对接 Responses API。
AI 深度解读
Codex 进程还在,测试脚本也像是在忙,却没有产出可验收的结果。作者给 agentpolicy 接入 Codex CLI 时,连续遇到传输协议、标准输入和请求路径三个问题。它们没有以清晰的失败结果结束测试,反而让排查停在了「看起来还在运行」。
这篇最有用的结论是:接通 AI 编程工具,不能只看进程有没有退出,还要确认请求去了哪里、响应有没有落盘、命令是否真的执行,以及权限限制到底由谁保证。
接口兼容,为什么仍然接不通
这次集成属于 agentpolicy v0.1.0 的实地测试。它是一个本地优先、基于 Cedar 的策略决策点,用规则判断 Agent 的动作应该放行、拒绝、询问人工、限流还是脱敏,并提供预置规则包。产品已上架 PyPI,安装命令是 pip install agentsec-agentpolicy。
作者首先踩中的坑,是把「兼容 OpenAI」理解成「继续走 chat completions 就行」。
原文记录,Codex 启动时明确拒绝了 wire_api = "chat",要求使用 OpenAI Responses API。作者的本地模型服务 oMLX 恰好原生支持 /v1/responses,但这个能力不是靠配置猜出来的,而是通过一次 curl 探测确认的:HTTP 200,加上真实的 resp_* 响应体。
因此,这次不需要额外的协议转换层。前提是服务端已经支持目标接口;不能据此推断,所有声称兼容 OpenAI 的服务都能直接接入。
另一个坑发生在地址拼接上。Codex 会在 provider 的 base_url 后追加 /responses。作者配置的是 http://127.0.0.1:PORT,最终请求落到了 /responses,而服务端实际提供的是 /v1/responses。
修正后的配置是 base_url = "http://127.0.0.1:PORT/v1"。
连续、即时、统一的 404,在这里指向的是请求路径错误。对接 Node 代理或本地模型网关时,排查应先还原完整 URL,再检查服务端路由,不能只盯着配置里的域名和端口。
进程还活着,为什么不能算测试在推进
第二个问题更容易把自动化脚本拖住。作者从测试脚本执行 codex exec,看到提示 Reading additional input from stdin...,随后程序一直等待,没有退出,也没有产生证据。
原因是 CLI 仍在读取标准输入,而父进程留下的输入连接没有结束。作者在无交互调用中加上 </dev/null,让读取立即遇到输入结束,才解除阻塞。
这里要区分两个概念:进程存活,只能证明它还没结束;测试推进,需要有可观察的工作产物。
作者把模型流量记录设成了硬性验收条件:每一组请求和响应都必须写入磁盘,否则用例失败。这条要求让那些「忙了半天却什么都没做」的运行暴露出来。
最终,Codex CLI 0.135.0 连接本机模型,没有使用 OpenAI key。中间的 Python 标准库日志代理 t1_proxy.py 捕获了经过清理的 4 组请求与响应,状态码全部为 2xx。
自动化测试需要证明工作已经发生。
不过,原文没有说明这些无产出运行最终靠什么超时机制终止,也没给出超时阈值。流量落盘能帮助验收和定位,仍不能单独解决无限等待的问题。
权限测试能证明多少,要看接入点允许多少
作者还做了一个比修配置更关键的取舍:没有强行让 Codex 的测试长得像 Claude Code。
按原文描述,Claude Code 提供可以暂停的逐次调用审批 hook,策略引擎可以接进人工确认流程;本次 Codex 无交互集成可用的控制面,则是沙箱、配置文件和执行命令,包括 --sandbox read-only。
因此,作者把验证拆成了两部分。
第一部分检查真实执行结果:allow 对应一次实际执行并打印内容的 cat;deny 对应破坏性命令被阻止,目标目录和其中的 keep.txt 保持完整,Agent 随后重新规划。
第二部分检查策略结果的一致性:同样的 3 条命令,在执行前交给引擎判断,审计文件记录的 allow、escalate、deny 与进程内引擎一致。
这两部分证明的东西不同。前者证明这次环境下的执行与拦截结果,后者证明决策记录一致。它们没有证明 Codex 已经接入可暂停的人工审批闭环。
尤其不能把「沙箱挡住了命令」直接写成「策略引擎在每次执行前完成了拦截」。作者承认接入边界,是这组测试有价值的地方。
我的判断
我赞同作者把证据放在进程状态前面,也赞同先测单层再组合:先通过 evaluate 验证策略,再用 curl 验证代理,最后让 CLI 经过代理访问模型。这样每一步的失败范围都比较明确。
但标题和开头的表述比正文更绝对。启动阶段其实出现了不支持 wire_api = "chat" 的明确提示,路径错误也返回了 404。更准确的教训是:测试脚本没有把这些信号及时转成清晰的失败结论,而不是整个过程完全没有错误信号。
这也是一次特定版本、特定本地服务的实测。原文没有给出其他 CLI 版本、其他模型服务或不同测试方案的对照数据,所以「每次组合都重新探测」属于有实践依据的工程经验,不能包装成量化验证过的收益。
相比另写一套模拟审批流程,这种按真实控制面收缩验证范围的做法更可信。代价也要写清楚:决策一致性、沙箱限制和逐次人工审批,仍是三个不同的验收目标。
能拿来做什么
- 给日常 AI 编程脚本接入模型服务前,先用
curl验证实际端点、状态码和响应结构,并记录 CLI 版本,避免沿用旧配置。 - 在不需要输入的
codex exec自动化调用中使用</dev/null,同时设置明确的超时和失败条件,避免 CI 只剩一个持续旋转的状态。 - 调试 Node 转发代理时,记录客户端最终请求的完整路径,并检查请求与响应是否成对保存;统一 404 时先核对
/v1和/responses的拼接。 - 给 Agent 权限集成写验收条件时,分别检查引擎决策、真实命令结果和人工审批能力。涉及拒绝执行的用例,还应检查目标文件是否完整保留。