Open WebUIでツールが呼ばれないときの切り分け:Native Mode、Tool Search、モデル互換性

元の接続を削除せず、4条件の比較テストでOpen WebUIの可視性・権限、Native Mode、Tool Search、モデルbackend、MCP/OpenAPI実行のどこが原因かを特定します。

目次
Open WebUIでツールが呼ばれないときの切り分け:Native Mode、Tool Search、モデル互換性

ツールを有効にしているのに、モデルが「使います」と言うだけで実際のtool callが残らない。この症状だけでは、原因がモデル、Open WebUI、MCP/OpenAPIサーバーのどこにあるか判断できません。最初に副作用のない小さなreverse_stringで基準を作り、Native Mode、Tool Search、モデル接続を一つずつ変えると、短い手順で原因を絞れます。

元の接続は削除しません。最終的には4条件の比較結果と実行ログを残し、Tool Searchを無効にする、重要なツールをAlways Loadedにする、または検証済みのモデル接続へ切り替える、という最小の修正を選びます。

ツール実行を5つの層に分ける

UIでツールが有効に見えることは、UIの状態しか証明しません。実行成功には5つの層がすべて通る必要があります。

層確認すること誤解しやすい症状
1. 表示と権限現在のユーザーがツールを表示・読み取りできる管理者では動くが、別ユーザーには黙って消える
2. チャット、モード、capabilityチャットが Native で対象ツールが有効。組み込みシステムツールなら Workspace → Models → Capabilities → Builtin Tools と該当カテゴリも有効Builtin Toolsが無効、またはWorkspace/MCP/OpenAPI共通の主スイッチだと誤認している
3. リクエストpayloadbackendが完全なツール定義、または導入バージョンが対応する遅延ツール用helperを受け取るTool Searchがschemaを遅延したのにUIでは有効のままに見える
4. モデルbackend正しい対象への構造化callと有効な引数が返るモデルが本文で「呼んだ」と書く、別operationを選ぶ、引数を誤る
5. 実行Open WebUI、MCP、OpenAPI serverが正しいcallを実行して結果を返す正しいcallはあるが、認証、route、protocol、serverで失敗する

上から順に確認します。アクセス権と実際の対象callを見ずにMCPを作り直すと、有用な証拠を失います。

変更前に元の状態を保存する

最低限、次を記録します。

  • Open WebUIのversionとdeployment方法
  • connection名、正確なModel ID、UI上のモデル名、実際のprovider、gateway、Base URLまたはroute
  • Model Settings → Advanced Params → Function Calling の実効値
  • 組み込みシステムツールの場合、Workspace → Models → Capabilities → Builtin Tools と該当カテゴリの状態
  • 現在のチャットで Integrations → Tools から有効にしたツールと、テストユーザーのread権限
  • Settings → Admin → Interface → Chat に実際に表示される4項目:Tool Search、Defer Built-in Tools、Deferral Threshold (characters)、Always Loaded Tools
  • 対応する完全な設定名:ENABLE_TOOL_SEARCH、TOOL_SEARCH_DEFER_BUILTIN_TOOLS、TOOL_SEARCH_DEFER_THRESHOLD、TOOL_SEARCH_ALWAYS_LOADED
  • 問題が組み込みシステムツール、Workspace Tool、MCP、OpenAPIのどれか
  • 失敗したprompt、timestamp、chat exportまたはscreen shot、同じ時間帯のOpen WebUI/tool server logs

connectionはtoggleで一時停止でき、設定を削除する必要はありません。比較用には control-tool-test など別名のconnectionを追加し、本番connectionを上書きしないでください。

次の2つを分けます。

  1. 通常チャットが動く:text requestが完了しただけです。
  2. ツールcallが動く:対象の構造化call、有効な引数、実行記録、返却結果が必要です。

モデルが本文で「reverse_string を使った」と書いても証拠ではありません。

現在のチャットがNative Modeか確認する

Open WebUIの現行ドキュメントでは、Native がdefaultかつsupportedなtool-calling modeです。Legacy は旧挙動向けのunsupportedなopt-outです。

上書きされ得る3箇所を確認します。

  1. global Model Defaults
  2. 選択モデルのAdvanced Params
  3. 現在のチャットのChat Controls

テストでは実効値を Native に固定します。Tool SearchはNative Mode向けなので、Legacy の確認と同時に混ぜないでください。

