Уявіть: студент-медик на прийомі — пацієнт скаржиться на біль у спині, але замовчує про нещодавнє падіння. Скриптовий тренажер не помітить хитрощі, а AI-персонаж «запам'ятовує» пропущене запитання і в кінці сесії вкаже на помилку. Ми будуємо саме такі системи — з реалістичною психологією персонажів та адаптивним сценарієм під кожного учня. Це не просто симуляція діалогу, а повноцінна ситуаційна задача, де кожна відповідь впливає на розвиток сценарію. За даними дослідження IBM Training Report, компанії, що використовують AI-симуляції, скорочують час навчання на 40%.
Як AI-симуляції вирішують проблему масштабованого навчання?
Класичні рольові ігри вимагають акторів і сценаристів — це дорого, а повторне проходження дає одну й ту саму відповідь. AI-симуляції генерують унікальний діалог щоразу: персонаж реагує на конкретні слова, змінює емоції й тактику. В основі лежить LLM, обрамлена системним промптом із роллю, цілями та секретною інформацією. Код нижче показує мінімальну реалізацію такого персонажа.
from openai import AsyncOpenAI
from dataclasses import dataclass, field
from typing import Optional
client = AsyncOpenAI()
@dataclass
class SimulationCharacter:
name: str
role: str
personality: str
objectives: list[str] # Що персонаж хоче досягти
knowledge: str # Що персонаж знає
emotional_state: str = "neutral"
secret_info: str = "" # Інформація, яку персонаж приховує
@dataclass
class SimulationScenario:
title: str
learning_objectives: list[str]
characters: list[SimulationCharacter]
context: str
success_criteria: list[str]
difficulty: str = "medium"
@dataclass
class SimulationSession:
scenario: SimulationScenario
conversation_history: list[dict] = field(default_factory=list)
score: float = 0.0
attempts: int = 0
feedback_notes: list[str] = field(default_factory=list)
class InteractiveSimulator:
def __init__(self):
self.client = AsyncOpenAI()
async def create_character_response(
self,
session: SimulationSession,
learner_input: str,
character: SimulationCharacter
) -> dict:
"""Генеруємо реалістичну відповідь персонажа + оцінку дій учня"""
system_prompt = f"""Ти — {character.name}, {character.role}.
Особистість: {character.personality}
Твої цілі в цій ситуації: {', '.join(character.objectives)}
Контекст сценарію: {session.scenario.context}
Інформація, яку ти знаєш: {character.knowledge}
{'Прихована інформація (не розкривати явно): ' + character.secret_info if character.secret_info else ''}
Поточний емоційний стан: {character.emotional_state}
ВАЖЛИВО:
- Відповідай від імені персонажа, реалістично
- Реагуй на тактику учня: хороші аргументи пом'якшують позицію, тиск посилює опір
- Після відповіді додай блок [INSTRUCTOR_EVAL] з оцінкою дій учня (не показується йому)
Поверни JSON: {{
character_response: "відповідь персонажа",
emotional_state_change: "як змінився настрій",
instructor_eval: {{
technique_used: "...", effective: true/false, score_delta: -5..+10, tip: "..."
}}
}}"""
messages = [{"role": "system", "content": system_prompt}]
# Історія діалогу
for turn in session.conversation_history[-10:]: # останні 10 реплік
messages.append({"role": turn["role"], "content": turn["content"]})
messages.append({"role": "user", "content": learner_input})
response = await self.client.chat.completions.create(
model="gpt-4o",
messages=messages,
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
async def evaluate_session(self, session: SimulationSession) -> dict:
"""Фінальна оцінка сесії симуляції"""
response = await self.client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": f"""Оціни результати навчальної симуляції.
Цілі навчання: {json.dumps(session.scenario.learning_objectives, ensure_ascii=False)}
Критерії успіху: {json.dumps(session.scenario.success_criteria, ensure_ascii=False)}
Проаналізуй діалог і поверни JSON:
{{
overall_score: 0-100,
objectives_achieved: [{{"objective": "...", "achieved": true/false, "evidence": "..."}}],
strengths: ["..."],
areas_for_improvement: ["..."],
specific_feedback: "детальний розбір ключових моментів",
recommended_practice: "що відпрацювати додатково"
}}"""
}, {
"role": "user",
"content": f"Історія діалогу:\n{json.dumps(session.conversation_history, ensure_ascii=False, indent=2)}"
}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
Чому генерація діалогів через LLM краща за скриптові дерева?
Скриптові дерева скінченні: будь-яка неочікувана відповідь ламає сценарій, і учень отримує «вас не зрозумів». LLM-генерація покриває нескінченний простір вводів — персонаж може адекватно відповісти на «а ви впевнені?», «покажіть дослідження», або навіть «давайте обговоримо знижку». Ми використовуємо JSON mode (gpt-4o), що гарантує структурований вивід з оцінкою дій — без парсингу тексту.
| Характеристика | Скриптові симуляції | AI-симуляції на LLM |
|---|---|---|
| Кількість можливих діалогів | 5–20 (обмежено гілками) | Теоретично нескінченно |
| Реакція на нестандартний ввід | Помилка або «вас не зрозумів» | Доречна відповідь у рамках ролі |
| Емоційна адаптація | Ні | Так (через промпт та історію) |
| Складність створення | Низька (діаграми) | Середня (промпти + тестування) |
| Вартість за сесію | Фіксовано | ~2-10 центів (токени) |
Для персонажа з довготривалою пам'яттю ми підключаємо RAG з ChromaDB: ключові факти з історії діалогу зберігаються у векторну базу і витягуються при наступних зустрічах. Це дозволяє симуляції пам'ятати рішення учня через кілька сесій — критично для оцінки навичок і відстеження прогресу.
Готові симуляції за нішами
SIMULATION_TEMPLATES = {
"sales_objection_handling": SimulationScenario(
title="Робота з запереченнями: 'Дорого'",
learning_objectives=["Виявити справжнє заперечення", "Обґрунтувати цінність", "Запропонувати альтернативи"],
characters=[SimulationCharacter(
name="Михайло Іванов",
role="Потенційний клієнт, керівник відділу закупівель",
personality="Прагматичний, цінує конкретику, скептичний до продавців",
objectives=["Отримати кращу ціну", "Переконатися в надійності постачальника"],
knowledge="Знає ринок, порівнював з конкурентами",
emotional_state="slightly_negative",
secret_info="Бюджет є, але хоче перевірити, наскільки продавець гнучкий"
)],
context="Фінальний етап переговорів щодо річного контракту на IT-рішення",
success_criteria=["Виявив бюджетні обмеження", "Запропонував ROI розрахунок", "Не знизив ціну більш ніж на 10%"]
),
"medical_consultation": SimulationScenario(
title="Первинний прийом пацієнта з болем у спині",
learning_objectives=["Зібрати анамнез", "Провести диференціальну діагностику", "Призначити обстеження"],
characters=[SimulationCharacter(
name="Пацієнт: Олена Смирнова, 42 роки",
role="Пацієнт з болем у попереку 2 тижні",
personality="Тривожна, багато читала в інтернеті про діагнози",
objectives=["Отримати конкретний діагноз", "Дізнатися, чи потрібна операція"],
knowledge="Біль посилюється при нахилі, є оніміння пальців ноги",
secret_info="Падала на роботі, але соромиться сказати"
)],
context="Первинний прийом у невролога в поліклініці",
success_criteria=["Запитав про травми", "Призначив МРТ", "Пояснив наступні кроки"]
)
}
Адаптивна складність
async def adjust_difficulty(
session: SimulationSession,
current_score: float
) -> str:
"""Адаптуємо поведінку персонажа під рівень учня"""
if current_score > 75:
return "more_resistant" # Персонаж жорсткіше
elif current_score < 40:
return "more_cooperative" # Персонаж м'якше, дає підказки
else:
return "neutral" # Стандартна поведінка
Адаптивна складність реалізована через зміну параметрів персонажа: рівень опору, обсяг підказок, частоту зміни емоцій. Це дозволяє використовувати один сценарій для новачків і досвідчених співробітників — економія на розробці сягає 80%.
Як оцінюється ефективність симуляції?
Ми впроваджуємо метрики на кожному етапі:
| Метрика | Опис | Норма |
|---|---|---|
| completeness | Частка досягнутих цілей сценарію | >80% |
| score | Оцінка LLM за тактику і результат | 0-100 |
| user_satisfaction | Опитування після сесії | >4.0 з 5 |
| retention | Повторне проходження через місяць | >60% |
В одному проєкті A/B-тест показав покращення retention на 34% порівняно зі скриптовим тренажером.
Чек-лист для запуску першої симуляції
- Визначити навчальні цілі та цільову аудиторію
- Написати Character-картку: роль, особистість, секретна інформація
- Налаштувати системний промпт з роллю та критеріями оцінки
- Протестувати 50+ діалогів на коректність JSON та latency
- Провести A/B-тест: контрольна група на скрипті, тестова на AI
Процес роботи та що входить
- Аналітика: розбираємо навчальні цілі, цільову аудиторію, типові помилки. Формуємо карту сценаріїв і персонажів.
- Проектування: пишемо Character-картки (роль, особистість, метрики успіху). Налаштовуємо системні промпти — це 80% якості симуляції.
- Реалізація: збираємо бекенд на Python (FastAPI + asyncio), підключаємо LLM, версіонуємо промпти через MLflow. Для дешевих сценаріїв використовуємо Llama 3 через vLLM, для складних — GPT-4o.
- Тестування: прогоняємо 50+ діалогів на кожен сценарій, перевіряємо коректність JSON, заміряємо latency. Автоматично генеруємо робастні тести.
- Деплой: ставимо контейнер у Kubernetes, підключаємо аналітику (які сесії завершилися успішно, де учні «застрягають»).
Зазначимо: що входить у результат: документація по сценаріях, API-специфікація, веб-компонент для вбудовування, панель аналітики, 2 тижні підтримки після деплою. Пишіть — оцінимо ваш сценарій за 1 день. Під ключ реалізуємо симуляцію з 1–3 персонажами за місяць.
Строки: MVP симуляції з одним сценарієм і AI-персонажем — 2–3 тижні. Платформа з бібліотекою сценаріїв, аналітикою та LMS-інтеграцією — 2–3 місяці. Більше 5 років досвіду в AI-рішеннях, 10+ впроваджених тренажерів для медичних та продаючих департаментів. Зв'яжіться з нами, щоб обговорити ваш навчальний сценарій — ми запропонуємо архітектуру та строки безкоштовно.







