Мобильное · приватность

Kyndsy — приватный тренер речи и поведения для iOS и Android

Мобильное приложение слышит голос своего владельца и считает грубые выражения, вежливые, слова-паразиты и резкий тон — на тридцати языках, включая смешанную речь. Разбор идёт на устройстве: звук не сохраняется, расшифровка не пишется, учётной записи и имени нет вовсе. Мы сделали продукт целиком — приложение, содержимое на тридцати языках, лёгкий сервер и сайт.

Категория
Мобильное · приватность
Оценка стоимости
от €26 000
Сроки
≈ 12–16 недель
kyndsy.appKyndsy
Сайт проекта — kyndsy.app

01Обзор проекта

Kyndsy — мобильное приложение, отвечающее на вопрос, на который почти никто не может ответить о себе сам: как я на самом деле говорю? Оно слышит голос владельца в обычном разговоре и считает грубые выражения, вежливые, слова-паразиты и моменты, когда тон становится резким. Показывает динамику по дням и неделям. И на этом останавливается — оно не говорит человеку, каким человеком его это делает.

Замысел в том, что приложения для саморазвития по большей части рисуют график вашего же мнения. Вы отчитываетесь о дне, они визуализируют отчёт. Kyndsy начинает с того, с чем сложнее спорить: со слов, которые действительно были сказаны, посчитанных, пока человек был занят жизнью, а не сел рефлексировать.

Это же делает продукт трудным. Считать речь — значит включить микрофон, а микрофон — значит, что человек должен доверять приложению больше, чем почти всему остальному в телефоне. Поэтому весь продукт построен вокруг обещания, которое обязано быть устройством, а не текстом: звук не сохраняется, слова не записываются, чужие голоса не разбираются, и нет учётной записи, к которой всё это можно было бы привязать.

Мы сделали всё: приложение для iOS и Android, содержимое на тридцати языках, лёгкий сервер, путь выпуска в магазины и сайт продукта. Ниже — задача, решения и то, что мы сознательно отказались делать.

02Контекст и задача

Приложение, которое слушает, — это область, где очевидная реализация одновременно неправильная. Разбор задачи дал набор ограничений, определивших всё дальнейшее.

  • Доверие и есть продукт. У приложения, измеряющего речь, ровно один актив, и это не алгоритм. Если человек заподозрит, что звук уходит с телефона, точность не спасёт — он удалит приложение.
  • Окружающие ни на что не соглашались. Микрофон в комнате слышит всех, кто в ней есть. Разбор речи людей вокруг владельца — это другое приложение, и куда худшее.
  • Число о человеке опасно. Любая единая оценка, претендующая описать человека, — утверждение, которое продукт не может честно сделать; и её прочитают как приговор, что бы ни было написано рядом мелким шрифтом.
  • Сырые счётчики врут. «Вы выругались девять раз» поощряет молчание: тот, кто ничего не говорил, выглядит как исправившийся.
  • Слова неоднозначны. Одно и то же слово — шутка, цитата, жалоба на себя или настоящее оскорбление, в зависимости от тона и контекста. Счёт по строке даёт числа, в которых никто не узнаёт свой день.
  • Люди говорят не на одном языке. Они переключаются посреди фразы. Счётчик, идущий только за одним языком, отчитается подозрительно спокойным днём каждый раз, когда владелец перешёл на другой.
  • У магазинов есть правила про микрофон, про заявления о здоровье и психологии и про то, что вообще может закрывать подписка, — и проверяются они на подаче, а не в день запуска.

Всё это должно было работать на телефоне, в фоне, не съедая ни батарею, ни терпение человека.

