結論には賞味期限がある — LM Studio 0.4.12 で Qwen3.5 が静かに動くようになっていた話
TL;DR: 3 日前 (v1.8.1) に「Qwopus3.5 (Qwen3.5 + Opus 蒸留) は llama.cpp が qwen35 architecture 未対応で詰み、フレームワーク本体の対応待ち」と書いた。今日 LM Studio の changelog を覗いたら 0.4.12 で Qwen 3.6 サポート + Qwen 3.5 性能改善 + Anthropic 互換 /v1/messages 公式化 が入っていて、Staff Picks の GGUF タブには Qwen3.5 9B / 35B A3B が並んで いた。「フレームワーク待ち」って書いた 6 日後には、フレームワークが追いついていた。実機検証で Qwen3.5 9B (qwen35 Dense) と Qwen3.6 35B-A3B (qwen35moe MoE) の 2 つの architecture が共に完全動作 + CodeRouter から kind: anthropic で adapter 翻訳ゼロ接続 + Anthropic prompt caching まで成立 することを確認 (cache_read_input_tokens: 280 観測)。CodeRouter として examples/providers.yaml に LM Studio provider 4 種類 + test profile 2 種類を追加。「結論には賞味期限がある」というメタ教訓を 4 連作の最後に追加。
検証追加: 2026/04/27 22:00
あらすじ — 4 連作になりました
第 1 話 (v1.8.1)ガチで動かしてみたら 3 連敗した話 — note 推奨の Qwen3.6 / Qwopus3.5 / Gemma 4 を Ollama 経由で動かして 3 連敗、「先回り実装より実機 evidence」原則確認
第 2 話 (v1.8.2)自分が作った診断ツールに自分が騙された話 — Gemma 4 は実は完全動作していて、CodeRouter の doctor probe が偽陽性を出していた、メタ教訓「diagnostic ツール自身も diagnostic され続ける必要がある」第 3 話 (v1.8.3)Ollama で詰んだ Qwen3.6 を llama.cpp で動かしたら、自分の診断ツールがもう 1 つ偽陽性を出してた話 — Qwen3.6 + llama.cpp 直叩きで native tool_calls 確認、tool_calls probe にも同じバグ pattern が残っていた active-harmful 誤診断を発見
第 4 話 (本記事 v1.8.4)「フレームワーク待ち」の前提が崩れた話 — LM Studio 0.4.12 が Qwen 3.6 + Qwen 3.5 + Anthropic 互換を一気に公式化、3 日前に「詰み」と書いた Qwopus3.5 が動く可能性が浮上
第 1 話で「Qwopus3.5 系は llama.cpp 本体の対応待ち、ユーザーレベルでは詰み」と書いた、その結論が 6 日で書き換わった話です。
検証環境
マシン: M3 Max 64GB unified memory
LM Studio: 0.4.12 (2026-04 リリース)
CodeRouter: v1.8.3
検証対象: Qwen3.6 27B Dense / Qwen3.6 35B A3B / Qwen3.5 9B / Qwen3.5 35B A3B / Qwopus3.5-9B (Jackrong/Qwopus3.5-9B-v3-GGUF)
段 1: LM Studio 0.4.12 のリリースノート
3 日前の v1.8.3 article 公開の後、LM Studio が更新を出していました:
0.4.12 - Release Notes
Build 1
* Support for Qwen 3.6
* Improved style in chat PDF exports
* Fixed bug where MCP servers with OAuth would not work on some Windows environments
* Improved Qwen 3.5 performance with OpenAI-compatible
`/v1/chat/completions`, `/v1/responses` and Anthropic-compatible
`/v1/messages`3 つの観点で「私たちが今日まで追ってた問題のドンピシャ」を解決しに来ています:
1. Qwen 3.6 サポート
llama.cpp 直叩き経路とは別に、LM Studio 経由でも Qwen 3.6 が公式に動く第 2 経路に。Ollama 経由詰みを救う代替が複線化される。
2. Qwen 3.5 性能改善 + 公式 endpoint 対応
「Improved Qwen 3.5 performance」を OpenAI-compatible /v1/chat/completions、/v1/responses、Anthropic-compatible /v1/messages の 3 endpoint に明示的に挙げている。これは LM Studio の中で qwen35 architecture が 動く前提が公式化 されているということ。
→ 私が v1.8.1 で「llama.cpp が qwen35 architecture 未対応で Qwopus3.5 詰み」と書いた結論が、文字通り過去のものになった可能性。
3. Anthropic 互換 /v1/messages
CodeRouter から kind: anthropic で直接接続できる 経路が公式化された。OpenAI 互換層の翻訳を skip して、Anthropic native shape (tool_use block / cache_control / thinking block) をそのまま透過できる。
段 2: Staff Picks の GGUF タブを見る
LM Studio の "Staff Picks" を GGUF タブで眺めると:
Qwen3.6 27B (4 days ago) Dense 27B、👁🔧⚡
Qwen3.6 35B A3B (10 days ago) prioritizes stability、👁🔧⚡
Gemma 4 31B (16 days) vision+tools+thinking
Gemma 4 E4B (16 days)
Gemma 4 E2B (16 days)
Gemma 4 26B A4B (24 days)
Nemotron 3 Nano 4B (41 days)
Qwen3.5 9B (55 days ago) significant leap、👁🔧⚡ ← !!
Qwen3.5 35B A3B (61 days ago) reasoning vision-language、👁🔧⚡ ← !!!
Lfm2 24B A2B (61 days)
...Qwen3.5 9B と Qwen3.5 35B A3B が 55-61 日前から GGUF Staff Picks に並んでいる。
これが意味すること:
llama.cpp 本体に qwen35 architecture がもう merge 済み (もしくは LM Studio が独自実装)
私たちが v1.8.1 で「ユーザーレベルでは詰み」と書いていた間、LM Studio は静かに動かせる状態だった
アイコン構成 (👁 vision + 🔧 tools + ⚡ thinking) を見ると、Claude Code 用途の必要 capability が全部揃っている
派生発見:
Qwen3.6 系は GGUF only、MLX タブには無い: MLX backend の Qwen3.6 サポートはまだ。Apple Silicon 最適化 backend を使いたい場合は当面 GGUF (llama.cpp 系) ルート
Qwen3 30B A3B 2507 / GPT-OSS 20B / Qwen3 VL 系は MLX で速度メリット: Qwen3 / 旧世代モデルは MLX 最適化が乗ってる
qwen35.ssm.* のような hybrid Transformer-SSM キーが GGUF metadata にあるモデルが動くようになっている = 相当大きい進歩
段 3: 実機検証 (2026-04-27、すべて pass)
3-A. Qwen3.5 9B を LM Studio でロード
LM Studio 0.4.12+ の "Discover" タブから lmstudio-community/Qwen3.5 9B (Q4_K_M、6.5GB) をダウンロード、Chat タブで Load Model:
Context Length: 32768 (default 4096 では Claude Code system prompt 詰む)
GPU Offload: max (全 32 layer Metal)
Flash Attention: ON
K/V Cache Quantization: OFF (default F16、検証時は実験機能オフ)
Estimated memory: 8.14 GB
ロード完了。Chat タブで「Hello」を送信、1-2 秒で応答 (M3 Max 64GB / Metal GPU 全 layer offload)。
Local Server タブで Port 1234 / "Just-in-time Model Loading: ON" / Start Server。curl http://localhost:1234/v1/models で model 一覧を確認:
$ curl -s http://localhost:1234/v1/models | jq '.data[] | {id, owned_by}'
{"id": "qwen/qwen3.5-9b", "owned_by": "organization_owner"}
{"id": "qwen/qwen3.6-35b-a3b","owned_by": "organization_owner"}
...3-B. OpenAI 互換 /v1/chat/completions で native tool_calls
$ curl -s http://localhost:1234/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "qwen3.5-9b",
"messages": [{"role":"user","content":"Call the echo tool with message=\"hi\""}],
"tools": [{
"type": "function",
"function": {
"name": "echo",
"description": "Echo a message back.",
"parameters": {
"type": "object",
"properties": {"message": {"type":"string"}},
"required": ["message"]
}
}
}],
"tool_choice": "auto",
"max_tokens": 500,
"temperature": 0
}' | jq '.choices[0]'{
"index": 0,
"message": {
"role": "assistant",
"content": "\n\n",
"reasoning_content": "The user wants me to call the echo tool with a specific message parameter set to \"hi\". I need to use the echo function with the message parameter.",
"tool_calls": [{
"type": "function",
"id": "573125855",
"function": {
"name": "echo",
"arguments": "{\"message\":\"hi\"}"
}
}]
},
"finish_reason": "tool_calls"
}✅ finish_reason: "tool_calls" + 正規 OpenAI tool_calls[] array が native で返る。v1.8.1 で「llama.cpp が qwen35 architecture 未対応で Qwopus3.5 詰み、フレームワーク本体待ち」と書いた結論が、ここで完全に覆りました。
Qwen3.6 35B-A3B (qwen35moe architecture) も同様に動作確認済み。LM Studio を 9B → 35B-A3B にロードし直して同じ curl を投げると、finish_reason: "tool_calls" + native tool_calls[] array が同じ pattern で返る (output_tokens: 185、reasoning_content も同じ field 名で付帯)。Qwen3.5 の Dense (qwen35) と Qwen3.6 の MoE (qwen35moe) という 2 つの architecture が両方 LM Studio 経由で動くことが確定。
3-C. Anthropic 互換 /v1/messages で native tool_use
LM Studio 0.4.12 で公式サポートされた Anthropic 互換 endpoint:
$ curl -s http://localhost:1234/v1/messages \
-H 'Content-Type: application/json' \
-H 'anthropic-version: 2023-06-01' \
-d '{
"model": "qwen3.5-9b",
"max_tokens": 500,
"messages": [{"role":"user","content":"Call the echo tool with message=\"hi\""}],
"tools": [{
"name": "echo",
"description": "Echo a message back.",
"input_schema": {
"type": "object",
"properties": {"message": {"type":"string"}},
"required": ["message"]
}
}]
}' | jq '.'{
"id": "msg_4w8746j0jnngapmqvl0zi",
"type": "message",
"role": "assistant",
"content": [
{"type": "text", "text": "\n\n"},
{
"type": "tool_use",
"id": "998041094",
"name": "echo",
"input": {"message": "hi"}
}
],
"model": "qwen3.5-9b",
"stop_reason": "tool_use",
"stop_sequence": null,
"usage": {
"input_tokens": 284,
"output_tokens": 59,
"cache_read_input_tokens": 0
}
}✅ stop_reason: "tool_use" + Anthropic native tool_use block が完璧に返る。cache_read_input_tokens field 付き。これで kind: anthropic で直接接続できる前提が成立。
Qwen3.6 35B-A3B でも同じ shape を確認済み。stop_reason: "tool_use" + content[] に text block + tool_use block、output_tokens: 185 (35B-A3B は 9B より reasoning が長め)。これで Dense / MoE 両 architecture が Anthropic 互換ルートでも完全互換と確定。
3-D. CodeRouter 経由 end-to-end
~/.coderouter/providers.yaml に LM Studio provider を 2 経路で登録 (詳細は CodeRouter examples/providers.yaml 参照):
- name: lmstudio-qwen3-5-9b # OpenAI 互換ルート
kind: openai_compat
base_url: http://localhost:1234/v1
...
- name: lmstudio-qwen3-5-9b-anthropic # Anthropic 互換ルート (v1.8.4 目玉)
kind: anthropic
base_url: http://localhost:1234
...doctor 6 probe (OpenAI 互換ルート)
[1/6] auth+basic-chat …… [OK] 200 OK (in=19, out=16)
[2/6] num_ctx ………………… [SKIP] not Ollama-shape (port 1234)
[3/6] tool_calls ………… [OK] native `tool_calls` observed; matches declaration.
[4/6] thinking ………… [SKIP] capabilities.thinking=true on openai_compat is informational
[5/6] reasoning-leak …… [OK] upstream emits non-standard `reasoning`; v0.5-C/v1.8.3 adapter strips it
[6/6] streaming ………… [SKIP] streaming-path detection is Ollama-shape gated
Summary: all probes match declarations.
Exit: 0doctor 6 probe (Anthropic 互換ルート)
[1/6] auth+basic-chat …… [OK] 200 OK (in=19, out=16)
[2/6] num_ctx ………………… [SKIP] not Ollama-shape
[3/6] tool_calls ………… [OK] native `tool_calls` observed; matches declaration.
[4/6] thinking ………… [OK] thinking block emitted; matches declaration. ← !!
[5/6] reasoning-leak …… [SKIP] only openai_compat emits non-standard reasoning field
[6/6] streaming ………… [SKIP]
Summary: all probes match declarations.
Exit: 0★ Anthropic 互換ルートでは thinking [OK] が出る — opt-in (thinking: {type: enabled}) を request body に入れると、LM Studio 0.4.12 が thinking content block を Anthropic native 形式で返す。これは正規 Anthropic API (Claude Sonnet 4.5+) と完全互換の挙動。
CodeRouter 経由 Anthropic 互換 round-trip
$ coderouter serve --port 8088 --mode test-lmstudio-anthropic &
$ sleep 2
# tool 呼び出し (max_tokens=500 で十分)
$ curl -s -X POST http://localhost:8088/v1/messages \
-H 'Content-Type: application/json' \
-H 'anthropic-version: 2023-06-01' \
-H 'x-api-key: dummy' \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 500,
"messages": [{"role":"user","content":"Call the echo tool with message=\"hi\""}],
"tools": [{
"name": "echo",
"description": "Echo a message back.",
"input_schema": {
"type": "object",
"properties": {"message": {"type":"string"}},
"required": ["message"]
}
}]
}' | jq '.'{
"id": "msg_pgpz5kcbudsu61h77z3yn",
"type": "message",
"role": "assistant",
"model": "qwen3.5-9b",
"content": [
{"type": "text", "text": "\n\n"},
{
"type": "tool_use",
"id": "311305849",
"name": "echo",
"input": {"message": "hi"}
}
],
"stop_reason": "tool_use",
"usage": {
"input_tokens": 284,
"output_tokens": 59,
"cache_read_input_tokens": 280 ← !!! prompt caching が動いてる
},
"coderouter_provider": "lmstudio-qwen3-5-9b-anthropic"
}CodeRouter ログ:
try-provider provider=lmstudio-qwen3-5-9b-anthropic stream=false native_anthropic=true
HTTP Request: POST http://localhost:1234/v1/messages "HTTP/1.1 200 OK"
provider-ok provider=lmstudio-qwen3-5-9b-anthropic stream=false native_anthropic=truecapability-degraded ログは出ない (Anthropic native shape は strip するものがない)。
★ cache_read_input_tokens: 280 がここで出ているのが超重要 — ローカル LLM (LM Studio) で Anthropic prompt caching が成立しています。
段 3-E: 検証マトリクスのまとめ

