Створюємо Meeting Minutes за допомогою AI: мій досвід з AWS
Привіт! Мене звати Оксана, і я працюю бекенд-інженером, спеціалізуючись на AWS. Ще в університеті я захоплювалася машинним навчанням і навіть розпочала свою кар’єру як науковий співробітник у цій галузі. Але життя внесло свої корективи: через фінансові обставини я перейшла в розробку, адже на той час машинне навчання ще не було у центрі уваги. Проте я не покинула своє захоплення повністю, підтримуючи інтерес до цієї сфери через участь у Kaggle-змаганнях та хакатонах.
З роками популярність машинного навчання то зростала, то знижувалася. Аж ось новий тренд — генеративний штучний інтелект — знову підігрів мою цікавість. Щоб глибше познайомитися з цією технологією, я вирішила скласти сертифікацію Amazon AI Practitioner. Хоча сертифікація й знаходиться на рівні Foundational, підготовка до неї виявилася однією з найцікавіших у моїй кар’єрі.
Під час навчання я дізналася про:
- Prompt engineering — як правильно формулювати запити для моделей ШІ.
- Слабкі сторони генеративних моделей та способи їх усунення в production-системах (biased responses, prompt attacks, hallucinations).
- Архітектури AI в клауді — створення простих рішень та вибір між детерміністичними методами й генеративними моделями для конкретних задач.
Складання сертифікації стало лише початком. Після цього я захотіла реалізувати кілька практичних проєктів у хмарі:
- Pipeline для сентимент-аналізу відгуків користувачів із використанням Step Functions та Amazon Comprehend (приклад для малого бізнесу).
- Сентимент-аналіз для великої кількості фідбеків, та сама задача, але через s3-тригери, SQS та Lambda.
- Візуалізація зібраних сентиментів через Athena та QuickSight.
- Перетворення мітингу у сторінку Meeting Minutes на Confluence за допомогою генеративного AI.
- LLM fine-tuning для адаптації чат-бота під конкретну доменну область та вирішення тої самої задачі за допомогою RAG та порівняння результатів.
- Якщо залишиться час, зробити LLM Agent Application.
Всі мої проєкти доступні у репозиторії, а їх детальний опис ви знайдете в моєму блозі.
У цій статті я хочу поділитися досвідом автоматизації meeting minutes, адже цей проєкт став для мене найзахопливішим. Було дуже цікаво побачити ефектний результат у Confluence після завантаження мітингу на s3-бакет.
Автоматизація meeting minutes
Ну що ж, настав час написати, як на мене, найзахопливішу частину статті, адже я давно хотіла попрацювати з Large Language Model у контексті реального бізнес-проєкту. Як розробниця я, як і всі інші, брала участь у корпоративних мітингах. Після них хтось із менеджерів сідав за написання протоколу (meeting minutes) зустрічі в Confluence. З одного боку, це було частиною процесів компанії, а з іншого — надзвичайно корисною практикою. Протокол дозволяв зафіксувати важливі моменти, які інакше швидко би забулися, а також допомагав повернутися до деталей пізніше, при імплементації конкретних активностей.
Для реалізації цього проєкту я вирішила використати такий підхід:
- Публічні мітинги з інтернету: на щастя, YouTube-канал GitLab пропонує різноманітні доступні для всіх записи мітингів, що охоплюють інженерні обговорення, оновлення маркетингових команд та сесії продуктових департаментів. В коментарях до цих мітингів я з посмішкою прочитала, що розробники на ремоуті інколи включають їх, щоби уникнути побутових домашніх завдань від родини.
- Обробка аудіо: мітинги конвертуються у формат mp3, після чого обробляються за допомогою сервісу Transcribe в асинхронному режимі. Transcribe Job створює субтитри на основі аудіофайлу. Субтитри записуються на s3 бакет.
- Субтитри та тайм-коди: субтитри передаються в LLM (я вирішила залишатися в інфраструктурі AWS та LLM активувала в Amazon Bedrock), у форматі prompt для генерації структурованих даних, які відповідають стандартному формату meeting minutes для Confluence.
- Публікація в Confluence: згенерований структурований результат використовується для створення сторінки і публікації її безпосередньо в Confluence через API.
Від audio segments до summary
Це був захопливий досвід, і результати перевершили мої очікування. Результатом роботи Amazon Transcribe був набір невеликих аудіосегментів, перетворених у текст і відмічених часовими мітками початку та кінця, причому одна презентація (наприклад, доповідь інженера А) могла розподілятися між кількома сегментами. Потім, коли я передивилася мітинг, побачила, що саме цей проходив не у форматі «презентери роблять доповіді», а у вигляді дискусії між всіма інженерами потрошку, що ускладнювало задачу.
Я сумнівалася, чи зможе LLM точно визначити, як розподілити конкретні аудіосегменти між учасниками, правильно розрахувати часові мітки та витягнути імена осіб. Нижче ви бачите шматочок відповіді від Amazon Transcribe, для передачі в prompt я використовувала лише транскріпти та мітки часу. Тут, в офіційній документації AWS, ви знайдете докладний опис формату результату від Transcribe.
{ "audio_segments": [ { "id":0, "transcript":"If, if it's like my family, I am definitely, I definitely have no subjects.", "start_time":"0.86", "end_time":"4.829", "items":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] }, { "id":1, "transcript":"Hey Daniel, hey Eric.", "start_time":"6.909", "end_time":"8.439", "items":[18,19,20,21,22,23] }, { "id":2, "transcript":"Hello. Welcome. Welcome back here. Yeah, it's great to be here.", "start_time":"9.26", "end_time":"13.329", "items":[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40] } ] }
Хоча я не реалізувала цю функціональність, додати систему сповіщень через SNS, яка б повідомляла менеджерів електронною поштою та пропонувала переглянути згенеровану сторінку в Confluence, було б відносно нескладно. Наразі імплементація не має можливості тегати окремих осіб у Confluence, він лише витягує імена спікерів на основі транскрипту. Думаю, що для production варіанту можна би було публікувати статтю в режимі Draft та надсилати листа модератору. Можна було б також збирати фідбеки від модераторів та поліпшувати промпт для отримання кращих результатів.
Огляд архітектури
Розгляньмо детальніше архітектуру проєкту. Вона досить проста, а завдяки легкості інтеграції з сервісами AWS її імплементація стала просто приємною розвагою на вільний час. Все працювало з першої спроби, а на реалізацію пішло лише пару сесій, кожна тривалістю близько чотирьох годин. Колись я, як, мабуть, і всі, обпеклася об рахунок від Амазону після розгортання проєктів для навчання, тому в цей раз від початку налаштувала аудит та перед кожним деплоєм робила теоретичний розрахунок бюджету проєкту. Після тестування відразу вичищала всі ресурси. Тому на цей раз все моє навчання вийшло мені $2.50.
Як і в попередніх проєктах, я вирішила залишитися в екосистемі Amazon. Для створення транскриптів із записів зустрічей я використовувала Amazon Transcribe, а генерацію підсумків забезпечив Amazon Bedrock. Крім того, я створила пробний обліковий запис у Confluence, а також ознайомилася з вимогами API для подання сторінок у правильному форматі.
Основні компоненти проєкту
- s3-бакети: використовуються для зберігання аудіофайлів мітингів і їх транскриптів.
- Lambda-функції: автоматизують робочі процеси створення транскриптів і генерації підсумків мітингів.
- Інтеграція з Confluence: ключі API та Confluence Space зберігаються у AWS Parameter Store для безпечного доступу.
- Serverless Framework: для розгортання інфраструктури та управління ресурсами в мене був попередній досвід, тому я обрала цей спосіб для provision інфраструктури.
- Anthropic Claude-v2: LLM я обрала на основі розміру контекстного вікна та за описом в Amazon Bedrock, де значилося, що ця модель натренована на роботу з текстом та побудову summary.
- Інструменти попередньої обробки: створила скрипт для конвертації відео з YouTube у формат mp3 та очищення транскриптів для формування промптів.
Спочатку я конвертувала обраний мітинг в mp3 формат, потім цей файл записувався на s3-бакет, що тригерило подію ObjectCreated. Ця подія запускала лямбду, яка створювала новий job в Amazon Transcribe. Job виконувався асинхронно та записував результат (транскріпти) на інший s3-бакет. Це, в свою чергу, трігерило іншу лямбду, яка формувала prompt та робила виклик в Amazon Bedrock. По отриманню саммарі робився реквест в Confluence API та створювалася сторіночка Meeting Minutes.
Нижче ви можете побачити мій промпт, який я вирішила зберігати в текстовому форматі. Промпт має в собі плейсхолдер для аудіосегментів. Я описала в точності, яку json структуру очікую у відповіді (на картинці знизу), а також дала підказки, як визначати цілі та ключові моменти мітингів. Повний промпт ви зможете знайти в моєму репозиторії.
{ "Participants": ["Participant 1", "Participant 2", "..."], "Goals": ["Goal1 of the meeting", "Goal2 of the meeting", "..."], "DiscussionTopics": [ { "Time": "start_time - end_time", "Item": "Main Discussion Topic", "Presenter": "Name of Presenter (if available)", "Notes": "Key points discussed" } // Additional presentations ], "ActionItems": ["Action item1", "Action item2", "..."], "Decisions": ["Meeting decision1", "Meeting decision2", "..."] }
Виклики
1. Throttling-моделі
- Проблема: спочатку я експериментувала з коротким, однихвилинним записом TED Talks, але пізніше використала
40-хвилинний мітинг із YouTube-каналу GitLab. Транскрипт містив понад 4500 слів, і через обмеження вікна контексту моделі (5000 токенів) я зіткнулася з throttling. - Рішення: використовувати стиснення сегментів за допомогою LLM або інструментів NLP перед створенням prompt.
2. Непослідовність структури JSON у відповіді від LLM
- Проблема: щоб отримати послідовну JSON-структуру від моделі, я визначила очікувані поля в запиті та попросила модель надсилати відповідь лише у форматі JSON. Проте вона постійно додавала додаткові коментарі або формувала JSON у неконсистентному форматі (наприклад, обгортала його в ‘’’json{}’’’ або включала у вигляді рядка).
- Рішення: я вирішила чітко інструктувати модель про необхідність огортання JSON у структуру ‘’’json{}’’’ і додати регулярний вираз, щоби точно показати, в якому вигляді я чекаю цей шматок респонсу.
3. Тривалий час обробки
- Проблема: для
40-хвилинного мітингу функція Lambda, відповідальна за створення підсумків, обробляла дані понад хвилину. - Рішення: врахувати час обробки при налаштуванні тайм-аутів у при створенні лямбди, яка формує підсумки.
Найбільш хвилююча частина цього проєкту — це побачити результат в Confluence. Я швидко продивилася сам мітинг, щоби мати змогу співставити результат з очікуваннями. Як я побачила з самого мітингу, він не проходив в форматі оголошення презентера — презентація — визначення наступних кроків, спочатку було вступне слово CTO про поточні відкриті питання (і Anthropic розпізнав це як два окремих виступи). Потім почалася загальна дискусія на півгодини, де всі говорили потрошку, що було розпізнано як окремий виступ презентера на ім’я Мак, бо він був активним учасником. Загалом є куди рухатися та як тюнити prompt, але результати для відправної точки отримані й можуть бути підлаштовані для конкретного бізнес-кейсу.
Попереду ще імплементація декількох проєктів для самонавчання. Також, ці експерименти розбудили цікавість до більш глибокого розуміння трансформерів, так що попереду ще немало роботи! Я передивилась багато відео в інтернет про архітектуру трансформерів, але найбільш зрозуміле інтуїтивне пояснення, достатнє, як я думаю, для бекенд інтеграторів, я знайшла в Гранта Сандерса: Transformers (how LLMs work) explained visually.
Якщо ви є більш досвідченим інтегратором, поділіться, як ви долали проблеми з неконсистентністю в форматі відповіді, або які техніки Prompt Engineering використовували, щоби досягти результату. Або яку передобробку можна було б зробити, щоби зменшити розмір контекстного вікна.
Взагалі я вважаю, що зараз чудовий час для нас, бекенд-інженерів, спробувати себе в штучному інтелекті (навіть як інтеграторів), бо тренд на генеративні моделі відкриває потенціал для розвитку гібридних професій!
Немає коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів