Reimagining Voice Testing with AI: як Role-Play Framework перетворює тестування голосових агентів на вимірювану систему
Всім привіт! Мене звати Денис Ціон, я займаю позицію Backend Engineer в Master of Code Global. До цього понад вісім років працював QA Engineer. Протягом своєї кар’єри в QA мав досвід роботи з продуктовими та сервісними проєктами, де впроваджував сучасні підходи до автоматизації. Також активно займався інтеграцією AI у робочі процеси — використовуючи його для оптимізації тестування, прискорення аналізу даних та валідації результатів.
Голосові AI-агенти швидко переходять із демо-зони в реальні customer-facing продукти: банки, страхові компанії, e-commerce, healthcare, contact centers, CRM і платформи для автоматизації клієнтського сапорту. Але разом із цим зʼявляється дуже незручне питання: як тестувати voice-рішення, якщо воно не має одного стабільного expected result?
Класичний E2E-підхід добре працює там, де система детермінована: натиснув кнопку, отримав конкретний результат, порівняв з expected value. Але генеративний AI працює інакше. Він може відповісти правильно, але іншими словами. Може пройти сценарій, але зробити це занадто довго. Може звучати ввічливо, але не вирішити задачу. А у voice-домені до цього додаються ще latency, speech-to-text, text-to-speech, акценти, перебивання, тиша, емоції, якість аудіо і поведінка телефонної інфраструктури.
Саме з цієї проблеми виросла концепція AI Role-Play Testing Framework — підхід, у якому ми симулюємо повноцінну розмову між клієнтом і системою, після чого незалежний AI Judge оцінює якість взаємодії за структурованими критеріями.
Одним із найбільш вдалих технічних варіантів реалізації Voice Role-Play підходу стала cloud-based архітектура, у якій тестовий фреймворк запускається в AWS, ініціює outbound calls до voice agent у платформі для автоматизації клієнтського сапорту через Twilio, використовує AI-generated voice personas через ElevenLabs, збирає transcript розмови та формує структуровані репорти для подальшого аналізу. У такому стеку Python відповідає за core orchestration logic, AWS Lambda — за виконання окремих етапів тестового flow, API Gateway — за trigger endpoint, DynamoDB — за збереження test status і score metadata, S3 — за prompts, transcripts і reports, Twilio — за телефонну інфраструктуру, ElevenLabs — за voice simulation layer, а AWS Bedrock може виступати як
Іншими словами, voice testing більше не обмежується ручною перевіркою окремих сценаріїв або читанням транскриптів після дзвінків. Його можна перетворити на повторюваний, вимірюваний і частково автоматизований процес, де кожен діалог має сценарій, мету, синтетичну user persona, оцінку, обґрунтування та результат pass/fail.
Звідки все почалося: коли expected result перестав бути рядком тексту
Перший поштовх до Role-Play framework зʼявився ще не у voice, а в текстовому conversational AI. На одному з проєктів потрібно було тестувати чатбота на базі генеративного ШІ, який допомагав нетехнічним користувачам робити запити до бази даних. Користувач писав natural language request in plain English, а бот мав згенерувати SQL query, яку потім можна було використати для отримання даних в сторонніх системах.
На перший погляд, це виглядає як звичайний automation task: відправити запит, отримати відповідь, порівняти результат. Але на практиці все було складніше.
Проблема була очевидна: Playwright міг відправити повідомлення як через UI, так і напряму через API, отримати відповідь від бота, зберегти її в процесі виконання тесту, але не міг надійно перевірити її класичним способом. SQL-запит міг бути семантично правильним, але відрізнятися структурою, форматуванням, порядком умов, назвами alias-ів або стилем написання. Наприклад, два різні SQL-запити могли повертати однаковий результат, але виглядати по-різному як текст. Через це literal string comparison або простий очікуваний результат у стилі «відповідь має дорівнювати X» майже не мав сенсу. Потрібна була не перевірка exact match, а оцінка семантичної відповідності: чи справді бот зрозумів запит користувача і згенерував правильну query logic.
Тоді зʼявилось перше рішення: Playwright відправляв test suite в бот, отримував відповідь, а потім ця відповідь передавалась в Azure OpenAI разом із промптом, який пояснював, що саме потрібно перевірити. На виході ми отримували similarity score і могли прийняти рішення pass/fail через поріг, наприклад 70%+. Це ще не був Role-Play Framework у повному вигляді, але вже була головна ідея: LLM може бути не тільки System Under Test, а й інструментом оцінки результату.
Звідси народився наступний логічний крок: якщо AI може оцінювати відповідь, то чому б не змусити AI також грати роль користувача?
Три ролі: SUT, SimUser і Judge
Концепція Role-Play framework дуже проста, але сильна. В її основі лежать три сутності: SUT, SimUser і Judge.
SUT — System Under Test. Це бот, voice agent або conversational AI-рішення, яке ми тестуємо. Він може бути локальним LLM, remote chatbot, voice assistant у CRM/contact-center платформі, custom API-based assistant або будь-яким іншим conversational system.
SimUser — simulated user, або synthetic user. Це AI-персона, яка імітує реального користувача: має конкретну задачу, рівень технічної грамотності, емоційний стан, стиль комунікації, обмеження та сценарій поведінки. У контексті voice testing SimUser може бути не просто текстовою сутністю, а повноцінною голосовою персоною з акцентом, темпом мовлення, паузами, нечіткими відповідями або емоційною реакцією.
Judge — незалежний оцінювач. Він не бере участі в діалозі. Його завдання — проаналізувати transcript або окремі turn pairs і надати структуровану оцінку: оцінку (score), обґрунтування, результат pass/fail, критичні умови відмови (hard-fail conditions) та якісний зворотний зв’язок.

