Spaces:
Running
A newer version of the Gradio SDK is available:
5.42.0
MAI-DX Orchestrator - Повний керівник користувача
📋 Зміст
- Огляд системи
- Установка та налаштування
- Швидкий старт
- Режими роботи
- Детальне використання
- Приклади використання
- Troubleshooting
- Production рекомендації
- API Reference
🔬 Огляд системи
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)
- Регулярно оновлюйте систему та залежності
📞 Підтримка
- Документація: GitHub Repository
- Issues: GitHub Issues
- Дискусії: GitHub Discussions
Версія документації: 1.0 | Останнє оновлення: Липень 2025