ИИ-ассистент по лекарствам с голосовым управлением
Отсканируйте упаковку лекарства или загрузите инструкцию и получите ответы, основанные на материалах, голосом или текстом.
English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Español · Português · Français · Deutsch
MedVision-RAG помогает незрячим и пожилым людям разобраться в лекарствах. Направьте камеру на упаковку препарата или загрузите PDF/Word-документ — система:
- Извлекает текст через OCR (macOS Vision / Tesseract как запасной вариант)
- Нормализует OCR-текст, сохраняя полезную структуру абзацев
- Создаёт базу знаний, векторизуя текст в ChromaDB
- Отвечает на вопросы с помощью адаптивного RAG — для коротких текстов используется прямая вставка контекста, для длинных — векторный поиск по сходству
- Озвучивает ответ через edge-tts
Система поддерживает веб-браузер, мини-программу WeChat и панель администратора для мониторинга журналов чатов и аналитики.
- Фотографии: упаковки, коробки, блистеры — напрямую через камеру
- PDF: как текстовые, так и отсканированные (автоопределение и рендеринг в изображение для OCR)
- Word: извлечение текста и таблиц; если текста недостаточно — OCR встроенных изображений
- HEIC/HEIF: фотографии с iPhone автоматически конвертируются в JPEG перед OCR
- Короткий текст (< 1500 символов): Context Stuffing — полный документ вставляется в промпт LLM
- Длинный текст (>= 1500 символов): векторный поиск — текст разбивается на фрагменты, сохраняется в ChromaDB, извлекаются наиболее релевантные отрывки (top-K)
- Переключение между препаратами: когда пользователь упоминает другое лекарство, система автоматически переключает контекст
- Веб: нативный Speech Recognition API браузера (нулевая задержка, без затрат на API)
- Мини-программа: Groq Whisper Large-V3 для распознавания речи, edge-tts для синтеза речи
- Коррекция медицинских терминов: LLM постобрабатывает результат ASR для исправления неверно распознанных названий лекарств
- Прерываемое воспроизведение: нажмите кнопку озвучки, чтобы немедленно остановить текущий TTS
- Обнаружение ключевых слов: настраиваемые ключевые слова риска в
risk_keywords.json - Аудит журналов: все диалоги сохраняются в MySQL для проверки
- Оповещения по email: автоматическое уведомление при срабатывании ключевых слов (настраивается)
- Панель администратора: мониторинг в реальном времени через Streamlit с защитой по IP-адресам
- Высококонтрастный интерфейс (соответствие WCAG AA)
- Увеличенные области нажатия (48px+)
- Полностью голосовой рабочий процесс для незрячих пользователей
- Переключение китайского и английского языков с синхронизацией ответа ИИ и выбора голоса TTS
┌─────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Web Front │────▶│ Java Backend │────▶│ Python AI │
│ :5174 │ │ Spring Boot │ │ FastAPI │
│ Vue 3 CDN │ │ :8080 │ │ :8001 │
└─────────────┘ │ │ │ │
│ - REST API │ │ - OCR (ocrmac) │
┌─────────────┐ │ - JPA / MySQL │ │ - ASR (Groq) │
│ WeChat │────▶│ - Auth / CORS │ │ - RAG (LangChain)│
│ Mini App │ │ - IP Whitelist │ │ - TTS (edge-tts) │
└─────────────┘ └────────┬─────────┘ │ - Risk Detection │
│ └────────┬──────────┘
▼ ▼
┌──────────────┐ ┌──────────────┐
│ MySQL 8 │ │ ChromaDB │
│ :3306 │ │ (local) │
└──────────────┘ └──────────────┘
| Зависимость | Версия | Примечания |
|---|---|---|
| Python | 3.10+ | Среда выполнения ИИ-сервиса |
| Java | 17+ | Среда выполнения бизнес-бэкенда |
| Maven | 3.8+ | Сборщик Java |
| MySQL | 8.0+ | Реляционное хранилище данных |
| macOS (рекомендуется) | 13+ | ocrmac использует фреймворк Apple Vision для OCR |
Linux: поддерживается, но требуется Tesseract для OCR. Установка:
apt install tesseract-ocr tesseract-ocr-chi-sim, затем изменитеbackend-ai/services/ocr.py.
Необходим DeepSeek API Key (обязательно) и опционально Groq API Key (для распознавания речи в мини-программе WeChat).
Как получить DeepSeek API Key (обязательно)
DeepSeek предоставляет LLM для ответов на вопросы.
- Перейдите на platform.deepseek.com
- Зарегистрируйтесь или войдите
- Перейдите в раздел API Keys в боковом меню
- Нажмите Create API Key, задайте имя (например "MedVision")
- Скопируйте ключ немедленно (начинается с
sk-, повторно не отображается)
Стоимость: модель по умолчанию deepseek-v4-flash крайне дешёвая. Полный день разработки и тестирования обычно стоит менее $0.01.
Как получить Groq API Key (опционально — только для мини-программы)
Groq обеспечивает быстрое распознавание речи через Whisper Large-V3 на аппаратуре LPU.
- Перейдите на console.groq.com
- Зарегистрируйтесь через GitHub или Google
- Перейдите в раздел API Keys в боковом меню
- Нажмите Create API Key
- Скопируйте ключ (начинается с
gsk-)
Стоимость: бесплатный тариф включает щедрый лимит на Whisper. Веб-интерфейс использует встроенный Speech API браузера и не расходует кредиты Groq — только мини-программа WeChat использует Groq.
git clone https://github.com/Ha1baraA11/MedVision_RAG.git
cd MedVision_RAGcp .env.example .envОткройте .env в любом текстовом редакторе и заполните значения:
# macOS
open -e .env
# VS Code
code .env| Переменная | Обязательна | Описание |
|---|---|---|
MYSQL_PASSWORD |
Да | Пароль root-пользователя MySQL |
DEEPSEEK_API_KEY |
Да | Получить на platform.deepseek.com |
DEEPSEEK_BASE_URL |
Нет | По умолчанию: https://api.deepseek.com |
GROQ_API_KEY |
Для мини-программы | Получить на console.groq.com |
SMTP_SERVER |
Нет | SMTP-сервер для оповещений о рисках (например smtp.qq.com) |
SMTP_PORT |
Нет | SMTP-порт (QQ Mail: 465) |
SMTP_USER |
Нет | Адрес электронной почты отправителя |
SMTP_PASSWORD |
Нет | SMTP-код авторизации (не пароль от почты) |
SMTP_RECEIVER |
Нет | Адрес получателя |
INTERNAL_TOKEN |
Нет | Токен авторизации между сервисами Java и Python |
Примечание:
MYSQL_PASSWORD— единственное действительно обязательное значение для запуска системы. Всё остальное имеет безопасные значения по умолчанию или корректно деградирует.
Как получить SMTP-код авторизации QQ Mail
- Войдите на mail.qq.com → Настройки → Аккаунт
- Найдите раздел POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV Service
- Включите IMAP/SMTP Service
- Следуйте инструкции SMS-подтверждения для получения кода авторизации
- Используйте этот код (не пароль QQ) в качестве
SMTP_PASSWORD
cd backend-ai
# Создание виртуального окружения
python3 -m venv venv
# Активация
source venv/bin/activate
# Установка зависимостей (только первый раз, ~2 мин)
pip install -r requirements.txtПри первом запуске будет загружена модель эмбеддингов bge-small-zh-v1.5 (~90 МБ) с HuggingFace.
cd backend-java
# Загрузка зависимостей и компиляция (только первый раз, ~3 мин)
mvn clean install -DskipTestsmysql -u root -p < sql/init.sqlБудут созданы:
- База данных
medvision(UTF8MB4) - Таблица
medicines— информация о препаратах и полный текст - Таблица
chat_logs— история диалогов и аналитика - Таблица
admin_users— учётные записи администраторов
Учётная запись администратора по умолчанию (admin / admin) создаётся автоматически при первом запуске Java-бэкенда.
Альтернатива: если пропустить этот шаг, Spring Boot с
hibernate.ddl-auto=updateавтоматически создаст таблицы при запуске. SQL-скрипт предусмотрен для явного управления схемой и промышленного развёртывания.
./start_all.shСкрипт запускает все сервисы в порядке зависимостей, дожидается готовности каждого и выводит статус. Логи записываются в backend-ai/service.log, backend-java/backend.log и dashboard.log.
Терминал 1 — Python AI-сервис (запускать первым, он самый медленный)
cd backend-ai
source venv/bin/activate
python main.pyДождитесь: Uvicorn running on http://0.0.0.0:8001
При первом запуске модель эмбеддингов (
bge-small-zh-v1.5) будет загружена и закэширована. Последующие запуски занимают ~3 секунды.
Терминал 2 — Java-бэкенд
cd backend-java
mvn spring-boot:runДождитесь: Started MedVisionApplication in X.XXX seconds
Maven загружает зависимости при первом запуске. Бэкенд автоматически создаст таблицы в базе данных и учётную запись администратора по умолчанию.
Терминал 3 — Веб-интерфейс
cd frontend
python3 -m http.server 5174Откройте http://localhost:5174 в браузере.
Опционально — Панель администратора
streamlit run admin_dashboard.py --server.port 8502Откройте http://localhost:8502. Логин: admin / admin.
./stop_all.shИли вручную:
lsof -t -i:5174 -i:8080 -i:8001 -i:8502 | xargs kill -9- Скачайте и установите WeChat Developer Tools
- Откройте инструмент, нажмите Import Project
- Выберите директорию
frontend-wechat/ - Выберите Test AppID или гостевой режим
- Отредактируйте
frontend-wechat/config.js:
const API_CANDIDATES = [
'http://192.168.x.x:8080', // замените на локальный IP вашего компьютера
];# macOS
ifconfig | grep "inet " | grep -v 127.0.0.1
# Windows
ipconfig | findstr "IPv4"- Убедитесь, что телефон и компьютер подключены к одной сети Wi-Fi
- В WeChat Developer Tools нажмите Debug on Device
- Отсканируйте QR-код телефоном
- Если соединение не устанавливается, проверьте:
- Брандмауэр компьютера разрешает порт
8080 - В
config.jsуказан правильный локальный IP (неlocalhost) - Java-бэкенд запущен
- Брандмауэр компьютера разрешает порт
Отредактируйте backend-ai/core/config.py:
llm = ChatOpenAI(
model="deepseek-v4-flash", # измените модель здесь
api_key=API_KEY,
base_url=BASE_URL,
temperature=0.3 # 0.0 = детерминированный, 1.0 = творческий
)Доступные модели DeepSeek:
| Модель | Скорость | Стоимость | Рекомендуется для |
|---|---|---|---|
deepseek-v4-flash |
Быстрая | Очень низкая | Разработка, демонстрация (по умолчанию) |
deepseek-v4 |
Средняя | Низкая | Более качественные ответы |
По умолчанию используется ocrmac (macOS Vision). Для переключения на Tesseract в Linux:
# Установка Tesseract с поддержкой китайского языка
sudo apt install tesseract-ocr tesseract-ocr-chi-sim
# Установка Python-обёртки
pip install pytesseractЗатем измените backend-ai/services/ocr.py для использования pytesseract вместо ocrmac.
Модель по умолчанию — BAAI/bge-small-zh-v1.5 (оптимизирована для китайских медицинских текстов, ~90 МБ). Работает локально на CPU — вызовы API не требуются. Для смены:
# backend-ai/core/config.py
embedding_model = HuggingFaceEmbeddings(
model_name="BAAI/bge-small-zh-v1.5", # измените модель здесь
model_kwargs={"local_files_only": True, "device": "cpu"}
)При первом использовании измените
local_files_onlyнаFalseдля загрузки с HuggingFace.
Отредактируйте risk_keywords.json, чтобы добавить или удалить триггерные слова:
{
"keywords": ["overdose", "poisoning", "allergy", "contraindication", "side effect", "..."]
}Если в вопросе пользователя встречается настроенное ключевое слово, система фиксирует событие риска и может отправить email-уведомление.
Панель администратора ограничивает доступ по IP-адресам. Настройка в backend-java/src/main/resources/application.properties:
admin.security.enabled=true
admin.security.ip-whitelist=127.0.0.1,::1Добавьте свой IP в белый список для удалённого доступа.
Модель эмбеддингов кэшируется локально после первой загрузки. Для принудительного повторного скачивания:
cd backend-ai
source venv/bin/activate
python -c "from langchain_huggingface import HuggingFaceEmbeddings; HuggingFaceEmbeddings(model_name='BAAI/bge-small-zh-v1.5')"| Метод | Путь | Описание |
|---|---|---|
GET |
/health |
Проверка работоспособности |
POST |
/ocr |
OCR изображения/PDF/Word → извлечение текста |
POST |
/chat |
RAG ответы на вопросы |
POST |
/transcribe |
Распознавание речи (Whisper через Groq) |
POST |
/analyze |
Ручной анализ текста |
GET |
/tts |
Синтез речи (edge-tts) |
GET |
/search |
Поиск по истории лекарств |
| Метод | Путь | Описание |
|---|---|---|
GET |
/api/medicine/health |
Проверка работоспособности |
POST |
/api/medicine/recognize |
Загрузка и распознавание инструкции к препарату |
POST |
/api/medicine/chat |
Проксирование в AI-сервис для чата |
GET |
/api/medicine/list |
Список всех сохранённых препаратов |
GET |
/api/medicine/chat-logs |
История чатов (для администратора) |
GET |
/api/medicine/analytics |
Аналитика использования (для администратора) |
POST |
/api/medicine/admin/login |
Вход администратора |
# Юнит-тесты Python (17 тестов, ~0.2 с)
cd backend-ai
source venv/bin/activate
python -m pytest tests/ -v
# Юнит-тесты Java (6 тестов)
cd backend-java
mvn test| Модуль | Тесты | Что покрывают |
|---|---|---|
check_risk_keywords |
6 | Совпадение, кэш, истечение, пустой ввод |
smart_rag_search |
4 | Короткий текст, длинный текст, откат при ошибке, граничные случаи |
correct_medical_terms |
7 | Фильтр галлюцинаций, чёрный список, коррекция LLM, откат при ошибке |
MedicineController |
6 | MockMvc-тесты REST-эндпоинтов |
MedVision-RAG/
├── frontend/ # Одностраничное веб-приложение Vue 3 CDN
│ └── index.html # Полный фронтенд (848 строк)
├── frontend-wechat/ # Мини-программа WeChat
│ ├── pages/index/ # Главная страница (WXML + JS + WXSS)
│ ├── app.js # Точка входа приложения
│ └── config.js # Конфигурация API-эндпоинтов
├── backend-java/ # Spring Boot бизнес-бэкенд
│ ├── src/main/java/com/medvision/
│ │ ├── controller/ # REST-эндпоинты
│ │ ├── service/ # Бизнес-логика
│ │ ├── entity/ # JPA-сущности (Medicine, ChatLog, AdminUser)
│ │ ├── repository/ # Репозитории Spring Data JPA
│ │ └── config/ # Безопасность, CORS, IP-список, инициализация данных
│ ├── src/test/ # MockMvc-тесты
│ └── pom.xml # Maven-зависимости
├── backend-ai/ # FastAPI AI-сервис
│ ├── main.py # Точка входа маршрутов (~250 строк)
│ ├── core/
│ │ ├── config.py # Глобальные синглтоны (LLM, эмбеддинги, Groq-клиент)
│ │ ├── logging_config.py # Структурированное логирование + middleware трассировки
│ │ └── security.py # Верификация внутреннего токена
│ ├── services/
│ │ ├── ocr.py # OCR (ocrmac + Tesseract как запасной вариант)
│ │ ├── asr.py # Распознавание речи (Groq Whisper)
│ │ ├── rag.py # Адаптивный RAG (context stuffing + векторный поиск)
│ │ ├── tts.py # Синтез речи (edge-tts)
│ │ ├── risk.py # Обнаружение ключевых слов риска + TTL-кэш
│ │ ├── email.py # Email-оповещения о рисках (асинхронный пул потоков)
│ │ ├── intent.py # Анализ намерений (текущий vs исторический препарат)
│ │ ├── search.py # Поиск по истории лекарств
│ │ └── chat_model.py # Переключение чат-модели
│ ├── models/
│ │ └── schemas.py # Pydantic-модели запросов
│ └── tests/ # Юнит-тесты pytest
├── admin_dashboard.py # Панель администратора на Streamlit
├── risk_keywords.json # Словарь ключевых слов риска
├── sql/
│ └── init.sql # Скрипт инициализации базы данных
├── Package-Insert_Test/ # Примеры инструкций для тестирования
├── .env.example # Шаблон переменных окружения
├── .gitignore # Правила Git
├── start_all.sh # Единый скрипт запуска всех сервисов
└── stop_all.sh # Единый скрипт остановки всех сервисов
No module named 'ocrmac'
ocrmac использует фреймворк macOS Vision и работает только на macOS. Для Linux установите Tesseract:
sudo apt install tesseract-ocr tesseract-ocr-chi-sim
pip install pytesseractЗатем измените backend-ai/services/ocr.py для использования pytesseract.
Connection refused при запуске Java-бэкенда
MySQL не запущен или указан неверный пароль.
# Проверка состояния MySQL
mysql -u root -p -e "SELECT 1"
# Проверка пароля в .env
cat .env | grep MYSQL_PASSWORDПредупреждение torchaudio при запуске Python
Это некритичное предупреждение о VAD (Voice Activity Detection). Система автоматически переключается в режим без VAD и работает нормально. Для исправления: pip install torchaudio.
Maven загружает зависимости медленно
Добавьте зеркало в ~/.m2/settings.xml:
<mirrors>
<mirror>
<id>aliyun</id>
<mirrorOf>central</mirrorOf>
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
</mirrors>Белый экран в браузере
Откройте DevTools (F12) → вкладка Console. Типичные причины:
- AI-сервис не запущен → проверьте порт
8001 - Java-бэкенд не запущен → проверьте порт
8080 - Ошибка CORS → убедитесь, что вы обращаетесь через
localhost:5174, а неfile://
Мини-программа не подключается к бэкенду
- Убедитесь, что телефон и компьютер подключены к одной сети Wi-Fi
- Проверьте, что в
config.jsуказан локальный IP (неlocalhostили127.0.0.1) - Убедитесь, что брандмауэр компьютера разрешает входящие подключения на порту
8080 - Попробуйте
curl http://YOUR_LAN_IP:8080/api/medicine/healthиз браузера телефона
Распознавание речи не работает (веб)
Браузеры требуют HTTPS или localhost для доступа к микрофону. Убедитесь, что вы открываете страницу через http://localhost:5174, а не через локальный IP.
Распознавание речи не работает (мини-программа)
Проверьте, что GROQ_API_KEY указан в .env. Перезапустите Python AI-сервис после изменения .env.
OCR возвращает "неизвестный препарат" или искажённый текст
- Убедитесь, что фотография чёткая и хорошо освещённая
- Название препарата должно быть видно на изображении
- Для PDF проверьте, является ли файл отсканированным изображением (не текстовым) — система автоматически определит и использует OCR изображений
Как сбросить базу данных
mysql -u root -p -e "DROP DATABASE IF EXISTS medvision;"
mysql -u root -p < sql/init.sqlЗатем перезапустите Java-бэкенд для повторного создания учётной записи администратора по умолчанию.
Как изменить пароль администратора
Используйте панель администратора (http://localhost:8502) после входа или обновите напрямую в MySQL:
USE medvision;
UPDATE admin_users SET password_hash = '$2a$10$...' WHERE username = 'admin';Сгенерируйте хеш BCrypt с помощью любого онлайн-инструмента или Python:
from passlib.hash import bcrypt
print(bcrypt.hash("your_new_password"))В репозитории пока нет файла лицензии. Добавьте явную лицензию до распространения или повторного использования проекта за пределами предусмотренной области.