03Цели проекта

  • Считать речь на устройстве. Разбор идёт на телефоне; звук не сохраняется и не выгружается.
  • Только голос владельца. Чужие голоса отбрасываются, а не разбираются, и режима «направить приложение на другого человека» не существует.
  • Ни учётной записи, ни имени. Утекать нечему, потому что собирать нечего.
  • Доли, а не сырые счётчики. Всё на тысячу сказанных слов, чтобы тихий день оставался тихим днём, а не достижением.
  • Тридцать языков, включая смешанную речь — словари должны существовать во всех сразу, иначе число врёт тем, кто переключается.
  • Различать оттенки. Ирония, сарказм, шутка и настоящая резкость разведены и помечены как догадка, а не как приговор.
  • Полезно и без микрофона. Дневник, компас ценностей, тесты и вечерние вопросы работают сами по себе.
  • Мотивация, которую нельзя обыграть. Серии, уровни и программы оцениваются измерением, а не открытием приложения.
  • Никакой общей оценки человека. Ни в первой версии, ни потом.

04Что мы сделали

Приложение устроено как четыре места, каждое отвечает на свой вопрос, плюс то, что их держит:

  • Сегодня — что только что было: показатель речи, цели дня и одна подсказка, а не список из шести.
  • Прогресс — идёт ли это куда-нибудь: серии, уровни, программы и недельный отчёт.
  • Компас — на что человек решил ориентироваться: три-пять ценностей, выбранных им самим, и движение к ним.
  • Вы — всё, что принадлежит только ему: тесты самопроверки, семейный доступ, свои данные и поддержка.

Снизу лежит то, что делает эти четыре места честными: разбор речи на устройстве, словари и правила для тридцати языков, определение оттенков, модель счёта в долях, а не в итогах, лёгкий сервер, который почти ничего не знает, и реестр настроек, позволяющий менять продукт без выпуска в магазине.

05Приватность — это код, а не текст

Обещания приватности на сайте — не рекламный текст, который следующая оптимизация может тихо сделать неправдой. Это свойства сборки, и правка, делающая любое из них ложным, считается в проекте дефектом, а не разменом.

  • Звук никуда не пишется — ни в файл, ни во временный буфер на диске, ни в журнал. И в отладочной сборке тоже, потому что именно так такие вещи и утекают.
  • Разбирается только голос владельца. Чужая речь отбрасывается до того, как из неё получатся слова.
  • Расшифровки нет. Приложение производит счётчики, а не текст; нет сохранённой фразы, которую можно было бы получить по запросу или случайно синхронизировать.
  • Сессию запускает только человек. Ни автозапуска после перезагрузки, ни тихого возобновления в фоне.
  • Голосовой профиль не покидает телефон и исключён из резервных копий — это биометрические данные, а копия как раз то место, о котором забывают.
  • Серверу говорят четыре вещи и не больше: запрос настроек, разовая загрузка моделей, обращение в поддержку, если человек сам его написал, и чек подписки. Учётной записи нет.
  • Человек — это пара случайных чисел, придуманных его же телефоном. Мы их не выдаём и не считаем — а значит, не знаем числа установок, и это была осознанная цена.
  • Вход необязателен и ничего не открывает. Он нужен, чтобы перенести подписку и историю на новый телефон. Обязательный вход создал бы связь с настоящей учётной записью там, где её сейчас нет.

На последнем пункте стоит задержаться. Требование владельца было — знать только анонимный идентификатор, и соблазнительный способ его выполнить это обязательный вход, который мы затем обещаем не читать. Мы сделали наоборот: учётной записи нет вовсе, а необязательный вход читает из токена ровно одно поле и хранит его хешем.

06Что именно считает приложение

Четыре вещи: грубые выражения, вежливые выражения, слова-паразиты и поднятый, резкий тон. Всё это показывается на тысячу сказанных слов, а не сырым итогом: сырой счётчик делает молчание похожим на прогресс, а приложение, награждающее владельца за то, что он молчал, не поняло собственной работы.

