Codex with local Qwen3.8-27B over the Responses API
Codex can use a custom provider over the Responses wire. This guide shows the minimum profile, support boundary and our Qwen result in that harness.
Syntalith
Codex has a documented custom-model-provider surface. In an after-hours experiment on a home PC, we used it to connect the Codex client to Qwen3.8-27B behind patched vLLM. Transport, tools and compaction worked. The coding result still scored 87/100, against 100/100 for Qwen Code on the same endpoint.
The distinction matters: Codex supports the custom-provider configuration, but OpenAI does not thereby certify Qwen, the model weights or the patched vLLM instance. Re-run acceptance tests after a client or server update.
The profile we actually used
Official Codex documentation describes base_url, the key source and wire protocol. This is the measured profile with local paths and host identity removed:
# ~/.codex/qwen-vllm.config.toml
model = "qwen3.8-27b"
model_provider = "qwen_vllm"
model_context_window = 150000
model_auto_compact_token_limit = 120000
model_auto_compact_token_limit_scope = "total"
model_reasoning_effort = "medium"
tool_output_token_limit = 6000
[model_providers.qwen_vllm]
name = "Qwen3.8-27B through local vLLM"
base_url = "http://127.0.0.1:18020/v1"
env_key = "QWEN_VLLM_API_KEY"
wire_api = "responses"
request_max_retries = 1
stream_max_retries = 1
On another device, 127.0.0.1 should terminate a local tunnel to the GPU host rather than expose the port publicly. Put the key in QWEN_VLLM_API_KEY, outside TOML and Git, then launch the isolated profile:
export QWEN_VLLM_API_KEY="$(< ~/.config/qwen-vllm/api-key)"
codex --profile qwen-vllm
Codex documentation also says project-level .codex/config.toml cannot override model_provider or model_providers. Put the provider in user configuration or a separate profile file. A valid provider table in the wrong config layer otherwise looks mysteriously ineffective.
A five-minute gate before repository access
Once the model is running, check HTTP first:
curl -fsS http://127.0.0.1:18020/health
curl -fsS \
-H "Authorization: Bearer $QWEN_VLLM_API_KEY" \
http://127.0.0.1:18020/v1/models
Launch the profile in an empty disposable repository and use this exact task:
Createresult.jsonwithsource: "codex-qwen-smoke"andok: true. Validate it withjq -e '.source == "codex-qwen-smoke" and .ok == true' result.json. Change no other files.
That tiny task covers a Responses turn, tool call, file write, command result and clean completion. Our small-task cells took roughly 33 to 113 seconds. If this smoke exceeds five minutes, we stop and inspect transport or an agent loop instead of normalising the delay.
Then ask in the same session to change source to codex-qwen-resume and validate again. A fresh turn can work while resume is broken.
Two failures we actually saw
Wrong key. Sending the old llama.cpp key to vLLM produced HTTP 401. The runner initially risked treating a textual API error as a result. We changed it so a provider error is recorded as a failed run and excluded from model-quality scoring.
Session resume. In the llama.cpp profile, a fresh Codex turn worked while a resumed thread failed with System message must be at the beginning. Codex had placed a later developer message in history, while the Qwen template accepted system content only at the front. The corrected template collects system and developer content into the leading block. We separately verified a fresh turn, a system,user,assistant,developer,user history and a resume returning resumed-ok.
That is why /health alone is not an agent integration test.
The Codex result in the home experiment
On patched vLLM at 150k and medium effort on the home RTX 3090:
| Measure | Codex | Qwen Code |
|---|---|---|
| Score | 87/100 | 100/100 |
| Wall time | 1,150.42 s | 502.14 s |
| Compactions | 1 | 0 |
| Calls | 56 shell | 52 tools |
Codex built the project, passed focused tests and wrote documentation. Independent review found a material defect: a fallback described as deterministic could print a memory address for a pointer or channel. Its tests covered easier cases and missed that property.
Qwen Code was the better client in this cell. Codex remained a useful candidate and scored a full 5/5 on a small import where Qwen Code missed one validation rule. Let the task suite select the client. Brand preference has no place in acceptance.
A slimmer Codex profile
The full environment carried many instructions and skill descriptions. An isolated codex-qwen-vllm-slim profile reduced measured prompt input from 19,748 to 10,573 bytes, or 46.5%.
That result measures prompt footprint alone. It says nothing about quality. Less instruction can lower cost and free context for code while also removing a needed procedure. The profile needs a fresh scored task before it can be called better.
Safe operating pattern
- Use a separate Codex profile without changing the normal provider.
- Store the local key in a mode-
0600file. - Begin in a disposable worktree.
- Exclude deployment commands and secrets.
- Advertise the server's actual context limit.
- Independently test tool shape and session resume.
- Retain a tested profile or approved API as fallback.
- Re-run the smoke after every Codex, vLLM or chat-template update.
The home RTX 3090 served as a test bed. Syntalith's offer covers configuration, acceptance cases, permission controls, failure documentation and team training. The AI-Native course teaches teams to separate client, model and protocol. A free process scan determines whether a local profile is sensible and which controls it must pass.
Free process scan
Start with a free process scan.
- A 30-minute call with the engineer who would lead the work.
- A review of the processes that cost you the most time and money.
- A written summary of what to automate first and the likely cost range.
The scan chooses one process to assess, and within 2 business days you receive a recommendation, including when a simpler route is the better fit.
€0
30 minutes · written takeaway within 2 business days
Times are shown in your own time zone. We work with clients across time zones.
Describe the process in the form