Open WebUI n’appelle pas les outils : vérifier Native Mode, Tool Search et la compatibilité
Une matrice de quatre tests distingue les problèmes de visibilité et de droits dans Open WebUI, le chargement différé de Tool Search, le backend du modèle et l’exécution MCP/OpenAPI, sans supprimer la connexion initiale.
Sommaire

L’outil est activé et le modèle affirme qu’il va l’utiliser, mais aucune vraie tool call n’apparaît. Ce symptôme ne suffit pas à désigner le modèle, Open WebUI ou le serveur MCP/OpenAPI. La méthode la plus fiable consiste à établir une référence avec un petit reverse_string sans effet de bord, puis à modifier séparément Native Mode, Tool Search et la connexion du modèle.
La connexion d’origine reste intacte. À la fin, vous disposerez de quatre conditions comparables, appuyées par des traces d’appel et d’exécution. Vous pourrez alors choisir le correctif minimal : désactiver Tool Search, conserver les outils critiques dans Always Loaded ou utiliser une connexion ayant réussi le même test.
Découper le parcours en cinq couches
Voir un outil activé dans l’interface ne confirme que l’état de l’interface. Pour obtenir une exécution réelle, cinq couches doivent fonctionner.
| Couche | Ce qui doit être vrai | Symptôme trompeur |
|---|---|---|
| 1. Visibilité et accès | L’utilisateur actuel peut voir et lire l’outil | Il fonctionne pour un administrateur, mais disparaît silencieusement pour un autre utilisateur |
| 2. Chat, mode et capacité | Le chat utilise Native et l’outil cible est activé ; pour un outil système intégré, Workspace → Models → Capabilities → Builtin Tools et la catégorie concernée le sont aussi | Builtin Tools est désactivé ou pris à tort pour un interrupteur global de Workspace, MCP et OpenAPI |
| 3. Charge de la requête | Le backend reçoit la définition complète ou les helpers d’outil différé pris en charge par la version installée | Tool Search diffère le schema alors que l’interface affiche toujours l’outil |
| 4. Backend du modèle | Le backend renvoie l’appel structuré de la bonne cible avec des arguments valides | Le modèle affirme en texte avoir appelé l’outil, choisit une autre opération ou produit de mauvais arguments |
| 5. Exécution | Open WebUI, MCP ou le serveur OpenAPI exécute le bon appel et renvoie le résultat | Le bon appel existe, mais l’authentification, la route, le protocole ou le serveur échoue |
Diagnostiquez de haut en bas. Reconstruire MCP avant de vérifier l’accès et l’appel cible peut détruire des preuves utiles.
Conserver l’état initial
Avant toute modification, notez au minimum :
- la version d’Open WebUI et le mode de déploiement ;
- le nom de la connexion, le Model ID exact, le nom affiché et le provider, gateway, Base URL ou routage réel ;
- la valeur effective de Model Settings → Advanced Params → Function Calling ;
- pour un outil intégré, l’état de Workspace → Models → Capabilities → Builtin Tools et des catégories utiles ;
- les outils activés dans le chat via Integrations → Tools et le droit de lecture de l’utilisateur de test ;
- les quatre valeurs réellement affichées dans Settings → Admin → Interface → Chat : Tool Search, Defer Built-in Tools, Deferral Threshold (characters) et Always Loaded Tools ;
- leurs noms complets :
ENABLE_TOOL_SEARCH,TOOL_SEARCH_DEFER_BUILTIN_TOOLS,TOOL_SEARCH_DEFER_THRESHOLDetTOOL_SEARCH_ALWAYS_LOADED; - si le problème touche un outil système intégré, une Workspace Tool, MCP ou OpenAPI ;
- un prompt en échec, son heure, un export ou une capture du chat et les logs Open WebUI/serveur du même intervalle.
Une connexion peut être désactivée par son interrupteur sans supprimer sa configuration. Pour comparer, créez une connexion séparée, par exemple control-tool-test, sans écraser celle de production.
Séparez deux affirmations :
- Le chat normal fonctionne : seule une requête texte a abouti.
- L’appel d’outils fonctionne : il faut l’appel structuré cible, des arguments valides, une trace d’exécution et le résultat renvoyé.
Une phrase comme « j’ai utilisé reverse_string » ne constitue pas une preuve.
Confirmer que le chat utilise réellement Native Mode
La documentation actuelle d’Open WebUI présente Native comme mode par défaut et pris en charge. Legacy reste une option non prise en charge pour l’ancien comportement.
Vérifiez les trois niveaux susceptibles de se remplacer :
- les Model Defaults globaux ;
- les Advanced Params du modèle choisi ;
- les Chat Controls de la conversation actuelle.
Pour le test, fixez la valeur effective sur Native. Ne mélangez pas un essai de Legacy avec le diagnostic de Tool Search, qui concerne Native Mode.
Si la fonction manquante est un outil système intégré d’Open WebUI, ouvrez Workspace → Models, modifiez le modèle sélectionné et vérifiez Capabilities. Builtin Tools et la catégorie nécessaire doivent être activés. Ce réglage contrôle uniquement l’injection des outils système intégrés en Native Mode ; ce n’est pas un interrupteur global pour la Workspace Tool reverse_string, MCP ou OpenAPI.
Pour Workspace, MCP et OpenAPI, vérifiez leurs contrôles distincts :
- ouvrez Integrations près de la zone de saisie ;
- choisissez Tools et activez l’outil de diagnostic ou externe pour ce chat ;
- s’il est attaché au modèle, vérifiez malgré tout le droit de lecture de l’utilisateur actuel.
Attacher une Workspace Tool au modèle ne contourne pas le contrôle d’accès. Sans droit de lecture, Open WebUI peut l’omettre avant de l’envoyer au modèle.
Créer un outil minimal en lecture seule
Workspace Tools exécute du Python dans l’environnement Open WebUI. Seuls des administrateurs de confiance doivent créer ou importer ce code. Pour le diagnostic, utilisez une fonction qui ne touche ni aux fichiers, ni au réseau, ni aux bases de données, ni aux commandes système.
Dans Workspace → Tools, créez :
"""
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:
"""
Inverse le texte fourni sans lire ni modifier de données externes.
:param string: Texte à inverser exactement.
:return: Texte dans l’ordre inverse.
"""
return string[::-1]
Enregistrez l’outil, accordez l’accès à l’utilisateur de test, puis activez-le dans Integrations → Tools.
Dans un nouveau chat, utilisez toujours le même prompt :
Vous devez utiliser l’outil reverse_string sur la chaîne tool-check-7.
Ne l’inversez pas vous-même et ne devinez pas.
Après le retour de l’outil, affichez uniquement son résultat.
Résultat attendu :
7-kcehc-loot
Le bon texte ne suffit pas pour déclarer un PASS. Exigez les quatre signaux :
- une tool call structurée vers
reverse_string; - l’argument
tool-check-7; - une trace d’exécution correspondante dans Open WebUI ou le serveur ;
- le retour
7-kcehc-loot, repris par la réponse finale.
Conservez le chat, les détails de l’appel et les lignes de log portant le même horaire. Exécutez chaque condition suivante dans un nouveau chat.
Comparer quatre conditions contrôlées
Ne changez qu’une variable à la fois et utilisez l’Admin UI existante, pas seulement les noms de variables d’environnement :
- Ouvrez Settings → Admin → Interface → Chat.
- Réglez Tool Search, Defer Built-in Tools, Deferral Threshold (characters) et Always Loaded Tools pour chaque condition.
- Enregistrez, rouvrez la page et notez les valeurs effectivement affichées.
- Ouvrez un nouveau chat et exécutez le même prompt fixe.
Les quatre champs correspondent à ENABLE_TOOL_SEARCH, TOOL_SEARCH_DEFER_BUILTIN_TOOLS, TOOL_SEARCH_DEFER_THRESHOLD et TOOL_SEARCH_ALWAYS_LOADED ; tous sont des ConfigVar. Avec la valeur par défaut ENABLE_PERSISTENT_CONFIG=True, les valeurs déjà enregistrées dans l’Admin UI/base de données sont prioritaires sur les variables d’environnement. Modifier .env puis redémarrer ne garantit donc pas que la condition ait changé. Si le déploiement utilise volontairement ENABLE_PERSISTENT_CONFIG=False, notez-le : les valeurs d’environnement font autorité au démarrage, tandis que les modifications UI ne durent que pendant la session en cours et sont perdues après redémarrage.
| Condition | Native | Tool Search | Defer Built-in Tools | Seuil | Always Loaded | Objectif |
|---|---|---|---|---|---|---|
| A | Oui | Non | Noter la valeur actuelle ; sans effet sur cette Workspace Tool | Sans objet | Sans objet | Baseline avec la définition complète de reverse_string |
| B | Oui | Oui | Oui et noté ; concerne les outils intégrés, pas reverse_string | 0 | Nom exact visible par le modèle | Vérifier le chemin Always Loaded |
| C | Oui | Oui | Oui et noté | 0 | Vide | Forcer le chemin différé et observer search_tools puis l’appel cible |
| D | Oui | Comme C | Comme C | 0 | Vide | Qualifier d’abord la seconde connexion avec A, et B si nécessaire, puis répéter C |
Le seuil 0 est important. La règle normale ne diffère que les définitions sérialisées plus longues que le nombre configuré. Une petite fonction comme reverse_string peut rester entièrement chargée avec le seuil par défaut ; C ne testerait alors pas le chemin différé. Restaurez les valeurs de production après le diagnostic.
Condition A : prouver d’abord le chemin Native de base
Dans Settings → Admin → Interface → Chat, désactivez Tool Search, enregistrez, rouvrez la page et vérifiez la valeur effective. Utilisez ensuite un nouveau chat avec le prompt fixe. Un redémarrage seul ne prouve pas que la valeur a changé.
- A réussit : l’accès, Native, cette route modèle et l’exécution de Workspace Tool fonctionnent sur le cas minimal.
- Aucun appel structuré cible : vérifiez la sélection de l’outil, le droit de lecture, le Function Calling effectif et la prise en charge des appels structurés natifs par le backend.
- L’appel existe mais l’exécution échoue : le modèle a atteint l’étape de l’appel ; vérifiez arguments, schema et logs d’exécution Open WebUI.
Tant que A échoue, ne diagnostiquez pas Tool Search.
Condition B : vérifier Always Loaded
Dans la même interface, activez Tool Search, activez et notez Defer Built-in Tools, fixez Deferral Threshold (characters) à 0 et ajoutez dans Always Loaded Tools le nom exact vu par le modèle. Enregistrez, rouvrez et vérifiez avant d’utiliser un nouveau chat.
La correspondance Always Loaded respecte la casse et accepte un nom exact ou un glob. Pour MCP, le nom visible ressemble généralement à <server ID>_<tool name>. Copiez-le depuis la liste réelle ou le trace, pas depuis le nom interne de la méthode.
- B réussit : Tool Search peut rester actif et l’outil fonctionne lorsque son schema complet reste dans la requête.
- A réussit mais B échoue : vérifiez les valeurs enregistrées et relues, le nom et la casse, la vraie source de configuration et l’instance testée.
Condition C : forcer le chemin différé
Laissez Tool Search et Defer Built-in Tools actifs, le seuil à 0, videz Always Loaded Tools, enregistrez puis relisez les valeurs. Exécutez ensuite le même prompt dans un nouveau chat.
Notez séparément les deux étapes :
- un appel à
search_toolsa-t-il eu lieu ? - a-t-il renvoyé la définition de
reverse_string? - l’appel structuré cible est-il apparu ensuite ?
- avec Open WebUI v0.12.2 ou ultérieur,
call_toolest-il apparu et sestool_name/arguments JSON ciblent-ilsreverse_stringettool-check-7? reverse_stringa-t-il réellement été exécuté avec le résultat attendu ?- le modèle a-t-il choisi un autre outil, écrit une pseudo-call en texte ou n’a-t-il rien appelé ?
Si A et B réussissent mais que C ne produit même pas search_tools, vérifiez les valeurs UI effectives, le seuil, la version et la capacité du modèle/route à sélectionner le helper. Si search_tools réussit sans appel cible, gardez ouvertes les branches capacité du modèle, nom/schema visible, route réelle du provider, version et compatibilité différée.
Le comportement d’un backend strict dépend de la version. Depuis Open WebUI v0.12.2, l’outil différé est invoqué via le call_tool déjà déclaré, avec tool_name et arguments JSON, ce qui permet de travailler avec les backends n’acceptant que les outils de la liste tools courante. Les anciennes versions appelaient directement le nom différé et pouvaient être rejetées. Vérifiez la version avant d’appliquer un ancien Issue ; un Issue public reste un retour utilisateur sur un déploiement et une famille de backend, pas une règle universelle.
Condition D : changer uniquement la connexion du modèle
Le libellé Native ne suffit pas à qualifier la seconde connexion comme contrôle de compatibilité différée. Notez son Model ID exact, son provider/gateway réel, sa Base URL ou route et la version d’Open WebUI. Avec Tool Search désactivé, exécutez d’abord le même test read-only A, puis B si nécessaire. Ce n’est qu’après avoir réussi le chemin ordinaire et Always Loaded qu’il faut répéter C comme D, sans modifier outil, prompt, valeurs UI, seuil ni champ Always Loaded vide.
- D réussit et C échoue : la route modèle d’origine est le facteur différenciant. Gardez-la pour le chat texte si utile et utilisez la route validée pour les outils différés.
- La seconde connexion échoue à A ou B : elle n’est pas encore un contrôle valide ; corrigez ou remplacez cette baseline.
- A/B réussissent sur les deux mais C/D échouent : gardez la branche où les deux backends/routes réels ne prennent pas en charge le flux différé de la version installée. Deux noms de modèles peuvent partager le même provider, gateway ou router strict. Vérifiez route et version, puis décidez selon la réussite de
search_toolset la présence de l’appel cible ; ne réduisez pas le résultat à la configuration, au nom ou à l’exécution. - C et D réussissent : la définition visible, le choix d’opération, les arguments, les droits ou le serveur de l’outil de production deviennent plus probables.
Choisir la plus petite correction
| Preuve | Étape suivante |
|---|---|
| A échoue sans appel cible | Corriger accès, activation dans le chat, Native ou choisir un backend avec de vrais appels natifs |
A/B réussissent, C n’appelle pas search_tools | Vérifier valeurs UI effectives, seuil, version et sélection du helper |
search_tools réussit sans appel cible | Vérifier capacité, nom/schema visible, route réelle, version et compatibilité ; fallback minimal : Always Loaded ou désactiver Tool Search |
L’appel cible existe mais reverse_string n’est pas exécuté | Vérifier logs et cible/arguments de call_tool |
| A–C réussissent mais l’outil réel échoue | Vérifier définition visible, opération choisie, arguments, traitement Tool Search, route, accès et preuves serveur |
| Une seule connexion qualifiée échoue | La conserver pour le texte ; utiliser pour les outils une connexion ayant réussi le même A/B/C |
| Les deux connexions qualifiées échouent à C/D | Conserver la branche d’incompatibilité des deux backends ou d’une route partagée et comparer search_tools, appel cible, route et version |
Avec peu d’outils, désactiver Tool Search est généralement le choix le plus simple et fiable. Avec de nombreux schemas volumineux, conservez-le, mais gardez toujours chargés les outils fréquents et à faible risque, puis qualifiez chaque connexion séparément.
Après le test local, diagnostiquer MCP ou OpenAPI
La réussite de reverse_string prouve seulement que cette route sait appeler une Workspace Tool simple avec un seul string. Elle ne prouve pas que le même modèle choisira un outil externe complexe, la bonne opération, des arguments valides ou terminera un workflow multi-étapes. La documentation MCP et OpenAPI conserve explicitement ces limites, même lorsque la connexion fonctionne.
Avant de passer au serveur, capturez la définition de production telle que le modèle la voit et les preuves de l’appel cible réel :
- Pas d’appel cible, mauvaise opération ou arguments invalides : gardez les branches modèle, nom/description/schema, Tool Search et route réelle.
- Le bon appel structuré est émis mais n’atteint pas le serveur, ou renvoie une erreur transport/auth : vérifiez URL, accès, authentification, protocole, proxy, TLS et serveur.
- Le serveur reçoit la bonne opération mais rejette les arguments ou renvoie une erreur applicative : comparez l’appel au schema exposé et vérifiez le traitement serveur.
MCP : transport, accès et nom visible
La connexion MCP native d’Open WebUI utilise MCP (Streamable HTTP). Un serveur local exposant uniquement stdio nécessite un bridge/proxy approprié.
Vérifiez :
- Type est MCP et non OpenAPI ;
- l’URL Streamable HTTP est accessible depuis l’hôte/conteneur Open WebUI ;
- l’authentification est valide pour l’utilisateur actuel ;
- Access Control inclut l’utilisateur de test ;
- la définition et le nom visibles suivent
<server ID>_<tool name>; - le modèle a choisi la bonne cible avec des arguments valides ;
- le bon appel atteint les logs du serveur MCP ;
- le serveur renvoie un résultat de protocole et non une erreur HTTP, d’autorisation ou applicative.
Sans appel cible correct, restez dans la branche modèle/schema/Tool Search/route. Si l’appel correct existe mais n’atteint pas le serveur, vérifiez URL, proxy, certificats et réseau. S’il arrive mais que les arguments sont rejetés, comparez-les au schema montré au modèle.
OpenAPI : confirmer la découverte des opérations
Open WebUI découvre les opérations via la structure path-item d’OpenAPI 3.x. Vérifiez méthodes HTTP standard, paramètres utilisables et noms/descriptions stables permettant au modèle de distinguer l’opération voulue.
Conservez :
- l’URL et la version de la spécification ;
- les noms et définitions réellement présentés au modèle ;
- l’opération choisie et les arguments structurés ;
- l’access log et le statut de réponse ;
- le body renvoyé au modèle par Open WebUI.
Enregistrer une connexion ne prouve pas son exécution. Un échec de /models ne prouve pas automatiquement l’incompatibilité : certains providers compatibles n’implémentent pas cet endpoint. Saisissez le Model ID exact et décidez avec A/B/C et un appel réel de l’outil de production.
Ajouter éventuellement une connexion BetterToken de comparaison
Conservez la connexion initiale et ajoutez une connexion OpenAI-compatible. L’API Base URL de BetterToken est :
https://www.bettertoken.ai/v1
Dans le catalogue actuel, choisissez un Model ID exact dont supported_endpoint_types contient openai, puis utilisez votre propre API key. Ne déduisez pas l’ID du nom affiché. Un chat normal réussi ne certifie pas Tool Search.
Exécutez aussi A–D sur cette connexion. BetterToken sert ici de chemin API alternatif et de point d’observation de l’usage des requêtes ; ce n’est pas une preuve de correction d’Open WebUI, du modèle ou de Tool Search.
Références :
- Open WebUI Tools
- Développement de Workspace Tools
- Connexions OpenAI-compatible
- Open WebUI MCP
- OpenAPI Tool Servers
- BetterToken Chat Completions
- Catalogue des modèles et protocoles
Conserver une fiche reproductible
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:
Cette fiche devient un test de régression après une mise à jour, un changement de modèle ou une migration du serveur.
Commencer par une vraie call
Gardez la connexion initiale, utilisez Native, désactivez Tool Search et lancez reverse_string avec tool-check-7. N’activez le report forcé et la comparaison de connexions qu’après avoir vu une call structurée, une exécution et 7-kcehc-loot.
Vous saurez alors si la correction minimale concerne les droits, le mode, Always Loaded, Tool Search, le backend ou le serveur externe, sans vous fier à une affirmation rédigée par le modèle.