不足しているのがOpen WebUIの組み込みシステムツールなら、Workspace → Models で対象モデルを編集し、Capabilities を確認します。Builtin Tools と必要なカテゴリを有効にします。このswitchはNative Modeで組み込みシステムツールをinjectするためのもので、Workspaceの reverse_string、MCP、OpenAPIをまとめて制御する主スイッチではありません。

Workspace、MCP、OpenAPIは別の制御を確認します。

  • message box横の Integrations を開く
  • Tools で診断ツールまたは外部ツールをこのチャットに有効化する
  • モデルにattach済みでも、現在のユーザーにread権限があるか確認する

Workspace Toolをモデルにattachしてもaccess controlは回避されません。read権限がなければ、モデルに渡されないことがあります。

副作用のない最小ツールを作る

Workspace ToolsはOpen WebUIサーバー内でPythonを実行します。作成・importは信頼できる管理者だけが行ってください。診断では、ファイル、ネットワーク、データベース、system commandを使わない関数に限定します。

Workspace → Toolsで次のツールを作成します。

"""
title: Read-only Tool Check
description: Reverses a string for tool-call diagnostics
version: 1.0.0
"""

class Tools:
    async def reverse_string(self, string: str) -> str:
        """
        外部データを読み書きせず、受け取った文字列を逆順にします。

        :param string: 正確に逆順にする文字列。
        :return: 逆順にした文字列。
        """
        return string[::-1]

保存後、テストユーザーへアクセスを付与し、Integrations → Toolsで有効にします。

新しいチャットで毎回同じpromptを使います。

文字列 tool-check-7 は必ず reverse_string ツールで処理してください。
自分で逆順にせず、推測もしないでください。
ツールが返ったら、その結果だけを出力してください。

期待値は次です。

7-kcehc-loot

ただし、同じ文字列が表示されただけではPASSにしません。以下の4点をすべて確認します。

  • traceまたはtool activityに構造化されたreverse_string callがある
  • 引数にtool-check-7がある
  • Open WebUIまたはサーバーログに対応する実行記録がある
  • ツールが7-kcehc-lootを返し、最終回答がその値を使っている

チャット、call details、同時刻のログを保存してください。以後の条件は、同じツールとpromptを使い、毎回新しいチャットで実行します。

4条件で比較する

一度に1変数だけ変え、環境変数名だけでなく既存のAdmin UIで実際に設定します。

  1. Settings → Admin → Interface → Chat を開く
  2. 条件ごとに Tool Search、Defer Built-in Tools、Deferral Threshold (characters)、Always Loaded Tools を設定する
  3. 保存後にページを開き直し、実際に表示される値を記録する
  4. 新しいチャットで同じ固定promptを実行する

4項目は ENABLE_TOOL_SEARCH、TOOL_SEARCH_DEFER_BUILTIN_TOOLS、TOOL_SEARCH_DEFER_THRESHOLD、TOOL_SEARCH_ALWAYS_LOADED に対応し、すべて ConfigVar です。defaultの ENABLE_PERSISTENT_CONFIG=True では、Admin UI/databaseに保存済みの値が環境変数より優先されます。そのため .env を変更して再起動しても、条件が変わったとは限りません。意図的に ENABLE_PERSISTENT_CONFIG=False を使う場合は記録してください。起動時は環境変数が優先され、UI変更は実行中sessionだけに効き、再起動で失われます。

条件NativeTool SearchDefer Built-in ToolsThresholdAlways Loaded目的
AOnOff現在値を記録。このWorkspace Toolには作用しない対象外対象外reverse_string の完全定義を送る基本baseline
BOnOnOnにして記録。組み込みツール向けであり reverse_string は制御しない0モデルに見える正確なテストツール名Always Loaded経路を確認
COnOnOnにして記録0空遅延経路を強制し、search_tools と対象callを観測
DOnCと同じCと同じ0空2本目をA、必要ならBで先に適格化してからCを再現

Threshold 0 が重要です。通常はserialized definitionの長さが設定値を超えた場合だけ遅延されます。小さな reverse_string はdefault thresholdでは完全ロードのままになることがあり、Cが遅延経路を試さない可能性があります。診断後は本番値に戻します。

条件A:Nativeの基本経路を先に証明する

Settings → Admin → Interface → Chat で Tool Search をOffにし、保存してページを開き直し、実効値を確認します。その後、新しいチャットで固定promptを実行します。再起動だけを設定変更の証拠にしないでください。

  • A成功: user access、Native、このmodel route、Workspace Tool実行が最小例で成立します。
  • 対象の構造化callなし: chatのtool選択、read権限、Function Callingの実効値、backendのnative structured call対応を確認します。
  • callはあるが実行失敗: モデルはcall段階まで到達しています。引数、schema、Open WebUI execution logsを確認します。

