Le Protocole de Contexte de Modèle (MCP) a révolutionné la façon dont les grands modèles de langage (LLM) interagissent avec les outils et les sources de données externes. Cependant, à mesure que le nombre d'outils disponibles augmente, la fenêtre de contexte nécessaire pour les décrire s'agrandit également. Cette « surcharge de contexte » peut dégrader les performances du modèle, augmenter la latence et faire grimper les coûts d'API. La mise en œuvre d'un filtrage intelligent des outils n'est plus optionnelle ; c'est une pratique d'ingénierie essentielle pour des implémentations MCP évolutives.
Le problème : La surcharge de contexte dans MCP
Lorsqu'un serveur MCP enregistre un grand nombre d'outils, chaque définition d'outil — y compris son nom, sa description, son schéma d'entrée et les contraintes de ses paramètres — consomme des jetons dans le prompt système. Par exemple, un serveur avec 50 outils peut ajouter 10 000 à 15 000 jetons à chaque requête. Cette surcharge encombre la requête utilisateur réelle et l'historique de la conversation, obligeant le LLM à fonctionner avec une fenêtre de contexte effective plus petite. De plus, des définitions d'outils excessives peuvent confondre le modèle, entraînant des erreurs de sélection d'outils ou des hallucinations.
Stratégie : Élagage dynamique avant l'inférence
La solution réside dans le filtrage dynamique des outils avant qu'ils ne soient envoyés au LLM. Au lieu d'envoyer la liste complète des outils disponibles, le client MCP ne devrait inclure que ceux pertinents pour le contexte actuel. Cela peut être réalisé grâce à plusieurs stratégies :
- Filtrage basé sur l'intention : Utilisez un classifieur léger ou une correspondance de mots-clés pour prédire quelles catégories d'outils sont pertinentes pour la requête de l'utilisateur.
- Accès basé sur le rôle : Limitez les outils en fonction du rôle ou des autorisations de l'utilisateur, en veillant à n'exposer que les outils autorisés.
- Récence et fréquence : Priorisez les outils utilisés récemment ou fréquemment, en supposant qu'ils sont plus susceptibles d'être pertinents.
- Similarité d'intégration (Embedding) : Intégrez (embed) la requête de l'utilisateur et les descriptions des outils, puis sélectionnez les outils ayant la plus grande similarité sémantique.
Exemple d'implémentation
Voici un exemple simplifié en Python démontrant comment filtrer les outils en fonction de la similarité sémantique à l'aide d'intégrations de phrases. Cette approche est robuste et évolutive pour de grands ensembles d'outils.
import numpy as np
from sentence_transformers import SentenceTransformer
# Charger un modèle pré-entraîné pour l'intégration
model = SentenceTransformer('all-MiniLM-L6-v2')
def filter_tools_by_relevance(user_query, tools, top_k=10):
"""
Filtrer les outils en fonction de la similarité sémantique avec la requête de l'utilisateur.
Args:
user_query (str): L'entrée de l'utilisateur.
tools (list): Liste d'objets d'outils avec 'name', 'description' et 'schema'.
top_k (int): Nombre d'outils supérieurs à retourner.
Returns:
list: Les k outils les plus pertinents.
"""
# Préparer les textes pour l'intégration
tool_texts = [f"{tool['name']}: {tool['description']}" for tool in tools]
# Générer les intégrations
query_embedding = model.encode(user_query)
tool_embeddings = model.encode(tool_texts)
# Calculer la similarité cosinus
query_embedding = query_embedding / np.linalg.norm(query_embedding)
tool_embeddings = tool_embeddings / np.linalg.norm(tool_embeddings, axis=1, keepdims=True)
similarities = np.dot(tool_embeddings, query_embedding.T)
# Obtenir les indices des k similarités les plus élevées
top_indices = np.argsort(similarities)[::-1][:top_k]
return [tools[i] for i in top_indices]
# Exemple d'utilisation
all_tools = [
{"name": "search_web", "description": "Search the web for current information.", "schema": {...}},
{"name": "calculate", "description": "Perform mathematical calculations.", "schema": {...}},
{"name": "send_email", "description": "Send an email to a recipient.", "schema": {...}},
# ... des centaines d'autres outils
]
user_query = "What is the stock price of Apple today?"
relevant_tools = filter_tools_by_relevance(user_query, all_tools, top_k=5)
print(f"Selected {len(relevant_tools)} tools for inference:")
for tool in relevant_tools:
print(f"- {tool['name']}")
Dans cet exemple, l'outil `search_web` est susceptible d'être sélectionné en raison de sa forte similarité sémantique avec la requête sur les cours de bourse, tandis que `calculate` ou `send_email` sont élagués. Cela réduit considérablement la taille du contexte tout en maintenant une haute pertinence.
Meilleures pratiques et considérations
- Mise en cache : Mettez en cache les intégrations des descriptions d'outils pour éviter de les recalculer à chaque requête.
- Mécanisme de secours : Si aucun outil ne atteint un seuil de similarité, envisagez de retourner un ensemble par défaut d'outils polyvalents ou un message « aucun outil disponible ».
- Surveillance : Suivez quels outils sont sélectionnés et utilisés par le LLM pour affiner votre stratégie de filtrage au fil du temps.
- Compromis sur la latence : Assurez-vous que le processus de filtrage lui-même n'ajoute pas de latence significative. Utilisez des modèles d'intégration efficaces et des bases de données vectorielles si le nombre d'outils est très élevé.
Conclusion
Le filtrage intelligent des outils est une optimisation cruciale pour tout système MCP de qualité de production. En élaguant dynamiquement les définitions d'outils inutilisés avant l'inférence LLM, vous pouvez réduire la surcharge de contexte, améliorer la précision du modèle et diminuer les coûts opérationnels. À mesure que l'écosystème MCP mûrit et que les registres d'outils grandissent, investir dans des stratégies de filtrage efficaces sera essentiel pour fournir des applications IA rapides, fiables et rentables.