oMLX の opencode 接続定義
本書では、tsd-omlx の構成を前提に、devcontainer 内の opencode から Mac ホスト上の oMLX を利用するための設定方法を定義する。
1. 位置付け
oMLX は OpenAI 互換の /v1/* API を提供する。SpecDojo の opencode 連携では、opencode.json の custom provider 方式で OpenAI 互換 API に接続する。Ollama への接続(tsd-ollama-opencode)と同じ方式であり、両方の provider を併存させられる。
本書の対象は次のとおり。
- opencode から oMLX の Ornith-1.5 35B または Qwen3.6 35B-A3B を利用したい
- 2 つの opencode agent から同じモデルを並列に使いたい
- 既存の Claude、Codex、Ollama などの provider を残したまま、oMLX を追加したい
2. 前提条件
事前に tsd-omlx の手順で、次が完了していることを前提とする。
- Mac ホスト上の oMLX が、Admin UI で待ち受けを
0.0.0.0:8000、API key ありに設定され、メニューバーから起動されていること mlx-works/Ornith-1.5-35B-A3B-oQ4e-mtpがダウンロード済みで、Model Aliasornith-1.5-35bが設定されていることmlx-community/Qwen3.6-35B-A3B-4bitがダウンロード済みで、Model Aliasqwen3.6-35b-a3bが設定されていること- devcontainer 内から
http://host.docker.internal:8000/v1/modelsでモデル一覧を取得できること
3. 接続方式
opencode.json の custom provider で接続先を明示する。oMLX は API key が必須のため、API key の扱いが Ollama(apiKey: "not-needed")と異なる。
API key は opencode.json に直接書かない。opencode の credential store に保存する。
- opencode を起動し、
/connectを実行する。 Otherを選ぶ。- Provider ID に
omlxを入力する。 - API key に、Mac ホストの oMLX Admin UI で設定した API key と同じ値を入力する。
4. opencode.json 設定
4.1. provider 追加方針
既存の provider を置き換えず、omlx を追加して併存させる。Provider ID は、/connect で入力した値(omlx)と一致させる。
baseURL は OpenAI 互換 API のルートである http://host.docker.internal:8000/v1 を指定する。Chat Completions の個別の URL(/v1/chat/completions)は書かない。
4.2. 設定例
プロジェクトの opencode.json の provider に、次を追加する。既存の設定へ merge する。
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"omlx": {
"npm": "@ai-sdk/openai-compatible",
"name": "oMLX",
"options": {
"baseURL": "http://host.docker.internal:8000/v1",
},
"models": {
"ornith-1.5-35b": {
"name": "Ornith 1.5 35B-A3B oQ4e",
"limit": {
"context": 65536,
"output": 8192,
},
"options": {
"chat_template_kwargs": { "enable_thinking": false },
"top_k": 20,
"min_p": 0.05,
"presence_penalty": 0.0,
"repetition_penalty": 1.0,
},
},
"qwen3.6-35b-a3b": {
"name": "Qwen3.6 35B-A3B 4bit",
"limit": {
"context": 131072,
"output": 32768,
},
"options": {
"chat_template_kwargs": {
"enable_thinking": true,
"preserve_thinking": true,
},
"temperature": 0.6,
"top_p": 0.95,
"top_k": 20,
"min_p": 0.0,
"presence_penalty": 0.0,
"repetition_penalty": 1.0,
},
},
},
},
},
}limit の各値は次の方針で決める。
| モデル | limit.context | limit.output | 方針 |
|---|---|---|---|
| Ornith | 65536 | 8192 | thinking を使わないため、tool call 単位の編集にも、grade の 23 観点の判定にも十分な出力とする |
| Qwen3.6 | 131072 | 32768 | 公式が thinking 能力の維持に推奨する 128K context と、通常の問い合わせに推奨する 32K output を確保する |
opencode は limit.context から limit.output を差し引いた量を入力に使える量とみなし、超えそうになると会話を圧縮(compaction)する。Ornith は約 57K、Qwen3.6 は約 98K を入力に使える。
4.3. サンプリングと thinking
各モデルのサンプリングの値と thinking の有無は、opencode の設定で指定する。oMLX はリクエストで指定された値を、Admin UI のモデル設定より優先する。Admin UI の値は、opencode を介さないリクエストのための既定値として、tsd-omlx の「モデル設定」で同じ値にそろえる。
モデル全体の値は、opencode.json のモデルの options に書く。opencode はこれをリクエストの本文へそのまま加える。Ornith は既存の実測に基づいて thinking を無効にする。Qwen3.6 は公式の agent 用推奨に従い thinking と過去ターンの thinking の保持を有効にし、precise coding tasks 向けの値を使う。
| 項目 | 値 | 方針 |
|---|---|---|
chat_template_kwargs.enable_thinking | false | thinking を使わない。2026-10-04 の計測で、thinking ON は約3倍遅く、判定が甘く、検証の通過率も上がらなかった |
top_k | 20 | Qwen 系の推奨値 |
min_p | 0.05 | 確率の低いトークンを外し、中国語の字体や崩れた語の混入を抑える |
presence_penalty | 0.0 | 上げると言語の混在が増える |
repetition_penalty | 1.0 | executor の文の書き写しや、コードで同じ字句を繰り返すことを妨げないよう無効にする |
Qwen3.6 固有の値は次のとおり。
| 項目 | 値 | 方針 |
|---|---|---|
chat_template_kwargs.enable_thinking | true | Qwen3.6 の既定動作を維持する |
chat_template_kwargs.preserve_thinking | true | agent の過去ターンの reasoning を保持し、重複した reasoning を減らす |
temperature | 0.6 | precise coding tasks 向けの公式推奨値 |
top_p | 0.95 | precise coding tasks 向けの公式推奨値 |
top_k / min_p | 20 / 0 | precise coding tasks 向けの公式推奨値 |
presence_penalty / repetition_penalty | 0.0 / 1.0 | coding での言語混在や、正当な字句の繰り返しへのペナルティを避ける |
Qwen3.6 の temperature と top_p はモデルの options に置く。agent 定義はモデル名ではなく役割ごとに共用するため、モデル固有の値を .opencode/agents/*.md へ置かない。
OpenCode agent の temperature は役割ごとの frontmatter で指定し、どのモデルでも同じ役割の値を使う。opencode は agent の値をリクエストで送る。
| agent role | temperature | 方針 |
|---|---|---|
opencode-executor | 0.2 | 通常の編集・検証向け |
opencode-expert-executor | 0.2 | thinking を伴う複雑な編集・検証向け |
opencode-grade-executor | 0.3 | grade など厳密な出力形式を求める作業向けに、確率の低い候補を選びにくくする。grade の判定(根拠と finding)は英語で出力する。英語では日本語より判定が厳しくなり、中国語の字体が混ざらなかった(2026-10-04、検証通過 5/6) |
opencode-review-executor | 0.1 | 多観点 review 向け |
opencode-expert-review-executor | 0.1 | thinking を伴う多観点 review 向け |
opencode-reporter | 0.1 | 渡された内容を構造化結果へ写すだけのため、ほぼ決定的にする |
opencode の reasoningEffort は、oMLX では thinking の切り替えに使われない。thinking を agent ごとに変える場合は、agent の frontmatter に chat_template_kwargs を書く。agent の値は opencode.json の値より優先される。
chat_template_kwargs:
enable_thinking: true.opencode/AGENTS.md は日本語での回答を求めるが、agent の定義が出力の言語を指定する場合はそれを優先する。計測の経緯と結果は prj-0001:pjr-vqb5-agent-grade-comparison の「ornith の executor の改善(2026-10-04)」に記録している。
4.4. 既定のモデルにする場合
既定のモデルにする場合は、トップレベルに次を追加する。
{
"model": "omlx/ornith-1.5-35b",
}最初は既定のモデルにせず、/models から選んで、Ollama の Gemma / Qwen と比べてから決める。
Qwen3.6 を既定にする場合は、model を omlx/qwen3.6-35b-a3b にする。
5. 接続確認
opencode で /models を実行し、次のように表示されれば認識できている。
oMLX
Ornith 1.5 35B-A3B oQ4e
Qwen3.6 35B-A3B 4bit次に、tool call を伴う短い依頼で動作を確かめる。
- ファイルの読み取り: 「このリポジトリの package.json を読んで、npm test で実行されるコマンドだけ答えてください。」
- shell の実行: 「npm test を実行してください。失敗した場合は原因だけ報告し、まだファイルは修正しないでください。」
ファイルの読み取り、shell の実行、tool call、reasoning、最終回答が正しく分かれていればよい。
失敗した場合は、まず tsd-omlx の「devcontainerからの接続」の curl による確認に戻る。curl が通らない状態で opencode 側だけを調べても、切り分けにならない。
6. 2つのagentの並列実行
2 つの opencode を、別々の worktree で起動する。同じ作業ツリーを 2 つの agent で同時に編集しない。
cd /workspaces/specdojo-workspace/worktrees/task-a
opencodecd /workspaces/specdojo-workspace/worktrees/task-b
opencode両方で同じモデル(omlx/ornith-1.5-35b または omlx/qwen3.6-35b-a3b)を選び、oMLX の Admin UI で Concurrent Requests が 2 になっていることを確認する。
7. 使い分け
| 担当 | 向いている作業 |
|---|---|
| Ornith(oMLX) | 既存コードの調査、小~中規模の実装、テストの修正、lint の修正、仕様 Markdown とコードの同期、単純なリファクタ、速度を優先する並列タスク |
| Qwen3.6(oMLX) | repository-level reasoning、tool call を伴う agentic coding、長めの文脈を使う実装、Ornith との品質比較 |
| Claude Code / Codex | 大規模な設計判断、複数の仕様にまたがる高度な整合性の判断、難しい根本原因の解析、大規模なリファクタの最終レビュー、セキュリティに関わる変更、ローカル LLM の結果のレビュー |
Claude / Codex
│
├─ 難しい設計・レビュー
│
└─ Orchestrator
│
├─ local agent A
└─ local agent B8. Qwen3.8との比較
tsd-omlx の「段階的な最適化」のフェーズ1では、Ollama の Qwen3.8(tsd-ollama-opencode)と同じ実タスクで比べる。公平に比べるため、同じ commit から始める。
タスクの例は次のとおり。
- 既存の仕様を読み、関連するコードを修正し、テストを実行して仕様の Markdown も更新する。
- 既存のテストの失敗の原因を調べ、最小の変更で直す。
- 3~5 ファイルにまたがる小規模な機能を追加し、テストとドキュメントまで完了する。
比較する項目は、総時間、Prompt / Prefill、Generation、thinking の量、tool call の回数、テストの成功、修正漏れ、不要な変更、人間が修正にかけた時間とする。最も重視する指標は、人間が最終的に作業を完了するまでの総時間である。
Qwen3.6 は thinking を有効にし、Thinking Budget を設定しない。同じ Qwen 系の Ornith では、grade の計測で thinking を有効にすると約3倍遅くなり、判定の質と出力形式の安定性も上がらなかった(prj-0001:pjr-vqb5-agent-grade-comparison)。agentic coding の比較では thinking の量と総時間を必ず記録する。grade など厳密な出力形式を求める用途に Qwen3.6 を使う場合は、計測してから採否を決める。
9. 運用上の注意
9.1. model 名の整合
opencode.json の models のキーは、oMLX の Model Alias(ornith-1.5-35b、qwen3.6-35b-a3b)と一致させる。一致しない場合、Chat Completions のリクエストがエラーになる。alias を変えた場合は、opencode.json も合わせて更新する。
9.2. API key の管理
API key は opencode の credential store に保存する。Mac ホストでは oMLX が ~/.omlx/settings.json に永続化するため、このファイルや API key を opencode.json、Git、またはリポジトリ内のファイルに書かない。
9.3. oMLX の起動確認
Mac ホスト側で oMLX が止まっていると、devcontainer からの接続はタイムアウトになる。接続できない場合は、Mac ホスト側で次を確認する。
- メニューバーで oMLX サーバーが起動中であること
- Admin UI のサーバー全体の設定で、待ち受けが
0.0.0.0、ポートが8000、API key が設定済みであること - 設定変更後にメニューバーからサーバーを再起動したこと
- Mac ホストで、tsd-omlx の「devcontainerからの接続」の確認を接続先
http://127.0.0.1:8000で実行し、モデル一覧を取得できること(API key はread -sで読み込み、確認後にunsetで破棄する) - devcontainer が Docker Desktop 上で動いていること
host.docker.internalを名前解決できること:getent hosts host.docker.internal