Spaces:
Sleeping
Sleeping
#!/usr/bin/env python3 | |
""" | |
Production-ready MAI-DX Orchestrator | |
Оптимізовано для реального використання | |
""" | |
import os | |
import sys | |
import warnings | |
from dotenv import load_dotenv | |
# Завантажуємо змінні середовища | |
load_dotenv() | |
# Виробничі налаштування для стабільності | |
os.environ["SWARMS_VERBOSITY"] = "SILENT" | |
os.environ["RICH_TRACEBACK"] = "0" | |
os.environ["SWARMS_SHOW_PANEL"] = "false" | |
os.environ["SWARMS_AUTO_PRINT"] = "false" | |
os.environ["LOGURU_LEVEL"] = "WARNING" # Менше спаму в логах | |
warnings.filterwarnings("ignore") | |
# Rich formatter патч (довелося ефективність!) | |
def patch_rich_formatter(): | |
try: | |
import swarms.utils.formatter | |
def dummy_print_panel(*args, **kwargs): | |
pass | |
if hasattr(swarms.utils.formatter, 'Formatter'): | |
swarms.utils.formatter.Formatter._print_panel = dummy_print_panel | |
return True | |
except: | |
return False | |
patch_rich_formatter() | |
from mai_dx import MaiDxOrchestrator | |
from loguru import logger | |
class ProductionMAIDX: | |
"""Production-wrapper для MAI-DX з поліпшеннями""" | |
def __init__(self, model="gemini/gemini-2.5-flash"): | |
self.model = model | |
self.available_modes = ["question_only", "budgeted", "no_budget"] | |
def create_optimized_orchestrator(self, mode="question_only", budget=2000, max_iterations=5): | |
"""Створює оптимізований оркестратор для production""" | |
# Рекомендовані налаштування для кожного режиму | |
configs = { | |
"question_only": {"budget": 1000, "iterations": 3}, | |
"budgeted": {"budget": 3000, "iterations": 5}, | |
"no_budget": {"budget": 10000, "iterations": 7} | |
} | |
config = configs.get(mode, {"budget": budget, "iterations": max_iterations}) | |
try: | |
orchestrator = MaiDxOrchestrator( | |
model_name=self.model, | |
max_iterations=config["iterations"], | |
initial_budget=config["budget"], | |
mode=mode | |
) | |
print(f"✅ MAI-DX готовий: {mode} режим, бюджет ${config['budget']}") | |
return orchestrator | |
except Exception as e: | |
print(f"❌ Помилка створення: {e}") | |
return None | |
def diagnose_case(self, case_description, expected_diagnosis=None, mode="question_only"): | |
"""Основний метод для діагностики""" | |
print(f"\n🩺 Запуск MAI-DX діагностики...") | |
print(f"📋 Режим: {mode}") | |
# Створюємо оркестратор | |
orchestrator = self.create_optimized_orchestrator(mode) | |
if not orchestrator: | |
return None | |
try: | |
# Якщо немає expected_diagnosis, використовуємо загальний | |
ground_truth = expected_diagnosis or "Unknown diagnosis" | |
print("🔄 Аналіз випадку... (це може зайняти 2-5 хвилин)") | |
# Запускаємо діагностику | |
result = orchestrator.run( | |
initial_case_info=case_description, | |
full_case_details=case_description, | |
ground_truth_diagnosis=ground_truth | |
) | |
return self._format_result(result, mode) | |
except Exception as e: | |
print(f"❌ Помилка діагностики: {e}") | |
return None | |
def _format_result(self, result, mode): | |
"""Форматуємо результат для зручного відображення""" | |
# Оцінюємо якість результату | |
if result.accuracy_score >= 4.0: | |
quality = "🎉 ВІДМІННО" | |
elif result.accuracy_score >= 3.0: | |
quality = "👍 ДОБРЕ" | |
elif result.accuracy_score >= 2.0: | |
quality = "⚠️ ЗАДОВІЛЬНО" | |
elif "not reached" in result.final_diagnosis.lower(): | |
quality = "🔄 ПОТРІБНО БІЛЬШЕ ЧАСУ" | |
else: | |
quality = "🔍 ПОТРЕБУЄ ПЕРЕВІРКИ" | |
formatted = { | |
"diagnosis": result.final_diagnosis, | |
"confidence": result.accuracy_score, | |
"quality": quality, | |
"cost": result.total_cost, | |
"iterations": result.iterations, | |
"mode": mode, | |
"reasoning": getattr(result, 'accuracy_reasoning', 'Недоступно')[:200] + "..." | |
} | |
return formatted | |
def batch_diagnose(self, cases, mode="question_only"): | |
"""Діагностика кількох випадків""" | |
results = [] | |
for i, case in enumerate(cases, 1): | |
print(f"\n📋 Випадок {i}/{len(cases)}") | |
case_text = case.get("description", "") | |
expected = case.get("expected", None) | |
result = self.diagnose_case(case_text, expected, mode) | |
if result: | |
results.append({"case_id": i, **result}) | |
return results | |
def demo_production_usage(): | |
"""Демонстрація production використання""" | |
print("=" * 70) | |
print("🏥 MAI-DX PRODUCTION DEMO") | |
print("=" * 70) | |
# Створюємо production instance | |
mai_dx = ProductionMAIDX() | |
# Тестові випадки | |
test_cases = [ | |
{ | |
"description": "35-year-old man with sudden severe chest pain radiating to left arm, sweating, nausea. Pain started 2 hours ago during exercise.", | |
"expected": "Myocardial infarction" | |
}, | |
{ | |
"description": "22-year-old woman with severe headache, neck stiffness, fever 39°C, photophobia. Symptoms started this morning.", | |
"expected": "Meningitis" | |
}, | |
{ | |
"description": "45-year-old smoker with persistent cough for 3 months, weight loss 10kg, bloody sputum occasionally.", | |
"expected": "Lung cancer" | |
} | |
] | |
print(f"📋 Тестування {len(test_cases)} випадків...") | |
# Запускаємо діагностику | |
results = mai_dx.batch_diagnose(test_cases, mode="question_only") | |
# Виводимо результати | |
print(f"\n{'='*70}") | |
print("📊 РЕЗУЛЬТАТИ ТЕСТУВАННЯ") | |
print("="*70) | |
for result in results: | |
print(f"\n🔍 Випадок {result['case_id']}:") | |
print(f" Діагноз: {result['diagnosis']}") | |
print(f" Якість: {result['quality']}") | |
print(f" Оцінка: {result['confidence']}/5.0") | |
print(f" Вартість: ${result['cost']}") | |
print(f" Ітерації: {result['iterations']}") | |
# Статистика | |
successful = sum(1 for r in results if r['confidence'] >= 2.0) | |
print(f"\n📈 Статистика: {successful}/{len(results)} успішних діагнозів") | |
if successful >= len(results) * 0.7: | |
print("🎉 MAI-DX готовий для production!") | |
else: | |
print("⚠️ Потрібне додаткове налаштування") | |
def simple_diagnostic_session(): | |
"""Простий інтерактивний сеанс діагностики""" | |
print("\n🩺 Простий сеанс діагностики") | |
print("-" * 40) | |
# Простий випадок для демонстрації | |
case = """ | |
29-year-old woman with sore throat and peritonsillar swelling and bleeding. | |
Symptoms did not abate with antimicrobial therapy. | |
History: Onset 7 weeks ago, worsening right-sided pain. | |
Physical Exam: Right peritonsillar mass, displaces uvula. | |
Biopsy: Round-cell neoplasm, positive for desmin and MyoD1. | |
""" | |
expected = "Embryonal rhabdomyosarcoma of the pharynx" | |
mai_dx = ProductionMAIDX() | |
result = mai_dx.diagnose_case(case, expected, "question_only") | |
if result: | |
print(f"\n🎯 Діагноз: {result['diagnosis']}") | |
print(f"⭐ Якість: {result['quality']}") | |
print(f"💰 Вартість: ${result['cost']}") | |
# Аналіз близькості діагнозу | |
if "rhabdomyosarcoma" in result['diagnosis'].lower(): | |
print("✅ Правильний тип пухлини ідентифіковано!") | |
return True | |
else: | |
print("❌ Діагностика не вдалася") | |
return False | |
if __name__ == "__main__": | |
try: | |
# Запускаємо простий тест | |
simple_diagnostic_session() | |
# Опціонально - повний demo | |
print("\n" + "="*50) | |
print("Запустити повний production demo? (y/n): ", end="") | |
# Для автоматичного запуску в тестах - пропускаємо input | |
try: | |
choice = input().lower() | |
if choice == 'y': | |
demo_production_usage() | |
except: | |
print("Пропускаємо інтерактивний demo") | |
except KeyboardInterrupt: | |
print("\n⏹️ Зупинено користувачем") | |
except Exception as e: | |
print(f"\n💥 Помилка: {e}") |