GUI_MAI-DxO / USER_GUIDE.md
DocUA's picture
Додано нові правила до .gitignore для ігнорування файлів середовища (.env), кешованих файлів Python (__pycache__/) та байтових файлів (.pyc).
c85225d

A newer version of the Gradio SDK is available: 5.42.0

Upgrade

MAI-DX Orchestrator - Повний керівник користувача

📋 Зміст


🔬 Огляд системи

MAI-DX (MAI Diagnostic Orchestrator) - це ШІ-система медичної діагностики, що реалізує дослідження Microsoft Research "Sequential Diagnosis with Language Models". Система імітує консиліум з 8 спеціалізованих лікарів-агентів для проведення поетапної медичної діагностики з оптимізацією економічної ефективності.

Наукові результати

Дослідження на Sequential Diagnosis Benchmark:

  • 304 складних діагностичних випадки з New England Journal of Medicine (NEJM-CPC)
  • 80% точність діагностики з OpenAI o3 моделлю
  • 85.5% точність у максимальному режимі
  • В 4 рази точніше за лікарів-загальників (20% базовий показник)
  • 20% економія витрат порівняно з лікарями
  • 70% економія витрат порівняно з прямим використанням LLM

Ключові особливості

  • 🧠 8 ШІ-агентів лікарів з різними спеціалізаціями
  • 💰 Контроль витрат на 25+ медичних тестів та процедур
  • 🎯 5 режимів роботи для різних сценаріїв (instant, question_only, budgeted, no_budget, ensemble)
  • 🤖 Підтримка різних LLM (GPT, Gemini, Claude, Grok, DeepSeek, Llama)
  • 📊 5-бальна система оцінювання точності діагнозів
  • 🔄 Ітеративний процес секвенціальної діагностики
  • 🏥 Model-agnostic orchestrator - працює з будь-якими LLM

Архітектура агентів

Агент Роль Функція
🧠 Dr. Hypothesis Діагност Формує та оновлює диференційний діагноз
🔬 Dr. Test-Chooser Лабораторний координатор Обирає найефективніші діагностичні тести
🤔 Dr. Challenger Критик Запобігає когнітивним упередженням
💰 Dr. Stewardship Економіст Контролює витрати на обстеження
Dr. Checklist Контролер якості Перевіряє повноту діагностики
🤝 Consensus Coordinator Модератор Координує рішення панелі
🔑 Gatekeeper Інформаційний портал Надає клінічні дані
⚖️ Judge Оцінювач Оцінює точність фінального діагнозу

📊 Benchmark Results та Валідація

Sequential Diagnosis Benchmark (NEJM-CPC)

Офіційні результати тестування на 304 складних випадках:

Model Combination Accuracy Cost Efficiency Notes
MAI-DxO + o3 80.0% 70% економія vs raw o3 Найкраща комбінація
MAI-DxO + o3 (max mode) 85.5% - Максимальна точність
Generalist physicians 20.0% Baseline cost Контрольна група
Raw o3 (no orchestrator) ~65% Baseline cost Без оркестратора

Результати по моделях (з MAI-DxO):

  • OpenAI o3: 80% точність
  • GPT-4: ~70% точність
  • Gemini Pro: ~68% точність
  • Claude: ~72% точність
  • Grok: ~65% точність
  • DeepSeek: ~63% точність
  • Llama: ~60% точність

Економічна ефективність

Середня вартість діагностики:

  • Лікарі: $2,400 (базова лінія)
  • MAI-DxO: $1,920 (20% економія)
  • Raw LLM: $6,400 (170% переплата)

Оптимальні бюджети по режимах:

  • instant: $500-800 (60-75% точність)
  • question_only: $800-1200 (70-85% точність)
  • budgeted: $1500-3000 (80-90% точність)
  • no_budget: $3000-8000 (85-95% точність)
  • ensemble: $5000-15000 (90-98% точність)

Передумови

  • Python 3.10+ (рекомендовано 3.11)
  • UV package manager (або pip)
  • API ключі для LLM сервісів

Крок 1: Установка UV (якщо потрібно)

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

# Через Homebrew (macOS)
brew install uv

Крок 2: Встановлення MAI-DX

Варіант 1: Через pip (рекомендовано)

# Встановлення опублікованого пакету
pip install mai-dx python-dotenv

# Перевірка установки
python -c "from mai_dx import MaiDxOrchestrator; print('✅ MAI-DX готовий')"

Варіант 2: Development версія (для розробників)

# Клонування репозиторію
git clone https://github.com/The-Swarm-Corporation/Open-MAI-Dx-Orchestrator.git
cd Open-MAI-Dx-Orchestrator

# Встановлення залежностей
pip install -r requirements.txt

# Встановлення в режимі розробки
pip install -e .

Варіант 3: З UV (альтернативний пакетний менеджер)

# Якщо використовуєте UV
uv add mai-dx python-dotenv

# Створення UV-сумісного pyproject.toml
uv init --name mai-dx-local --no-readme
uv add mai-dx python-dotenv
uv sync

Крок 3: Налаштування API ключів

# Створюємо .env файл
cat > .env << 'EOF'
# API ключі (ОБОВ'ЯЗКОВО)
OPENAI_API_KEY="your-openai-api-key-here"
GEMINI_API_KEY="your-gemini-api-key-here"  
ANTHROPIC_API_KEY="your-anthropic-api-key-here"

# Додаткові налаштування
PROJECT_NAME="MAI-Dx-Local"
ENVIRONMENT="development"
DEBUG=true

# Відключення проблемних виводів
SWARMS_VERBOSITY="ERROR"
RICH_TRACEBACK="0"
SWARMS_SHOW_PANEL="false"
EOF

# Захищаємо файл
chmod 600 .env

Крок 4: Перевірка установки