Aが通るまでTool Searchの診断に進まないでください。

条件B:Always Loadedを確認する

同じUIで Tool Search をOn、Defer Built-in Tools をOnにして記録し、Deferral Threshold (characters) を 0、Always Loaded Tools にモデルが見る正確な名前を入れます。保存・再表示で値を確認してから、新しいチャットを使います。

Always Loadedのmatchingはcase-sensitiveで、exact nameまたはglobを使えます。MCPのmodel-visible nameは通常 <server ID>_<tool name> です。内部method名から推測せず、実際のtool listまたはtraceからコピーします。

  • B成功: Tool SearchがOnでも、完全schemaを常時送ればcallできます。
  • A成功、B失敗: 保存・再表示したUI値、名前と大文字小文字、実際の設定source、対象instanceを確認します。

条件C:遅延経路を強制する

Tool Search と Defer Built-in Tools をOn、thresholdを 0、Always Loaded Tools を空にします。保存後に実効値を再確認し、新しいチャットで同じpromptを実行します。

2段階を別々に記録します。

  • search_tools callがあったか
  • reverse_string definitionが返ったか
  • その後に対象の構造化callが出たか
  • Open WebUI v0.12.2以降では call_tool が出て、tool_name とJSON argumentsが reverse_string / tool-check-7 を指しているか
  • reverse_string が実際に実行され、期待値を返したか
  • 別ツール選択、本文への擬似call出力、callなしがなかったか

A/Bが成功し、Cで search_tools 自体がない場合は、実効UI値、threshold、version、モデル/routeがTool Search helperを選べるか確認します。search_tools 成功後に対象callがない場合は、model capability、見えるname/schema、実provider route、version、deferred compatibilityを候補に残します。

strict backendの解釈はversion依存です。Open WebUI v0.12.2以降は、既に宣言された call_tool を tool_name とJSON argumentsで使い、現在の tools list内だけを許可するbackendにも対応します。旧versionは遅延ツール名を直接callしていたため、strict backendが拒否することがありました。古いIssueを当てはめる前に導入versionを確認してください。公開Issueは特定deployment/backend familyのuser reportであり、一般則ではありません。

条件D:モデル接続だけを変える

Native の表示だけでは、2本目をdeferred compatibilityのcontrolとは見なせません。正確なModel ID、実provider/gateway、Base URLまたはroute、Open WebUI versionを記録します。Tool Search Offで同じread-only toolのAを先に実行し、必要ならBも行います。通常経路とAlways Loadedが通った場合だけ、tool、prompt、UI値、threshold、空のAlways Loadedを変えずにCをDとして再実行します。

  • D成功、C失敗: 元のmodel routeが差分です。通常チャット用に残し、遅延ツールは検証済みrouteを使います。
  • 2本目がAまたはB失敗: 有効なcontrolではありません。baselineを修正または交換します。
  • 両方でA/B成功、C/D失敗: 両方の実backend/routeが導入versionのdeferred flowを未対応という分岐を残します。異なるモデル名でも同じstrict provider、gateway、routerを共有し得ます。実routeとversionを確認し、search_tools と対象callの有無で次を決め、単に設定、名前、実行だけへ帰属しないでください。
  • C/D成功: 本番ツールのvisible definition、operation選択、引数、権限、serverがより疑わしいです。

証拠に合わせて最小の修正を選ぶ

証拠次の手順
A失敗、対象callなしaccess、chat tool toggle、Native、またはnative tool calling対応backendを修正
A/B成功、Cで search_tools なし実効UI値、threshold、version、helper選択能力を確認
search_tools 成功、対象callなしcapability、visible name/schema、実route、version、compatibilityを確認。最小fallbackはAlways LoadedまたはTool Search Off
対象callあり、reverse_string 未実行Open WebUI logsと call_tool のtarget/argumentsを確認
A–C成功、本番ツール失敗model-visible definition、operation、arguments、Tool Search処理、route、access、server evidenceを確認
適格化済み1本だけ失敗text用途に残し、同じA/B/Cを通るconnectionをtool用途に使う
適格化済み2本がC/D失敗両backendまたは共有routeの非対応分岐を残し、search_tools、対象call、route、versionを比較

ツール数が少なければ、実験的なTool SearchをOffにするのが最も単純で安定します。大きなschemaが多い場合は、頻繁で低riskなツールをAlways Loadedにし、connectionごとに検証します。

Local toolが通ったらMCP/OpenAPIを確認する