両モデルとも M3 Max 64GB / Metal 全 layer offload で快適動作。35B-A3B は MoE のおかげで active 3.8B 相当の推論速度、サイズ感は 9B のおよそ 3 倍だが体感差はそこまで大きくない (per-step latency は近い、合計 token 数だけ多い)。
両 architecture が動くことが確認できたので、v1.8.1 で「フレームワーク待ち」と書いた箇所は Qwen3 系全体について (Qwen3.5 / Qwen3.6 / Qwopus3.5 含む) 覆ったと結論できる。
段 4: 副次発見 — Anthropic prompt caching がローカル LLM で動く
/v1/messages 応答に cache_read_input_tokens フィールドが含まれていて、2 回目以降の同種リクエストで実値が出る (今回のテストで 280 token cache hit)。これは Anthropic 公式 API の prompt caching 機能と同じインターフェース で、LM Studio が独自実装している。
何が嬉しいか:
Claude Code が長い system prompt を毎回送るが、2 回目以降は cache hit → token 単価が下がる (cloud Anthropic では実費削減)
ローカル LLM では cache hit によって prefill 時間が短縮される可能性 (大きな system prompt の embedding 再計算が省略)
CodeRouter kind: anthropic 経路では cache_control capability が透過される ので、Claude Code → CodeRouter → LM Studio の経路で透明に効く
これは v1.8.4 article で予告した「Anthropic 互換ルートの方が情報量が多くて優位」の具体的な裏付けの 1 つ。OpenAI 互換ルート経由ではこの cache 情報は表に出ない (エンドポイント仕様で非対応)。
段 5: thinking モデル独自の落とし穴 — max_tokens 慣例
検証中に踏んだ罠を共有:
# 最初 (max_tokens=500)
$ curl ... -d '{"max_tokens": 500, "messages": [{"role":"user","content":"Say hello in one word."}]}'
{
"content": [], ← 空!
"stop_reason": "max_tokens", ← 500 全消費
"usage": {"output_tokens": 500}
}
# 2 回目 (max_tokens=2048)
$ curl ... -d '{"max_tokens": 2048, ...}'
{
"content": [{"type": "text", "text": "Hello"}],
"stop_reason": "end_turn",
"usage": {"output_tokens": 309}
}
max_tokens=500 だと content が空、max_tokens=2048 だと正常完結。理由:
Qwen3.5 / Qwen3.6 / gpt-oss / DeepSeek-R1 系の thinking モデルは 内部 reasoning に 100-500 token 消費してから本文を吐く
thinking opt-in しなくても 内部 reasoning は走って output_tokens に計上される
max_tokens=500 だと reasoning だけで予算切れ、stop_reason: "max_tokens" で content: [] 返却
実用的な慣例:
thinking モデル を呼ぶときは max_tokens: 2048 以上 を default に
CodeRouter providers.yaml の timeout_s も generous (120s+)
doctor probe は v1.8.3 ですでに 1024 まで bump 済み (this matches)
段 6: メタ教訓 — 「結論には賞味期限がある」
3 連作で書いた教訓をふり返ると:

