Söyle:基于 OpenAI gpt-4o-mini 的儿童言语沟通练习平台 MVP
whynicky19/Soyle
Söyle 是一个面向儿童言语沟通练习的 Web 平台 MVP,整合儿童模式、家长后台与基于 OpenAI gpt-4o-mini 的 AI 助手,AI 仅从许可题库中生成简短练习计划并回答家长提问,不提供诊断或治疗。
Söyle
Учебный MVP веб-платформы для поддерживаемой коммуникации, игровых заданий и домашней практики. Söyle объединяет детский режим, кабинет родителя и AI-помощника на базе OpenAI. Публичный лендинг доступен на /, вход и кабинеты — на /app.
Söyle AI не ставит диагноз, не назначает лечение и не заменяет врача или логопеда.
Возможности
- Регистрация родителей и серверная сессия в защищённой HttpOnly-cookie с CSRF-защитой; bearer-токен оставлен только для локальных API-тестов.
- Роли: администратор, родитель и ученик. Отдельная роль специалиста удалена.
- Профили детей и изоляция данных родителей.
- Безопасная библиотека заданий на понимание речи и AAC-коммуникацию. Моторные и артикуляционные упражнения в текущей версии недоступны.
- Необязательное локальное зеркало камеры без распознавания изображения, биометрии, оценки движения или диагностических выводов.
- Озвучивание слов и AAC-фраз: обработанный серверный голос при доступном локальном движке и автоматический браузерный голос в Linux/Vercel.
- Запись хода занятий: однозначные игровые ответы отделены от участия, отказа, перерыва и технической ошибки. Эти данные не являются измерением речи или развития.
- Söyle AI на модели
gpt-4o-mini: подбирает короткий план только из разрешённой библиотеки и отвечает на вопросы родителя о домашней практике. - Отдельное согласие на AI, минимизация передаваемых данных, почасовой лимит запросов и учёт токенов/расчётной стоимости.
- Занятия на 3, 5 или 10 минут: соответственно 2, 3 или 5 спокойных заданий, визуальное расписание, пауза и сохранение незавершённого занятия.
- Защита от повторного создания занятия: после перезагрузки продолжается та же сохранённая сессия.
- AAC-конструктор сообщений до восьми карточек с понятным порядком и удалением отдельных карточек.
- Открываемый профиль аккаунта и ребёнка со статистикой и текущими настройками.
- Учёт самостоятельности, подсказок, времени ответа и коммуникационных инициатив.
- Админ-панель: статистика, роли, блокировка аккаунтов, добавление и архивация заданий.
- Учёт ресурсов автоматических функций: запросы, токены, модель, функция и расчётная стоимость.
- Проверенный интерфейс текущего этапа — только русский. Незавершённые KK/EN скрыты до полной лингвистической, контентной и TTS-проверки.
- Четыре различимые темы: шалфей, океан, лаванда и высокий контраст.
- Ограничение попыток входа по сочетанию клиента и аккаунта, журнал критических действий, согласия, расширенный экспорт и удаление данных ребёнка через API.
Стек
- Frontend: Next.js 16, React 19, TypeScript, Web Speech API.
- Backend: FastAPI, PostgreSQL/SQLite, Pydantic, OpenAI Responses API, PyJWT, Argon2.
Как запустить локально
Что понадобится
- macOS или Linux;
- Python 3.11 или новее;
- Node.js 20 или новее;
npmиcurl.
Быстрый запуск фронтенда и бэкенда одной командой
Откройте терминал, перейдите в корневую папку проекта и выполните:
cd /путь/к/Soyle
./start.shПри первом запуске скрипт автоматически:
- создаст Python-окружение в
backend/.venv; - установит зависимости backend и frontend;
- загрузит только настройки OpenAI из
backend/.env.local, если файл существует; - запустит локальную SQLite-базу, API и веб-приложение с корректными localhost/CORS-настройками.
После этого для обычного локального запуска не нужно выполнять source, export или отдельно запускать два сервера — достаточно ./start.sh. Production-переменные Vercel из backend/.env.local не применяются к локальной базе, cookie и CORS.
После появления сообщения Ready откройте:
- главная страница: http://localhost:3000;
- вход в платформу: http://localhost:3000/app;
- документация API: http://127.0.0.1:8010/docs.
Оба сервера работают, пока открыт терминал. Для остановки нажмите Ctrl+C.
Если macOS не разрешает выполнить скрипт, один раз выдайте ему право на запуск:
chmod +x start.sh ./start.sh
Раздельный запуск фронтенда и бэкенда
Этот вариант удобен для разработки: backend и frontend будут работать в двух отдельных терминалах.
Терминал 1 — backend
При первом запуске выполните:
cd /путь/к/Soyle/backend python3 -m venv .venv source .venv/bin/activate python -m pip install -r requirements.txt export SOYLE_SECRET_KEY="local-development-secret-change-me" export SOYLE_SEED_DEMO_DATA=true export OPENAI_API_KEY="ваш-ключ-openai" python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8010
При следующих запусках достаточно:
cd /путь/к/Soyle/backend source .venv/bin/activate export SOYLE_SECRET_KEY="local-development-secret-change-me" export SOYLE_SEED_DEMO_DATA=true export OPENAI_API_KEY="ваш-ключ-openai" python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8010
Backend будет доступен по адресам:
- API: http://127.0.0.1:8010;
- документация API: http://127.0.0.1:8010/docs;
- проверка состояния: http://127.0.0.1:8010/health.
Терминал 2 — frontend
При первом запуске выполните:
cd /путь/к/Soyle/frontend
npm install
cp .env.local.example .env.local
npm run devЕсли файл frontend/.env.local уже существует, команду cp выполнять не нужно.
При следующих запусках достаточно:
cd /путь/к/Soyle/frontend
npm run devFrontend откроется на http://localhost:3000 и подключится к API по адресу http://localhost:8010. Не смешивайте в браузерной конфигурации localhost и 127.0.0.1: для cookie-сессии они считаются разными сайтами. Сначала запускайте backend, затем frontend. Каждый сервер останавливается сочетанием Ctrl+C в его терминале.
Если приложение не запускается
- Убедитесь, что порты
3000и8010не заняты другими программами. - Проверьте версии командами
node --versionиpython3 --version. - Если страница открылась без данных, убедитесь, что API отвечает по адресу http://127.0.0.1:8010/health.
- После изменения зависимостей остановите сервер через
Ctrl+Cи снова выполните./start.sh.
Автоматические тесты
cd backend source .venv/bin/activate pip install -r requirements-dev.txt pytest -q
Тесты проверяют cookie-сессию, CSRF, выход, авторизацию и роли, изоляцию данных детей, согласия и их немедленный отзыв, ограничение попыток входа, безопасный AI-план только из разрешённой библиотеки, отсутствие публичной роли специалиста, блокировку моторных заданий, паузу занятия, серверный расчёт игровых результатов, неоцениваемые исходы, AAC-грамматику и целостность фраз, экспорт/удаление, активный каталог, уведомления и языковую валидацию TTS.
Для интерфейса доступны отдельные регрессионные проверки безопасных настроек, линтер и production-сборка:
cd frontend npm test npm run lint npm run build
Локальные демо-аккаунты
Демо-данные создаются только при явном SOYLE_SEED_DEMO_DATA=true; start.sh выставляет этот флаг для удобного локального запуска. В production/staging включение демо-данных блокируется с ошибкой; администратор создаётся один раз из SOYLE_ADMIN_USERNAME и SOYLE_ADMIN_PASSWORD.
На чистой локальной базе доступны следующие аккаунты:
| Роль | Логин | Пароль или PIN |
|---|---|---|
| Родитель | parent |
Parent123! |
| Ребёнок | alikhan |
1234 |
| Администратор | admin |
Admin123! |
Для ребёнка на экране входа выберите вкладку «Ребёнок». Родитель и администратор входят через вкладку «Взрослый».
Deployment на Vercel
Проект разворачивается как два Vercel-проекта из одного репозитория:
frontend— Next.js, переменнаяNEXT_PUBLIC_API_URLуказывает на адрес API;backend— FastAPI, подключённый к PostgreSQL черезDATABASE_URL.
Обязательные переменные backend перечислены в backend/.env.example. Для реальных AI-ответов задайте серверную переменную OPENAI_API_KEY; по умолчанию используется экономичная модель gpt-4o-mini, которую можно изменить через SOYLE_OPENAI_MODEL. Почасовой лимит на пользователя задаётся через SOYLE_AI_REQUESTS_PER_HOUR и по умолчанию равен 30. Ключ нельзя помещать во frontend или переменные NEXT_PUBLIC_*. В production также задайте SOYLE_ENV=production и уникальный SOYLE_SECRET_KEY длиной не менее 32 байт.
Если frontend и API находятся на разных сайтах, backend дополнительно требует SOYLE_COOKIE_SAMESITE=none, точный SOYLE_ALLOWED_ORIGINS и HTTPS. Для одного сайта оставьте более строгий режим lax. CSRF-токен передаётся в JSON при входе и проверке текущего сеанса, хранится frontend только в памяти вкладки; JWT остаётся в HttpOnly-cookie API.
На macOS API использует системный голос say и ffmpeg. В Linux/Vercel системного say обычно нет, поэтому приложение автоматически переключается на Web Speech API браузера; дополнительные серверные пакеты для этого не требуются.
При запуске init_db() применяются совместимые добавочные изменения схемы: цели, домашняя практика, согласия, журнал действий, ограничение входа и контекст занятий. Для production перед развёртыванием всё равно необходимы проверка миграции на копии базы и план отката.
Приватность
- Камера после отдельного согласия используется только как локальное зеркало: приложение не анализирует кадры и не отправляет их в API.
- Видео и звук не сохраняются.
- Backend хранит аккаунты, профили детей, согласия, описательные записи занятий, AAC-историю и служебный аудит.
- OpenAI получает данные только после отдельного согласия: вопрос родителя либо обезличенный контекст плана без имени и точной даты рождения.
- Для реального пилота нужны юридически проверенное согласие законного представителя, политика обработки данных, резервное копирование и проверка упражнений логопедом.
- До внешнего пилота нужны проверка упражнений профильными специалистами, юридическая проверка обработки детских данных и production-smoke на реальных устройствах.
来源:GitHub · github.com