reverse_string 成功は、単一stringの単純なWorkspace schemaをそのrouteで呼べることしか証明しません。同じモデルが複雑な外部ツール、正しいoperation、有効な引数、multi-step workflowを扱えるとは限りません。Open WebUIのMCP/OpenAPI文書も、connectionが動いていてもこのmodel limitationを明示しています。

server診断へ進む前に、モデルが実際に見る本番tool definitionと対象call evidenceを保存します。

  • 対象callなし、operation違い、引数不正: model capability、tool name/description/schema、Tool Search、実model/provider routeを候補に残す
  • 正しい構造化callは出たがserverへ届かない、またはtransport/auth error: URL、access control、authentication、protocol、proxy、TLS、serverを確認
  • serverが正しいoperationを受けたが引数拒否/application error: callと公開schemaを比較し、server処理を確認

MCP:transport、アクセス、表示名

Open WebUIのnative MCP connectionは MCP (Streamable HTTP) を使います。stdio だけのlocal serverには適切なbridge/proxyが必要です。

確認項目:

  • TypeがMCPでOpenAPIではない
  • Streamable HTTP URLがOpen WebUI host/containerから到達可能
  • authenticationが現在ユーザーに有効
  • Access Controlにテストユーザーが含まれる
  • model-visibleな完全定義とnameが <server ID>_<tool name> 形式
  • モデルが正しいtargetと有効な引数を選んだ
  • 正しいcallがMCP server logsへ到達した
  • protocol resultでありHTTP/auth/application errorではない

正しい対象callがなければmodel/schema/Tool Search/route分岐に残ります。callはあるがserverに届かないならURL、proxy、certificate、networkを確認し、serverが正しいoperationを受けて引数拒否したなら見えているschemaと比較します。

OpenAPI:operation discoveryを確認する

Open WebUIはOpenAPI 3.xのpath-item構造からoperationを発見します。標準HTTP method、利用可能なparameter、対象operationを識別できる安定したname/descriptionを確認します。

保存するもの:

  • spec URLとtested version
  • Open WebUIがモデルへ実際に見せたtool names/definitions
  • モデルが選んだoperationと構造化arguments
  • server access logとresponse status
  • Open WebUIがモデルへ返したbody

connection保存は実行証明ではありません。/models verification失敗も自動的に非互換を意味しません。標準 /models を実装しないcompatible providerもあります。正確なModel IDを手入力し、A/B/Cと本番ツールの実callで判断します。

BetterTokenを比較接続として追加する場合

元の接続を残し、OpenAI-compatibleの比較接続を追加できます。BetterTokenのAPI Base URLは次です。

https://www.bettertoken.ai/v1

現在のカタログから、supported_endpoint_typesにopenaiを含む正確なModel IDを選び、自分のAPI keyを使います。表示名からIDを推測しないでください。通常チャットが成功してもTool Search互換の証明にはなりません。

この接続でもA〜Dを実施します。ここでのBetterTokenは別のmodel API経路とrequest usageを観察する選択肢であり、Open WebUI、モデル、Tool Searchの修正を保証するものではありません。

参考:

再現できる診断記録を残す

Open WebUI version:
Deployment:
Connection:
Exact model ID:
Actual provider/gateway route:
Function Calling:
Builtin Tools capability/categories:
Tool Search UI value:
Defer Built-in Tools UI value:
Deferral Threshold UI value:
Always Loaded Tools UI value:
ENABLE_PERSISTENT_CONFIG mode:
ENABLE_TOOL_SEARCH:
TOOL_SEARCH_DEFER_BUILTIN_TOOLS:
TOOL_SEARCH_DEFER_THRESHOLD:
TOOL_SEARCH_ALWAYS_LOADED:
Tool visible name:
Prompt:
search_tools call observed:
target call_tool / structured invocation observed:
reverse_string execution log observed:
Returned value:
Timestamp:

アップグレード、モデル変更、server migrationの後も、同じ記録を回帰テストとして使えます。

最初に行うこと

接続を削除したりMCP全体を作り直したりせず、まず現在のchatをNativeにし、Tool Searchをoffにして、tool-check-7をreverse_stringへ渡します。構造化call、実行ログ、7-kcehc-lootの三つが確認できてから、強制遅延と別接続を比較してください。

これで原因を権限、モード、Tool Search、model backend、MCP/OpenAPI executionのどこかに限定し、最小の変更で直せます。

LLM ワークフローを最適化しませんか?

単一 API でモデルを接続し、キーと AI コストを管理できます。

無料で始める