rts-commander / tests /scripts /qwen_mcp_evaluation.py
Luigi's picture
Organize project structure: move test scripts to tests/scripts and documentation to docs/reports
d28c36c
"""
Évaluation des capacités MCP de Qwen2.5 0.5B
Test maintenant que le modèle fonctionne correctement
"""
import sys
import os
import json
import time
# Ajouter le chemin pour les imports
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
def test_qwen_mcp_capabilities():
"""Test des capacités MCP avec le modèle fonctionnel"""
print("🔍 ÉVALUATION DES CAPACITÉS MCP DE QWEN2.5 0.5B")
print("=" * 70)
# Importer et initialiser le modèle
try:
from llama_cpp import Llama
model_path = "qwen2.5-0.5b-instruct-q4_0.gguf"
print("🔄 Initialisation du modèle...")
llm = Llama(
model_path=model_path,
n_ctx=2048,
n_threads=2,
verbose=False
)
print("✅ Modèle initialisé avec succès\n")
except Exception as e:
print(f"❌ Erreur d'initialisation: {e}")
return
# Tests MCP
tests = [
{
"name": "Compréhension MCP de base",
"prompt": """Tu es un assistant IA qui contrôle un jeu RTS via MCP (Model Context Protocol).
Outils MCP disponibles:
- get_game_state(): Obtenir l'état actuel du jeu
- move_units(unit_ids, target_x, target_y): Déplacer des unités
Commande utilisateur: "Montre-moi l'état du jeu"
Réponds avec un objet JSON contenant l'appel d'outil MCP à exécuter.
""",
"expected_tool": "get_game_state"
},
{
"name": "Traduction d'action simple",
"prompt": """Tu es un assistant IA qui contrôle un jeu RTS via MCP.
Outils MCP disponibles:
- move_units(unit_ids, target_x, target_y): Déplacer des unités
Commande utilisateur: "Déplace mon infanterie vers la position 150, 200"
Réponds avec un objet JSON contenant l'appel d'outil avec les paramètres extraits.
""",
"expected_tool": "move_units"
},
{
"name": "Extraction de paramètres complexes",
"prompt": """Tu es un assistant IA qui contrôle un jeu RTS via MCP.
Outils MCP disponibles:
- move_units(unit_ids, target_x, target_y): Déplacer des unités
Commande utilisateur: "Déplace les tanks 1, 3 et 7 vers les coordonnées 120, 80"
Extrais les paramètres et réponds avec un objet JSON d'appel d'outil.
""",
"expected_tool": "move_units"
},
{
"name": "Planification stratégique",
"prompt": """Tu es un assistant IA qui contrôle un jeu RTS via MCP.
Outils MCP disponibles:
- get_game_state(): Obtenir l'état du jeu
- move_units(): Déplacer des unités
- attack_unit(): Attaquer l'ennemi
- build_building(): Construire un bâtiment
Commande utilisateur: "Construis une base près du minerai et défends-la"
Décompose cette stratégie en une séquence d'actions MCP.
""",
"expected_complex": True
},
{
"name": "Gestion d'ambiguïté",
"prompt": """Tu es un assistant IA qui contrôle un jeu RTS via MCP.
Outils MCP disponibles:
- move_units(unit_ids, target_x, target_y): Déplacer des unités
Commande utilisateur: "Déplace mes unités vers la base ennemie"
Comment gérerais-tu cette instruction ambiguë?
""",
"expected_clarification": True
}
]
results = []
for i, test in enumerate(tests, 1):
print(f"🧪 TEST {i}: {test['name']}")
print("-" * 50)
try:
start_time = time.time()
# Utiliser le chat template pour de meilleurs résultats
messages = [
{"role": "system", "content": "Tu es un assistant IA spécialisé dans les jeux RTS et le protocole MCP. Réponds avec des objets JSON valides."},
{"role": "user", "content": test['prompt']}
]
# Utiliser la méthode standard pour llama-cpp-python
response = llm.create_chat_completion(
messages=messages,
max_tokens=300,
temperature=0.1
)
response_time = time.time() - start_time
# Extraire le texte de la réponse correctement
if response and 'choices' in response and len(response['choices']) > 0:
response_text = response['choices'][0]['message']['content']
else:
# Fallback: utiliser la méthode simple
simple_response = llm(test['prompt'], max_tokens=300, temperature=0.1)
response_text = simple_response['choices'][0]['text'] if 'choices' in simple_response else str(simple_response)
print(f"⏱️ Temps de réponse: {response_time:.2f}s")
print(f"📝 Réponse: {response_text[:300]}...")
# Analyser la réponse
score = analyze_mcp_response(response_text, test)
results.append({
'test': test['name'],
'response': response_text,
'response_time': response_time,
'score': score,
'success': score >= 5
})
print(f"📊 Score: {score}/10")
except Exception as e:
print(f"❌ Erreur: {e}")
results.append({
'test': test['name'],
'error': str(e),
'score': 0,
'success': False
})
print()
# Générer le rapport final
generate_evaluation_report(results)
def analyze_mcp_response(response, test_config):
"""Analyser la réponse MCP et la noter"""
if not response or response.strip() == "":
return 0
score = 0
# Vérifier la structure JSON
try:
json_data = json.loads(response)
score += 3 # JSON valide
# Vérifier la présence d'outils MCP
if 'tool' in json_data:
score += 2
if 'args' in json_data:
score += 1
except json.JSONDecodeError:
# Vérifier les patterns dans le texte
mcp_tools = ["get_game_state", "move_units", "attack_unit", "build_building"]
tools_found = [tool for tool in mcp_tools if tool in response]
if tools_found:
score += 2
if any(param in response for param in ['unit_ids', 'target_x', 'target_y']):
score += 1
# Vérifier la cohérence sémantique
if 'game' in response.lower() or 'rts' in response.lower():
score += 1
# Vérifier la pertinence par rapport au test
if 'expected_tool' in test_config:
if test_config['expected_tool'] in response:
score += 2
elif test_config.get('expected_complex'):
if any(word in response.lower() for word in ['sequence', 'steps', 'build', 'defend']):
score += 2
elif test_config.get('expected_clarification'):
if any(word in response.lower() for word in ['clarify', 'coordinates', 'which', 'ambiguous']):
score += 2
return min(score, 10)
def generate_evaluation_report(results):
"""Générer un rapport d'évaluation complet"""
print("=" * 70)
print("📊 RAPPORT D'ÉVALUATION MCP")
print("=" * 70)
successful_tests = [r for r in results if r.get('success', False)]
total_score = sum(r.get('score', 0) for r in results)
avg_score = total_score / len(results) if results else 0
print(f"\n📈 STATISTIQUES:")
print(f" Tests réussis: {len(successful_tests)}/{len(results)}")
print(f" Score moyen: {avg_score:.1f}/10")
print(f"\n🔍 DÉTAILS PAR TEST:")
for result in results:
status = "✅" if result.get('success', False) else "❌"
print(f" {status} {result['test']}: {result.get('score', 0)}/10")
if 'response_time' in result:
print(f" ⏱️ Temps: {result['response_time']:.2f}s")
print(f"\n🎯 ÉVALUATION FINALE:")
if avg_score >= 8:
print("💪 EXCELLENT - Qwen2.5 0.5B est très capable pour les tâches MCP")
recommendation = "UTILISER AVEC CONFIANCE"
elif avg_score >= 6:
print("👍 BON - Qwen2.5 0.5B est capable avec quelques limitations")
recommendation = "UTILISER AVEC VALIDATION"
elif avg_score >= 4:
print("⚠️ MODÉRÉ - Limitations significatives")
recommendation = "UTILISER POUR TÂCHES SIMPLES"
else:
print("❌ FAIBLE - Pas adapté aux tâches MCP")
recommendation = "CONSIDÉRER AUTRE SOLUTION"
print(f"💡 RECOMMANDATION: {recommendation}")
print(f"\n🚀 PROCHAINES ÉTAPES:")
if avg_score >= 6:
print("1. ✅ Implémenter la traduction MCP dans le jeu")
print("2. 🎯 Commencer par les commandes simples")
print("3. 📊 Ajouter des métriques de performance")
print("4. 🔍 Tester avec des vrais joueurs")
else:
print("1. 🔧 Améliorer les prompts et exemples")
print("2. 📚 Entraîner avec des données MCP spécifiques")
print("3. 🔄 Considérer un modèle plus grand")
print("4. 🛠️ Implémenter des règles de secours")
# Sauvegarder les résultats
with open("qwen_mcp_evaluation_results.json", "w", encoding="utf-8") as f:
json.dump(results, f, indent=2, ensure_ascii=False)
print(f"\n📄 Résultats détaillés sauvegardés dans: qwen_mcp_evaluation_results.json")
if __name__ == "__main__":
test_qwen_mcp_capabilities()