# Створюємо тестовий файл
cat > test_setup.py << 'EOF'
import os
from dotenv import load_dotenv

load_dotenv()

def test_installation():
    print("🔧 Тестування установки...")
    
    # Перевірка API ключів
    required_keys = ['OPENAI_API_KEY', 'GEMINI_API_KEY', 'ANTHROPIC_API_KEY']
    missing = [k for k in required_keys if not os.getenv(k)]
    
    if missing:
        print(f"❌ Відсутні ключі: {', '.join(missing)}")
        return False
    
    # Перевірка імпорту
    try:
        from mai_dx import MaiDxOrchestrator
        print("✅ MAI-DX імпортовано успішно")
        return True
    except ImportError as e:
        print(f"❌ Помилка імпорту: {e}")
        return False

if __name__ == "__main__":
    success = test_installation()
    print("🎉 Готово до роботи!" if success else "🔧 Потрібні виправлення")
EOF

# Запускаємо тест
uv run python test_setup.py

🚀 Швидкий старт

Базовий приклад

import os
from dotenv import load_dotenv
from mai_dx import MaiDxOrchestrator

# Завантажуємо налаштування
load_dotenv()

# Відключаємо verbose вивід
os.environ["SWARMS_VERBOSITY"] = "ERROR"
os.environ["SWARMS_SHOW_PANEL"] = "false"

# Створюємо оркестратор
orchestrator = MaiDxOrchestrator(
    model_name="gemini/gemini-2.5-flash",
    max_iterations=3,
    initial_budget=1000,
    mode="question_only"
)

# Медичний випадок
case_info = """
25-year-old male with severe headache for 2 days.
Pain is bilateral, throbbing, 8/10 intensity.
Photophobia and nausea present.
No fever or neck stiffness.
"""

# Запускаємо діагностику
result = orchestrator.run(
    initial_case_info=case_info,
    full_case_details=case_info,
    ground_truth_diagnosis="Migraine"
)

# Результат
print(f"Діагноз: {result.final_diagnosis}")
print(f"Точність: {result.accuracy_score}/5.0")
print(f"Вартість: ${result.total_cost}")

Швидкий діагностичний скрипт

#!/usr/bin/env python3
"""
Швидкий діагностичний інструмент
Використання: python quick_diagnose.py "медичний випадок"
"""
import sys
import os
from dotenv import load_dotenv
from mai_dx import MaiDxOrchestrator

def quick_diagnose(case_description, mode="question_only"):
    """Швидка діагностика медичного випадку"""
    
    # Налаштування
    load_dotenv()
    os.environ["SWARMS_VERBOSITY"] = "ERROR"
    
    # Створення оркестратора
    orchestrator = MaiDxOrchestrator(
        model_name="gemini/gemini-2.5-flash",
        max_iterations=3,
        initial_budget=1500,
        mode=mode
    )
    
    print("🩺 MAI-DX діагностика...")
    print("⏳ Аналіз випадку...")
    
    try:
        result = orchestrator.run(
            initial_case_info=case_description,
            full_case_details=case_description,
            ground_truth_diagnosis="Unknown"
        )
        
        print(f"\n🎯 Діагноз: {result.final_diagnosis}")
        print(f"⭐ Впевненість: {result.accuracy_score}/5.0")
        print(f"💰 Вартість: ${result.total_cost}")
        print(f"🔄 Ітерації: {result.iterations}")
        
        return result.final_diagnosis
        
    except Exception as e:
        print(f"❌ Помилка: {e}")
        return None

if __name__ == "__main__":
    if len(sys.argv) > 1:
        case = " ".join(sys.argv[1:])
        quick_diagnose(case)
    else:
        print("Використання: python quick_diagnose.py 'медичний випадок'")

🎛️ Режими роботи

1. instant - Миттєвий режим

Призначення: Найшвидший режим для термінових консультацій

orchestrator = MaiDxOrchestrator(
    mode="instant",
    initial_budget=800,     # Мінімальний бюджет
    max_iterations=2        # Дуже швидкі ітерації
)

Характеристики:

  • ⚡ Швидкість: 30-90 секунд
  • 💰 Вартість: $200-600
  • 🎯 Точність: 60-75%
  • 📝 Методи: Швидкий аналіз без складних тестів

Ідеально для:

  • Невідкладних ситуацій
  • Первинного скринінгу
  • Швидких консультацій

2. question_only - Тільки питання

Призначення: Швидкі консультації без дорогих тестів

orchestrator = MaiDxOrchestrator(
    mode="question_only",
    initial_budget=1000,    # Мінімальний бюджет
    max_iterations=3        # Швидкі ітерації
)

Характеристики:

  • ⚡ Швидкість: 1-3 хвилини
  • 💰 Вартість: $300-800
  • 🎯 Точність: 70-85%
  • 📝 Методи: Тільки клінічні питання

Ідеально для:

  • Первинних консультацій
  • Швидких оцінок
  • Освітніх цілей

3. budgeted - З бюджетними обмеженнями

Призначення: Збалансований підхід з контролем витрат

orchestrator = MaiDxOrchestrator(
    mode="budgeted",
    initial_budget=3000,    # Середній бюджет
    max_iterations=5        # Збалансовані ітерації
)

Характеристики:

  • ⚡ Швидкість: 3-7 хвилин
  • 💰 Вартість: $800-3000
  • 🎯 Точність: 80-90%
  • 📝 Методи: Питання + обрані тести

Ідеально для:

  • Рутинної діагностики
  • Амбулаторних випадків
  • Економічно ефективної медицини

4. no_budget - Без обмежень бюджету

Призначення: Повна діагностика без фінансових обмежень

orchestrator = MaiDxOrchestrator(
    mode="no_budget",
    initial_budget=10000,   # Великий бюджет
    max_iterations=7        # Повний аналіз
)

