Rustam Rakhamnov

+5
с 2024
0 подписчиков
0 подписок
Бекэнд на fastify для няшных котят (aura8)

Мы разработали приложение, где пользователь может свайпать картинки, и с учетом лайков пользователя мы генерируем новые картинки. Ниже рассказ, с чем интересным мы столкнулись во время разработки этого приложения.

Речевая аналитика в контакт-центре, или в отделе продаж — это ключевой инструмент для оценки качества обслуживания и соблюдения стандартов общения. С развитием больших языковых моделей (LLM), таких как YandexGPT, подход к анализу диалогов кардинально изменился. Теперь вместо поиска словосочетаний и настройки сложных шаблонов — достаточно передать в…

Перевод статьи из блога Rasa, Kazeem Omisore

Если вам доводилось когда-нибудь заниматься разработкой виртуального ассистента…

Разработали речевую аналитику для контакт-центра. Распознавание речи через сервис Yandex Speechkit, а анализ полученного текста уже в контуре, на нашем решении. По ходу разработки встречались интересные моменты, которые постараюсь описать.

1. Yandex Speechkit. Распознает речь в текст очень хорошо, по моему для казахского языка на сегодня вооб…

4

Перевод статьи от 30.01.2023 г., из блога Rasa

Курс «NLP (Natural Language Processing) для разработчиков» в учебном центре Rasa — это прост…

1

Перевод статьи от 01.02.2023 г., из блога Rasa

Недавно технический директор и соучредитель Rasa Алан Никол (Alan Nichol) провел б…