そしてこの v1.8.4 で追加されるのは:
結論には賞味期限がある。「フレームワーク本体の対応待ち」と書いて諦めた箇所も、6 日でひっくり返ることがある。
これは OSS のローカル LLM 界隈に固有の現象で、llama.cpp / Ollama / LM Studio / vLLM / MLX-LM の各 backend がそれぞれ独立に進化していて、ある backend で詰むモデルが別の backend で動く、というのは日常茶飯事になりつつある。qwen35 architecture も典型例:
v1.8.1 時点 (2026-04-26 朝): Ollama 0.21.2 / llama.cpp 0.X 両方で unknown model architecture: 'qwen35' 500 エラー
v1.8.4 時点 (2026-04-26 夜?): LM Studio 0.4.12 が公式に Qwen 3.5 性能改善を謳う、Staff Picks に Qwen3.5 系が並ぶ
私たちの結論「ユーザーレベルでは詰み」は、当時の Ollama + llama.cpp 環境においては正しかったが、LM Studio という別 backend を視野に入れていなかった視野狭窄でもあった。
教訓 5 つ目を 4 連作の総括として:
OSS の進化速度は記事を書いてる速度を超える — 「フレームワーク本体の対応待ち」と書いた箇所は 1 週間で覆る前提で書く、もしくは backend 多様性 (Ollama / llama.cpp / LM Studio / vLLM / MLX-LM) を最初から視野に入れた "matrix 検証" を習慣にする
v1.8.x で何を変えたか
実機検証で CodeRouter 側に追加コードは不要 という結論に至りました — kind: anthropic adapter は v0.4-A 以来安定していて、LM Studio 0.4.12 の Anthropic 互換 endpoint をそのまま透過できる。kind: openai_compat の reasoning_content strip も v1.8.3 で済んでいるので、LM Studio が emit する両 field 名 (reasoning / reasoning_content) は綺麗に消える。
ドキュメント / examples 側のみ更新:
✅ examples/providers.yaml に LM Studio provider 4 種類 (lmstudio-qwen3-5-9b / lmstudio-qwen3-5-9b-anthropic / lmstudio-qwen3-6-35b-a3b / lmstudio-qwen3-6-35b-a3b-anthropic) + test profile 2 種類 (test-lmstudio-openai / test-lmstudio-anthropic) を追加。inline コメントで事前準備手順 (LM Studio 0.4.12+ install / モデル DL / Load Model 設定 / Local Server 起動) を網羅
⏳ docs/lmstudio-direct.md 新規作成 (LM Studio 経由 backend の専用ガイド) — 次の patch で
⏳ docs/troubleshooting.md §4-2 に「Qwopus3.5 / Qwen3.5 系は LM Studio 0.4.12+ で動く」を追記 — 次の patch で
v1.8.5 patch 候補 (今回の検証で見えた小さな改善ネタ)
実機検証中に見つけた、すぐ重大ではないが将来潰すべき小さな整合性の話:
doctor の thinking probe の suggestion メッセージ更新
[4/6] thinking [SKIP] で出る:
capabilities.thinking=true on an openai_compat provider has no effect — Remove the flag or switch kind to anthropic...
これは v1.8.3 改修 (thinking: true を _is_reasoning_model() の hint として使う) を反映していない。実際は:
thinking block (Anthropic 形式) の保持 → openai_compat では確かに lost
しかし v1.8.3 以降は thinking: true が num_ctx / streaming / tool_calls probe budget の 1024 拡大に効く
正しい suggestion:
openai_compat では thinking block は lost するが、thinking: true を残しておくと doctor probe が thinking モデル用 budget (1024 token) を使う。完全に消したければ false に。
これは v1.8.5 patch ネタとして plan.md に記録。
振り返り — 4 連作のテーマ進化