Характеристики:

  • ⚡ Швидкість: 5-15 хвилин
  • 💰 Вартість: $1000-8000
  • 🎯 Точність: 85-95%
  • 📝 Методи: Усі доступні тести та процедури

Ідеально для:

  • Складних випадків
  • Рідкісних захворювань
  • Критичних ситуацій

5. ensemble - Консенсус кількох запусків

Призначення: Максимальна точність через множинні аналізи

orchestrator = MaiDxOrchestrator(
    mode="budgeted",  # Базовий режим для кожного запуску
    max_iterations=3
)

# Запуск ensemble
result = orchestrator.run_ensemble(
    initial_case_info=case,
    full_case_details=case,
    ground_truth_diagnosis=truth,
    num_runs=3  # Кількість незалежних запусків
)

Характеристики:

  • ⚡ Швидкість: 10-30 хвилин
  • 💰 Вартість: $2000-15000
  • 🎯 Точність: 90-98%
  • 📝 Методи: Консенсус кількох діагностичних сесій

Результати з наукової роботи Microsoft Research:

  • 80% точність з OpenAI o3 моделлю
  • 85.5% точність у максимальному режимі
  • В 4 рази точніше за лікарів-загальників (20% базовий показник)
  • 20% економія витрат порівняно з лікарями
  • 70% економія витрат порівняно з прямим використанням o3

🔧 Детальне використання

Створення оркестратора з повним контролем

from mai_dx import MaiDxOrchestrator

# Повна конфігурація
orchestrator = MaiDxOrchestrator(
    model_name="gemini/gemini-2.5-flash",  # Модель LLM
    max_iterations=5,                       # Максимум ітерацій
    initial_budget=3000,                    # Початковий бюджет ($)
    mode="budgeted",                        # Режим роботи
    verbose=False                           # Детальний вивід
)

# Перевірка налаштувань
print(f"Модель: {orchestrator.model_name}")
print(f"Бюджет: ${orchestrator.initial_budget}")
print(f"Режим: {orchestrator.mode}")

Структура медичного випадку

# Мінімальна інформація
simple_case = "35-year-old man with chest pain for 2 hours"

# Детальний випадок
detailed_case = """
Patient: 35-year-old male, construction worker
Chief Complaint: Severe chest pain for 2 hours

History of Present Illness:
- Sudden onset of crushing chest pain during physical work
- Pain radiates to left arm and jaw
- Associated with shortness of breath and sweating
- No relief with rest

Past Medical History:
- Hypertension (controlled with medication)
- Smoking 1 pack/day for 15 years
- Family history of heart disease (father had MI at 50)

Physical Examination:
- Vital signs: BP 150/95, HR 110, RR 22, Temp 98.6°F
- Cardiovascular: Tachycardic, no murmurs
- Respiratory: Clear bilaterally
- Extremities: No edema

Initial Assessment:
- High suspicion for acute coronary syndrome
- Requires immediate evaluation
"""

# Ground truth для оцінювання (опціонально)
expected_diagnosis = "ST-elevation myocardial infarction (STEMI)"

Запуск діагностики з обробкою помилок

import time
from contextlib import contextmanager

@contextmanager
def diagnostic_session(orchestrator):
    """Контекстний менеджер для діагностичної сесії"""
    print("🩺 Початок діагностичної сесії...")
    start_time = time.time()
    
    try:
        yield orchestrator
    except KeyboardInterrupt:
        print("\n⏹️ Діагностика перервана користувачем")
        raise
    except Exception as e:
        print(f"\n❌ Помилка діагностики: {e}")
        raise
    finally:
        duration = time.time() - start_time
        print(f"⏱️ Тривалість сесії: {duration:.1f} секунд")

# Використання
with diagnostic_session(orchestrator) as dx:
    result = dx.run(
        initial_case_info=case_description,
        full_case_details=detailed_case,
        ground_truth_diagnosis=expected_diagnosis
    )
    
    # Обробка результату
    print(f"\n📋 РЕЗУЛЬТАТИ ДІАГНОСТИКИ")
    print(f"🎯 Діагноз: {result.final_diagnosis}")
    print(f"🏆 Еталон: {result.ground_truth}")
    print(f"⭐ Точність: {result.accuracy_score}/5.0")
    print(f"💰 Загальна вартість: ${result.total_cost:,}")
    print(f"🔄 Ітерації: {result.iterations}")
    
    # Детальний аналіз
    if hasattr(result, 'accuracy_reasoning'):
        print(f"💭 Обґрунтування: {result.accuracy_reasoning[:200]}...")

Пакетна обробка випадків

def batch_diagnose(cases, mode="question_only"):
    """Діагностика кількох випадків підряд"""
    
    results = []
    
    for i, case_data in enumerate(cases, 1):
        print(f"\n📋 Випадок {i}/{len(cases)}: {case_data.get('name', f'Case {i}')}")
        
        # Створюємо новий оркестратор для кожного випадку
        orchestrator = MaiDxOrchestrator(
            model_name="gemini/gemini-2.5-flash",
            mode=mode,
            initial_budget=2000,
            max_iterations=4
        )
        
        try:
            result = orchestrator.run(
                initial_case_info=case_data["description"],
                full_case_details=case_data.get("details", case_data["description"]),
                ground_truth_diagnosis=case_data.get("expected", "Unknown")
            )
            
            # Зберігаємо результат
            case_result = {
                "case_id": i,
                "name": case_data.get("name", f"Case {i}"),
                "diagnosis": result.final_diagnosis,
                "accuracy": result.accuracy_score,
                "cost": result.total_cost,
                "iterations": result.iterations,
                "success": True
            }
            
            results.append(case_result)
            print(f"✅ Завершено: {result.final_diagnosis}")
            
        except Exception as e:
            print(f"❌ Помилка: {e}")
            results.append({
                "case_id": i,
                "name": case_data.get("name", f"Case {i}"),
                "error": str(e),
                "success": False
            })
    
    return results