Перша реалізація PoC була написана на Node.js. Локальні LLM запускались через Ollama, а для ролей використовувались різні моделі. Ідея була така: взяти одну conversational model для SimUser, іншу — для SUT, а сильнішу reasoning/evaluation model — для Judge.
У різних ітераціях framework використовувались як локальні, так і хмарні моделі. Для локальних role-play експериментів застосовувались Mistral і LLaMA3, які запускались через Ollama та дозволяли будувати безкоштовні test runs на локальній машині. Для сильнішої оцінки, складніших reasoning-сценаріїв і enterprise-grade judging також використовувались OpenAI GPT-4o, Claude та Azure OpenAI. Саме Azure OpenAI був задіяний у першому similarity-score підході, де відповідь бота оцінювалась не через exact match, а через семантичну близькість до очікуваного результату.
Згодом ця концепція стала основою для багатьох сценаріїв тестування conversational AI — від простих текстових ботів до складних голосових агентів і взаємодій із ними.
Чому Node.js був нормальним стартом, але не ідеальним ядром для локальних LLM
Node.js добре підходить для інтеграцій, API, оркестрації, тестових runner-ів, HTTP adapters і швидкого PoC. Це чудовий інструмент для того, щоб швидко зібрати working prototype: відправити запит, отримати відповідь, прокинути дані між сервісами, підключити remote bot або API.
Але коли мова заходить про нативну взаємодію з локальними LLM, особливо на ARM MacBook, починаються нюанси.
Локальні LLM — це робота з великими model weights, quantization, memory allocation, streaming tokens, GPU/Metal acceleration, lifecycle management, context windows, model loading/unloading і стабільністю runtime. У Python-екосистемі для цього історично більше tooling:
Саме тут важливу роль зіграв Ollama.
Ollama дав можливість запускати локальні моделі як окремий model server і звертатися до них через API. Для Role-Play framework це означало, що код застосунку не мусить напряму «тримати» модель у своєму процесі. Node.js або Python просто відправляє запит до Ollama server, а Ollama бере на себе обслуговування моделі (model serving).
Це було особливо важливо на MacBook Air з ARM-чипом, де ресурси обмежені. Завдяки Ollama можна було запускати локальні LLM, тестувати різні ролі, експериментувати з Mistral/LLaMA3 і не платити за кожен тестовий діалог у хмарі. Так зʼявилась практична формула: безкоштовне локальне тестування conversational AI через role-play simulations.
Міграція на Python, Docker і адаптери
Згодом рішення було переписано на Python. Причина не була в тому, що Node.js «поганий». Причина була в тому, що Python краще відповідав природі задачі: LLM evaluation, adapters, judge logic, робота з transcriptами, інтеграції з observability та audit tools.
У Python-версії framework отримав чіткіші межі:
- agents: SimUser, SUT, Judge;
- adapters/connectors для різних ботів;
- prompts/personas/scenarios;
- reports;
- integrations;
- Docker setup;
- optional local або remote LLM execution.
Окрема важлива частина — адаптери (adapters). У різних проєктах боти були реалізовані по-різному: різні хостинги, різні API, різна авторизація, різна логіка старту діалогу. Одні боти були proactive і самі починали розмову. Інші чекали першого повідомлення від користувача. Десь потрібно було виконати попередню обробку відповіді, десь передати ідентифікатор цільового користувача (target user ID), десь підготувати специфічний payload. Тому framework не міг бути «одним скриптом для всіх». Він мав стати core + adapter layer.
Саме це дозволило використовувати Role-Play framework на інших проєктах без повного переписування. Команда могла взяти існуючу структуру, додати новий адаптер, налаштувати авторизацію, змінити prompts, додати сценарії та запустити regression role-play suite проти нового remote bot.
Також були інтеграції з observability/evaluation tooling: Langfuse для tracing, prompt/version visibility, token/cost/latency tracking; Giskard для risk/audit checks; експерименти з Promptfoo і LangSmith як potential layers для prompt assertions, traces і auto-scoring. У практичному сенсі це перетворювало framework з «скрипта, який ганяє діалоги» на систему, де можна аналізувати, чому саме сценарій провалився.
Docker став ще одним важливим етапом. Ідея була проста: рішення має запускатись локально, повторювано і не ламати машину. Особливо якщо це MacBook Air, де кожен зайвий гігабайт RAM помітно впливає на роботу. Тому підбирались мінімальні ресурси для контейнерів, Ollama виносився в окремий service, prompts монтувались read-only, reports — у dedicated output folder, а великі model files не пушились у git.
У результаті framework можна було запускати локально, адаптувати під нові проєкти, використовувати одну локальну або remote LLM як для SimUser, так і для Judge, або навпаки — розділяти ролі між різними моделями залежно від задачі, бюджету і доступних ресурсів.
Контекст — це головна зона ризику
У Role-Play testing дуже легко зламати систему неправильним context management.
- SimUser не має знати judge rubric
- Judge не має «грати» користувача
- SUT не має отримувати internal scenario notes
- Persona prompt не має протікати в evaluation prompt
Якщо контекст починає гуляти між ролями, ми отримуємо hallucinations, role confusion, prompt leakage і красиві, але некоректні результати.
Тому один із ключових engineering lessons: кожна роль повинна мати ізольований context «space», власний system message, власну memory policy і чітко визначений input/output contract.
Judge має отримувати тільки те, що потрібно для оцінки: transcript, scoring rubric, expected behavior, user goal, можливо metadata сценарію. Але він не має отримувати зайвий prompt soup, який впливає на оцінку.
Саме так виникла ідея multi-judge evaluation. Не один Judge «про все», а кілька спеціалізованих оцінювачів. Наприклад:
Judge-CX оцінює conversational experience: tone & warmth, clarity & naturalness, responsiveness.
Judge-OP оцінює operational performance: intent recognition, flow completion, fallback & error handling.
Це важливо, бо бот може бути дуже приємним, але операційно безпорадним. Або навпаки: він формально виконав задачу, але звучав як банкомат, який втомився від людей.
У результаті UI/report може показувати не один «магічний score», а зрозумілу структуру:
CX Overall Result
CX: completed Score: /1
CX: Tone & Warmth
CX: Clarity & Naturalness
CX: Responsiveness
OP Overall Result
OP: completed Score: /1
OP: Intent Recognition
OP: Flow Completion
OP: Fallback & Error Handling
Це вже діагностика: що саме погане, наскільки, і де це видно в transcript.
Як усе це лягає у voice
На перший погляд voice testing здається окремою категорією. Але якщо розкласти voice agent pipeline, він усе одно значною мірою зводиться до тексту:
- користувач говорить;
- STT перетворює голос у text transcript;
- LLM або dialogue system приймає рішення;
- система викликає tools/API або формує відповідь;
- TTS перетворює текст у голос;
- користувач чує відповідь.
Тобто в центрі voice-рішення все одно лежать turns, text, context, intent, business logic і response quality. Але voice додає новий шар ризиків: якість аудіо, latency, interruptions, варіативність акцентів, помилки розпізнавання мовлення, емоційне забарвлення, обробка пауз і обриви дзвінків.

