Сделать AI RAG-ассистента, который принимает документы (фото/сканы), голос, текст; извлекает факты; сохраняет; и по запросу пользователя возвращает нужную информацию. Это не «память модели», а управляемое хранилище + поиск + генерация ответа. 1) Что именно строим (компоненты) Ingestion (загрузка данных) Фото/сканы (билеты, паспорт) ? OCR ? текст + поля. Голос ? ASR (speech-to-text) ? текст. Текстовые заметки ? сразу текст. Нормализация и структурирование Разбиваем на чанки (кусочки текста). Опционально: извлекаем сущности/поля (ФИО, номер паспорта, даты вылета, PNR, номер рейса). Сохраняем: исходный файл (объектное хранилище), текст/чанки, структуру (JSON с полями), метаданные (пользователь, тип документа, дата загрузки, язык и т.д.). Индекс для RAG Эмбеддинги чанков ? векторная БД (Qdrant/Milvus/pgvector). Параллельно — ключевый поиск (BM25/Elastic) полезен для номеров/дат/кодовых строк. Гибридный поиск (vector + keyword) обычно лучший вариант. Retrieval + Answering Пользовательский вопрос ? переписывание запроса (опционально) ? поиск релевантных чанков ? LLM отвечает строго на основе найденного. Для «точных данных» (номер паспорта, дата, PNR) лучше дополнительно делать извлечение/проверку из структурных полей. Безопасность и изоляция Все данные привязаны к user_id (или tenant_id). Шифрование, контроль доступа, аудит. Для паспортов и билетов (PII) — маскирование при показе или политика “показывать только последние 4 цифры” по умолчанию. 2) Поток обработки: фото билета/паспорта Фото ? OCR ? классификация документа ? извлечение полей ? сохранение ? индексирование Рекомендуемые техники: OCR: Tesseract (просто) / PaddleOCR (часто лучше на сложных изображениях) / облачные OCR (Google/AWS/Azure). Паспорт: часто важен MRZ (машиночитаемая зона) — отдельный парсер MRZ даёт высокую точность. Билет: парсинг ключевых паттернов (рейс, дата, аэропорты, PNR/booking reference). 3) Поток обработки: голос Голос ? ASR ? текст ? (опционально) выделение фактов ? сохранение ? индекс ASR: OpenAI Whisper (локально/облачно) или аналоги. Сохраняйте также таймкоды/аудио-ссылку, если нужно подтверждение. 4) Как отвечать на запросы (2 режима) Режим A: “RAG-ответ” Вопрос: “Когда мой вылет в Берлин?” ? retrieval ? LLM формирует ответ + ссылка на источник (“из билета от …”). Режим B: “Факт из профиля” (структурные поля) Вопрос: “Какой номер паспорта я загружал?” ? лучше брать из структурных полей, а не из LLM-пересказа. ? выводить с маскированием: *******1234, и по запросу пользователя показывать полностью. На практике делают router: если вопрос про конкретные поля (номер документа, дата рождения, PNR) ? structured store иначе ? RAG 5) Минимальный стек (быстро собрать) Backend: Python + FastAPI OCR: PaddleOCR (или Tesseract на старте) ASR: Whisper Embeddings: любой совместимый (например, text-embedding-*), локальные тоже можно Vector DB: Qdrant (самый простой старт) Файлы: S3-совместимое (MinIO) Реляционка: Postgres (метаданные, пользователи, поля) 6) Схема данных (упрощённо) documents (id, user_id, type, created_at, original_uri) doc_chunks (id, document_id, chunk_text, chunk_index) embeddings (chunk_id, vector, metadata: user_id, doc_type, даты) extracted_facts (document_id, jsonb) — структурные поля 7) Ключевые детали, чтобы “работало как память” Версионирование: если пользователь перезалил документ, сохраняйте новую версию. Дедупликация: хэш файла/текста. Цитирование источника: возвращайте “взято из: билет …”. Политика конфиденциальности: какие поля можно показывать сразу, какие только после подтверждения. Оценка качества OCR: хранить confidence; при низком — просить переснять/переговорить. Многоязычность: нормализация дат/форматов. 8) Пример логики ответа (псевдопроцесс) Вопрос пользователя Классификатор запроса: “паспорт номер / дата рождения / PNR / номер рейса” ? structured lookup иначе ? RAG retrieval Retrieval: filter: user_id = текущий topK = 5–10 LLM: строгий системный промпт “отвечай только по контексту”.