Заголовок дня — индекс уважительной речи, и правила вокруг него продуманы не меньше самого числа:

  • Он полностью скрыт, пока не услышано пятьдесят слов. Ноль в тихое утро читается как обвинение, а не как отсутствие данных.
  • Дни, где слов меньше пятидесяти, показываются, но не считаются — видны пустыми, а не притворяются хорошим днём.
  • Вежливость поднимает индекс не более чем на десять пунктов. Дальше показатель было бы дешевле набрать любезностями, чем заработать отсутствием резкости.
  • Любое событие можно пометить как ошибочное, и это меняет число, а не просто вычёркивает строку из списка.

Виды поверх этого обычны по форме и внимательны в мелочах: недельный тренд, картина дня по часам, тридцатидневная сетка по квадрату на день. Часовой вид отказывается объявлять «худший час», пока у него нет десяти событий; тридцатидневная сетка оставляет тихие дни бежевыми, а не красит их в спокойные. Графики, уверенные на тонких данных, — это способ, которым продукт-измеритель теряет доверие читателя, обычно навсегда.

07Оттенки речи: ирония, шутка, укол

Шутка и оскорбление — не одно и то же слово дважды. Kyndsy отделяет иронию от настоящей резкости, шутку от укола, цитату от того, что человек имел в виду, — и показывает словами, что ему послышалось, рядом с событием.

Честность этой функции держат два правила. Первое: это догадка, а не приговор — приложение пишет «возможно, ирония» или «шутка — не засчитано» и показывает, на чём основывалось. Второе, и более важное: оттенок никогда не двигает индекс. Он сообщает человеку, но не подкручивает его показатель молча. Число, взвешенное по уверенности, никто не смог бы проверить, и оно быстро стало бы самой спорной функцией продукта.

Так же аккуратно устроен контекст: одно и то же слово считается по-разному, когда человек кого-то цитирует, говорит о себе или находится посреди спора. А поскольку ни один словарь не знает, что чьи-то слова значат лично для него, у человека есть свои списки.

08Тридцать языков — и смешанная речь

Приложение работает на тридцати языках — английский, испанский, португальский, немецкий, французский, итальянский, нидерландский, шведский, датский, норвежский, финский, польский, чешский, хорватский, румынский, венгерский, греческий, турецкий, русский, украинский, белорусский, иврит, арабский, хинди, индонезийский, вьетнамский, тайский, китайский, японский и корейский — и на нескольких сразу, потому что очень многие именно так и говорят.

Тридцать языков — это не тридцать переводов интерфейса. Это тридцать наборов словарей (грубые выражения, вежливые обороты, паразиты), и появляться они обязаны одновременно. Язык с недоделанным словарём не падает громко — он отчитывается спокойным днём. Человек видит хорошее число и верит ему, а это хуже сообщения об ошибке.

Один урок этого проекта выходит далеко за его пределы: признак, угаданный по виду текста, ломается на первом же языке с другой письменностью. Считать «оборотом» строку с пробелом работает ровно до японского, китайского и тайского, которые пишутся без пробелов, — и там приложение не находит ничего, молча, продолжая выглядеть работающим. Поведение языка должно браться из данных самого языка, и оно обязано быть закрыто тестом сразу по всем тридцати.

09Компас и дневник

Речь — только половина продукта. Вторая половина — то, на что человек решил ориентироваться: он выбирает три-пять ценностей из семи (уважение, честность, самообладание, ответственность, забота, справедливость, надёжность), и приложение показывает движение к ним, а не к чьему-то чужому представлению о хорошем человеке.

Движение складывается из двух источников: измерений речи и собственного дневника поступков — сдержал обещание, извинился, сорвался, исправил. Плюс три вопроса в конце дня, когда они нужны.

Общей оценки нравственности нет — ни сейчас, ни потом. Это единственное, что продукт отказывается вычислять. И именно поэтому компас работает: честные ценности человек выберет только для приложения, которое не собирается ставить ему за них отметку.