各話で教訓が「外側のレイヤー」に向かって 1 段ずつ抽象化されている螺旋構造が、結果的にできていました。
v1.8.1: モデル評判の鵜呑み
v1.8.2: 自分の診断ツール
v1.8.3: 自分の教訓
v1.8.4: 自分の前提条件 (どの backend を視野に入れるか)
ローカル LLM コミュニティに対するメッセージ
「Ollama で詰んだから諦めた」と判断する前に、必ず別 backend (llama.cpp 直叩き / LM Studio / vLLM / MLX-LM) を試してください。各 backend は独立に進化していて、ある backend で詰むモデルが別の backend で動く現象は、ローカル LLM 界隈で日常茶飯事になりつつあります。
特に:
Qwen3.5 系 (Qwopus 含む) は v1.8.1 時点では llama.cpp / Ollama で詰みでしたが、LM Studio 0.4.12+ で公式サポート されました
Qwen3.6 系 は v1.8.3 時点では Ollama 経由で chat template / tool 仕様が未成熟ですが、llama.cpp 直叩き (Unsloth UD-Q4_K_M GGUF) で native tool_calls 動作 します
Anthropic 互換 /v1/messages に LM Studio が対応したことで、Claude Code 互換クライアント → LM Studio 直結 (CodeRouter 経由なら kind: anthropic) の経路が現実的に
CodeRouter 側の対応は v1.8.x patch series で順次進めます。examples/providers.yaml に LM Studio provider 例を 2 経路追加、docs/lmstudio-direct.md 新設、と。
v1.8.4 / v1.9 の入手方法
実機検証完了 + 必要なら code 修正後、PyPI publish:
uv tool upgrade coderouter-cli詳細は CHANGELOG.md で。
まとめ
3 日前 (v1.8.1) に「Qwopus3.5 系は llama.cpp 未対応で詰み、フレームワーク本体待ち」と書いた
6 日後 (v1.8.4 = 本日) に LM Studio 0.4.12 を見たら、Qwen3.5 性能改善 + Anthropic 互換 /v1/messages を公式化、Staff Picks に Qwen3.5 9B / 35B A3B が並ぶ
「フレームワーク本体の対応待ち」の前提自体が古くなっていた = 結論には賞味期限がある
CodeRouter として LM Studio backend を examples/providers.yaml に追加 + docs/lmstudio-direct.md 新設 + Qwopus3.5 / Qwen3.5 系をローカル primary 候補として再評価
メタ教訓 (4 連作の総括): OSS の進化速度は記事を書いてる速度を超える、backend 多様性を最初から視野に入れた matrix 検証を習慣に
関連記事 (4 連作)
第 1 話: ガチで動かしてみたら 3 連敗した話 (v1.8.1)
第 3 話: Ollama で詰んだ Qwen3.6 を llama.cpp で動かしたら、自分の診断ツールがもう 1 つ偽陽性を出してた話 (v1.8.3)
第 4 話: 本記事 (v1.8.4)
質問・感想は GitHub Issues または X (@zephel01) までどうぞ。
ローカル LLM の運用は、結論を書いた瞬間にも刻一刻と前提が変わってる世界です。4 連作読み通してくださった方、本当にありがとうございました。
(リリース日: 2026 年 4 月 27 日 / バージョン: v1.8.4 — 実機検証完了済み)
いいなと思ったら応援しよう!
サーバー代とコーヒー代になります☕ 役に立ったら応援よろしくお願いします!