Реализация AI-ассистента для медицинских консультаций (Symptom Checker) в мобильном приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация AI-ассистента для медицинских консультаций (Symptom Checker) в мобильном приложении
Сложный
от 2 недель до 3 месяцев
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Реализация AI-ассистента для медицинских консультаций (Symptom Checker) в мобильном приложении

Symptom Checker — одна из самых ответственных AI-задач в мобильной разработке. Ошибочный вывод «вероятно, это просто усталость» при симптомах, требующих немедленной помощи, может стоить жизни. Это не преувеличение — это требование к архитектуре.

Юридические и медицинские ограничения

Прежде чем писать код — базовые ограничения, которые диктуют архитектуру:

  • Приложение не ставит диагнозы. Выводит «вероятные причины», «рекомендуется консультация врача»
  • Симптомы высокого риска (боль в груди, затруднённое дыхание, признаки инсульта) — автоматический редирект на звонок 112, без AI-анализа
  • Все данные о симптомах — медицинские данные, требуют шифрования уровня HealthKit / HIPAA
  • Disclaimer должен быть виден до первого запроса, не мелким шрифтом

На iOS — HealthKit для хранения анамнеза с HKHealthStore authorization. На Android — Health Connect с HealthPermission.READ_STEPS и аналогичными разрешениями.

Детерминированная проверка критических симптомов

До любого LLM-вызова — жёсткий фильтр по критическим симптомам:

struct CriticalSymptomChecker {
    // Симптомы, требующие немедленной скорой помощи
    static let emergencySymptoms = [
        "chest pain", "боль в груди",
        "difficulty breathing", "затруднение дыхания", "не могу дышать",
        "sudden severe headache", "внезапная сильная головная боль",
        "face drooping", "numbness arm", "speech difficulty",  // FAST-тест инсульта
        "loss of consciousness", "потеря сознания",
        "severe bleeding", "сильное кровотечение",
        "choking", "подавился"
    ]

    static func requiresEmergency(_ symptomText: String) -> Bool {
        let lowercased = symptomText.lowercased()
        return emergencySymptoms.contains { lowercased.contains($0) }
    }
}

// Проверяем ДО отправки в LLM
func processSymptoms(_ userInput: String) async {
    if CriticalSymptomChecker.requiresEmergency(userInput) {
        showEmergencyAlert()  // Кнопка 112, заблокировать продолжение
        return
    }
    await analyzeWithAI(userInput)
}

Это не AI — это детерминированная логика. Нельзя доверять LLM решение о вызове скорой помощи.

Структурированный сбор симптомов

Свободный ввод текста — не лучший UX для медицинского контекста. Пользователь в стрессе пишет неточно. Лучше — чат с уточняющими вопросами по протоколу.

// Протокол сбора симптомов (адаптация OPQRST для мобильного)
enum SymptomQuestion: CaseIterable {
    case onset          // когда началось
    case provocation    // что усиливает/ослабляет
    case quality        // характер (острая, тупая, давящая)
    case radiation      // куда отдаёт
    case severity       // 1-10 шкала
    case time           // как давно, постоянно/периодически

    var prompt: String {
        switch self {
        case .onset: return "Когда появился симптом? (недавно, несколько часов, несколько дней)"
        case .severity: return "Оцените интенсивность по шкале от 1 до 10"
        // ...
        }
    }
}

AI генерирует следующий уточняющий вопрос на основе предыдущих ответов — адаптивный опрос, а не фиксированный список.

Промпт для анализа симптомов

func buildSymptomAnalysisPrompt(
    symptoms: SymptomCollection,
    patientContext: PatientContext
) -> String {
    return """
    You are a medical triage assistant. Analyze symptoms and suggest possible conditions.

    IMPORTANT: Always recommend consulting a qualified doctor. Never provide a definitive diagnosis.
    If symptoms suggest any serious condition, clearly state urgency level.

    Patient context:
    - Age: \(patientContext.age)
    - Known conditions: \(patientContext.knownConditions.joined(separator: ", "))
    - Current medications: \(patientContext.medications.isEmpty ? "none" : patientContext.medications.joined(separator: ", "))

    Symptoms:
    - Main complaint: \(symptoms.mainComplaint)
    - Duration: \(symptoms.duration)
    - Severity (1-10): \(symptoms.severity)
    - Character: \(symptoms.quality)
    - Associated symptoms: \(symptoms.associated.joined(separator: ", "))

    Return JSON:
    {
      "urgency": "emergency|urgent|routine",
      "possible_conditions": [{"name": "", "likelihood": "high|medium|low", "brief_explanation": ""}],
      "recommended_action": "call_112|er_today|see_doctor_soon|see_doctor_routine|home_care",
      "home_care_advice": "",
      "red_flags": ["symptoms to watch for that require immediate care"],
      "disclaimer": "This is not a medical diagnosis..."
    }
    """
}

urgency: emergency в ответе LLM — дополнительный триггер для показа кнопки 112, даже если детерминированный фильтр его не поймал.

Отображение результатов

Медицинская информация требует особой подачи в UI:

@Composable
fun SymptomCheckResult(result: SymptomAnalysis) {
    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {

        // Уровень срочности — первым, крупно
        UrgencyBanner(urgency = result.urgency)

        Spacer(Modifier.height(16.dp))

        // Рекомендованное действие — вторым
        RecommendedActionCard(action = result.recommendedAction)

        Spacer(Modifier.height(16.dp))

        // Возможные причины — с оговорками
        Text("Возможные причины", style = MaterialTheme.typography.titleMedium)
        Text(
            "Информация носит ознакомительный характер и не является диагнозом",
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )

        result.possibleConditions.forEach { condition ->
            ConditionCard(condition)
        }

        // Красные флаги — отдельным блоком
        if (result.redFlags.isNotEmpty()) {
            RedFlagsSection(flags = result.redFlags)
        }

        // Disclaimer — обязателен, но не мелким шрифтом
        DisclaimerCard(text = result.disclaimer)
    }
}

Интеграция с телемедициной

Если приложение связано с телемедицинским сервисом, кнопка «Проконсультироваться с врачом» появляется в результатах. Контекст из Symptom Checker (структурированные симптомы, анамнез) передаётся врачу автоматически — это экономит 10–15 минут опроса.

Ориентиры по срокам

Базовый Symptom Checker с чатом, детерминированным фильтром экстренных случаев и AI-анализом — 2–3 недели. Полная реализация с адаптивным опросом, HealthKit/Health Connect, профилем пациента, интеграцией телемедицины и соответствием требованиям GDPR/HIPAA — 2–3 месяца.