Всё в этой половине работает без микрофона. Дневник, компас, тесты и вечерние вопросы стоят сами по себе, так что голосовую часть можно настроить позже или никогда — и приложение всё равно останется полезным. Это продуктовое решение с настоящими последствиями для удержания, и мы приняли бы его снова: запрос разрешения на первом экране — то место, где приложение о приватности теряет тех, ради кого его писали.

10Программы, серии и недельный отчёт

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

  • Программы идут от 7 до 30 дней с одной целью и одним числом — неделя без грубых слов, мягче отвечать две недели, меньше паразитов за месяц. Сработало или нет, решают измерения, а не галочка.
  • Серия считает дни, в которые человек действительно удержал уровень. Тихие дни её не рвут и не продлевают — убрать телефон не способ выиграть.
  • Уровни зарабатываются днями, а не открытиями приложения: Наблюдение, Контроль, Спокойная речь.
  • Щиты закрывают срыв, но не бесконечно, а сорванный день можно выкупить — только серия из тридцати дней, четыре из которых куплены, это не серия из тридцати дней, поэтому такие дни считаются и показываются отдельно.
  • Недельный отчёт прямо говорит, когда сравнивать не с чем. Сводка, в которой всегда что-то улучшилось, перестаёт читаться к третьей неделе.

Стоит назвать одну намеренную асимметрию: бесплатный уровень ограничивает показ истории, а не счёт. Считать серию только по видимому окну значило бы показывать тридцатидневную серию как семидневную — это не ограничение бесплатного тарифа, а враньё про человека.

11Сто тестов самопроверки

Рядом с измерениями лежит сотня структурированных тестов самопроверки: по двадцать пять утверждений, около четырёх минут, пять граней оцениваются отдельно, поэтому ответ никогда не сводится к одному плоскому числу. Темы — речь, чувства, близкие, работа, вы сами, привычки и жизнь в сети.

Это явным образом не диагнозы и не измерения личности — это структурированная саморефлексия, и приложение говорит об этом там, где человек прочтёт, а не в настройках. Ответы остаются на телефоне, как и всё остальное.

Инженерный смысл здесь в том, что сотню тестов нельзя вести как сотню написанных руками экранов. Они лежат ресурсом, а не кодом: собираются из исходников, проверяются на сборке и отвергаются, если у теста нет полного набора утверждений и граней. Именно эта проверка делает возможным иметь их сто, и она же позволила раздать правила открытия единообразно, а не расставить руками.

Половина открывается трудом, половина покупается. Товаров под платную половину намеренно немного, а не по одному на тест: сотню позиций в магазинах никто не заведёт руками и никто не переведёт на тридцать языков. Продаётся открытие; какой именно тест на него потратить, человек выбирает в приложении уже после подтверждения покупки.

12Подписка, семья и магазины

Платный уровень — подписка, и семья её делит: шесть мест на год, включая место покупателя. Важно, что именно делит семья и чего не делит: семья делит право, а не данные. Никто не видит чужих чисел, событий и дневника, а тот, кто оплатил, видит свободные места и даты, а не то, кто их занял.

Это не оговорка мелким шрифтом, а устройство: чужих показателей на сервере нет вовсе, поэтому в семейном экране нечего случайно раскрыть. Вводя код, человек соглашается разделить подписку, а не назваться.

Два правила из этой части пережили саму функцию. Первое: подписка и семейное право — один флаг в приложении; второй вопрос вида «а может, он в семье» забыли бы ровно там, где он важен. Второе: молчание сервера право не снимает — сеть пропадает намного чаще, чем кончается подписка, и приложение, запирающее платящего человека в поезде, сделало очевидный выбор плохо.

Правила магазинов определили здесь многое: что вправе утверждать приложение с микрофоном, как можно показывать платный уровень и то, что сломанную сборку не откатишь хотфиксом. Поэтому политика версий — минимальная поддерживаемая версия, требование обновиться, режим обслуживания и текст сообщения на всех языках проекта сразу — это серверная настройка, а не то, что вкомпилировано внутрь.