# Приклад використання
test_cases = [
    {
        "name": "Гострий інфаркт",
        "description": "55-year-old man with crushing chest pain, sweating, nausea",
        "expected": "Myocardial infarction"
    },
    {
        "name": "Менінгіт",
        "description": "20-year-old with severe headache, neck stiffness, fever",
        "expected": "Meningitis"
    }
]

results = batch_diagnose(test_cases)

# Аналіз результатів
successful = [r for r in results if r.get("success", False)]
print(f"\n📊 Успішно: {len(successful)}/{len(results)}")

for result in successful:
    print(f"   {result['name']}: {result['diagnosis']} (Score: {result['accuracy']}/5)")

💡 Приклади використання

1. Кардіологічний випадок

# Випадок гострого коронарного синдрому
cardiac_case = """
Patient: 58-year-old male executive
Chief Complaint: "Crushing chest pain like an elephant sitting on my chest"

History:
- Pain started 3 hours ago while climbing stairs
- Severe, substernal, radiating to left arm and jaw
- Associated with diaphoresis, nausea, shortness of breath
- No relief with rest or antacids

Risk Factors:
- Diabetes mellitus type 2
- Hypertension
- Hyperlipidemia  
- Smoking 2 packs/day for 30 years
- Family history: father died of MI at 52

Physical Exam:
- Appears uncomfortable, diaphoretic
- Vital signs: BP 180/110, HR 105, RR 24
- Heart: S4 gallop, no murmurs
- Lungs: Clear bilaterally
- Extremities: No edema

ECG: ST-elevations in leads II, III, aVF
Troponin I: 8.5 ng/mL (normal <0.04)
"""

orchestrator = MaiDxOrchestrator(
    mode="no_budget",  # Повна діагностика для критичного випадку
    initial_budget=5000,
    max_iterations=6
)

result = orchestrator.run(
    initial_case_info=cardiac_case,
    full_case_details=cardiac_case,
    ground_truth_diagnosis="Inferior STEMI"
)

print(f"Діагноз: {result.final_diagnosis}")
# Очікуваний результат: "Acute ST-elevation myocardial infarction (STEMI)"

2. Неврологічний випадок

# Випадок інсульту
neuro_case = """
Patient: 67-year-old female with sudden onset neurological symptoms

Presentation:
- Sudden onset of right-sided weakness 2 hours ago
- Difficulty speaking (slurred speech)
- Facial drooping on right side
- No loss of consciousness

History:
- Atrial fibrillation (not on anticoagulation)
- Hypertension
- Previous TIA 6 months ago

Examination:
- Alert but confused
- Right facial droop
- Right arm drift
- Dysarthria
- NIHSS score: 8

CT Head: No acute hemorrhage
Time from onset: 2 hours 15 minutes
"""

# Використовуємо швидкий режим для невідкладних випадків
orchestrator = MaiDxOrchestrator(
    mode="question_only",
    max_iterations=2,  # Швидко для невідкладної допомоги
    initial_budget=800
)

result = orchestrator.run(
    initial_case_info=neuro_case,
    full_case_details=neuro_case,
    ground_truth_diagnosis="Acute ischemic stroke"
)

3. Педіатричний випадок

# Дитячий випадок з лихоманкою
pediatric_case = """
Patient: 3-year-old boy brought by parents for fever and irritability

History:
- Fever up to 39.5°C for 2 days
- Decreased appetite and activity
- Pulling at right ear
- Crying more than usual, especially when lying down
- No cough, runny nose, or vomiting

Past Medical History:
- Full-term delivery, normal development
- Up to date on vaccinations
- No known allergies

Physical Examination:
- Temperature: 39.2°C, HR: 130, RR: 28
- Generally irritable but consolable
- HEENT: Right tympanic membrane erythematous and bulging
- Neck: Supple, no lymphadenopathy
- Chest: Clear bilaterally
- Abdomen: Soft, non-tender

Assessment needed for appropriate treatment
"""

# Для педіатричних випадків використовуємо обережний підхід
orchestrator = MaiDxOrchestrator(
    mode="budgeted",
    initial_budget=1500,
    max_iterations=4
)

result = orchestrator.run(
    initial_case_info=pediatric_case,
    full_case_details=pediatric_case,
    ground_truth_diagnosis="Acute otitis media"
)

4. Складний диференційний діагноз

# Випадок з широким диференційним діагнозом
complex_case = """
Patient: 45-year-old female with progressive fatigue and weight loss

Chief Complaint: "I'm exhausted all the time and losing weight despite eating"

History of Present Illness:
- 6-month history of progressive fatigue
- Unintentional 15-pound weight loss
- Heat intolerance and excessive sweating
- Palpitations and anxiety
- Difficulty sleeping
- Tremor in hands

Review of Systems:
- Frequent bowel movements (3-4 times daily)
- Hair thinning
- Menstrual irregularities
- No fever, night sweats, or lymph node swelling

Physical Examination:
- Vital signs: BP 150/85, HR 110, RR 16, Temp 98.8°F
- General: Thin, anxious-appearing female
- Eyes: Mild exophthalmos, lid lag
- Thyroid: Diffusely enlarged, no nodules
- Cardiovascular: Tachycardic, no murmurs
- Neurologic: Fine tremor of outstretched hands
- Skin: Warm and moist

This case requires careful consideration of multiple differential diagnoses
"""

# Для складних випадків використовуємо ensemble підхід
orchestrator = MaiDxOrchestrator(
    mode="budgeted",
    initial_budget=3000,
    max_iterations=5
)

# Запускаємо кілька незалежних аналізів
ensemble_result = orchestrator.run_ensemble(
    initial_case_info=complex_case,
    full_case_details=complex_case,
    ground_truth_diagnosis="Graves' disease (hyperthyroidism)",
    num_runs=2
)

