4.9 KiB
モデル capability の責務を llm-worker 外へ移す
背景
llm-worker は「wire scheme の送受信」に専念する低レベル基盤に留める方針。にもかかわらず、現状は各 scheme に capability.rs が同居していて、claude-* / gpt-5 prefix / gemini-2.5 prefix / codex- prefix 等の個別モデル ID 知識が llm-worker に閉じ込められている。
該当箇所:
crates/llm-worker/src/llm_client/scheme/anthropic/capability.rs::lookupcrates/llm-worker/src/llm_client/scheme/openai_chat/capability.rs::classify/lookupcrates/llm-worker/src/llm_client/scheme/openai_responses/capability.rs::lookupcrates/llm-worker/src/llm_client/scheme/gemini/capability.rs::lookupScheme::capability_for(model_id) -> Option<ModelCapability>trait メソッド
「モデル ID から能力を決める」は wire 実装の責務ではない。カタログ/プロバイダ構築層(高レベル側)の責務で、ここに居るのは層の漏出。新モデル(gpt-6 等)が出るたびに llm-worker を触る構造は抽象が壊れている。
要件
-
Scheme::capability_forの廃止: trait から削除。llm-workerは wire-level の安全側フォールバックであるdefault_capability()のみ持つ。 -
モデル知識を
crates/providerへ移す:crates/provider/src/capability.rs(またはcapability/モジュール)を新設- 現
scheme/*/capability.rsのlookup(およびclassify)を移植 - 公開 API:
pub fn lookup(scheme: SchemeKind, model_id: &str) -> Option<ModelCapability>
-
build_clientの capability 解決順は維持:ModelConfig.capability明示指定provider::capability::lookup(scheme, model_id)(移設先)scheme.default_capability()(llm-workerに残る)
-
llm-worker/examples/*の追従:scheme.capability_forを使っている箇所(worker_cli/worker_cancel_demo/record_test_fixtures)はscheme.default_capability()か明示ModelCapabilityに置換する。examples を provider に依存させない。 -
テストの移設: scheme 側 capability テストは provider 側に移す(テーブル本体と一緒に移動)。
-
完了時の動作:
cargo build --workspaceが通り、test_pod.codex.local.toml経由の疎通テストが引き続き成功する。
設計判断
scheme 側に default_capability() を残す理由
wire format 固有の保守的 default (例: OpenAI 互換は Parallel tool call, JsonSchema structured output) は wire 層の知識で、モデル固有ではない。「この scheme では何が最低限送れるか」を示す安全側の宣言なので llm-worker に残す。
examples を provider に依存させない
worker_cli 等は scheme の使い方を示す最小例。provider クレートに依存させると低レベル例として壊れるし、循環依存の気配も出る。examples では scheme.default_capability() を使い、モデル固有最適化が必要なら ModelCapability 手組みで済ませる。
llm-provider-catalog との関係
カタログチケットは「プロバイダと代表モデル ID の提示」が主題で、capability は意図的に載せない判断だった。本チケットはその決定を変えない。provider::capability::lookup は provider 層のうちカタログとは別の関数として置く(将来的にカタログが capability ヒントを提供する余地は残すが、本チケットでは扱わない)。
新モデル追加の運用
provider::capability::lookup が「知ってるモデル ID」のテーブルを持つ設計は維持する(本チケットの焦点は場所の正しさ)。新モデル対応はテーブル追記で済むが、新スキーマ/新プロバイダ経路が出たときに llm-worker を触らずに済むのが改善点。
Scope 外
- ランタイム capability 検出 (OpenAI
/v1/modelsや ChatGPT backend の動的モデル列挙) providers.tomlカタログ連携 (llm-provider-catalogチケット側)- prefix match から厳密マッチへの切替(別論点、今回は挙動保存)
影響範囲
crates/llm-worker/src/llm_client/scheme/mod.rs:capability_fortrait メソッド削除crates/llm-worker/src/llm_client/scheme/*/scheme_impl.rs:capability_forimpl 削除crates/llm-worker/src/llm_client/scheme/*/capability.rs:lookup/classify削除、default_capabilityのみ残すcrates/provider/src/capability.rs: 新設(テーブル統合)crates/provider/src/lib.rs:build_clientの capability 解決経路を更新crates/llm-worker/examples/*:capability_for呼び出し除去
依存
llm-model-config完了済llm-scheme-openai-responses完了済llm-auth-codex-oauth完了済
Review
- 状態: Approve
- レビュー詳細: ./llm-capability-ownership.review.md
- 日付: 2026-04-21