13Архитектура: приложение, сервер, реестр

Архитектура следует из обещания приватности: как можно больше на телефоне, как можно меньше на сервере.

  • Приложение ведёт разбор, хранит историю и владеет голосовым профилем. Оно и есть продукт; сервер здесь на подхвате.
  • Лёгкий сервер отвечает на четыре вида запросов — настройки, разовая загрузка моделей, обращения в поддержку и чеки подписки. Таблицы пользователей у него нет, потому что нет пользователей, которых туда класть.
  • Реестр настроек держит то, что иначе было бы зашито в приложение: идентификатор пакета, адрес API, параметры входа, список языков, флаги функций и политику версий. Значения не пишутся в исходники руками, а генерируются в них, и сгенерированный файл помечен «не править» по простой причине: ручная правка теряется при следующей генерации.
  • Предполётная проверка стоит гейтом перед каждой сборкой: она отказывает, если идентификатор пакета разошёлся с реестром, если версия не выше собранной, если сервер приложения не отвечает, если словарь неполон хоть на одном языке проекта, если статический анализ не чист, если падают тесты или если в исходниках нашлось похожее на ключ. Она возвращает ненулевой код, поэтому годится гейтом в любом CI.
  • Платный уровень стоит за флагом, который гасится без пересборки и без новой версии в магазине.

Сайт — небольшое PHP-приложение без собственной базы, кроме переписки поддержки: тот же принцип, применённый на уровень выше.

14Технологический стек

  • Flutter для iOS и Android из одного кода — с дизайн-системой в коде, чтобы цвет, отступ и скругление задавались в одном месте, а не у каждого виджета.
  • Распознавание речи и разбор на устройстве: модели скачиваются один раз и работают локально, а манифест с их размерами и хешами строится из файлов, а не пишется руками.
  • PHP 8.4 для сервера приложения и сайта, с небольшой базой только под переписку поддержки.
  • Реестр настроек как источник истины для параметров приложения, с генерацией кода и предполётным гейтом.
  • Тридцать языковых наборов в приложении и три на сайте, с паритетом словарей, который держат тесты, а не ревью.
  • Строгая политика безопасности содержимого на сайте — ни одного инлайнового стиля, вычисляемые значения собираются в отдельную таблицу стилей, шрифт свой: страница про приватность не тянет ни одного чужого ресурса.

15Дизайн и UX

Визуальный язык — одна тёмная тема, снятая с сайта продукта, чтобы человек открывал ровно то, что ему обещали. Светлый вариант написан в токенах и намеренно не подключён: две темы означают два набора снимков и вдвое больше мест, где вёрстка ломается незаметно.

Цвет, отступ и скругление живут в одном файле дизайна, а переход из тревожного цвета в спокойный идёт через тёплый жёлтый: напрямую середина даёт оливковую грязь — то, что выглядит небрежностью, а на деле является пропущенной опорной точкой.

У приложения есть персонаж, и правила вокруг него не столько про обаяние, сколько про честность: настроение читается силуэтом, а не только цветом, поэтому дальтоник видит то же, что все; настроение — непрерывная шкала с анимацией между значениями, а не пять готовых картинок, потому что скачок читается как другая картинка, а не как тот же герой; а при тревоге брови идут внутренними концами вверх, потому что опущенные внутрь — это злость на того, кто смотрит.

Во всём остальном интерфейс следует главному правилу продукта: показывать измеренное, говорить вслух, когда сказать нечего, и никогда не сводить человека к одному числу.

