Помилка в Symptom Checker може коштувати життя. Коли 30% існуючих застосунків для оцінки симптомів дають невірні рекомендації щодо екстрених випадків, ціна помилки — людське життя. Уникнути цього допомагає детермінований фільтр екстрених симптомів, який працює до будь-якого AI-аналізу. Нижче — архітектура, яку ми використовуємо в комерційних проєктах, з дотриманням стандартів HIPAA та GDPR. Якщо вам потрібне надійне медичне застосування, зв'яжіться з нами для консультації.
Чому детермінований фільтр критичний?
AI-моделі можуть помилятися, особливо на граничних випадках. Детермінований фільтр — надійна гарантія: якщо користувач вводить «біль у грудях», застосунок зобов'язаний показати кнопку виклику швидкої, не чекаючи відповіді від LLM. Це не AI — це просте порівняння рядків, яке працює швидко та точно. Ми використовуємо список із 30+ фраз на кількох мовах, протестованих медичними експертами.
Які юридичні та медичні обмеження потрібно враховувати?
Перш ніж писати код — базові обмеження, які диктують архітектуру:
- Застосунок не ставить діагнози. Виводить «ймовірні причини», «рекомендується консультація лікаря»
- Симптоми високого ризику (біль у грудях, утруднене дихання, ознаки інсульту) — автоматичний редирект на дзвінок 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:
// Протокол збору симптомів (адаптація 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 хвилин опитування.
Що входить у розробку AI Symptom Checker під ключ
| Етап | Тривалість | Результат |
|---|---|---|
| Аудит вимог | 1-3 дні | Технічне завдання з урахуванням регуляторів |
| Прототипування UI/UX | 3-5 днів | Дизайн-макети екранів опитування та результатів |
| Реалізація ядра Symptom Checker | 5-10 днів | Детермінований фільтр + AI-модуль + структурований збір |
| Інтеграція HealthKit / Health Connect | 2-4 дні | Шифрування та синхронізація даних |
| Тестування з медичними експертами | 5-7 днів | Звіт про відповідність та виправлення кейсів |
| Деплой в App Store / Google Play | 1-2 дні | Реліз з урахуванням вимог App Review |
| Документація та передача | 1-2 дні | Архітектурна документація, інструкції з підтримки |
| Підтримка після запуску | 1 місяць | Виправлення багів, консультації |
Порівняння підходів: детермінований vs AI для екстрених симптомів
| Критерій | Детермінований фільтр | AI-аналіз |
|---|---|---|
| Надійність | 99.99% (немає хибних спрацьовувань) | Залежить від моделі, до 95% |
| Швидкість | <10 мс | 1-3 сек (з урахуванням LLM) |
| Гнучкість | Тільки відомі симптоми | Розпізнає будь-які формулювання |
| Безпека | Висока (повний контроль) | Середня (ризик помилкового пропуску) |
| Рекомендація | Обов'язковий для екстрених | Як додатковий шар |
Орієнтири за термінами
Базовий Symptom Checker з чатом, детермінованим фільтром екстрених випадків та AI-аналізом — 2–3 тижні. Повна реалізація з адаптивним опитуванням, HealthKit/Health Connect, профілем пацієнта, інтеграцією телемедицини та відповідністю вимогам GDPR/HIPAA — 2–3 місяці.
Наші інженери мають сертифікати iOS/Android та багаторічний досвід у розробці медичних застосунків. Ми гарантуємо дотримання всіх регуляторних вимог та проведемо аудит безпеки перед релізом. Отримайте консультацію щодо вашого проєкту — зв'яжіться з нами для оцінки термінів та вартості. Замовте розробку AI Symptom Checker під ключ — надійне медичне рішення із захистом даних.







