Open WebUI не вызывает инструменты: проверяем Native Mode, Tool Search и совместимость модели
Пошаговая проверка с четырьмя контрольными режимами помогает отделить права и настройки Open WebUI от Tool Search, совместимости backend и ошибок MCP/OpenAPI, не удаляя исходное подключение.
Содержание

Инструмент включён, модель обещает его вызвать, но в чате нет настоящего tool call. По одному такому симптому нельзя понять, виновата ли модель, Open WebUI или сам MCP/OpenAPI-сервер. Надёжнее сначала проверить цепочку на маленьком безопасном reverse_string, а затем по одному менять Native Mode, Tool Search и подключение модели.
Исходное подключение удалять не нужно. В результате у вас будет таблица из четырёх режимов с фактическими записями вызова и выполнения. По ней уже можно выбрать минимальное исправление: отключить Tool Search, добавить важные инструменты в Always Loaded или перенести инструментальные задачи на другое проверенное подключение.
Разделите проблему на пять уровней
Надпись «инструмент включён» подтверждает только состояние интерфейса. Для успешного выполнения должны пройти пять уровней.
| Уровень | Что должно работать | Обманчивый симптом |
|---|---|---|
| 1. Видимость и права | Текущий пользователь видит инструмент и имеет право чтения | У администратора работает, у обычного пользователя инструмент молча пропадает |
| 2. Чат, режим и capability | В чате выбран Native, а целевой инструмент включён; для встроенного системного инструмента также включены Workspace → Models → Capabilities → Builtin Tools и нужная категория | Builtin Tools выключен либо его ошибочно считают общим переключателем для Workspace, MCP и OpenAPI |
| 3. Запрос к backend | Backend получает полное определение инструмента или поддерживаемые текущей версией вспомогательные определения отложенного пути | Tool Search отложил schema, хотя в интерфейсе всё выглядит включённым |
| 4. Backend модели | Модель вернула вызов именно нужного инструмента с корректными аргументами | В обычном тексте написано «я вызвал инструмент», выбрана другая операция или переданы неверные аргументы |
| 5. Выполнение | Open WebUI, MCP или OpenAPI-сервер исполнил правильный вызов и вернул результат | Правильный вызов есть, но запрос сломался на авторизации, маршруте, протоколе или сервере |
Проверяйте сверху вниз. Так вы не будете заново настраивать MCP, если проблема на самом деле в правах пользователя или целевой вызов вообще не появился.
Зафиксируйте исходное состояние
Перед изменениями сохраните:
- версию Open WebUI и способ развёртывания;
- имя подключения, точный Model ID, отображаемое имя модели и реальный provider, gateway, Base URL или маршрут;
- фактическое значение Model Settings → Advanced Params → Function Calling;
- для встроенного системного инструмента — состояние Workspace → Models → Capabilities → Builtin Tools и нужных категорий;
- список инструментов, включённых в текущем чате через Integrations → Tools, и право чтения тестового пользователя;
- четыре фактических значения в Settings → Admin → Interface → Chat: 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, экспорт/скриншот чата и логи Open WebUI и сервера за тот же интервал.
Подключение можно временно выключить переключателем, не удаляя его настройки. Для сравнения создайте отдельное подключение с понятным именем, например control-tool-test, и не переписывайте рабочее.
Не смешивайте два разных утверждения:
- обычный чат отвечает — значит, прошёл текстовый запрос;
- инструменты работают — значит, есть целевой структурированный вызов с корректными аргументами, запись выполнения и возвращённый результат.
Фраза модели «я использовал reverse_string» доказательством не является.
Проверьте, что в этом чате используется Native Mode
В актуальной документации Open WebUI Native указан как режим по умолчанию и единственный поддерживаемый режим вызова инструментов. Legacy оставлен для обратной совместимости и не поддерживается.
Проверьте три уровня, где значение может быть переопределено:
- глобальные Model Defaults;
- Advanced Params конкретной модели;
- Chat Controls текущего диалога.
Для теста зафиксируйте Native. Не пытайтесь одновременно оценивать Legacy и Tool Search: Tool Search относится к Native Mode.
Если пропал встроенный системный инструмент Open WebUI, откройте Workspace → Models, отредактируйте выбранную модель и проверьте Capabilities. Должны быть включены Builtin Tools и нужная категория в строке Builtin Tools. Этот переключатель управляет инъекцией встроенных системных инструментов в Native Mode. Он не является общим переключателем для Workspace Tool reverse_string, MCP или OpenAPI.
Для Workspace, MCP и OpenAPI отдельно проверьте их собственные элементы управления:
- откройте Integrations рядом с полем ввода;
- выберите Tools и включите диагностический или внешний инструмент в этом чате;
- если инструмент прикреплён к модели, проверьте право чтения у текущего пользователя.
Привязка Workspace Tool к модели не отменяет контроль доступа. Если у пользователя нет права читать инструмент, Open WebUI может просто не передать его модели.
Создайте минимальный инструмент без побочных эффектов
Workspace Tools выполняют Python-код внутри Open WebUI. Создавать или импортировать их должны только доверенные администраторы. Для диагностики используйте функцию, которая не обращается к файлам, сети, базе данных или shell.
В 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:
Обязательно используй инструмент reverse_string для строки tool-check-7.
Не разворачивай строку самостоятельно и не угадывай.
После ответа инструмента выведи только его результат.
Ожидаемое значение:
7-kcehc-loot
Но совпавшего текста недостаточно. Успех фиксируйте только при наличии всех четырёх признаков:
- в trace или карточке действий есть структурированный вызов
reverse_string; - в аргументах есть
tool-check-7; - в логах Open WebUI или сервера есть соответствующая запись выполнения;
- инструмент вернул
7-kcehc-loot, а итоговый ответ использовал этот результат.
Сохраните чат, детали вызова и строки логов с тем же временем. Каждый следующий режим запускайте в новом чате с тем же prompt.
Сравните четыре режима
Меняйте только один фактор за раз и выполняйте переключение через существующий Admin UI, а не только через имена переменных окружения:
- Откройте Settings → Admin → Interface → Chat.
- Для каждого режима задайте Tool Search, Defer Built-in Tools, Deferral Threshold (characters) и Always Loaded Tools.
- Сохраните настройки, снова откройте страницу и запишите значения, которые она фактически показывает.
- Создайте новый чат и отправьте тот же фиксированный prompt.
Эти четыре поля соответствуют ENABLE_TOOL_SEARCH, TOOL_SEARCH_DEFER_BUILTIN_TOOLS, TOOL_SEARCH_DEFER_THRESHOLD и TOOL_SEARCH_ALWAYS_LOADED. Все они являются ConfigVar. При стандартном ENABLE_PERSISTENT_CONFIG=True сохранённые в Admin UI/базе значения имеют приоритет над переменными окружения, поэтому изменение .env и перезапуск не гарантируют, что условие теста изменилось. Если развёртывание намеренно использует ENABLE_PERSISTENT_CONFIG=False, зафиксируйте это: после запуска приоритет имеют environment values, а изменения через UI действуют только в текущей сессии и пропадут после перезапуска.
| Режим | Native | Tool Search | Defer Built-in Tools | Threshold | Always Loaded | Зачем |
|---|---|---|---|---|---|---|
| A | Вкл. | Выкл. | Записать текущее значение; для этого Workspace Tool не используется | Не применяется | Не применяется | Базовая проверка с полным определением reverse_string |
| B | Вкл. | Вкл. | Вкл. и записать; настройка относится к встроенным инструментам, а не к reverse_string | 0 | Точное видимое имя тестового инструмента | Проверка пути Always Loaded при включённом Tool Search |
| C | Вкл. | Вкл. | Вкл. и записать | 0 | Пусто | Принудительный отложенный путь: наблюдаем search_tools и целевой вызов |
| D | Вкл. | Как в C | Как в C | 0 | Пусто | Сначала квалифицировать второе подключение режимом A, при необходимости B, затем без других изменений повторить C |
Временный Threshold 0 важен: обычное правило откладывает только определения длиннее заданного числа символов. Маленький reverse_string при стандартном пороге может остаться полностью загруженным, и режим C проверит не тот путь. После диагностики верните рабочие значения.
Режим A: сначала докажите базовый Native-вызов
В Settings → Admin → Interface → Chat выключите Tool Search, сохраните, снова откройте страницу и убедитесь в фактическом значении. Затем откройте новый чат и отправьте фиксированный prompt. Один перезапуск сам по себе не доказывает, что настройка изменилась.
- A пройден: права пользователя, Native, этот маршрут модели и выполнение Workspace Tool работают хотя бы на минимальном примере.
- Нет целевого структурированного вызова: проверьте выбор инструмента в чате, права чтения, фактический Function Calling и поддержку native structured tool calls у backend.
- Вызов есть, выполнение упало: модель дошла до стадии вызова; смотрите аргументы, schema и логи исполнения Open WebUI.
Пока A не пройден, Tool Search диагностировать рано.
Режим B: проверьте Always Loaded
На той же странице включите Tool Search, включите и запишите Defer Built-in Tools, задайте Deferral Threshold (characters) равным 0, а в Always Loaded Tools добавьте точное имя тестового инструмента, которое видит модель. Сохраните, снова откройте страницу для проверки и используйте новый чат.
Сопоставление Always Loaded чувствительно к регистру; допустимы точные имена и glob-паттерны. Для MCP имя, которое видит модель, обычно выглядит как <server ID>_<tool name>. Копируйте его из фактического списка или trace, а не из внутреннего имени метода на MCP-сервере.
- B пройден: сам факт включения Tool Search не ломает соединение; инструмент работает, когда его полная schema остаётся в запросе.
- A пройден, B нет: проверьте сохранённые и повторно прочитанные значения UI, видимое имя и регистр, реальный источник конфигурации и тот ли экземпляр Open WebUI вы тестируете.
Режим C: принудительно проверьте отложенный инструмент
Оставьте Tool Search и Defer Built-in Tools включёнными, Threshold равным 0, очистите Always Loaded Tools, сохраните и повторно проверьте фактические значения. Затем в новом чате повторите prompt.
Отдельно запишите два этапа:
- был ли вызван
search_tools; - вернул ли он определение
reverse_string; - появился ли после этого целевой структурированный вызов;
- в Open WebUI v0.12.2 и новее появился ли
call_tool, а егоtool_nameи JSON-аргументы указывают ли наreverse_stringиtool-check-7; - был ли действительно выполнен
reverse_stringи вернулся ли ожидаемый результат; - не выбрала ли модель другой инструмент, не вывела ли предполагаемый вызов простым текстом и не отказалась ли от вызова совсем.
Если A и B проходят, а в C нет даже search_tools, проверьте фактические значения UI, Threshold, версию и способность модели/маршрута выбрать помощник Tool Search. Если search_tools успешен, но целевого структурированного вызова нет, оставьте в диагностике capability модели, видимые имя/schema, реальный provider route, версию и совместимость с отложенным путём.
Строгий backend нужно оценивать с учётом версии. В Open WebUI v0.12.2 и новее отложенный инструмент вызывается через уже объявленный call_tool с tool_name и JSON-аргументами, что поддерживает backend, разрешающие только инструменты из текущего списка tools. Более ранние версии вызывали отложенный инструмент напрямую по его имени, и строгий backend мог отказать. Перед применением старого Issue проверьте установленную версию. Публичный Issue остаётся пользовательским отчётом об одном развёртывании и одном семействе backend, а не универсальным правилом.
Режим D: поменяйте только подключение модели
Метки Native недостаточно, чтобы считать второе подключение контрольным для deferred tools. Сначала запишите точный Model ID, реальный provider/gateway, Base URL или маршрут и версию Open WebUI. При выключенном Tool Search прогоните через это подключение тот же read-only режим A, при необходимости — B. Только если второе подключение проходит обычный путь и Always Loaded, повторите C как режим D, не меняя инструмент, prompt, значения UI, Threshold и пустое поле Always Loaded.
- D проходит, C нет: отличающимся фактором является исходный маршрут модели. Его можно оставить для обычного чата, а deferred tools запускать через проверенный маршрут.
- Второе подключение не проходит A или B: оно ещё не является валидным контролем deferred compatibility; сначала исправьте или замените baseline.
- A/B проходят на обоих подключениях, но C и D не проходят: сохраните ветку «оба реальных backend/маршрута не поддерживают deferred flow этой версии». Разные имена моделей могут вести к одному строгому provider, gateway или router. Сверьте реальные маршруты и версию, затем разделите диагностику по тому, сработал ли
search_toolsи появился ли целевой структурированный вызов; не сводите результат только к конфигурации, имени, версии или исполнению. - C и D проходят: причина, вероятнее всего, в видимом определении конкретного производственного инструмента, выборе операции, аргументах, правах или сервере.
Выберите исправление по фактам
| Результат | Что делать |
|---|---|
| A не проходит, целевой tool call отсутствует | Исправить права, включение инструмента в чате, Native или выбрать backend с реальным native function calling |
A и B проходят, в C нет search_tools | Проверить фактические значения UI, Threshold, установленную версию и способность модели/маршрута выбрать помощник Tool Search |
search_tools успешен, но целевого структурированного вызова нет | Проверить capability модели, видимые имя/schema, реальный provider route, версию и deferred compatibility; минимальный fallback — Always Loaded или отключение Tool Search |
Целевой вызов есть, но reverse_string не выполнен | Проверить execution logs Open WebUI, цель и аргументы call_tool |
| A–C проходят, реальный инструмент нет | Проверить его определение, видимое модели, выбранную операцию, аргументы, обработку Tool Search, реальный маршрут, доступ и серверные доказательства |
| Не работает только одно квалифицированное подключение | Сохранить его для текста; инструментальные задачи отправлять через подключение, прошедшее те же A/B/C |
| Оба квалифицированных подключения не проходят C/D | Сохранить ветку несовместимости обоих backend или общего маршрута и сравнить search_tools, целевой вызов, реальный route и версию |
При небольшом количестве инструментов отключение экспериментального Tool Search обычно проще и надёжнее. Если schemas много и они большие, оставьте Tool Search, но поместите ежедневные низкорисковые инструменты в Always Loaded и отдельно сертифицируйте каждое подключение.
После локального теста проверьте MCP или OpenAPI
Успешный reverse_string доказывает только то, что этот маршрут умеет вызвать один простой Workspace Tool со schema из одной строки. Это не доказывает, что та же модель выберет сложный производственный инструмент, правильную операцию, сформирует допустимые аргументы или завершит многошаговый внешний сценарий. Документация Open WebUI для MCP и OpenAPI прямо сохраняет эти ограничения модели даже при рабочем подключении.
До перехода к серверной диагностике сохраните определение производственного инструмента именно в том виде, в котором его видит модель, и фактические данные целевого вызова:
- Целевого вызова нет, выбрана не та операция или аргументы неверны: не исключайте capability модели, имя/описание/schema инструмента, Tool Search и реальный маршрут модели/provider.
- Правильный структурированный вызов отправлен, но не дошёл до сервера или вернул transport/authentication error: переходите к URL, access control, авторизации, протоколу, proxy, TLS и серверу.
- Сервер получил правильную операцию, но отверг аргументы или вернул application error: сравните вызов с видимой schema и проверьте обработку на сервере.
MCP: транспорт, права и имя
Нативное подключение Open WebUI использует MCP (Streamable HTTP). Сервер только со stdio нельзя подключить как HTTP MCP без подходящего proxy/bridge.
Проверьте:
- выбран Type MCP, а не OpenAPI;
- Streamable HTTP URL доступен из контейнера или хоста Open WebUI;
- авторизация действует для тестового пользователя;
- Access Control включает этого пользователя;
- полное определение и имя, видимые модели, соответствуют формату
<server ID>_<tool name>; - модель выбрала правильную цель и допустимые аргументы;
- правильный вызов попал в логи MCP-сервера;
- сервер вернул результат протокола, а не HTTP, authorization или application error.
Если правильного целевого вызова нет, оставайтесь в ветке модель/schema/Tool Search/route. Если правильный структурированный вызов есть, но сервер его не видит, проверяйте URL, reverse proxy, TLS и сеть. Если сервер получил правильную операцию, но отверг аргументы, сравните их с schema, показанной модели.
OpenAPI: убедитесь, что операции обнаружены
Open WebUI извлекает операции из структуры path-item OpenAPI 3.x. Проверьте стандартные HTTP-методы, пригодные определения параметров, а также стабильные имена и описания, по которым модель может отличить нужную операцию.
Сохраните:
- URL и версию spec;
- имена и определения, которые Open WebUI фактически показал модели;
- выбранную моделью операцию и аргументы структурированного вызова;
- access log сервера и HTTP status;
- body, который Open WebUI вернул модели.
Сохранённое подключение ещё не означает рабочее выполнение. Ошибка проверки /models тоже не всегда означает несовместимость чата или инструментов: некоторые OpenAI-compatible сервисы не реализуют стандартный /models. В таком случае вручную укажите точный Model ID и решайте по A/B/C и реальному вызову производственного инструмента.
Опциональный контроль через BetterToken
Можно сохранить исходное подключение и добавить ещё одно OpenAI-compatible подключение. Base URL BetterToken:
https://www.bettertoken.ai/v1
Возьмите из текущего каталога точный Model ID, у которого supported_endpoint_types содержит openai, и используйте собственный API key. Не угадывайте ID по названию в интерфейсе и не считайте успешный обычный чат доказательством Tool Search.
На новом подключении также выполните A–D. В этой схеме BetterToken — только альтернативный API-маршрут и источник данных об использовании запросов, а не обещание исправить Open WebUI, модель или экспериментальную функцию.
Полезные ссылки:
- Open WebUI Tools
- Разработка Workspace Tool
- OpenAI-compatible подключения
- Open WebUI MCP
- OpenAPI Tool Servers
- BetterToken Chat Completions
- Текущий каталог моделей и протоколов BetterToken
Сохраните воспроизводимую карточку
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:
Такую карточку можно повторить после обновления Open WebUI, смены модели или миграции MCP/OpenAPI.
С чего начать
Не удаляйте подключения и не переделывайте весь MCP. Сначала в Native отключите Tool Search, вызовите reverse_string со строкой tool-check-7 и добейтесь трёх доказательств: структурированного вызова, записи исполнения и результата 7-kcehc-loot.
Только после этого включайте принудительную отложенную загрузку, проверяйте Always Loaded и сравнивайте model connection. Тогда решение будет основано на наблюдаемой границе сбоя, а не на словах модели.