Open WebUIでツールが呼ばれないときの切り分け:Native Mode、Tool Search、モデル互換性
元の接続を削除せず、4条件の比較テストでOpen WebUIの可視性・権限、Native Mode、Tool Search、モデルbackend、MCP/OpenAPI実行のどこが原因かを特定します。
目次

ツールを有効にしているのに、モデルが「使います」と言うだけで実際の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. リクエストpayload | backendが完全なツール定義、または導入バージョンが対応する遅延ツール用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つを分けます。
- 通常チャットが動く:text requestが完了しただけです。
- ツールcallが動く:対象の構造化call、有効な引数、実行記録、返却結果が必要です。
モデルが本文で「reverse_string を使った」と書いても証拠ではありません。
現在のチャットがNative Modeか確認する
Open WebUIの現行ドキュメントでは、Native がdefaultかつsupportedなtool-calling modeです。Legacy は旧挙動向けのunsupportedなopt-outです。
上書きされ得る3箇所を確認します。
- global Model Defaults
- 選択モデルのAdvanced Params
- 現在のチャットの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_stringcallがある - 引数に
tool-check-7がある - Open WebUIまたはサーバーログに対応する実行記録がある
- ツールが
7-kcehc-lootを返し、最終回答がその値を使っている
チャット、call details、同時刻のログを保存してください。以後の条件は、同じツールとpromptを使い、毎回新しいチャットで実行します。
4条件で比較する
一度に1変数だけ変え、環境変数名だけでなく既存のAdmin UIで実際に設定します。
- Settings → Admin → Interface → Chat を開く
- 条件ごとに Tool Search、Defer Built-in Tools、Deferral Threshold (characters)、Always Loaded Tools を設定する
- 保存後にページを開き直し、実際に表示される値を記録する
- 新しいチャットで同じ固定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だけに効き、再起動で失われます。
| 条件 | Native | Tool Search | Defer Built-in Tools | Threshold | Always Loaded | 目的 |
|---|---|---|---|---|---|---|
| A | On | Off | 現在値を記録。このWorkspace Toolには作用しない | 対象外 | 対象外 | reverse_string の完全定義を送る基本baseline |
| B | On | On | Onにして記録。組み込みツール向けであり reverse_string は制御しない | 0 | モデルに見える正確なテストツール名 | Always Loaded経路を確認 |
| C | On | On | Onにして記録 | 0 | 空 | 遅延経路を強制し、search_tools と対象callを観測 |
| D | On | Cと同じ | 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_toolscallがあったかreverse_stringdefinitionが返ったか- その後に対象の構造化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 Tools
- Workspace Tool development
- OpenAI-compatible connections
- Open WebUI MCP
- OpenAPI Tool Servers
- BetterToken Chat Completions
- BetterToken model protocol catalog
再現できる診断記録を残す
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のどこかに限定し、最小の変更で直せます。