База знаний (RAG) — администрирование¶
Администраторы наполняют медицинскую базу знаний, которую использует AI-репетитор. UI: Admin → блок База знаний (RAG) на http://localhost:8001/admin.
Роли
Загрузка через форму и POST /api/tutor/knowledge/ingest доступна ролям admin и super_admin. Статус KB могут видеть пользователи с доступом к learning API (после входа в админку — только админы).
Предварительные требования¶
MEDICAL_ASSISTANT_ENABLED=true
RAG_ENABLED=true
RAG_COLLECTION_NAME=medical_knowledge
RAG_MODE=local # local | external | hybrid
RAG_EXTERNAL_URL= # для external / hybrid
RAG_EXTERNAL_API_KEY=
RAG_EXTERNAL_TIMEOUT_SECONDS=8.0
RAG_HYBRID_LOCAL_WEIGHT=0.5
Локальный стек Docker: контейнеры aima-*, приложение на порту 8001, Redis на хосте 6380.
Форма ingest в Admin UI¶
- Откройте
/adminи найдите База знаний (RAG). - Переключите вкладку языка EN или RU — документ попадёт только в выбранную дорожку.
- Заполните:
- Title — короткий заголовок;
- Category — guidelines / diseases / medications / admin;
- Text — полный текст фрагмента.
- Отправьте форму. Успех покажет число
upserted(локально) иexternal_upserted(если настроен внешний API).
Документы сохраняются в индекс MedicalRAG и дублируются в storage/rag_uploads/user_knowledge.json для повторного seed / mock.
Одна дорожка за раз
Не смешивайте русский и английский текст в одном документе. Создайте два чанка: один на EN, один на RU.
Статус базы¶
Кнопка / автозагрузка статуса вызывает GET /api/tutor/knowledge/status и показывает:
| Поле | Смысл |
|---|---|
enabled |
RAG включён |
mode |
local / external / hybrid |
collection |
Имя коллекции Chroma |
external_configured |
Задан ли RAG_EXTERNAL_URL |
admin_uploads |
Число загрузок из формы |
admin_uploads_by_language |
Счётчики en / ru |
languages |
Допустимые языки: en, ru |
Режимы RAG_MODE¶
| Режим | Поведение |
|---|---|
local |
Поиск в Chroma / memory (по умолчанию) |
external |
POST {RAG_EXTERNAL_URL}/search; soft-fallback на local, если пусто |
hybrid |
Слияние local + external с весом RAG_HYBRID_LOCAL_WEIGHT |
Контракт внешнего поиска:
POST …/search
{"query": "troponin", "limit": 3}
→ {"results":[{"id","text","title","category","language","similarity"}]}
Ingest во внешний API (если URL задан): POST …/ingest с телом {"documents":[…]}.
Seed скрипт¶
Из контейнера приложения:
# Локальные JSON → индекс (+ опционально БД)
docker compose exec app python scripts/seed_medical_knowledge.py --also-db
# ETL с внешнего dump
docker compose exec app python scripts/seed_medical_knowledge.py \
--from-url https://kb.example.com/export/documents.json \
--api-key "$RAG_EXTERNAL_API_KEY" \
--skip-local-files
Файлы по умолчанию: app/data/medical_knowledge/{guidelines,diseases,medications}.json.
Demo mock RAG¶
Для разработки без настоящей внешней KB:
docker compose --profile mock-rag up -d mock_rag
RAG_MODE=external
RAG_EXTERNAL_URL=http://mock_rag:8090/v1
# MOCK_RAG_API_KEY=dev-mock-key
# RAG_EXTERNAL_API_KEY=dev-mock-key
Либо на хосте:
python scripts/mock_rag_server.py
# RAG_EXTERNAL_URL=http://127.0.0.1:8090/v1
Проверка:
curl -s http://127.0.0.1:8090/health
curl -s -X POST http://127.0.0.1:8090/v1/search \
-H 'Content-Type: application/json' \
-d '{"query":"troponin","limit":3}'
API ingest (скрипты / ETL)¶
curl -s -X POST http://localhost:8001/api/tutor/knowledge/ingest \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"documents": [{
"title": "ACS — initial steps",
"category": "guidelines",
"language": "en",
"text": "Obtain ECG within 10 minutes..."
}]
}'
Требуются роли admin и включённый RAG. Ответ: upserted, external_upserted, ids, mode.
Чеклист после деплоя¶
MEDICAL_ASSISTANT_ENABLEDиRAG_ENABLED= true.- Выполнить seed.
- Проверить статус в Admin UI.
- Задать тестовый вопрос на
/tutorна EN и RU. - При
external/hybrid— убедиться, что mock или прод-KB доступны из сети контейнераaima-*.