\n }\n }\n }\n }","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E3. Если новый ID прошел проверку в fastify, то проверяем ID по bloom фильтру пользователей. Если ID нет в массиве пользователей, то это новый пользователь.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E4. Проверяем ID нового пользователя на корректность.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПервая половина ID, это закодированная в ID дата, эта дата должна быть в периоде между датой запуска нашего проекта, и датой сегодня.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EКак проверить вторую половину, которая случайный набор символов? Если энтузиасты будут генерировать ID типа 19bc19e00ab-aaaaaaaaaaaa? Вторую половину ID проверяем на энтропию, энтропия должна быть больше 2.\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"function getEntropyString( str: string ): number {\n const frequencies = new Map();\n for (const char of str) {\n frequencies.set(char, (frequencies.get(char) || 0) + 1); }\n return [...frequencies.values()].reduce((acc, count) =\u003E {\n const p = count / str.length;\n return acc - p * Math.log2(p);\n },\n 0);\n }","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E5. Если новый ID корректный, то добавляем его в массив bloom фильтра существующих пользователей, и отправляем INSERT в таблицу пользователей, не ожидая завершение INSERT. Да, есть проблема, с вставкой нового пользователя может что то пойти не так, и по хорошему нужно сначала завершить вставку, обработать ошибку, и только потом считать этого пользователя за существующего. Но это накладно с точки зрения нагрузки на бекэнд, смиримся с тем, что есть вероятность потери какого то пользователя после рестарта бекэнда. Под «потерей пользователя» подразумевается, что при рестарте бекэнда, этот пользователь будет считаться новым, по нему не сохранится история свайпов картинок.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Статичный контент через nginx"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EБекенд приложения собирает статистику лайков по картинкам, генерирует новые картинки, и складывает новые картинки в папки, структура папок Год — Месяц — День. В приложении картинки подгружаются по URL. Но как отдавать статичный контент с бекэнда, чтобы это происходило с минимальной нагрузкой на сервер? Да, в fastify есть возможность раздавать статичный контент, и это реализовано хорошо. Но еще лучше на бекэнд сервере запустить nginx, под отдельным доменом, и настроить раздачу контента из папки, куда бекэнд приложение складывает картинки.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Серия картинок для пользователя"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДля пользователя генерируем новую серию URL картинок для просмотра, сериями по 10 штук. ID картинок в серии, добавляем в bloom фильтр «Просмотренные картинки» для каждого пользователя. При генерации новой серии проверяем, была ли эта картинка в предыдущих сериях, по bloom фильтру для этого пользователя.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТаким образом, бекэнд и мобильное приложение общаются сериями по 10 картинок.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E1. При старте мобильного приложения загружается две серии по 10 штук.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E2. Далее, каждые 10 лайков, мобильное приложение отправляет реакции на бекэнд, и получает новую серию 10 картинок.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПока пользователь лайкает серию из 10 картинок, приложение отдает лайки по предыдущим 10 картинкам, и получает новую серию из 10 следующих картинок.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Ограничение по количеству запросов"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ fastify есть rateLimit, ограничивающий количество запросов от одного пользователя. RateLimit можно настроить на использование redis как хранилища IP адресов и времени последних запросов. Но если бекэнд сервер пока один, то можно обойтись без redis, хранить все в памяти node.js приложения.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Проверка лайков по картинкам"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EМобильное приложение собирает реакции пользователей, и отправляет реакции на бекэнд пачками, по 10 штук. Одна реакция это ID картинки, и лайк или дизлайк. Опять же, как решить проблему с энтузиастами, которые могут генерировать эти реакции, и завалить бекэнд? Добавляем limitRate, и проверяем реакции по следующей логике:\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E1. ID пользователя и ID картинки должны пройти проверку на уровне fastify схемы. Реакции, лайк или дизлайк, можно также проверять как enum в fastify схеме.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E2. ID пользователя должен пройти проверку по bloom фильтру «Существующие пользователи».\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E3. ID картинки должен пройти проверку по bloom фильтру «Просмотренные картинки» для этого пользователя.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E4. На всякий случай, проверяем лайки на чередование, если пользователь просто смахивает картинки в одну сторону, или чередует влево — вправо, то эта серия реакция не заслуживает доверия, и игнорируется:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"function trustLikeInBatch10( batch: string[] ): boolean {\n if( batch.length != feedLimit ) return false;\n const likes = batch.filter( v =\u003E v === 'like' ).length;\n if( likes === 0 || likes === feedLimit ) return false;\n const switches = batch.slice(1).reduce( ( acc, val, i ) =\u003E acc + ( val !== batch[ i ] ? 1 : 0 ), 0 );\n if( switches \u003E= 8 ) return false;\n return true;\n }","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E5. Если ID пользователя, и ID картинки, прошли проверки, то эту реакцию можно отправлять как INSERT в таблицу реакция в базу данных, причем опять, не ждем завершения вставки, и не обрабатываем ошибки вставки, чтобы уменьшить нагрузку на бекэнд. Более того, в таблице реакций не делаем CONSTRAINT FOREIGN KEY по ID таблицы пользователей, и по ID таблицы картинок, так это лишняя нагрузка на базу данных при вставке. Хотя отсутствие CONSTRAINT FOREIGN KEY в связанных таблицах выглядит очень непривычно.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Маскируем ошибки валидации fastify"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСнова вспомним про энтузиастов, которые могут попробовать положить бекэнд приложения, из любопытства, или еще непонятно для чего. Чтобы чуть усложнить жизнь таким энтузиастам, мы маскируем ошибки fastify при валидации JSON схемы запроса. По умолчанию fastify сообщает в ответе, в чем именно ошибка. Если в объявленной схеме указана длина, или паттерн, то при ошибке fastify в ответе укажет, в чем именно проблема.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПоэтому в fastify route добавляем перехват ошибки:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"fastify.setErrorHandler((\n error: FastifyError,\n request: FastifyRequest,\n reply: FastifyReply ) =\u003E \n{\n console.error( 'setErrorHandler', error );\n countErrorStatistics();\n reply.code(200).send( 'Hello World!' );\n });","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТеоретически, мобильное приложение тоже может получить в ответе от бекэнда вместо нормальной ошибки, вот такую замаскированную ошибку. Это нужно учитывать на стороне мобильного приложения.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Сделать тип из массива строк"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНебольшая проблема, у которой нашлось решение. Есть какой то массив строк, например перечень состояний картинки. Картинка может быть новой, может быть в состоянии генерации, в состоянии ошибки, и т.п. В тоже время, в коде бекэнда у переменных, в которых хранится состояние картинки, должен быть тип, допускающий присвоение только таких значений. То есть в коде должен быть и массив строк, и тип с этими строками. В TypeScript нашлась элегантная конструкция для этого:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"// Usually it's like this:\n const imageStateArray1 = [ 'new', 'broken', 'gpt', 'ready', 'download', 'done', 'bad' ];\n type tpImageState1 = 'new' | 'broken' | 'gpt' | 'ready' | 'download' | 'done' | 'bad';\n\n // or better yet:\n const imageStateArray2 = [ 'new', 'broken', 'gpt', 'ready', 'download', 'done', 'bad' ] as const;\n type tpImageState2 = ( typeof imageStateArray2 )[ number ];","lang":""}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Резюме по проекту"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРезюме, фактически приложение может жить само по себе, без базы данных. После старта бекэнд приложения, после загрузки ID пользователей, и ID картинок, в память приложения, из запросов к базе данных осталась только вставка новых пользователей, и вставка реакций. И эти вставки происходят без await, чтобы уменьшить время обработки запросов. Внутри контроллера, который обрабатывает запросы со стороны мобильного приложения, только математика и работа с bloom фильтрами.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EПримечание:\u003C/b\u003E На 2026-03-27 проект находится на стадии MVP. Бекэнд и приложение работоспособны, но адаптация ленты картинок под лайки пользователя пока отключена.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЗагрузить \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dkz.crm.aura8&postId=2817285\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eприложение из Google Play\u003C/a\u003E.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h3","text":"Что дальше"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ планах добавить другие категории картинок, кроме няшных котят и щенков, например: Природа, Фентези, и т.п.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНарод, напишите плиз в комментариях, какую категорию AI картинок есть смысл добавлять в приложение:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Природа.","Фэнтези.","Арт с девушками.","Другое (что?)"],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПод \"Арт с девушками\" подразумевается типа: \u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"199abba7-204a-5562-a421-1a6a9c204e0a","width":720,"height":960,"size":187315,"type":"jpg","color":"7c6641","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAKAAoDASEAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABgUH/8QAIxAAAgEDAwQDAAAAAAAAAAAAAQIDBAURACEiBgcTMRJBQv/EABcBAAMBAAAAAAAAAAAAAAAAAAIEBQb/xAAaEQEAAwADAAAAAAAAAAAAAAABAAIDESEx/9oADAMBAAIRAxEAPwCHU2+8PRz1dvmn+HklMcIIUNzILqf0MHcfXv1plaqe5z2ylnEc48kKNggZ3UHWewuNO3uUb56UDjyBu5QFHbI5KQCncSHDRcTuxzuNbT0u7t01a2Z2LGjhJJO54DR6h7GeVAn/2Q=="}}}]}}],"customUri":"backend-na-fastify-dlya-generatsii-kartinok","commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":0,"favorites":0,"reposts":0,"views":28,"hits":21,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":0,"total":49},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":"Разработка бекэнда на Fastify, создание уникальных ID, использование Bloom фильтров, авторизация без регистрации, генерация картинок для пользователей","isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[],"reactionId":0},"url":"https://vc.ru/dev/2817285-backend-na-fastify-dlya-generatsii-kartinok","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":235819,"name":"Разработка","description":"Сообщество разработчиков: публикации о личном опыте, выдающиеся приёмы при решении рутинных задач, полезные материалы для профессионального роста.","uri":"/dev","avatar":{"type":"image","data":{"uuid":"fef5b5fb-e488-5b7f-8445-e3a26a910b44","width":1200,"height":1200,"size":7757,"type":"png","color":"343434","hash":"04042b2b1c1000","external_service":[]}},"cover":{"type":"image","data":{"uuid":"2a214cc5-35cc-58ca-bc07-fc1c892d2101","width":960,"height":280,"size":177,"type":"png","color":"343434","hash":"","external_service":[]}},"lastModificationDate":1642411346,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"dev","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"donations":{"amount":0,"isDonated":false},"isBlur":false}},{"type":"entry","data":{"id":2047667,"subsiteId":2770916,"date":1750156009,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"repostId":null,"isEditorial":false,"isPublished":true,"isDisabledAd":false,"source":null,"withheld":[],"dateModified":1750156752,"title":"YandexGPT и речевая аналитика: от поиска ключевых фраз — к пониманию смысла","isGame":false,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРечевая аналитика в контакт-центре, или в отделе продаж — это ключевой инструмент для оценки качества обслуживания и соблюдения стандартов общения. С развитием больших языковых моделей (LLM), таких как YandexGPT, подход к анализу диалогов кардинально изменился. Теперь вместо поиска словосочетаний и настройки сложных шаблонов — достаточно передать весь диалог модели и задать ей понятные вопросы\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРаньше аналитика работала по линейному сценарию: голосовые записи звонков из телефонии транскрибировались в текст, после чего специальный модуль искал в этом тексте заранее заданные ключевые слова и фразы. На основе наличия или отсутствия этих фраз делались выводы: был ли использован нужный скрипт, было ли приветствие, озвучено ли имя клиента и пр.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"\u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fspeechkit-demo.crm.kz%2F%23%2Fscript&postId=2047667\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003Ehttps://speechkit-demo.crm.kz/#/script\u003C/a\u003E","image":{"type":"image","data":{"uuid":"4df53614-08fc-5235-a4ba-5c902d44439a","width":1920,"height":1080,"size":62969,"type":"png","color":"f0f3f2","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAgUJ/8QAJBAAAQIFAgcAAAAAAAAAAAAAAQIDAAQFERIUkRUhMUFRY9H/xAAXAQADAQAAAAAAAAAAAAAAAAABAgME/8QAHBEAAgICAwAAAAAAAAAAAAAAAAECEQNhMXGx/9oADAMBAAIRAxEAPwDTZhqqSjKi46VgqOJccCiLmw54jaK5MsG+K6ESkHjXlCtj8hLDQqUpWjmzkbiZe7+ww80nOnrxEYOoyey0esSNB//Z"}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТеперь достаточно интегрировать аналитику с YandexGPT. Рассмотрим чуть более сложную аналитику, чем оценка «было ли приветствие». Оценим эмоциональность диалога (положительно, нейтрально, негативно), и пытался ли менеджер решить основную задач. Например, для автосалон, основная задача менеджера — пригласить клиента посетить автосалон. Еще желательно вылавливать случаи «Нет в наличии», когда клиент искал автомашину, которой нет в наличии.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EШаг 1. Собрать системный промпт\u003C/b\u003E\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ запросе на API Яндекс есть два промпта, system и user. В системном промпте описываем общее задание для GPT, и добавляем описание, как результаты обработки разложить в JSON.\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"const mainPrompt = \"Твоя компания продает автомашины. Ты аналитик, ты оцениваешь работу менеджеров отдела продаж. Оцени разговор менеджера с клиентом. Основной задачей менеджера является убедить клиента посетить автосалон.\";\n\nconst jsonPrompt = \n'Дай следующие результаты анализа:\\n' +\n'1. Тема разговора (результат в поле topic);\\n' +\n'2. Суммаризируй разговор (результат в поле summary);\\n' +\n'3. Подведи итоги разговора (результат в поле result);\\n' + \n'4. Поставь оценку менеджеру (от 0 до 5), пытался ли менеджер выполнить свою основную задачу (результат в поле rate);\\n' + \n'5. Сообщал ли менеджер клиенту, что какого-то товара нет в наличии: да (out), нет (nope) - (результат в поле stock);\\n' +\n'6. Оцени эмоции в разговоре: негативно (negative), нейтрально (neutral), позитивно (positive) - (результат в поле emotional);';","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСоединяем через точку оба промпта, получаем системный промпт:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"const systemPrompt = mainPrompt + '. ' + jsonPrompt;","lang":""}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"\u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fspeechkit-demo.crm.kz%2F%23%2Fclassifier&postId=2047667\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003Ehttps://speechkit-demo.crm.kz/#/classifier\u003C/a\u003E","image":{"type":"image","data":{"uuid":"a8cbeca4-9db2-5202-883b-8a5095c1080c","width":1920,"height":1080,"size":205300,"type":"png","color":"959899","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAwgJ/8QAJBAAAQMDAQkAAAAAAAAAAAAAAQIDBgAF0iEEERIUFlGUlcL/xAAYAQADAQEAAAAAAAAAAAAAAAAAAQIDBP/EABoRAAMBAAMAAAAAAAAAAAAAAAABAgMRMZH/2gAMAwEAAhEDEQA/ANK24RA1IHBErHuHfZGx80CF6ChJ1ENsfiN40DJKcm80CCRL737B3KqI5BVMJaVEmU3cknU887lXPWWbbbleGqukuz//2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EШаг 2. Собрать данные по диалогу\u003C/b\u003E\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВо второй промпт, который user, собираем простынь переписки. Автор реплики, и через двоеточие сама реплика. Следующая реплика через новую строку. Так как в системном промпте используются «Менеджер» и «Клиент», то соответственно в переписке тоже используем «Менеджер» и «Клиент», а не «сотрудник», «покупатель», или как то еще.\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"const userPrompt = 'Клиент: здравствуйте, меня интересует автомашина;\\n' +\n'Менеджер: да, есть автомашины, но в наличии осталось мало. Не хотите ли приехать в автосалон?;\\n'\n+\n...","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EШаг 3. Отправляем запрос в YandexGPT\u003C/b\u003E\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EУ YandexGPT в API есть несколько методов для работы с LLM, самый дешевый это асинхронный. Цены зависят от токенов. Если не в токенах, а в понятных единицах измерения, то оценка одного диалога (примерно 2-3 минуты разговор) будет стоить около 4-5 тенге за диалог, это порядка 1 руб за диалог. Может чуть больше, не считал эти токены.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЗапрос отправляем на «штатную» LLM. Есть еще вариант дообучить модель, и работать со «своей» LLM, но для общей оценки диалога, достаточно «штатной» LLM.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСоответственно url для асинхронного запроса:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"const urlYandex = 'https://llm.api.cloud.yandex.net/foundationModels/v1/completionAsync';","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДля запроса на API еще нужен folderId, это ID папки в консоли Яндекс. Так же в папке должен быть сервисный экаунт с ролью ai.languageModels.user, и для этого экаунта создать API-ключ.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТело запроса:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"const requestBody = {\n    \"modelUri\": \"gpt://\" + folderId + \"/yandexgpt/latest\", // \"Это если испольуем общую LLM\n    // \"modelUri\": \"ds://\" + modelId, // Это если используем дообученную \"свою\" LLM\n    \"completionOptions\": {\n      \"stream\": false,\n      \"temperature\": 0.3,\n      // \"maxTokens\": \"20\"\n    },\n    \"messages\": [\n        {\n            \"role\": \"system\",\n            \"text\": systemPrompt,\n        },\n        {\n            \"role\": \"user\", \n            \"text\": userPrompt\n        }\n    ],\n    \"jsonObject\": true,\n    \"jsonSchema\": {\n        \"schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"topic\": {\n                    \"type\": \"string\"\n                },\n                \"summary\": {\n                    \"type\": \"string\"\n                },\n                \"result\": {\n                    \"type\": \"string\"\n                },\n                \"rate\": {\n                    \"type\": \"number\",\n                    \"minimum\": 0,\n                    \"maximum\": 5,\n                },\n                \"stock\": {\n                    \"type\": \"string\",\n                    \"enum\": [ \"out\", \"nope\" ]\n                },\n                \"emotional\": {\n                    \"type\": \"string\",\n                     \"enum\": [ \"negative\", \"neutral\", \"positive\" ]\n                }\n            },\n            \"required\": [ \"topic\", \"summary\", \"result\", \"rate\", stock\", \"emotional\" ] // Если не указать required, то LLM может игнорировать поля\n        }\n    }\n}","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВыше, в системном промпте описано, как результаты оценки разложить в JSON. Соответственно в запрос вкладываем эту же самую JSON схему, и указываем, что поля обязательные (required). Если не указать required, то LLM может игнорировать поля.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПри отправке запроса заголовок x-client-request-id можно не присваивать, он не влияет ни на что. Пустой заголовок x-data-logging-enabled означает, что я не хочу, чтобы Яндекс использовал мои данные для обучения своих моделей, то есть я не хочу, чтобы Яндекс хранил у себя мои данные.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПо результатам запроса API должен вернуть resuestId, если тело корректное. Если некорректное, то в ответе не будет \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=http%3A%2F%2Fdata.id%2F&postId=2047667\" rel=\"nofollow noopener\" target=\"_blank\"\u003Edata.id\u003C/a\u003E.\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"let result = {\n      success: false,\n      state: 'dummy',\n      requestId: 'no',\n    }\n\n    axios.defaults.headers.common['Authorization'] = 'Api-Key ' + gptKeyAPI;\n    axios.defaults.headers.common['x-client-request-id'] = 'snt_' + UtilRandomNum( 10000000, 90000000 );\n    axios.defaults.headers.common['x-data-logging-enabled'] = '';\n\n    try {\n      const res = await axios.post(urlYandex, requestBody);\n      result.requestId = res.data.id;\n      result.state = 'gpt';\n      result.success = true;\n      return result;\n    } catch (e: any) {\n      result.success = true;\n      result.state = 'bad';\n      return result;\n    }","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПолученный requestId сохраняем.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003EШаг 4. Получаем результаты YandexGPT\u003C/b\u003E\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДалее через пару минут запрашиваем результаты, с url:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"axios.defaults.headers.common['Authorization'] = 'Api-Key ' + gptKeyAPI;\n\nconst url = 'https://operation.api.cloud.yandex.net/operations/' + requestId;","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЕсли в ответе есть поле done, и в нем значение true, то результаты готовы. Если не результаты не готовы, то через минуту повторяем запрос на результаты.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПарсим результаты:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"const responseString = response.data.response.alternatives[ 0 ].message.text;\n\nconst responseData: any = JSON.parse( responseString );","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ responseData будет JSON схема с ответом от YandexGPT.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДалее сохраняем, и показываем результаты довольным пользователям в карточке звонка на вкладке «GPT суммаризация».\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"\u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fspeechkit-demo.crm.kz%2F%23%2Fspeech-transcript-form%2FSP0003&postId=2047667\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003Ehttps://speechkit-demo.crm.kz/#/speech-transcript-form/SP0003\u003C/a\u003E","image":{"type":"image","data":{"uuid":"ada4fb36-7e67-5f52-bd56-c7d441bfd03e","width":1920,"height":1080,"size":120948,"type":"png","color":"ebf0f0","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAgMFCf/EACAQAAIBAwQDAAAAAAAAAAAAAAECAwAREhMhUVNxkaH/xAAVAQEBAAAAAAAAAAAAAAAAAAACAf/EABkRAQEAAwEAAAAAAAAAAAAAAAABAhIhMf/aAAwDAQACEQMRAD8A1GhXBVykuSNgWNLt8SHYt1/aKo0qJJIHdQzIbqSLlfHFPbLHkoC1ZOxvdBX/2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ целом оценка работает хорошо. Пишите звоните, переходите на \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fspeechkit-demo.crm.kz%2F&postId=2047667\" rel=\"nofollow noopener\" target=\"_blank\"\u003EДемо стенд\u003C/a\u003E.\u003C/p\u003E"}}],"customUri":"yandex-gpt-i-rechevaya-analitika","commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":0,"favorites":0,"reposts":0,"views":28,"hits":12,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":0,"total":40},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":"Yandex GPT, речевая аналитика, оценка качества обслуживания, анализ диалогов, автосалон, эмоциональность, работа менеджеров","isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[],"reactionId":0},"url":"https://vc.ru/ai/2047667-yandex-gpt-i-rechevaya-analitika","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":332941,"name":"AI","description":"Нейросети, искуственный интеллект, машинное обучение","uri":"/ai","avatar":{"type":"image","data":{"uuid":"47d7652c-7ff3-5ad3-b72c-3d0aa7d14f06","width":1200,"height":1200,"size":311374,"type":"png","color":"8dd2f1","hash":"2070ecd4e4745850","external_service":[]}},"cover":{"type":"image","data":{"uuid":"d830f642-8293-f95c-8c0a-cf31c79fd3aa","width":1920,"height":384,"size":110830,"type":"gif","color":"3b3846","hash":"","external_service":[],"duration":0}},"lastModificationDate":1602860409,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"ai","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"donations":{"amount":0,"isDonated":false},"isBlur":false}},{"type":"entry","data":{"id":1176961,"subsiteId":2770916,"date":1715836648,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"repostId":null,"isEditorial":false,"isPublished":true,"isDisabledAd":false,"source":null,"withheld":[],"dateModified":1715836648,"title":"Достижение лучших результатов в бизнесе благодаря отладке виртуального ассистента в Rasa X","isGame":false,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПеревод статьи \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Frasa.com%2Fblog%2Fachieving-better-business-results-by-tuning-your-assistant-in-rasa-x-enterprise%2F&postId=1176961\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eиз блога Rasa, Kazeem Omisore\u003C/a\u003E\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЕсли вам доводилось когда-нибудь заниматься разработкой виртуального ассистента на базе искусственного интеллекта, то я уверен, вы согласитесь, когда я скажу, что это очень сложно. Удивительно, но зачастую в качестве примера самого трудного этапа разработки ИИ-помощника приводят совсем не то, что ожидаешь услышать. Общаясь со множеством клиентов и пользователей Rasa на протяжении многих лет, мы часто слышим одно и то же: создание прототипа — это самая легкая часть. Настоящие проблемы возникают, когда нужно сделать из прототипа продукт, обеспечивающий лучший в своем классе опыт взаимодействия с компанией, который можно представить клиентам и пользователям.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EУзнав о таком положении вещей, компания Rasa создала методологию Conversation Driven Development (CDD) . Подробнее о ней можно прочитать в этой статье блога. Методология преследует две основные цели:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Помочь в создании лучших разговорных ИИ-ассистентов.","Избавить новичков в Rasa от необходимости учиться на собственном горьком опыте при разработке эффективных ассистентов."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРассмотрим ключевые принципы, которые лежат в основе Conversation Driven Development:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["прототипирование и ранняя обратная связь — диалоги представляют собой ценные данные, выясните, что именно пользователи говорят помощнику и как они взаимодействуют с ним;","непрерывная итерация ассистента — превращение реальных сообщений в учебные примеры для дальнейшего его совершенствования."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЗнакомьтесь: Rasa X/Enterprise — no-code решение для многопрофильных команд, которое поможет в разработке качественного виртуального ассистента на базе ИИ. Программное обеспечение, созданное и поддерживаемое экспертами отрасли. С помощью Rasa X/Enterprise ваши команды смогут:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["тестировать ИИ-ассистента с реальными пользователями, находясь на разных этапах разработки;","собирать и анализировать диалоги."],"type":"UL"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"e1635d0c-8103-5e77-bc17-76d3ed96d03c","width":1400,"height":733,"size":46013,"type":"jpg","color":"dfdde9","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAKAAoDASEAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAYI/8QAIxAAAQMCBQUAAAAAAAAAAAAAAQACAwQFERIhInETMTRSof/EABUBAQEAAAAAAAAAAAAAAAAAAAAD/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAEDEf/aAAwDAQACEQMRAD8A05c6ySSqfSsiqmXBkxEAyuxOu1wI25MO5J51VZ0mev1W1nJAd3nDlLUR/9k="}}}]}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Откройте проект для тестирования"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EАссистенты не могут разрабатываться в вакууме, а внутренние пользователи — команда и тестировщики — не могут точно и полностью воспроизводить действия реальных клиентов. Открытое тестирование ассистента как можно раньше — один из наиболее рекомендуемых шагов, к которым мы в Rasa призываем всех разработчиков. Как только ассистент сможет проходить «счастливый путь» (Happy path) для ключевых сценариев использования, попробуйте поделиться им с некоторыми пользователями и собрать данные о том, как они с ним взаимодействуют. Опыт, полученный за пределами «счастливого пути», является ключевым для совершенствования и повышения качества ИИ-помощников.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"19021863-fba5-5d03-bd31-f3a3c0274e3e","width":1400,"height":891,"size":100182,"type":"jpg","color":"e7e2f5","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAACAMJ/8QAIhAAAgIBAwQDAAAAAAAAAAAAAQIDBAUAESEGEhMxQYHR/8QAGAEAAwEBAAAAAAAAAAAAAAAAAgYHAQT/xAAjEQABBAECBwEAAAAAAAAAAAABAAIDEQQSIxRBUXGRkrHR/9oADAMBAAIRAxEAPwDSvK5SukTikkk8xB2YyMqAn598/Wu2KCzuGgtDeqpT6fE1SGSW5d8rIrP22nA3I52APGjdkaSQ1orsEWqkboMXTaGuDUgI8YOxjX802DJnu9Z8lRzj8yjvO9j+pEdO14kwGNVY0VRWiAAUAAdo0pzPcZHEnmfqo+LI90DC5xJIHxf/2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ пользовательском интерфейсе Rasa X/Enterprise можно легко создать URL-адрес, чтобы предоставить тестовым пользователям прямой доступ к ИИ-ассистенту и начать собирать отзывы о его работе.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"95902b12-c2a0-5e90-86be-31ea98c6264a","width":3840,"height":2575,"size":185920,"type":"jpg","color":"eaeef7","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAKAAoDASEAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABgEI/8QAIRAAAgEDBAMBAAAAAAAAAAAAAQIRAAMEBRIhMUFRkWH/xAAXAQADAQAAAAAAAAAAAAAAAAABAgQF/8QAGxEAAgEFAAAAAAAAAAAAAAAAAAECAwQSgcH/2gAMAwEAAhEDEQA/ANb67mJiWkMXxvBh7VhripHlgvQ+UefOyGdmGTojgmQzSCf0ieK0LaknHJp66KKpIbgnqrub2ftQhP/Z"}}}]}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Просмотр историй и бесед"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТегирование в диалогах — эффективный способ контролировать беседы в ассистенте. По мере развития ассистента, необходимость в маркировке диалогов будет только расти. Эта методика не просто упрощает аннотирование, но и может использоваться для распределения задач между новичками и более опытными членами команды.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"8edc0c41-9aa3-5f75-9826-3adabd772874","width":1272,"height":804,"size":119346,"type":"jpg","color":"f1f3f3","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFCf/EACEQAAIBAwMFAAAAAAAAAAAAAAECAwAEIQUGEhRBUWFx/8QAGAEAAwEBAAAAAAAAAAAAAAAAAgMEAAH/xAAfEQACAgEEAwAAAAAAAAAAAAAAAQIRIQMEEjFBUWH/2gAMAwEAAhEDEQA/ANN5bkxdQswNrCgxdOw4j3mmxjbVZ+Aq/IPOoZhg58ilcl7NgV3jK9ptjU5oHaGYICJIzxYZHcVZs0pa8VJWjjwmXI8xr8FSBLo//9k="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EКроме того, отмечайте диалоги по мере их просмотра — это отличный способ выделить важные моменты, не отвлекаясь от работы.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"7154f15d-e1a4-53f3-9875-4afd5dc12a9d","width":1280,"height":862,"size":115550,"type":"jpg","color":"303374","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABQcICf/EACIQAAEDBAICAwAAAAAAAAAAAAMBAhEABAUGBxITMSEyUf/EABcBAAMBAAAAAAAAAAAAAAAAAAIDBgT/xAAfEQADAAIABwAAAAAAAAAAAAAAAQIDEQUhMUFRYtH/2gAMAwEAAhEDEQA/ANB9y27Na5bsBe6hktrsrwZGFFhRDJ0bCIqEQhG/aViJ9LWmGpaqK010A2+4j7nlLji0uCgLwXtbSierHomEGsKiwvyhYX1VPOTjFyqnPyfsvovc+CmdbK8nn7vc6IiVn9qVtDZDUUkI/9k="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНа ранних этапах разработки ассистента работа с тегами вручную — вполне подходящее решение. Но по мере того, как ассистент будет развиваться и потребуется просматривать беседы на постоянной основе, вы сможете воспользоваться преимуществами API, доступными в Rasa X/Enterprise — это отличный способ упростить и ускорить связанные с этим процессы.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ нашем \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fgithub.com%2FRasaHQ&postId=1176961\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eрепозитории\u003C/a\u003E на GitHub, можно посмотреть несколько примеров, но вообще существует несколько способов. К примеру, вот этот скрипт можно использовать для автоматической маркировки диалогов на основе вашей собственной логики:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["отмечать все диалоги, в которых заполнен слот customer_IS_ANGRY — в последующем вы сможете легко отфильтровать и просмотреть эти диалоги в Rasa X."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПользовательский интерфейс Rasa X/Enterprise позволяет просматривать ВСЕ диалоги, которые вел ассистент. Кроме того, вы получаете доступ к расширенным возможностям фильтрации для отслеживания диалогов, имеющих для вас наибольшее значение — это могут быть диалоги с низкой точностью прогнозирования намерения, диалоги, в которых присутствовали определенный пользователь или намерение. Пользовательский интерфейс специально разработан для того, чтобы помочь быстро найти то, что вам нужно, и заниматься повышением эффективности ИИ-ассистента.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"940c1193-afcd-5583-adbe-4cb855bf1fd9","width":1039,"height":886,"size":56761,"type":"jpg","color":"f0eff2","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAgJ/8QAHhAAAgEEAwEAAAAAAAAAAAAAAQIDAAQFEQYSITH/xAAYAQACAwAAAAAAAAAAAAAAAAAAAQIDBv/EAB0RAAIBBAMAAAAAAAAAAAAAAAABAgMEETEhQVH/2gAMAwEAAhEDEQA/ANSYHaOVY2O1ZR1p8AJ1SANZHtZhj62j6fv01J7AnTkfIsrFyHKImTvERbqVVVbhwAA50AN1vra3ouhBuC0ul4V5P//Z"}}}]}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Аннотации"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EАннотирование — это процесс добавления контекста к диалогам, который помогает в обучении ассистента. С его помощью вы можете, например, маркировать диалоги с клиентами как позитивные или негативные по настроению. Это важный шаг для создания качественного обслуживания клиентов, которым не стоит пренебрегать.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСам процесс нужно начинать уже после того, как вы провели открытые тесты ассистента, включающие участие реальных пользователей, и у вас есть настоящие диалоги, с которыми можно работать. Так вы сможете убедиться, что помощник продолжает развиваться, чтобы лучше обслуживать конечных пользователей, делать более точные прогнозы и давать правильные и полные ответы на запросы клиентов.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВы можете обучать помощника и с помощью командной строки, но Rasa X/Enterprise предоставляет интуитивно понятный интерфейс, упрощающий этот важный шаг в успешном развитии ИИ-ассистента.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСтраница «Обучение» в Rasa X/Enterprise позволяет заниматься обучением помощника, управлять готовыми или создавать новые тренировочные примеры, а также обучать модели. С ее помощью вы можете просматривать диалоги, которые ведет бот, и видеть, как классифицировались намерения для каждого высказывания, а при необходимости — вносить соответствующие корректировки.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВоспользуйтесь страницей пользовательского интерфейса «Истории», чтобы создавать и визуализировать истории, наглядно просматривая пути диалога, по которым могут пойти конечные пользователи.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"7b91e891-0ca5-52f3-a5a8-5f80fb76010c","width":1101,"height":664,"size":87498,"type":"jpg","color":"f2f2f5","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABgIJ/8QAHxAAAgICAwADAAAAAAAAAAAAAQIDEQAEBRIhIkFh/8QAFgEBAQEAAAAAAAAAAAAAAAAAAgAF/8QAHREAAgEEAwAAAAAAAAAAAAAAAAECBBESITFS8P/aAAwDAQACEQMRAD8A1Fkkl19KWVgJHRS3WwLr9OOMcpJMgueP5/YJlGyqh/kFHahfv1LmnnTR1bj3UOxewtSD6MyyRKigMIj/2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ Rasa мы помогаем создавать ассистентов, которые понравятся вашим клиентам, с помощью технологий, которые любят команды разработчиков. Почему бы не выбрать решение, отвечающее не только вашим сегодняшним, но и завтрашним потребностям\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЕсли вы хотите узнать больше о том, как мы в Rasa используем Rasa X/Enterprise, свяжитесь с нами, и мы поделимся с вами нашими знаниями и опытом.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСтраница нашей компании по \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsanatel.kz%2Fsolution_rasa.htm&postId=1176961\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eбот-платформе Rasa\u003C/a\u003E\u003C/p\u003E"}}],"customUri":null,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":0,"favorites":0,"reposts":0,"views":60,"hits":99,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":0,"total":159},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":null,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[],"reactionId":0},"url":"https://vc.ru/ai/1176961-dostizhenie-luchshih-rezultatov-v-biznese-blagodarya-otladke-virtualnogo-assistenta-v-rasa-x","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":332941,"name":"AI","description":"Нейросети, искуственный интеллект, машинное обучение","uri":"/ai","avatar":{"type":"image","data":{"uuid":"47d7652c-7ff3-5ad3-b72c-3d0aa7d14f06","width":1200,"height":1200,"size":311374,"type":"png","color":"8dd2f1","hash":"2070ecd4e4745850","external_service":[]}},"cover":{"type":"image","data":{"uuid":"d830f642-8293-f95c-8c0a-cf31c79fd3aa","width":1920,"height":384,"size":110830,"type":"gif","color":"3b3846","hash":"","external_service":[],"duration":0}},"lastModificationDate":1602860409,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"ai","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"donations":{"amount":0,"isDonated":false},"isBlur":false}},{"type":"entry","data":{"id":1107783,"subsiteId":2770916,"date":1712168990,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"repostId":null,"isEditorial":false,"isPublished":true,"isDisabledAd":false,"source":null,"withheld":[],"dateModified":1712168990,"title":"PrimeNG + NestJS + Yandex = речевая аналитика","isGame":false,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРазработали речевую аналитику для контакт-центра. Распознавание речи через сервис Yandex Speechkit, а анализ полученного текста уже в контуре, на нашем решении. По ходу разработки встречались интересные моменты, которые постараюсь описать.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E1. Yandex Speechkit.\u003C/b\u003E Распознает речь в текст очень хорошо, по моему для казахского языка на сегодня вообще один из лучших сервисов, по качеству распознавания. Попадались тихие аудио записи, когда абонента еле слышно, но сервис распознавания справлялся. На мой взгляд, не хватает только списка языков, которые сервис распознал, в ответе. Так как в Казахстане все диалоги могут быть смешанными, казахский и русский языки, то на распознавание передаем с параметром lang = auto. И если сервис разобрался, какие в треке встретились языки, то почему бы не вернуть в ответе массив типа [ ru, kz ], или только [ kz ]. или только [ ru ]. Но пока такой опции нет, хотя команда Яндекс обещает.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E2. Проигрыватель аудио \u003C/b\u003Eв \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fspeechkit-demo.crm.kz%2F%23%2Fspeech-transcript-form%2FSP0003&postId=1107783\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eкарточке расшифровки\u003C/a\u003E. Карточка расшифровки выглядит как все карточки расшифровки в аналитиках ))), вверху информация об аудио записи, и бегунок проигрывателя, внизу реплики диалога.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"8baa50af-9550-5398-99b2-efb4625f876e","width":900,"height":521,"size":66399,"type":"png","color":"e3e7e7","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAQIECf/EACYQAAEDAgILAAAAAAAAAAAAAAEDBBEABRUhAhIUIyVBU5KTouL/xAAXAQEBAQEAAAAAAAAAAAAAAAAAAgED/8QAFxEBAQEBAAAAAAAAAAAAAAAAABEBIf/aAAwDAQACEQMRAD8A060WFrg8LYxy3ER61VSOG2w54Ky8HzWHEBcLlQArqRBy1jXSYin2hx11O40mFf/Z"}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПо клику на реплике нужно, чтобы проигрыватель переходил на соответствующий реплики участок аудио. Это оказалось просто, считываем из документа элемент audio, и у этого элемента есть нужны методы. К репликам добавили поле start_time, в секундах от начала аудио записи. По клику на реплике вызывается метод элемента audio, в него передаем нужные секунды:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"this.audio = document.querySelector('audio');\n\nplayAudioOnClickOnItem(time: number) {\n this.audio.currentTime = time; // В секундах\n this.audio.play();\n}","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E3. Выделение слов в репликах\u003C/b\u003E, и теги. В репликах нужно подчеркивать или выделять цветом найденные по словарям слова. Также в репликах есть колонка, где проставлены теги найденных словарей. Возник вопрос, где готовить эту html разметку реплик? С одной стороны это вроде задача фронта. С другой стороны на беке аналитика разбирает реплики, подсчитывает слова, почему бы заодно и теги не подготовить. Тем более, если html разметку реплик готовить на фронте, то с бека все равно приходилось бы передавать по каждой реплике данные, где и сколько там найдено слов. В итоге остановились на беке. С бека по каждой реплике приходит уже готовая html строка, в которую вписаны нужные стили, и фронт просто отображает их.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"a1941319-8d3a-589e-9d94-a4be0daf78a0","width":900,"height":247,"size":20440,"type":"png","color":"e9eaeb","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEFCf/EAB0QAQACAgIDAAAAAAAAAAAAAAEABQIDBCElUWT/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/EABcRAQEBAQAAAAAAAAAAAAAAAAARAVH/2gAMAwEAAhEDEQA/ANPG154Pic19G4lmdSmWNqglHt7+jCJnS6pyKIH/2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E4. Редактирование слов в фрагменте\u003C/b\u003E. \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fspeechkit-demo.crm.kz%2F%23%2Ffragment&postId=1107783\" rel=\"nofollow noopener\" target=\"_blank\"\u003EФрагменты \u003C/a\u003Eнужны чтобы составить скрипт разговора, для контроля соблюдения скриптов, в диалоге. Фрагмент состоит из набора слов. Фронт получает от бека сущность фрагмента, внутри сущности есть массив слов, входящих в этот фрагмент. На фронте сделали форму, в которой пользователь может изменить набор слов, исправить слова, и т.п. По нажатию кнопки «Сохранить» фрагмент с новым массивом слов отправляется на бек.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"9961948e-7de1-5f05-b475-784fb49e8fd4","width":900,"height":566,"size":86609,"type":"png","color":"989a9a","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAABAj/xAAjEAACAQIEBwAAAAAAAAAAAAABAhEABwMGElEEBRchQmXS/8QAGAEAAwEBAAAAAAAAAAAAAAAAAQMEAAL/xAAbEQEAAwADAQAAAAAAAAAAAAABAAIRAwRBkf/aAAwDAQACEQMRAD8AuZLLZOTCL41wsxDSupmbjVA3PjRX2cuVNYcWqtsRPVHnXf2CfNSvd6443PsdXg5LhatVGSy7sFgMY2mrsEiiHZQWJIEzWyGf/9k="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E5. Выбор колонок в реестре записей.\u003C/b\u003E Обычно в \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fspeechkit-demo.crm.kz%2F%23%2Fspeech-transcript&postId=1107783\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eреестре записей\u003C/a\u003E не очень много колонок, поэтому набор колонок статичный. Но в случае расшифровки аудио, полей у сущности может быть очень много. Начиная от «Входящий» или «Исходящий» звонок, до департамента, города, баллов за звонок, количество слов с одной стороны, и т. д. Поэтому в реестре звонков в аналитике должен быть выбор колонок, которые пользователь считает нужными. Единственная колонка статичная (обязательная) это кликабельная колонка с ID звонка, по которой проваливаемся в карточку звонка.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"ccfc0109-b731-5ddf-98f0-a4134c6ec14a","width":900,"height":566,"size":101370,"type":"png","color":"e6ebed","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAQMECf/EACIQAAIBAwIHAAAAAAAAAAAAAAECAwAEEQVREhMhI1OS0f/EABYBAQEBAAAAAAAAAAAAAAAAAAACA//EABsRAAIBBQAAAAAAAAAAAAAAAAABEQISEyFR/9oADAMBAAIRAxEAPwDTNdPslgJS0spJGVmVTCuc7Vs0roekSTtDaKxVtGtMg4PZX5WmOnpEoXLLKoPDI4wemCd6kB50vlf2NIB//9k="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНабор выбранных колонок в реестре сохраняем в куках в браузере, при повторном входе пользователя в раздел восстанавливаем выбранные колонки в реестре.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E6. JWT и учетка пользователя\u003C/b\u003E. В интернетах много статей и видео про авторизацию и роли в NestJs, но часто тема не раскрыта. Обычно автор объясняет, как создать токен JWT, объявляет strategies и guards, и показывает, что авторизация работает, и на этом закачивает. Но это ведь где то 5-10% от темы авторизации и роли пользователя. Начать с того, что на беке на момент запроса нужно понять, что это за пользователь, и дальше уже с этим работать.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДля этого объявляем простой декоратор. В этом примере учетка пользователя равна его email. Декоратор выбирает те поля, которые есть в pyaload внутри JWT токена. Если у нас содержимое JWT токен:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"async login(user: any) {\n\n const payload = {\n email: user.email,\n username: user.username,\n role: user.role\n };\n\n return {\n access_token: this.jwtService.sign(payload),\n };\n}","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТо в декораторе мы можем вытащить любое поле из payload, например email:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"export const User = createParamDecorator(\n (data: any, ctx: ExecutionContext): string =\u003E {\n const request = ctx.switchToHttp().getRequest();\n\n if(\n request.user !== undefined\n &&\n request.user.email !== undefined\n )\n {\n return request.user.email;\n }\n else {\n return 'unknown_user'\n }\n});","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДалее в контроллере мы получаем данные пользователе, и что-то уже можем с этим делать, например проверить права доступа на чтение записей:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"import { User } from '../user/user.decorator';\n\n @Get()\n @ApiOperation({ summary: 'Получить список разговоров' })\n @ApiOkResponse({ description: 'Список разговоров', type: SpeechEntity, isArray: true })\n findAll(@User() userMail: string): Promise\u003CSpeechEntity[]\u003E {\n return this.speechService.findAll( userMail );\n }","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E7. Роли и права доступа\u003C/b\u003E — самая спорная тема. Возникает ряд вопросов:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Где в архитектуре проекта NestJs правильнее проверять права доступа? В контроллере или в уже в сервисе?","Просится решение, проверять права доступа в контроллере, и в сервис уже передавать условие для поиска. Например, у пользователя есть права читать записи только где он ответственный. Тогда:"],"type":"UL"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"@Get()\n@ApiOperation({ summary: 'Получить список контактов' })\n@ApiOkResponse({ description: 'Список контактов', type: ContactEntity, isArray: true })\nfindAll( @User() userMail: string ): Promise\u003CContactEntity[]\u003E {\n const userAccessWhereOptions = this.userService.getUserAccessWhereOptions( userMail, controllerName );\n return this.contactService.findAll( userAccessWhereOptions);\n}","lang":""}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Но внутри сервиса findAll могут быть свои условия для поиска, например category = new, которые придется пристегнуть к условиям поиска по ответственному. А еще может быть такое, что «свои» записи, это где пользователь или ответственный, или автор. Тогда в сервис findAll попадет два условия поиска с ИЛИ, и придется добавлять условиям выборки category = new к каждому из этих двух условий.","А еще есть удаление записей, которое на самом деле не удаление, а deleted = yes. И обычный пользователь видит «свои» записи при условии deleted = no, а админ видит все записи."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПока получилось более менее, сервис проверки прав доступа возвращает условие для find, уже с учетом прав доступа, и в нем же условие про удаленные записи.\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"where = [\n        {\n          'owner': userEmail, // Ответственный за запись\n          'deleted': 'no'\n        }, // ИЛИ \n        {\n          'father': userEmail, // Создатель записи\n          'deleted': 'no'\n        }\n];","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EА внутри findAll есть функция, которая перебирает все условия и добавляет к ними собственные условия:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"async findAll( userAccessWhereOptions: {}[] ): Promise\u003CContactEntity[]\u003E {\n    const options: FindManyOptions = { \n      where: UtilWhereAssign(\n        userAccessWhereOptions,\n        {\n          \t'category': 'new'\n        }\n      ),\n      order: { updated: 'DESC' },\n    };\n    const result = await this.contactRepository.find( options );\n    return result;\n  }","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EИз UtilWhereAssign для «обычного пользователя» вернется новое условие поиска:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"where = [\n { \n'owner': userEmail, \n'deleted': 'no', \n'category': 'new' \n}, // ИЛИ \n{\n 'father': userEmail,\n 'deleted': 'no',\n 'category': 'new'\n }\n];","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E7. На фронте учитываем права пользователя\u003C/b\u003E. Но еще как-то нужно сообщить пользователю на фронте, что у него нет прав на запрашиваемую операцию. На беке есть метод, который возвращает \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fdemo.crm.kz%2F%23%2Frole&postId=1107783\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eроль пользователя\u003C/a\u003E. Соответственно, если у пользователя нет прав на добавление записей, то фронт должен отключить кнопку «Добавить запись», или «Удалить запись», и т.д.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"69c6425e-cc28-5a9e-9a6e-2d6a202dd612","width":900,"height":566,"size":47173,"type":"png","color":"e0e4e5","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAQIDCf/EACQQAAECBAUFAAAAAAAAAAAAAAECBAADBRIREyExwSQzQUTR/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwIE/8QAHREAAgIBBQAAAAAAAAAAAAAAAAECMRIDESFRgf/aAAwDAQACEQMRAD8A0zbtGU/PxpzQGVMKQclJx2PMXNqNBJt7gXSGN6ulbbn10fIjIrgZkTa51Pd4ELrUhlXhVRNx18xnDyfZ/9k="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Cb\u003E8. История изменений\u003C/b\u003E. Так как нужно сохранять журнал, кто какие изменения вносил в сущности, то делаем historyService, и во всех create, update, remove в различных сервисах передаем в historyService, данные о ID изменяемой записи, и пользователе.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЧтобы не делать создание истории изменений для каждой сущности, сделан универсальный метод calcChangeAndCreate в historyService, в который передаем старый экземпляр сущности, и новый экземпляр сущности, и имя пользователя. На примере update для контакта: \u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"async update(recordId: string, updateDto: ContactUpdateDTO, userMail: string): Promise\u003CContactEntity\u003E {\n const options = {\n where: [{ 'id': recordId }]\n }\n const oldResult = await this.contactRepository.findOne( options );\n await this.contactRepository.update( { \"id\": recordId }, updateDto);\n const newResult = await this.contactRepository.findOne( options );\n\n await this.historyService.calcChangeAndCreate( 'contact', newResult, oldResult, userMail, recordId );\n\n return newResult;\n}","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВнутри метода calcChangeAndCreate сравниваем поля старого и нового объекта, и если есть изменения, создаем запись в истории изменений:\u003C/p\u003E"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"calcChange( newEntity: object, oldEntity: object ): HistoryRecordChange {\n let result = {} as HistoryRecordChange;\n result.fieldChangeList = []; // массив полей с изменениями, HistoryFieldChange\n result.haveChange = false; // По умолчанию изменений нет\n result.user = 'no_user';\n result.table = 'no_table';\n result.record = 'no_record';\n\n for( let key of Object.keys( newEntity) ) {\n if( key != 'created' && key != 'updated' ) { // Пропустить авто поле\n // Тип дата из mysql возвращается как объект\n // а один объект не равен другому объекту\n let newValue: string;\n if(\n typeof newEntity[key] == 'object'\n &&\n newEntity[key] != null\n ) {\n newValue = newEntity[key].toISOString() + ' (UTC)';\n }\n else {\n newValue = newEntity[key];\n }\n\n // Тип дата из mysql возвращается как объект\n // а один объект не равен другому объекту\n let oldValue: string;\n if(\n typeof oldEntity[key] == 'object'\n &&\n oldEntity[key] != null\n ) {\n oldValue = oldEntity[key].toISOString() + ' (UTC)';\n }\n else {\n oldValue = oldEntity[key];\n }\n\n if( newValue != oldValue ) { // В этом поле есть расхождения\n result.haveChange = true;\n let fieldChange = {} as HistoryFieldChange;\n fieldChange.field = key;\n fieldChange.oldValue = oldValue;\n fieldChange.newValue = newValue;\n result.fieldChangeList.push( fieldChange );\n }\n }\n\n return result;\n}","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EАналогично для создания сущности, для удаления сущности. Еще есть дочерние сущности, например номер телефона в списке телефонов контакта. Об изменениях дочерних сущностей пишем в историю родительской сущности.\u003C/p\u003E\u003Cp\u003EСоотве\u003Cb\u003Eт\u003C/b\u003Eственно в карточке каждой сущности делаем \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fdemo.crm.kz%2F%23%2Fcontact-form%2Fe9644875-2827-43ba-aee9-65b1607a9cf9&postId=1107783\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eвкладку «История изменений»\u003C/a\u003E:\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"9a419d9c-ac5a-5f28-809a-13553f6bc334","width":900,"height":566,"size":41086,"type":"png","color":"e2e6e8","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAwQFCf/EACMQAAEDAgUFAAAAAAAAAAAAAAECAwQAEgURFSFBMYGT0eH/xAAXAQADAQAAAAAAAAAAAAAAAAAAAQID/8QAGhEAAgMBAQAAAAAAAAAAAAAAAAECESESQf/aAAwDAQACEQMRAD8A0zhxYTzriZWGMNoaNqVrbbIWM+ANx3recIxS5d35uEIf0bBTvpsXwp9VjbKpAFAWk5dflDbAooAsTtwKQz//2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНужно найти время, и сделать репозиторий, с примером бека на NestJs с правами доступа, и удалением записей, и с историей изменений. Ставьте лайки и подписывайтесь на канал если интересно посмотреть \u003Ci\u003E(новое видео про котят)\u003C/i\u003E ))) репозиторий с примером такого бека.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EА если уже есть такие репы на гите, просьба оставить ссылки. Но я что то не нашел на гите нормального бека на NestJs.\u003C/p\u003E"}}],"customUri":null,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":0,"favorites":0,"reposts":0,"views":901,"hits":107,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":4,"total":1012},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":null,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[{"id":1,"count":4}],"reactionId":0},"url":"https://vc.ru/id2770916/1107783-primeng-nestjs-yandex-rechevaya-analitika","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"donations":{"amount":0,"isDonated":false},"isBlur":false}},{"type":"entry","data":{"id":1067393,"subsiteId":2770916,"date":1709889154,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"repostId":null,"isEditorial":false,"isPublished":true,"isDisabledAd":false,"source":null,"withheld":[],"dateModified":1709889154,"title":"Платформа Rasa в действии: оценка работы виртуального ассистента с помощью конвейера данных диалогов и аналитики","isGame":false,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПеревод статьи \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Frasa.com%2Fblog%2Fconversational-analytics%2F&postId=1067393\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eиз блога Rasa, Alana Williams, Greg Stephens\u003C/a\u003E\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Определение метрик"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВы создали ассистента, настроили намерения, запустили его — клиенты с ним взаимодействуют. Но как определить, что все прошло успешно? Как вообще измерить успех? По каким признакам вы оцениваете удовлетворенность клиентов или определяете, что ассистент работает так, как было задумано? Как понять, что именно необходимо оптимизировать, если он работает недостаточно эффективно?\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E«Метрики можно сравнить с блюдами в меню. Они должны отражать удовлетворение потребностей и желаний»\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EБез метрик и аналитики невозможно по-настоящему точно определить, действительно ли работа, проделанная вами и командой разработчиков, помогает клиентам или оптимизирует бизнес-процессы. Я уверен, вы думаете: «Мы уже ведем подсчет количества диалогов, сессий и пользователей. Разве нужно что-то еще?»\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EОтличный вопрос! Мы считаем, что для бизнеса, будет правильным оценивать эффективность работы ассистента именно со стороны клиентов. Следует получить ответы на вопросы:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["используют ли клиенты ассистента;","планируют ли использовать ассистента повторно;","решает ли ассистент их проблемы;","переключаются ли они на операторов, а также процент переключений с бота на оператора."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EОтзывы клиентов — важнейшие показатели.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Сбор отзывов клиентов: удовлетворенность клиентов и показатели NPS (индекс потребительской лояльности)"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EОдин из лучших способов измерить удовлетворенность клиентов — это обратная связь. В настоящее время широко распространена метрика CSAT «Customer Satisfaction Score» — показатель, который демонстрирует, насколько клиент доволен взаимодействием с компанией. С его помощью вы сможете узнать, насколько клиенты удовлетворены работой бота. Это может быть простой опрос в конце разговора:\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E«Насколько вы удовлетворены работой ассистента?», «Ассистент помог решить проблему?»\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EМожно подобрать более точный вопрос, актуальный для конкретно вашего сценария использования бота, но основная идея заключается в том, чтобы понять настроения клиентов и то, как они оценивают общение с ИИ-помощником. Кроме прочего, это отличный способ дать возможность клиентам рассказать об их опыте с помощью дополнительных заметок или комментариев, которые помогут улучшить качество обслуживания клиентов.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"84727490-95f6-5b32-953c-26ebb453442d","width":900,"height":443,"size":47982,"type":"jpg","color":"eaebeb","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAQIDCf/EACMQAAICAAMJAAAAAAAAAAAAAAECAAMEBREUISIxM0JRodH/xAAYAQACAwAAAAAAAAAAAAAAAAAAAwEEBf/EAB0RAAICAQUAAAAAAAAAAAAAAAABAhESAxMxUoH/2gAMAwEAAhEDEQA/ANJcPRh7aATl9NXEwCNSvaefqLyeSVcjdSCgnUk6FVaWUHYaN416a/Yzwz96XUrAtg0HgQIpH//Z"}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДругой альтернативой CSAT является NPS или Net Promoter Score (Индекс потребительской лояльности) . Это снова контрольный вопрос для клиентов и пользователей в конце разговора, как и опрос CSAT, и его можно изменить в соответствии с вашей бизнес-стратегией, но часто используют следующий вопрос: «С какой вероятностью вы порекомендуете нас другу или коллеге?».\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"377375f1-614e-5faa-a64a-135eafd81650","width":900,"height":475,"size":39068,"type":"png","color":"ebebeb","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMFCf/EAB8QAAEEAgIDAAAAAAAAAAAAAAEAAgMRBAYSEwVBUf/EABcBAAMBAAAAAAAAAAAAAAAAAAAEBQH/xAAgEQABAQkBAQAAAAAAAAAAAAAAAQIDBBQVUVKS0ZGh/9oADAMBAAIRAxEAPwDQw5+ucS0S5jQR67xSZlHtk9TpPqkLkurXBzfNa2xoZ1SHiKsxzklEo+t9TplVhcl1a4VksUQofEAf/9k="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНезависимо от выбранного инструмента, — CSAT, NPS или любые другие методы сбора отзывов клиентов, — проведение опроса об удовлетворенности является фундаментальным шагом, который следует предпринять для достижения успешных показателей.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Отзывы клиентов реализованы, о чем еще нужно подумать?"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЕще одним показателем, который мы считаем полезным при составлении отчетов об эффективности бизнеса, является Containment Rate. Containment Rate — это процент разговоров, обработанных исключительно ассистентом, а не переданных человеку. Это важный показатель просто потому, что вы должны быть уверены, что клиенты не будут разочарованы ответами ассистента и не станут пытаться переключиться на оператора.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПредставьте, что вы потратили несколько месяцев на создание ассистента, чтобы сократить потребность во взаимодействии с операторами, и обнаружили, что только небольшой процент клиентов способен успешно им пользоваться. Не очень хорошая окупаемость инвестиций.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТем не менее, Containment Rate — это только один из показателей успеха, вместе с ним нужно рассматривать Abandonment Rate и Escalation Rate. Abandonment Rate часто рассматривается как процент разговоров, которые клиенты заканчивают преждевременно, а Escalation Rate — это процент разговоров, которые передаются от ассистента оператору. И Abandonment Rate, и Escalation Rate важны, поскольку они оба дают представление о том, насколько хорошо ассистент отвечает на вопросы клиентов: теряют ли они время, безрезультатно блуждая по веткам диалога или вынуждены обращаться к оператору, потому что ассистент не смог успешно ответить на их вопросы.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"0d6c99e0-62bc-5c9c-a19c-a22013b49902","width":900,"height":463,"size":42894,"type":"png","color":"f4f4f3","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAAJ/8QAHhAAAQQCAwEAAAAAAAAAAAAAAQACAxESUSEjMUH/xAAWAQEBAQAAAAAAAAAAAAAAAAABAgD/xAAZEQEAAwEBAAAAAAAAAAAAAAAAARESUQL/2gAMAwEAAhEDEQA/ANUsm3WQU6jpqVY2qAkjWhkLQBRysfDwtUMSI46HW3zSnHnhuX//2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВот тут-то и пригодится Rasa Pro Analytics.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EАналитика помогает визуализировать и обрабатывать показатели ассистента Rasa с помощью инструментов — BI-инструменты, хранилища данных — по вашему выбору. Визуализации и анализ работы ассистента и его разговоров позволяют оценить окупаемость инвестиций и со временем улучшить его эффективность.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003ERasa Pro Analytics сохраняет историю чат-бота и данные разговоров в хранилище данных по вашему выбору (PostgreSQL, Redshift, BigQuery или Snowflake) . Хранилище данных и BI-инструменты можно использовать для составления отчетов по ключевым показателям эффективности, таким как Containment Rate, Abandonment Rate и Escalation Rate.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EГрафики и информационные панели реализованы на базе Metabase и Tableau. Это дает возможность извлекать и визуализировать пользовательские ключевые показатели эффективности, недоступные в готовых решениях. Анализируя эти показатели в течение некоторого времени, вы можете выявить тенденции и закономерности, которые помогут улучшить общий пользовательский опыт.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003ERasa Pro Analytics позволяет оценивать ключевые показатели эффективности, связанные с контактами, на различных платформах, включая колл-центры, веб-приложения и мобильные приложения, путем интеграции с хранилищами данных и инструментами Business intelligence по вашему выбору.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"09353280-3b60-5728-bcb1-b514ce15e690","width":900,"height":445,"size":229692,"type":"png","color":"ebefe5","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAAJ/8QAJRAAAgECAgsAAAAAAAAAAAAAAQMEABECIgUSFBYhJDRBUZKT/8QAGAEAAwEBAAAAAAAAAAAAAAAAAAIDAQT/xAAgEQACAQMEAwAAAAAAAAAAAAAAAQIDERITMlGhUmGR/9oADAMBAAIRAxEAPwDTCHp5SsecIINwdQgE1yxjWg9ykuxNZPdBoXvJE7rPsKpnU8e0GrD38YtsWLtCeWVxuDkHg1TCPA9yECDbo0fMUYx4Nuz/2Q=="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EОпределив слабые места чат-бота, вы можете предпринять шаги для повышения производительности. Например, если вы заметили, что пользователи пытаются перевести разговор на оператора или преждевременно прекращают его, вы можете улучшить Natural Language Processing и диалоги, чтобы поддерживать высокую вовлеченность пользователей и не допускать их выхода из разговора.\u003C/p\u003E"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"79184783-5188-5631-916e-f459cf0adb4a","width":900,"height":439,"size":50808,"type":"png","color":"f2f1f0","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABAAJ/8QAIBAAAQMCBwAAAAAAAAAAAAAAAQACIQMSETFRU2Fikf/EABYBAQEBAAAAAAAAAAAAAAAAAAEAAv/EABgRAQEBAQEAAAAAAAAAAAAAAAARAVFB/9oADAMBAAIRAxEAPwDVC9+2eZRd4ZnVf0d4qqB14rsaIBEjWFpnwkgY5BBf/9k="}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EКроме этого, важно знать, насколько хорошо работают специфические ветки диалога бота, чтобы улучшить его в ключевых областях. Например, в чат-боте банка у вас может быть ветка, позволяющая переводить средства между счетами. Для этого пользователю необходимо указать отправителя и счет, а также сумму перевода. С помощью Rasa Pro Analytics мы можем измерить степень завершения ключевых веток, рассчитав процент пользователей, которые начали и успешно завершили процедуру.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНаконец, отслеживание ключевых показателей эффективности может помочь оценить окупаемость инвестиций в чат-бота. Понимая, как чат-бот работает с точки зрения вовлеченности и удовлетворенности пользователей, вы можете определить ценность, которую он предоставляет. Если вы вкладываете время и ресурсы в разработку и поддержку собственного ассистента, важно иметь возможность измерить его влияние на бизнес и продемонстрировать его ценность заинтересованным сторонам.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Ci\u003EСтраница нашей компании по \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsanatel.kz%2Fsolution_rasa.htm&postId=1067393\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eбот-платформе Rasa\u003C/a\u003E\u003C/i\u003E\u003C/p\u003E"}}],"customUri":null,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":0,"favorites":0,"reposts":0,"views":251,"hits":407,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":0,"total":658},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":null,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[],"reactionId":0},"url":"https://vc.ru/ai/1067393-platforma-rasa-v-deistvii-ocenka-raboty-virtualnogo-assistenta-s-pomoshyu-konveiera-dannyh-dialogov-i-analitiki","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":332941,"name":"AI","description":"Нейросети, искуственный интеллект, машинное обучение","uri":"/ai","avatar":{"type":"image","data":{"uuid":"47d7652c-7ff3-5ad3-b72c-3d0aa7d14f06","width":1200,"height":1200,"size":311374,"type":"png","color":"8dd2f1","hash":"2070ecd4e4745850","external_service":[]}},"cover":{"type":"image","data":{"uuid":"d830f642-8293-f95c-8c0a-cf31c79fd3aa","width":1920,"height":384,"size":110830,"type":"gif","color":"3b3846","hash":"","external_service":[],"duration":0}},"lastModificationDate":1602860409,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"ai","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"donations":{"amount":0,"isDonated":false},"isBlur":false}},{"type":"entry","data":{"id":1038969,"subsiteId":2770916,"date":1708405472,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"repostId":null,"isEditorial":false,"isPublished":true,"isDisabledAd":false,"source":null,"withheld":[],"dateModified":1708405472,"title":"Учебный центр Rasa: NLP для разработчиков","isGame":false,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Ci\u003EПеревод статьи от 30.01.2023 г., \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Frasa.com%2Fblog%2Frevisiting-the-rasa-learning-center-iii-nlp-for-developers%2F&postId=1038969\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eиз блога Rasa\u003C/a\u003E\u003C/i\u003E\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EКурс «NLP (Natural Language Processing) для разработчиков» в учебном центре Rasa — это простое и быстрое знакомство с современными инструментами и методами NLP, такими как токенизация, векторное представление слов и трансферное обучение. Если вы разработчик программного обеспечения, менеджер или любой другой человек, который хотел, но еще не ознакомился со всеми концепциями машинного обучения Rasa NLU — это лучший способ получить об этом общие понятия.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Векторное представление слов"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВекторное представление слов — это ввод числового вектора, который представляет слово. Он используется в качестве входных данных для моделей машинного обучения, визуализируя закономерности использования в обучающем корпусе.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества векторного представления:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["улавливает контекст слов;","быстрее создавать и обновлять, чем модели, созданные вручную;","стандартный подход в NLP."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедостатки:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["не может различать омофоны;","может занимать много памяти;","зависит от корпуса."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Трансформеры"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСуществует несколько архитектур нейронных сетей, таких как сверточные нейронные сети и рекуррентные нейронные сети. Transformer — одна из таких архитектур. Она предназначена для обработки последовательностей и работает с механизмами внимания. Архитектура трансформера состоит из двух частей: кодировщика и декодировщика. Кодировщик принимает последовательности и преобразует их в векторные представления, а декодировщик принимает эти векторные представления и создает выходные последовательности. Используется для обработки последовательностей и решения sequence-to-sequence задач, таких как, например, машинный перевод.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества трансформера:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["сокращение времени обучения за счет распараллеливания."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедостатки:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["огромные модели, которым требуется для обучения много памяти и вычислительных ресурсов."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Токенизация"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EДеление языкового ввода на более мелкие, комбинируемые фрагменты.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТипы токенизации:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["токенизация пробелов — для разделения текста на части с использованием пробелов;","токенизация на основе словаря — для языков без пробелов между токенами требуется словарь, созданный вручную;","токенизация подслова — токены изучаются путем поиска повторяющихся символов в обучающем наборе данных."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["стандартный подход в NLP;","части меньшего размера с большей вероятностью будут повторяться, а следовательно, их легче выучить;","позволяет использовать методы построения вокруг слов."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедостатки:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["в зависимости от языка, потребуется создать или улучшить токенизацию;","новые методы токенизации, как правило, требуют больших затрат труда и данных, что плохо для малоресурсных языков."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"BERT"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЯзыковые модели представляют собой распределение вероятностей по последовательностям слов. BERT — это маскированная языковая модель, которая использует векторное представление слов: теперь омофоны имеют разные представления, если они означают разные вещи.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EBERT — это большая языковая модель с 340 миллионами параметров в BERT-large и 110 миллионами в BERT-base. Архитектура работает сразу с несколькими кодировщиками, в слоях кодировщиков используется двустороннее внимание — необработанные вложения используются в качестве входных данных для классификатора, а также могут использоваться для обновления весов.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EМеньшие по размеру и более эффективные расширения:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Robert","Distilbert","Albert"],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EКак использовать:\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EИспользование последнего слоя в качестве входных данных для новой модели. Точная настройка предварительно обученной модели общего назначения для конкретных задач.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["переносимая модель — может использоваться в качестве входных данных для более мелких моделей, ориентированных на конкретные задачи;","при детальной настройке можно получить очень высокую точность.","предварительно обученные модели BERT доступны на более чем 100 языках."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедостатки:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["медленное обучение;","дорогостоящая;","необходима перенастройка для различных последующих задач."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Намерение и уверенность"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНамерение — представление задачи, которую пользователь хочет выполнить в разговоре. Использование намерений означает, что можно рассматривать моделирование действий пользователя в разговоре как задачу многоклассовой классификации.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EУверенность — это показатель уверенности модели в том, что введенная фраза относится к определенным обучающим данным (намерению).\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЗаблуждение:\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПоказатели высокой уверенности не означают высокую точность модели. Попытка максимизировать уверенность модели приводит к переобучению обучающего набора данных. Необходимо прямое сравнение показателей уверенности на разных источниках данных.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества оценки уровня уверенности:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["существует множество различных методов;","простота оценки модели;","уменьшает неопределенность в поведении модели."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Удаление стоп-слов"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EСтоп-слова — это слова, которые часто встречаются в корпусе, но не вносят особого вклада в контекст. Список распространенных, но неинформативных слов, которые можно игнорировать.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества удаления стоп-слов:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["меньше текстовые представления — быстрее и меньше модели;","в некоторых случаях удаление стоп-слов не ухудшает производительность модели, а напротив, может улучшить ее."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Featurizer"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EFeaturizer — это часть конвейера NLP, который преобразует входные данные в нужный формат (обработчик входных данных). Он принимает необработанные данные и предоставляет результаты, которые можно использовать в модели, например, метки или теги и векторное представление слов.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EКак часть конвейера NLP — это термин для ряда методов, которые используются для преобразования входных токенов в машиночитаемые данные.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["позволяет вводить текст и преобразовывать его в числовое представление;"],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедостатки:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["предварительно обученные функции могут зависеть от предметной области;","возможно, придется обучать свой собственный Featurizer."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"GPT- 3"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EGPT-3 — это тоже большая языковая модель. Исходя из вводимого текста, она предлагает его наиболее вероятное продолжение, предугадывая, какие токены из известного словаря будут следующими, работая по принципу автодополнения. Авторы предлагают большое разнообразие задач в дополнение к существующим бенчмаркам NLP.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["генерирует хороший текст;","единая, очень гибкая, предварительно обученная модель, которую можно применять для решения самых разных задач;","концептуально проста в использовании."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедостатки:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["93% данных для обучения представлены на английском языке;","дорогое обучение;","платный доступ к API;","непредсказуемые результаты."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Трансферное обучение"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EМетод, предполагающий использование модели, обученной для выполнения одной задачи, для другой, без повторного обучения с нуля. Используя предварительно обученную модель для решения смежных задач, потребуется меньше времени на обучение и меньшее количество данных.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТрансферное обучение позволяет тратить меньше времени на обучение новой модели.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРаспространенные примеры использования:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["векторное представление слов;","языковые модели;","межъязыковое трансферное обучение."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПреимущества:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["экономия времени и денег;","нет потребности в большом количестве данных."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедостатки:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["чем больше целевая задача похожа на исходную, тем лучше работает трансферное обучение и наоборот;","модель общего назначения требует большого количества данных для обучения и получится очень большой;","конечная модель может перенимать и усиливать искажения в предварительно обученной модели."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Ci\u003EСтраница нашей компании по \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsanatel.kz%2Fsolution_rasa.htm&postId=1038969\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eбот-платформе Rasa\u003C/a\u003E\u003C/i\u003E\u003C/p\u003E"}}],"customUri":null,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":1,"favorites":0,"reposts":0,"views":371,"hits":161,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":1,"total":534},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":null,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[{"id":1,"count":1}],"reactionId":0},"url":"https://vc.ru/ai/1038969-uchebnyi-centr-rasa-nlp-dlya-razrabotchikov","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":332941,"name":"AI","description":"Нейросети, искуственный интеллект, машинное обучение","uri":"/ai","avatar":{"type":"image","data":{"uuid":"47d7652c-7ff3-5ad3-b72c-3d0aa7d14f06","width":1200,"height":1200,"size":311374,"type":"png","color":"8dd2f1","hash":"2070ecd4e4745850","external_service":[]}},"cover":{"type":"image","data":{"uuid":"d830f642-8293-f95c-8c0a-cf31c79fd3aa","width":1920,"height":384,"size":110830,"type":"gif","color":"3b3846","hash":"","external_service":[],"duration":0}},"lastModificationDate":1602860409,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"ai","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"donations":{"amount":0,"isDonated":false},"isBlur":false}},{"type":"entry","data":{"id":1030270,"subsiteId":2770916,"date":1707901351,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"repostId":null,"isEditorial":false,"isPublished":true,"isDisabledAd":false,"source":null,"withheld":[],"dateModified":1707901351,"title":"Из грязи в князи: как Rasa помогла трансформировать крупную финансовую организацию","isGame":false,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Ci\u003EПеревод статьи от 01.02.2023 г., \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Frasa.com%2Fblog%2Ffrom-zero-to-hero-how-rasa-transformed-a-major-financial-institution%2F&postId=1030270\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eиз блога Rasa\u003C/a\u003E\u003C/i\u003E\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНедавно технический директор и соучредитель Rasa Алан Никол (Alan Nichol) провел беседу с Кейном Симмсом (Kane Simms), генеральным директором VUX World, о том, как Rasa помогла одному из крупнейших финансовых учреждений в США превратить своего чат-бота в успешного и чрезвычайно эффективного виртуального помощника\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ этом материале мы хотим отметить некоторые из лучших моментов вебинара, проанализировать закономерности, которые зачастую приводят к неэффективной работе помощников на основе ИИ, а также рассмотреть различные механизмы, которые делают чат-бота более эффективным, и обязательные советы по созданию разговорного ИИ, отвечающего требованиям компании и клиентов\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Проблемы, возникающие с ИИ-помощниками"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРаспространенная ситуация: мама купила вам в подарок какой-то бытовой кухонный прибор на Рождество, а он не работает.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВы открываете веб-сайт компании, чтобы узнать, как обменять его на исправный, переходите в справку — там вас встречает виртуальный помощник, предназначенный для решения подобных вопросов. Но все попытки правильно сформулировать вопрос и получить ответ раз за разом возвращают вас в главное меню. Обычная процедура по возврату бракованного товара выливается в длительный, сложный и запутанный процесс.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EТакая проблема обычно возникает по причине того, что компании перед запуском в работу недостаточно или совсем не тестируют своих ИИ-помощников на данных реальных покупателей и их поведении. В результате клиенты раздражены, команды разработчиков находятся в растерянности, а предприятия сталкиваются с еще большей головной болью при работе с клиентами, чем раньше\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВиртуальный помощник вашей компании должен всегда быть на высоте. Для этого и существует Rasa.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Тематическое исследование"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EИзвестное финансовое учреждение разработало помощника на основе искусственного интеллекта, который, как они ожидали, значительно повысит эффективность и качество обслуживания клиентов. Компания была уверена, что помощник будет работать хорошо — он был тщательно протестирован и показывал превосходные результаты.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EОднако, сразу после запуска виртуального помощника пользователи начали сообщать о его отвратительной работе с клиентами и общей неудовлетворенности этим нововведением. Почему так произошло?\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПроблема сводится к тому, как команда тестировала понимание естественного языка (NLU). NLU — это подраздел обработки естественного языка в искусственном интеллекте, отвечающий за интерпретацию того, что говорят люди. Эта технология преобразует человеческий язык в формат, который компьютеры могут использовать для выполнения запроса пользователя, используя намерения (цель пользователя), сущности (данные в речи) и обучающие данные (примеры того, как пользователи выражают свои намерения, используемые для обучения модели NLU). \u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПри анализе эффективности NLU баллы F-1 (F-score) показывают, насколько точно модель NLU классифицирует данные обучения в соответствии с заданными целями. Для получения надежной оценки F-1 необходимы качественные данные, но многие компании пропускают сбор разнообразных данных, основанных на том, как люди говорят в реальности.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВ этом случае компания использовала для обучения своей модели NLU синтезированные обучающие данные, основанные на предположениях команды разработчиков о том, как пользователи будут делать запросы. Когда они протестировали эти данные — они получили высокий балл F-1 и решили, что запуск разработанного ими ИИ-помощника будет успешным. Однако, вместо этого они создали для своего бота ветки диалогов, непонятные для большинства обычных людей.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EРазница между обучающими данными и поведением простых людей вводит компании в заблуждение, заставляя думать, что они улучшают своих виртуальных ИИ-ассистентов, когда на самом деле они делают их неэффективными. Как же предотвратить это?\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EШаблоны, которых следует избегать при создании цифрового помощника:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["\u003Cb\u003EНавязывание организационной структуры компании клиентам\u003C/b\u003E. Если при поиске решения клиента переключают от специалиста к специалисту, переводят с одного отдела на другой — это только расстраивает его и усложняет ситуацию больше, чем это необходимо.","\u003Cb\u003EПроработка диалогов, опираясь на свое видение\u003C/b\u003E. Собственный опыт не раскрывает всех особенностей человеческого общения при построении моделей NLU. Эффективное обучение NLU может быть достигнуто только через данные, основанные на реальном взаимодействие с людьми.","\u003Cb\u003EПерекрестная проверка данных для обучения вместо измерения фактической производительности\u003C/b\u003E. Оценка F-1 улучшится, если исключить из тестирования мусорные или неточные данные, но это не улучшит продукт! Чтобы ассистент был готов к успешному взаимодействию с клиентами, его необходимо познакомить с широким спектром реальных примеров."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Разработка, основанная на диалогах, как решение"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВместо того чтобы самостоятельно создавать пользовательские намерения, заполнять их синтетическими обучающими данными и тестировать производительность модели NLU с помощью этих данных, Rasa предлагает разработку на основе диалогов как наилучший подход к обучению и тестированию NLU. Вы получите реальные данные, слушая своих пользователей и обучая ИИ-помощника на разговорах, которые люди ведут ежедневно.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EВсе просто: если вы прислушиваетесь к своим клиентам и обучаете языковую модель на основе того, как и что они говорят, вы сможете лучше приспособить виртуального ассистента к их потребностям. Эта тактика позволит создать более цельный и постоянно развивающийся продукт.\u003C/p\u003E"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Влияние активного цикла обратной связи"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EПосле того, как компания начала использовать разработку, основанную на диалогах, она смогла улучшать, отслеживать и масштабировать свой продукт. Команды сосредоточили рабочий процесс на цикле обратной связи, включающем проверку ключевых показателей эффективности по целям пользователей, определяя, где и как можно улучшить пользовательский опыт.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EЦикл обратной связи также привел к более широким изменениям, реализованным командой:\u003C/p\u003E"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Оценка NLU, отражающая реальные показатели;","Более эффективный процесс анализа разговоров;","Более тщательная проработка диалогов, включающая больше взаимодействия с тестирующими пользователями;","Более активное межфункциональное взаимодействие;","Улучшенная таксономия намерений."],"type":"UL"}},{"type":"header","cover":false,"hidden":false,"anchor":"","data":{"style":"h2","text":"Четыре заключительных совета по улучшению ИИ-помощника"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["\u003Cb\u003EИспользуйте реальные данные\u003C/b\u003E. Данные для обучения можно брать из чатов, записей разговоров, стенограмм звонков, электронных писем, сообщений в социальных сетях, поисковых запросов и других каналов взаимодействия с клиентами — это допускается.","Не приводите данные в порядок. Убедитесь, что вы сохраняете исходные данные. Даже если какие-то слова или фразы кажутся вам семантически сложными или неуместными, это не значит, что другие люди их не используют. В реальном мире люди не говорят исключительно правильно и грамотно, поэтому познакомьте помощника со всеми возможными вариантами обращения.","Не обрезайте данные. Не удаляйте обучающие данные, вы всегда должны стремиться к тому, чтобы NLU соответствовал потребностям клиентов. Пополнение NLU новыми данными заставит его улучшить классификацию, а значит, и качество обслуживания клиентов в целом.","Определите свою Полярную звезду (North Star Metric, NSM). Устанавливайте цели и показатели и регулярно проверяйте их, чтобы иметь возможность отслеживать улучшения."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003EНащупать баланс между исследованием, разработкой и итерацией ассистента на основе искусственного интеллекта может быть трудно, но именно это сочетание обеспечивает успешный продукт, который приносит результаты. В Rasa мы понимаем, что человеческий язык сложен, он постоянно меняется, и нам повезло сыграть небольшую, но важную роль в миссии по обеспечению доступности, безопасности и надежности разговорного искусственного интеллекта в обычной жизни.\u003C/p\u003E"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"\u003Cp\u003E\u003Ci\u003EСтраница нашей компании по \u003Ca href=\"https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsanatel.kz%2Fsolution_rasa.htm&postId=1030270\" rel=\"nofollow noopener\" target=\"_blank\"\u003Eчат-платформе Rasa\u003C/a\u003E\u003C/i\u003E\u003C/p\u003E"}}],"customUri":null,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"commentsSeenCount":null,"counters":{"comments":0,"favorites":0,"reposts":0,"views":266,"hits":80,"reads":null,"online":0,"timespent":null,"shares":0,"reactions":0,"total":346},"isPinned":false,"isNews":false,"ogTitle":null,"ogDescription":null,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"summaryContent":null,"isExistSummaryContent":false,"reactions":{"counters":[],"reactionId":0},"url":"https://vc.ru/ai/1030270-iz-gryazi-v-knyazi-kak-rasa-pomogla-transformirovat-krupnuyu-finansovuyu-organizaciyu","repostData":null,"dateFavorite":0,"isFavorited":false,"warningFromEditorTitle":null,"warningFromEditor":null,"subscribedToTreads":false,"author":{"id":2770916,"name":"Rustam Rakhamnov","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"7b4f8b73-94f8-502c-b04d-bf281c5d6e1b","width":580,"height":580,"size":175714,"type":"png","color":"4f582b","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAKAAoDAREAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAABgcICf/EACIQAAIBBAIBBQAAAAAAAAAAAAECAwQFBhEAEiEHEyShwv/EABgBAAMBAQAAAAAAAAAAAAAAAAMEBgAH/8QAIhEAAQMBCQEAAAAAAAAAAAAAAQACBAMFERITITEyQbFR/9oADAMBAAIRAxEAPwAcsNlza8enE9fVUl2ilqdCkWOuQK0YG+zpvYJ2OoIBP3yTg2BJpRn5YDwQC24+dLOkUi04+SSC5dYJFDtkE22Gz8bf64EQat2rUPVVbhMspw23SmRi622hIbfkH2F8750CzQGxabW7YR4kKvIrO69Qwrea9ViQAVMoACjwO55LZj/pTo2X/9k="}},"cover":{"cover":{"type":"image","data":{"uuid":"0a59df9c-2d66-5fbf-bb38-fc69a92af186","width":1600,"height":1200,"size":822802,"type":"jpg","color":"627a96","hash":"","external_service":[],"base64preview":"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAACAf/xAAjEAACAgEDBQADAAAAAAAAAAABAwIEBQYHEQAIEhMhFCIx/8QAFQEBAQAAAAAAAAAAAAAAAAAABwj/xAAgEQABBAIBBQAAAAAAAAAAAAABAgMEEQUhABMyQVFh/9oADAMBAAIRAxEAPwC59wOH0vqTK47RGZ3B29EsvijmKWQo5cOjCsHXAxN+x+EpNK5NXqYK7GTk5xYW+uxGHtOiuxPQ1pS7Ud3ttICyuDxBmuqkWRDohgiwQseAnES4kI/qJAiPzjoZ7lucb9tpc0tKYgtLJlhEbuSEQZk+REQTwCeByeP70ZGZLIxYyMb90RE5gAWngACRAAAZwAB8AHwDqloDkJiM2lvFwrItSldclRtIug6K2Sda8feAk5GUdkKKsxJAHaAyxoaNWUkkUADez75//9k="}},"cover_y":55},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}],"collectibles":{"registration_1_year":{"type":"achievement","data":{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":2703370,"userId":2770916,"count":0,"shareImage":"https://api.vc.ru/achievements/share/2703370"}}},"lastModificationDate":1784908974,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"category":{"discoveryType":"blogs"},"counters":{"subscribers":0},"favoriteCollectible":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":332941,"name":"AI","description":"Нейросети, искуственный интеллект, машинное обучение","uri":"/ai","avatar":{"type":"image","data":{"uuid":"47d7652c-7ff3-5ad3-b72c-3d0aa7d14f06","width":1200,"height":1200,"size":311374,"type":"png","color":"8dd2f1","hash":"2070ecd4e4745850","external_service":[]}},"cover":{"type":"image","data":{"uuid":"d830f642-8293-f95c-8c0a-cf31c79fd3aa","width":1920,"height":384,"size":110830,"type":"gif","color":"3b3846","hash":"","external_service":[],"duration":0}},"lastModificationDate":1602860409,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"ai","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"donations":{"amount":0,"isDonated":false},"isBlur":false}}],"cursor":"PuR2GsZKFTvhhGtRBo7g78bbBa8hRyGI6YitsrXO+VvHeLfWP7Kpx0pS4mtHkCJg","isAnonymized":true}};