print(f"Ensemble діагноз: {ensemble_result.final_diagnosis}")
print(f"Consensus score: {ensemble_result.accuracy_score}/5.0")

🔧 Troubleshooting

Часті проблеми та рішення

1. Rich Console помилки

Проблема:

rich.errors.NotRenderableError: Unable to render None

Рішення:

import os

# Додайте на початок скрипта
os.environ["SWARMS_VERBOSITY"] = "ERROR"
os.environ["RICH_TRACEBACK"] = "0"
os.environ["SWARMS_SHOW_PANEL"] = "false"

# Патч для 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()

2. Function Call помилки

Проблема:

Could not extract function call output from response type: <class 'str'>

Рішення:

  • Це внутрішня проблема Swarms framework
  • НЕ блокує діагностику
  • Система продовжує працювати з fallback механізмами
  • Можна ігнорувати ці попередження

3. Проблеми з бюджетом

Проблема:

Remaining budget: $-100

Рішення:

# Використовуйте достатні бюджети для кожного режиму
budget_recommendations = {
    "question_only": 1000,   # Мінімум $800
    "budgeted": 3000,        # Мінімум $2000  
    "no_budget": 10000       # Мінімум $5000
}

orchestrator = MaiDxOrchestrator(
    mode="budgeted",
    initial_budget=budget_recommendations["budgeted"]
)

4. API помилки

Проблема:

API key not found or invalid

Рішення:

# Перевірте .env файл
cat .env | grep API_KEY

# Перевірте права доступу
ls -la .env

# Переконайтесь що файл завантажується
python -c "from dotenv import load_dotenv; load_dotenv(); import os; print(os.getenv('GEMINI_API_KEY')[:10] if os.getenv('GEMINI_API_KEY') else 'NOT FOUND')"

5. Повільна робота

Рішення:

# Оптимізовані налаштування для швидкості
fast_orchestrator = MaiDxOrchestrator(
    model_name="gemini/gemini-2.5-flash",  # Швидша модель
    max_iterations=2,                       # Менше ітерацій
    initial_budget=1000,                    # Менший бюджет
    mode="question_only"                    # Найшвидший режим
)

6. Низька точність діагнозів

Рішення:

# Поліпшення точності
precise_orchestrator = MaiDxOrchestrator(
    model_name="gpt-4",                     # Потужніша модель
    max_iterations=7,                       # Більше ітерацій
    initial_budget=5000,                    # Більший бюджет
    mode="no_budget"                        # Повний аналіз
)

# Або використовуйте ensemble
ensemble_result = orchestrator.run_ensemble(
    num_runs=3  # Кілька незалежних запусків
)

Діагностичні утиліти

def diagnose_mai_dx_issues():
    """Діагностика проблем MAI-DX"""
    
    print("🔧 Діагностика MAI-DX системи...")
    
    # Перевірка 1: Python версія
    import sys
    python_version = sys.version_info
    if python_version >= (3, 10):
        print("✅ Python версія підходить")
    else:
        print(f"❌ Python {python_version} застара, потрібен 3.10+")
    
    # Перевірка 2: Залежності
    try:
        import mai_dx, swarms, pydantic, loguru
        print("✅ Основні залежності встановлені")
    except ImportError as e:
        print(f"❌ Відсутня залежність: {e}")
    
    # Перевірка 3: API ключі
    from dotenv import load_dotenv
    load_dotenv()
    
    api_keys = ["OPENAI_API_KEY", "GEMINI_API_KEY", "ANTHROPIC_API_KEY"]
    for key in api_keys:
        value = os.getenv(key)
        if value:
            print(f"✅ {key}: {'*' * (len(value) - 4) + value[-4:]}")
        else:
            print(f"❌ {key}: не знайдено")
    
    # Перевірка 4: Створення оркестратора
    try:
        from mai_dx import MaiDxOrchestrator
        test_orchestrator = MaiDxOrchestrator(
            mode="question_only",
            initial_budget=500,
            max_iterations=1
        )
        print("✅ Оркестратор створюється без помилок")
    except Exception as e:
        print(f"❌ Помилка створення оркестратора: {e}")
    
    print("🔧 Діагностика завершена")

# Запуск діагностики
diagnose_mai_dx_issues()

🚀 Production рекомендації

Архітектура для Production

import logging
import asyncio
from typing import Dict, List, Optional
from dataclasses import dataclass
from datetime import datetime

@dataclass
class DiagnosisRequest:
    """Структура запиту на діагностику"""
    case_id: str
    patient_info: str
    clinical_details: str
    urgency_level: str = "routine"  # routine, urgent, emergency
    requested_mode: str = "budgeted"
    max_budget: int = 3000
    
@dataclass
class DiagnosisResponse:
    """Структура відповіді діагностики"""
    case_id: str
    diagnosis: str
    confidence_score: float
    cost: float
    duration_seconds: float
    timestamp: datetime
    recommendations: List[str]
    status: str  # success, partial, failed

class ProductionMAIDX:
    """Production-ready MAI-DX wrapper"""
    
    def __init__(self, config: Dict):
        self.config = config
        self.logger = self._setup_logging()
        
    def _setup_logging(self):
        """Налаштування логування для production"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('mai_dx_production.log'),
                logging.StreamHandler()
            ]
        )
        return logging.getLogger('MAI-DX-Production')
    
    async def diagnose_async(self, request: DiagnosisRequest) -> DiagnosisResponse:
        """Асинхронна діагностика для high-throughput"""
        
        start_time = time.time()
        self.logger.info(f"Starting diagnosis for case {request.case_id}")
        
        try:
            # Створення оркестратора з налаштуваннями
            orchestrator = MaiDxOrchestrator(
                model_name=self.config.get("model", "gemini/gemini-2.5-flash"),
                mode=request.requested_mode,
                initial_budget=request.max_budget,
                max_iterations=self._get_iterations_for_urgency(request.urgency_level)
            )
            
            # Запуск діагностики
            result = orchestrator.run(
                initial_case_info=request.patient_info,
                full_case_details=request.clinical_details,
                ground_truth_diagnosis="Unknown"
            )
            
            duration = time.time() - start_time
            
            # Формування відповіді
            response = DiagnosisResponse(
                case_id=request.case_id,
                diagnosis=result.final_diagnosis,
                confidence_score=result.accuracy_score,
                cost=result.total_cost,
                duration_seconds=duration,
                timestamp=datetime.now(),
                recommendations=self._extract_recommendations(result),
                status="success"
            )
            
            self.logger.info(f"Diagnosis completed for case {request.case_id} in {duration:.2f}s")
            return response
            
        except Exception as e:
            self.logger.error(f"Diagnosis failed for case {request.case_id}: {e}")
            return DiagnosisResponse(
                case_id=request.case_id,
                diagnosis="Diagnosis failed",
                confidence_score=0.0,
                cost=0.0,
                duration_seconds=time.time() - start_time,
                timestamp=datetime.now(),
                recommendations=[],
                status="failed"
            )
    
    def _get_iterations_for_urgency(self, urgency: str) -> int:
        """Налаштування ітерацій залежно від терміновості"""
        urgency_configs = {
            "emergency": 2,  # Швидко для невідкладних випадків
            "urgent": 3,     # Збалансовано
            "routine": 5     # Повний аналіз
        }
        return urgency_configs.get(urgency, 3)
    
    def _extract_recommendations(self, result) -> List[str]:
        """Витяг рекомендацій з результату"""
        recommendations = []
        
        # Базові рекомендації залежно від типу діагнозу
        diagnosis = result.final_diagnosis.lower()
        
        if "emergency" in diagnosis or "acute" in diagnosis:
            recommendations.append("Immediate medical attention required")
        elif "infection" in diagnosis:
            recommendations.append("Consider antibiotic therapy")
            recommendations.append("Monitor vital signs")
        elif "chronic" in diagnosis:
            recommendations.append("Long-term management plan needed")
            recommendations.append("Regular follow-up recommended")
        
        return recommendations

# Конфігурація для різних середовищ
PRODUCTION_CONFIG = {
    "model": "gpt-4",  # Найточніша модель для production
    "fallback_model": "gemini/gemini-2.5-flash",
    "max_concurrent_diagnoses": 5,
    "timeout_seconds": 600,
    "retry_attempts": 3
}

DEVELOPMENT_CONFIG = {
    "model": "gemini/gemini-2.5-flash",
    "max_concurrent_diagnoses": 2,
    "timeout_seconds": 300,
    "retry_attempts": 1
}

Monitoring та Metrics

import time
from collections import defaultdict
from typing import Dict, Any

class MAIDXMetrics:
    """Система метрик для моніторингу MAI-DX"""
    
    def __init__(self):
        self.metrics = defaultdict(list)
        self.counters = defaultdict(int)
    
    def record_diagnosis(self, result: DiagnosisResponse):
        """Запис метрик діагностики"""
        
        # Основні метрики
        self.metrics["diagnosis_duration"].append(result.duration_seconds)
        self.metrics["diagnosis_cost"].append(result.cost)
        self.metrics["confidence_score"].append(result.confidence_score)
        
        # Лічильники
        self.counters[f"status_{result.status}"] += 1
        self.counters["total_diagnoses"] += 1
        
        # Метрики якості
        if result.confidence_score >= 4.0:
            self.counters["high_confidence"] += 1
        elif result.confidence_score >= 2.0:
            self.counters["medium_confidence"] += 1
        else:
            self.counters["low_confidence"] += 1
    
    def get_summary(self) -> Dict[str, Any]:
        """Отримання зводки метрик"""
        
        if not self.metrics["diagnosis_duration"]:
            return {"message": "No diagnoses recorded yet"}
        
        durations = self.metrics["diagnosis_duration"]
        costs = self.metrics["diagnosis_cost"]
        scores = self.metrics["confidence_score"]
        
        return {
            "total_diagnoses": self.counters["total_diagnoses"],
            "success_rate": self.counters.get("status_success", 0) / self.counters["total_diagnoses"],
            "average_duration": sum(durations) / len(durations),
            "average_cost": sum(costs) / len(costs),
            "average_confidence": sum(scores) / len(scores),
            "high_confidence_rate": self.counters.get("high_confidence", 0) / self.counters["total_diagnoses"],
            "performance": {
                "min_duration": min(durations),
                "max_duration": max(durations),
                "min_cost": min(costs),
                "max_cost": max(costs)
            }
        }
    
    def export_metrics(self, filename: str = None):
        """Експорт метрик у файл"""
        import json
        
        summary = self.get_summary()
        
        if filename:
            with open(filename, 'w') as f:
                json.dump(summary, f, indent=2, default=str)
        
        return summary

# Використання metrics
metrics = MAIDXMetrics()

# Після кожної діагностики
# metrics.record_diagnosis(diagnosis_response)

# Періодичний звіт
# weekly_report = metrics.get_summary()
# metrics.export_metrics("mai_dx_weekly_report.json")

Безпека та конфіденційність

import hashlib
import base64
from cryptography.fernet import Fernet

class MAIDXSecurity:
    """Система безпеки для MAI-DX"""
    
    def __init__(self, encryption_key: bytes = None):
        if encryption_key:
            self.cipher_suite = Fernet(encryption_key)
        else:
            # Генерація нового ключа (зберігайте безпечно!)
            self.cipher_suite = Fernet(Fernet.generate_key())
    
    def anonymize_patient_data(self, patient_info: str) -> tuple:
        """Анонімізація пацієнтських даних"""
        
        # Створення анонімного ID
        patient_hash = hashlib.sha256(patient_info.encode()).hexdigest()[:16]
        
        # Видалення ідентифікаторів
        anonymized = patient_info
        
        # Замінюємо особистісні дані на плейсхолдери
        import re
        
        # Імена
        anonymized = re.sub(r'\b[A-Z][a-z]+ [A-Z][a-z]+\b', '[PATIENT_NAME]', anonymized)
        
        # Дати народження
        anonymized = re.sub(r'\b\d{1,2}/\d{1,2}/\d{4}\b', '[DATE_OF_BIRTH]', anonymized)
        
        # Номери телефонів
        anonymized = re.sub(r'\b\d{3}-\d{3}-\d{4}\b', '[PHONE_NUMBER]', anonymized)
        
        # Адреси
        anonymized = re.sub(r'\b\d+\s+[A-Za-z\s]+\b', '[ADDRESS]', anonymized)
        
        return patient_hash, anonymized
    
    def encrypt_diagnosis(self, diagnosis_data: str) -> bytes:
        """Шифрування діагностичних даних"""
        return self.cipher_suite.encrypt(diagnosis_data.encode())
    
    def decrypt_diagnosis(self, encrypted_data: bytes) -> str:
        """Розшифрування діагностичних даних"""
        return self.cipher_suite.decrypt(encrypted_data).decode()
    
    def audit_log(self, action: str, user_id: str, patient_id: str):
        """Аудит логування для HIPAA compliance"""
        
        timestamp = datetime.now().isoformat()
        log_entry = {
            "timestamp": timestamp,
            "action": action,
            "user_id": user_id,
            "patient_id": patient_id,
            "ip_address": "masked_for_privacy"
        }
        
        # Записуємо в захищений лог файл
        with open("mai_dx_audit.log", "a") as f:
            f.write(json.dumps(log_entry) + "\n")

# Приклад безпечного використання
security = MAIDXSecurity()

# Анонімізація даних перед діагностикою
patient_id, anonymized_case = security.anonymize_patient_data(patient_info)

# Аудит логування
security.audit_log("diagnosis_started", "dr_smith", patient_id)

# Шифрування результатів
encrypted_diagnosis = security.encrypt_diagnosis(result.final_diagnosis)

📚 API Reference

Основний клас MaiDxOrchestrator

class MaiDxOrchestrator:
    """
    Основний клас для медичної діагностики з використанням ШІ-агентів
    """
    
    def __init__(
        self,
        model_name: str = "gemini/gemini-2.5-flash",
        max_iterations: int = 5,
        initial_budget: int = 3000,
        mode: str = "budgeted",
        verbose: bool = False
    ):
        """
        Ініціалізація оркестратора
        
        Args:
            model_name: Назва LLM моделі
            max_iterations: Максимальна кількість діагностичних ітерацій
            initial_budget: Початковий бюджет у доларах
            mode: Режим роботи ("question_only", "budgeted", "no_budget")
            verbose: Детальний вивід логів
        """
    
    def run(
        self,
        initial_case_info: str,
        full_case_details: str,
        ground_truth_diagnosis: str = None
    ) -> DiagnosisResult:
        """
        Запуск діагностичного процесу
        
        Args:
            initial_case_info: Початкова інформація про випадок
            full_case_details: Повні деталі медичного випадку
            ground_truth_diagnosis: Еталонний діагноз для оцінювання
            
        Returns:
            DiagnosisResult: Результат діагностики
        """
    
    def run_ensemble(
        self,
        initial_case_info: str,
        full_case_details: str,
        ground_truth_diagnosis: str,
        num_runs: int = 3
    ) -> DiagnosisResult:
        """
        Запуск ensemble діагностики (кілька незалежних сесій)
        
        Args:
            initial_case_info: Початкова інформація про випадок
            full_case_details: Повні деталі медичного випадку
            ground_truth_diagnosis: Еталонний діагноз
            num_runs: Кількість незалежних запусків
            
        Returns:
            DiagnosisResult: Консенсус результат
        """

Структура DiagnosisResult

@dataclass
class DiagnosisResult:
    """Результат діагностичного процесу"""
    
    final_diagnosis: str          # Фінальний діагноз
    ground_truth: str            # Еталонний діагноз
    accuracy_score: float        # Оцінка точності (1.0-5.0)
    accuracy_reasoning: str      # Обґрунтування оцінки
    total_cost: float           # Загальна вартість діагностики
    iterations: int             # Кількість проведених ітерацій
    
    # Додаткові поля (якщо доступні)
    differential_diagnoses: List[str] = None
    recommended_tests: List[str] = None
    questions_asked: List[str] = None
    reasoning_chain: List[str] = None

Utilities та Helper функції

def create_optimized_orchestrator(
    case_complexity: str = "medium",
    urgency: str = "routine",
    budget_limit: int = None
) -> MaiDxOrchestrator:
    """
    Створення оптимізованого оркестратора базуючись на характеристиках випадку
    
    Args:
        case_complexity: "simple", "medium", "complex"
        urgency: "routine", "urgent", "emergency"
        budget_limit: Максимальний бюджет
        
    Returns:
        MaiDxOrchestrator: Налаштований оркестратор
    """
    
    # Конфігурації для різних сценаріїв
    configs = {
        ("simple", "routine"): {"mode": "question_only", "budget": 1000, "iterations": 2},
        ("simple", "urgent"): {"mode": "question_only", "budget": 1500, "iterations": 3},
        ("medium", "routine"): {"mode": "budgeted", "budget": 3000, "iterations": 4},
        ("medium", "urgent"): {"mode": "budgeted", "budget": 4000, "iterations": 5},
        ("complex", "routine"): {"mode": "no_budget", "budget": 8000, "iterations": 6},
        ("complex", "urgent"): {"mode": "no_budget", "budget": 10000, "iterations": 7},
        ("complex", "emergency"): {"mode": "budgeted", "budget": 5000, "iterations": 3}  # Швидко але ретельно
    }
    
    config = configs.get((case_complexity, urgency), configs[("medium", "routine")])
    
    if budget_limit:
        config["budget"] = min(config["budget"], budget_limit)
    
    return MaiDxOrchestrator(
        mode=config["mode"],
        initial_budget=config["budget"],
        max_iterations=config["iterations"]
    )

def validate_medical_case(case_text: str) -> Dict[str, Any]:
    """
    Валідація медичного випадку перед діагностикою
    
    Args:
        case_text: Текст медичного випадку
        
    Returns:
        Dict: Результат валідації з рекомендаціями
    """
    
    validation_result = {
        "is_valid": True,
        "warnings": [],
        "suggestions": [],
        "estimated_complexity": "medium"
    }
    
    # Перевірки мінімальної інформації
    required_elements = ["age", "gender", "complaint", "history"]
    missing_elements = []
    
    case_lower = case_text.lower()
    
    if not any(age_indicator in case_lower for age_indicator in ["year", "age", "old"]):
        missing_elements.append("age")
    
    if not any(gender_indicator in case_lower for gender_indicator in ["male", "female", "man", "woman"]):
        missing_elements.append("gender")
    
    if len(case_text.split()) < 20:
        validation_result["warnings"].append("Case description seems too brief")
        validation_result["suggestions"].append("Consider adding more clinical details")
    
    # Оцінка складності
    complexity_indicators = {
        "simple": ["headache", "cold", "fever", "cough"],
        "complex": ["multiple", "chronic", "rare", "syndrome", "differential"]
    }
    
    simple_count = sum(1 for indicator in complexity_indicators["simple"] if indicator in case_lower)
    complex_count = sum(1 for indicator in complexity_indicators["complex"] if indicator in case_lower)
    
    if complex_count > simple_count:
        validation_result["estimated_complexity"] = "complex"
    elif simple_count > 2:
        validation_result["estimated_complexity"] = "simple"
    
    return validation_result

def format_diagnosis_report(result: DiagnosisResult, include_reasoning: bool = True) -> str:
    """
    Форматування діагностичного звіту
    
    Args:
        result: Результат діагностики
        include_reasoning: Включати детальне обґрунтування
        
    Returns:
        str: Форматований звіт
    """
    
    report_lines = [
        "🏥 MAI-DX ДІАГНОСТИЧНИЙ ЗВІТ",
        "=" * 50,
        f"📅 Дата: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
        "",
        "📋 РЕЗУЛЬТАТИ:",
        f"   🎯 Діагноз: {result.final_diagnosis}",
        f"   ⭐ Оцінка точності: {result.accuracy_score}/5.0",
        f"   💰 Загальна вартість: ${result.total_cost:,.2f}",
        f"   🔄 Ітерації: {result.iterations}",
        ""
    ]
    
    # Оцінка якості
    if result.accuracy_score >= 4.0:
        quality_assessment = "🎉 ВІДМІННО - Високоточний діагноз"
    elif result.accuracy_score >= 3.0:
        quality_assessment = "👍 ДОБРЕ - Правильний напрямок діагностики"
    elif result.accuracy_score >= 2.0:
        quality_assessment = "⚠️ ЗАДОВІЛЬНО - Частково правильний діагноз"
    else:
        quality_assessment = "❌ ПОТРЕБУЄ ПОЛІПШЕННЯ - Неточний діагноз"
    
    report_lines.extend([
        f"📊 ОЦІНКА ЯКОСТІ: {quality_assessment}",
        ""
    ])
    
    # Детальне обґрунтування
    if include_reasoning and result.accuracy_reasoning:
        report_lines.extend([
            "💭 ОБҐРУНТУВАННЯ ОЦІНКИ:",
            result.accuracy_reasoning[:500] + ("..." if len(result.accuracy_reasoning) > 500 else ""),
            ""
        ])
    
    # Рекомендації
    report_lines.extend([
        "💡 РЕКОМЕНДАЦІЇ:",
        "   • Верифікуйте діагноз з лікарем",
        "   • Розгляньте додаткові тести при потребі",
        "   • Цей ШІ-діагноз є допоміжним інструментом",
        "",
        "⚠️ ВІДМОВА ВІД ВІДПОВІДАЛЬНОСТІ:",
        "   Цей діагноз згенеровано ШІ для освітніх/дослідницьких цілей.",
        "   Не замінює професійну медичну консультацію.",
        "=" * 50
    ])
    
    return "\n".join(report_lines)

📖 Підсумок

MAI-DX Orchestrator - це потужний інструмент для медичної діагностики з використанням штучного інтелекту. Система дозволяє:

✅ Можливості

  • Проводити складну медичну діагностику з 8 спеціалізованими ШІ-агентами
  • Контролювати витрати на діагностичні процедури
  • Отримувати оцінку точності діагнозів
  • Працювати в різних режимах залежно від потреб
  • Інтегруватися в існуючі медичні системи

⚠️ Обмеження

  • Потребує API ключі для LLM сервісів (витрати)
  • Не замінює професійної медичної консультації
  • Призначено для освітніх та дослідницьких цілей
  • Може мати косметичні помилки виводу (Rich console)

🎯 Рекомендації

  • Використовуйте для навчання та досліджень
  • Завжди верифікуйте результати з медичними професіоналами
  • Дотримуйтесь стандартів конфіденційності (HIPAA/GDPR)
  • Регулярно оновлюйте систему та залежності

📞 Підтримка


Версія документації: 1.0 | Останнє оновлення: Липень 2025