16Как мы работали

  • Сначала обещание. Мы записали, чего приложение не будет делать никогда — хранить звук, разбирать окружающих, спрашивать, кто вы, оценивать вас как человека, — до всякого проектирования: эти решения ограничивают архитектуру, а не следуют из неё.
  • Ядро измерения. Разбор на устройстве, счёт в долях, индекс с его порогами и отказом появляться на тонких данных.
  • Языковая работа. Тридцать словарей и правил, с паритетом, закрытым тестами сразу по всем.
  • Вторая половина. Компас, дневник, программы, серии, недельный отчёт — всё, что работает без микрофона.
  • Тесты как ресурс. Сотня тестов самопроверки, собираемых и проверяемых, с лестницей открытия, которую раздаёт сборщик.
  • Монетизация. Подписка, семья, небольшой набор товаров в магазинах и платный уровень за флагом.
  • Путь выпуска. Реестр, генерируемая конфигурация, предполётный гейт, регистрация сборок и политика версий.
  • Сайт. Три языка, строгая политика безопасности содержимого и лендинг, показывающий настоящие экраны приложения.

Две вещи возвращались по ходу работы постоянно, и обе стали правилами. Всё, что интерфейс утверждает о поведении человека, обязано проверяться измерением; всё, что приложение обещает о приватности, обязано держаться кодом, а не заметкой в документе — договорённость живёт ровно до следующего, кто её не прочитал.

17Результат

Получился измерительный продукт для того, о чём обычно только догадываются, — устроенный так, что измерение не стоит человеку приватности.

30
языков, включая смешанную речь
0
сохранённого звука, расшифровок и учётных записей
100
структурированных тестов самопроверки
  • Разбор речи на устройстве: ничего не записывается, ничего не расшифровывается, чужие голоса отбрасываются.
  • Всё показывается на тысячу слов, поэтому молчание не принимают за прогресс.
  • Ирония, сарказм и шутки разведены — и помечены как догадка, которая не двигает показатель.
  • Тридцать языков со словарями, появляющимися одновременно, и тестами сразу по всем.
  • Компас ценностей, дневник, программы и недельный отчёт, который признаёт, когда сравнивать не с чем.
  • Сотня тестов как проверяемые ресурсы и небольшой поддерживаемый набор товаров под платную половину.
  • Семейный тариф, который делит подписку и ничего больше — потому что данных на сервере нет.

18Выводы

Kyndsy — проект, где самая трудная инженерия была в ограничениях. Разбор на устройстве, отсутствие расшифровки, отсутствие учётной записи, отказ от общей оценки, отказ разбирать окружающих — каждое из них усложняло сборку и делало продукт возможным. Версия этого приложения с серверным конвейером и логином писалась бы быстрее и не заслуживала бы ничьего микрофона.

Урок, который мы уносим, — о том, как держатся обещания: гарантия, живущая в документе, — гарантия ровно до следующей правки, которую с ней не сверили. Здесь выдержали те, что выражены кодом и закрыты тестами: паритет по тридцати языкам, контраст, проверяемый числом, а не взглядом, движение, проверяемое значениями, а не снимком, и гейт сборки, который отказывает, а не предупреждает.

Если вы делаете мобильный продукт, где приватность — это функция, а не оговорка; что-то, что обязано работать сразу на многих языках; или приложение, числам которого люди должны верить о себе, — такую работу мы ведём от замысла до магазина.

Нужен похожий продукт?

Расскажите о задаче — предложим архитектуру и оценку. Консультация бесплатна.

На какие запросы отвечает эта страница

разработка мобильного приложения на заказ, разработка приложения flutter ios android, распознавание речи на устройстве приложение, приватное мобильное приложение разработка, приложение анализа речи разработка, счётчик мата приложение, трекер слов-паразитов приложение, сколько стоит разработка мобильного приложения, мультиязычное приложение 30 языков, мобильное приложение без регистрации разработка, gdpr биометрические данные в приложении, приложение отслеживания привычек разработка, мобильное приложение по подписке разработка, внутренние покупки в приложении реализация, семейная подписка в приложении, kyndsy приложение, kyndsy отзывы, kyndsy приватность, выпуск приложения в app store и google play, дизайн-система flutter в коде.