Саме тому voice QA не може бути лише transcript QA. Але transcript QA залишається його ядром. Якщо transcript показує, що voice agent не зрозумів intent, тричі повторив той самий fallback, попросив зайві персональні дані або не довів flow до завершення — це вже сигнал про проблему. Якщо додати до цього метадані про latency, тривалість дзвінка, події перебивання, STT confidence та досягнення user goal, ми отримаємо значно повнішу картину якості voice experience.
Role-Play framework дуже природно розширюється до voice, бо SimUser може бути голосовою персоною: з акцентом, емоцією, швидкістю мовлення, паузами та нечіткими відповідями. Наприклад, один сценарій може запускатися з «нейтральним користувачем», другий — з «роздратованим клієнтом», третій — з «людиною, яка говорить швидко і не надає повні дані з першого разу». Для класичного automation testing це майже неможливо покрити природним чином. Для AI Role-Play достатньо змінити persona prompt і voice profile.
В одній із практичних реалізацій Voice Role-Play підходу flow може виглядати так: ElevenLabs Agent інтегрується з Twilio, запускає outbound call до target voice agent у CRM/contact-center платформі, після завершення розмови transcript і метадані передаються в Webhook Lambda, а далі Judge evaluation і report generation виконуються через DynamoDB, Bedrock і S3.
ElevenLabs у цьому контексті виступає як voice simulation layer: забезпечує реалістичні голоси, різні стилі мовлення, акценти та емоційні варіації. Це дозволяє тестувати не тільки те, чи бот пройшов сценарій, а й те, як він поводиться з різними типами користувачів.
AWS Bedrock, зі свого боку, дає enterprise-grade шлях до потужніших Judge models. Для нас це означає, що SimUser може бути дешевшою або локальною моделлю, SUT — реальним remote bot, а Judge — потужнішою моделлю, здатною краще оцінювати довгі transcripts, compliance, user goals і multi-dimensional scoring.
Від platform-native тестування до zero-touch voice evaluation
Поточна platform-native реалізація важлива тим, що вона валідує core loop усередині реальної платформи для клієнтського сапорту: ініціювати voice interaction, провести розмову між synthetic user і target voice agent, отримати transcript, оцінити результат і зберегти структуровану оцінку. Але наступний логічний етап — зробити рішення менш залежним від конкретної production-конфігурації платформи та більш plug-and-play для різних CRM, contact-center і support automation environments.
Ціль наступної фази — максимально decoupled architecture. Ідеальний сценарій: не змінювати production configuration у CRM або support automation platform, не покладатися на platform-native surveys, applets або internal AI engines, а отримувати audio stream або transcript зовнішнім способом, проганяти його через AWS speech processing/STT, оцінювати через Bedrock і відображати результат в окремому reporting UI.
Це відкриває кілька сильних можливостей.
Parallel execution. Можна запускати багато сценаріїв одночасно: різні personas, accents, customer goals, edge cases. Це суттєво скорочує testing lifecycle і дозволяє швидше отримати regression feedback.
Dynamic scenario generation. AI Consultant може створити custom scenario на льоту: «перевір frustrated customer, який хоче routing number, але дає неповний SSN», або «перевір користувача, який починає з одного intent, а потім змінює його посеред розмови».
Goal mapping. Evaluation привʼязується не просто до transcript, а до user goal: що користувач хотів зробити, чи досяг він цього, де flow зламався, чи був clean handoff, чи система змогла запропонувати fallback.
Holistic reporting. Замість click-per-engagement view система має давати bird’s-eye view: які intent-и провалюються, де користувачі застрягають, який fallback повторюється, які сценарії мають низький CX при нормальному OP, які flows потребують retraining або configuration updates.
Саме це перетворює framework з QA automation tool на conversation intelligence system.
Чому multi-judge підхід важливий для enterprise voice testing
Базовий AI feedback може сказати: «відповідь була нормальною» або «бот не допоміг». Але цього недостатньо для enterprise QA.
Команді потрібні структуровані результати, які можна порівнювати між різними запусками тестів, відстежувати в часі, агрегувати в дашбордах і використовувати для прийняття рішень. Саме тому qualitative feedback має перетворюватися на quantitative scoring.
Наприклад, Judge-CX може оцінити:
- Tone & Warmth;
- Clarity & Naturalness;
- Responsiveness.
Judge-OP може оцінити:
- Intent Recognition;
- Flow Completion;
- Fallback & Error Handling.
Додатковий Compliance Judge може оцінювати:
- privacy boundaries;
- sensitive data handling;
- regulatory language;
- escalation rules;
- hallucinated policy or account data.
Таке розділення дозволяє уникнути ситуації, коли один загальний score приховує реальну проблему. Якщо overall score 0.72, це може виглядати «нормально». Але якщо OP score високий, а CX score низький, це означає, що система виконує задачу, але робить це сухо, механічно або незрозуміло. Якщо CX score високий, а OP score низький — користувач отримує приємну розмову, яка не вирішує його проблему. Для бізнесу це ще гірше, бо створює ілюзію якості.
Multi-judge approach дає чеснішу картину. Він дозволяє бачити, який саме аспект interaction потребує покращення: prompt, intent routing, fallback logic, voice persona, STT quality, knowledge base, tool integration або business flow.
Тестування не тільки ботів, а й людей
Один із найцікавіших напрямків — використовувати Judge не тільки для synthetic AI interactions, а й для оцінки реальних human agents.
Уявімо: команда технічної підтримки пройшла навчання. Після цього вони починають спілкуватися з клієнтами. Система бере transcripts дзвінків і проганяє їх через спеціальний Judge prompt, який оцінює конкретний контекст: наскільки добре агенти засвоїли новий матеріал і чи застосовують отримані рекомендації на практиці. Тобто тепер SUT — не бот, а людина-агент.
Judge може оцінити:
- чи агент правильно зрозумів intent клієнта;
- чи довів flow до завершення;
- чи не порушив compliance;
- чи не попросив зайві персональні дані;
- чи не дав hallucinated або incorrect information;
- чи був tone професійним;
- чи клієнт отримав clear next step;
- чи потрібна додаткова coaching session.
Це не має замінити team lead або QA manager. Але це може радикально прискорити первинний аналіз. Замість того щоб вручну аналізувати сотні транскриптів, AI Judge може підсвітити 10% найбільш проблемних interactions, пояснити причину та надати структуроване оцінювання.
Тобто один і той самий Role-Play framework може працювати у двох режимах:
Pre-production synthetic testing — SimUser тестує voice/chat bot до релізу.
Post-production conversation evaluation — Judge аналізує реальні транскрипти ботів або агентів після взаємодії.
Це особливо цінно для банків, insurance, healthcare та будь-яких regulated domains, де «ввічливо поговорив» недостатньо. Потрібно довести, що interaction був коректним, compliant, завершеним і комфортним для користувача.
Майбутнє Voice Role-Play testing
Найближчий розвиток такого framework виглядає дуже практично.
По-перше, зʼявиться більше zero-touch integrations, коли тестування можна буде запускати без змін у production configuration. Це важливо для великих enterprise-клієнтів, де будь-яка зміна в CRM або contact-center platform проходить довгий approval process.
По-друге, буде розвиватися automatic scenario generation. Якщо система може отримати customer-specific configuration, intents, flows, knowledge base або historical transcripts, вона може автоматично запропонувати baseline test scenarios: happy paths, edge cases, fallback cases, negative scenarios та compliance-sensitive scenarios.
По-третє, зросте роль reporting UI. Командам не потрібен просто JSON-файл із оцінками. Їм потрібна картина: які сценарії стабільно падають, які intent-и погіршилися після останнього релізу, які flows мають найгірший CX, які prompts треба переписати, які training examples додати та які knowledge gaps закрити.
По-четверте, voice testing буде все більше поєднувати synthetic і real-world data. Synthetic role-play дозволяє тестувати до релізу. Real transcript evaluation дозволяє бачити, що відбувається після релізу. Разом вони створюють feedback loop: test, release, observe, evaluate, retrain, retest.
І нарешті, stronger LLM-as-a-Judge models через AWS Bedrock, Claude, GPT-4o або інших enterprise-ready providers дозволять зробити evaluation точнішим, стабільнішим і більш domain-aware. Особливо якщо Judge prompts будуть напряму прив’язані до user goals, business rules та compliance requirements.
Висновок: voice testing має стати системним, вимірюваним і повторюваним
Голосові AI-рішення не можна якісно перевірити лише happy path сценаріями. Реальні користувачі говорять з акцентами, перебивають, нервують, плутаються, змінюють intent посеред розмови й очікують, що система все одно зрозуміє їхню потребу та допоможе. Саме тому voice QA/QC має рухатися від епізодичного ручного аналізу транскриптів до системного, повторюваного AI-assisted evaluation, де кожна розмова оцінюється за однаковими критеріями: intent recognition, flow completion, fallback handling, tone, clarity, responsiveness і user goal achievement.
Role-Play framework дає для цього практичну основу:
- SimUser створює реалістичну поведінку користувача;
- SUT проходить реальний conversational flow;
- Judge оцінює результат за CX, OP, compliance і business-goal критеріями;
- reports перетворюють субʼєктивне «бот працює погано» на structured data;
- adapters дозволяють підключати різні боти, voice agents і production-like environments;
- Docker, local LLM і Ollama роблять експерименти дешевими;
- Bedrock, Claude, GPT-4o та інші stronger models відкривають шлях до enterprise-grade judging;
- ElevenLabs, Twilio і AWS voice stack дозволяють тестувати не тільки текстову логіку, а й реальні голосові взаємодії.
І головне — цей підхід не обмежується ботами. Його можна використовувати для аналізу human agents, coaching, compliance review і conversation quality monitoring.
Якщо у вас уже є voice-рішення, але воно нестабільно поводиться в реальних діалогах, плутає intent-и, звучить роботизовано, зависає у fallback loops або не дає зрозумілих звітів для retraining — це саме той клас проблем, який Role-Play testing може виявити, виміряти і допомогти виправити.
Давайте поспілкуємось. Якщо ваш voice agent уже працює, але його якість складно виміряти, пояснити або покращити — ми можемо допомогти перетворити його з чорної скриньки на систему, яку можна тестувати, оцінювати, вдосконалювати і масштабувати.
1 коментар
Додати коментар Підписатись на коментаріВідписатись від коментарівСподобалась ця ідея заюзати на людях )
Сам фреймворк робив схожий на VAPI як тест-завдання але evals фіксовані робив — не симулюв на ходу користувачів та симулював на веб-сокетах без реального колу з Twilio.