Помилка в 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 під ключ — надійне медичне рішення із захистом даних.







