LLM ルーティングポリシー
Mister Morph には、次の問題を解決するための柔軟なルーティング設定があります。
- purpose ごとに向いた llm 設定を使い分けたい。
- llm リクエストを分流したい。
- ある llm 設定が失敗したときに、バックアップ llm 設定へ fallback したい。
LLM Profile
各 Profile は 1 つの LLM 設定です。トップレベルの llm.* 自体が default profile であり、llm.profiles.<name> で命名 profile を定義します。
注意点:
- 命名 profile はトップレベルの
llm.*を継承し、変更したいフィールドだけを上書きします。 defaultは予約名で、「トップレベルのllm.*をそのまま使う」という意味です。
下の例では、トップレベルのモデルは OpenAI の GPT-5.4 です。さらに 2 つの profile として GPT-4o mini と Claude Opus 4.6 を定義しています。
profile の名前を見るだけでも意図が分かります。GPT-4o mini は安いタスク向け、Claude Opus 4.6 はより深い思考向けです。
llm:
provider: "openai"
model: "gpt-5.4"
api_key: "${OPENAI_API_KEY}"
profiles:
cheap:
model: "gpt-4o-mini"
reasoning:
provider: "anthropic"
model: "claude-opus-4-6"
api_key: "${CLAUDE_API_KEY}"つまり、profile は再利用可能な LLM 設定が何かを定義し、その後の route、分流、fallback 機能がそれを使います。
ルート
llm.routes.* の設定では、異なる llm purpose に対してどのモデル設定を使うかを定義します。
main_loop は Agent の実行そのものを担当しますが、それ以外の purpose は独立した llm 呼び出しです。単純な sub agent と考えても構いません。
現在サポートしている purpose
main_loop: 主 Agent loop。addressing: グループチャットやチャンネルでの addressing 判定にのみ使う。heartbeat: 定期 heartbeat タスクにのみ使う。plan_create:plan_createツール内部の計画リクエストにのみ使う。memory_draft: memory 草稿整理にのみ使う。
下の例では、計画作成時には reasoning profile、つまり claude-opus-4-6 を使い、グループチャットの addressing 判定では安い gpt-4o-mini を使います:
llm:
routes:
plan_create: reasoning
addressing: cheapルートの分流
Mister Morph は LLM リクエストのトラフィック分流をサポートしています。分流表は candidates フィールドで定義します。
次の例では、default_apple と default_banana にトラフィックを分けています(あらかじめ llm.profiles で定義しておく必要があります):
llm:
routes:
main_loop:
candidates:
- profile: "default"
weight: 1
- profile: "default_apple"
weight: 1
- profile: "default_banana"
weight: 1ルール:
candidates.weightは選択重みを決めます。- 同じ Loop 内では 1 つの profile だけが使われ、途中で混在しません(
run_idベースで選ばれます)。 - 現在の llm が fallback 可能なエラーに当たった場合は、runtime はまず同じ route にある残りの candidate を試します。
ルートの fallback
分流に加えて、Mister Morph は LLM リクエストのエラー fallback もサポートしています。例えば:
llm:
routes:
plan_create:
profile: "reasoning"
fallback_profiles: [ "default" ]現在の llm が fallback 可能なエラーに当たり、ほかの candidate も使えない場合は、fallback_profiles に並んだ設定を順番に試します。
integration ではどう書くか
設定の考え方は同じで、YAML の代わりに cfg.Set(...) を使うだけです:
cfg := integration.DefaultConfig()
cfg.Set("llm.routes.plan_create", "reasoning")
cfg.Set("llm.routes.addressing", map[string]any{
"profile": "cheap",
"fallback_profiles": []string{"default"},
})