Мини-сервис для поиска c ИИ по смыслу на Python + FastAPI + MySQL + sentence-transformers.
-
Создайте SQL-файл в папке
queries/, например,fetch_by_price.sql:SELECT id, name, short_desc, long_desc FROM products WHERE price >= {{ min_price }} AND price <= {{ max_price }}
- id обязательно должен быть в SELECT (для идентификации товара)
- Все остальные поля (например, name, short_desc, long_desc) будут использоваться для ИИ-поиска по смыслу
- Используйте
{{ param }}для параметров, которые будут передаваться через query params
-
(Опционально) Создайте файл маппинга в папке
mappings/с именем, соответствующим SQL-файлу, например,fetch_by_price.mapping.json:{ "id": "id", "title": "name", "description": "short_desc" }Ключ — имя поля в API, значение — имя поля в базе данных.
-
Перезапустите сервис (или просто обновите файлы, если сервис уже запущен).
-
Пользуйтесь новым эндпоинтом:
- Пример:
/query/fetch_by_price?min_price=100&max_price=500 - Все параметры из
{{ param }}в SQL автоматически становятся query params. - Если есть файл маппинга, результат будет преобразован согласно ему.
- Пример:
- Любой эндпоинт
/query/имя_запросаподдерживает параметрqдля поиска по смыслу среди результатов SQL-запроса. - Поиск идёт по всем полям из SELECT, кроме id (например, name, short_desc, long_desc и т.д.).
- Пример:
— сначала фильтрует товары по цене, затем ищет по смыслу среди выбранных товаров.
GET /query/fetch_by_price?min_price=100&max_price=500&q=аромат вишни
queries/
fetch_products.sql
fetch_by_price.sql
mappings/
fetch_products.mapping.json
fetch_by_price.mapping.json
- Не нужно менять Python-код для новых выборок!
- Можно адаптировать под любую структуру БД и любые поля.
- Маппинг позволяет привести результат к нужному API-формату.
- ИИ-поиск работает по любым полям, которые ты укажешь в SELECT.
flowchart TD
A["Пользователь"]
B["FastAPI API /query/имя_запроса"]
C["База данных MySQL"]
D["Модель sentence-transformers"]
E["Сортировка по релевантности"]
F["Форматирует ответ (JSON)"]
A -- "Отправляет запрос (например, /query/fetch_by_price?q=...)" --> B
B -- "Выполняет SQL-запрос из queries/" --> C
C -- "Список товаров" --> B
B -- "Если есть q: преобразует все поля (кроме id) в эмбеддинги через ИИ" --> D
D -- "Векторы товаров и запроса" --> B
B -- "Сравнивает вектор запроса с векторами товаров (косинусное сходство)" --> E
E -- "Формирует список наиболее подходящих товаров" --> F
F -- "Отправляет результат пользователю" --> A
- Пользователь отправляет запрос через API (например,
/query/fetch_by_price?...&q=что-то). - FastAPI сервис выполняет SQL-запрос из папки
queries/с нужными параметрами. - Сервис получает список товаров (любые поля, которые указаны в SELECT).
- Если есть параметр q:
- Для каждого товара склеиваются все поля (кроме id) в одну строку.
- Модель sentence-transformers преобразует эти строки и запрос пользователя в эмбеддинги.
- Сравниваются векторы, выбираются наиболее релевантные товары.
- Формируется JSON-ответ и отправляется пользователю.
ИИ в сервисе — это модель sentence-transformers, которая умеет понимать смысл текста и находить похожие товары даже по синонимам и разным формулировкам.
ИИ — это модель sentence-transformers (на базе нейросетей), которая:
- Понимает смысл текста на естественном языке.
- Может находить похожие по смыслу тексты, даже если слова не совпадают.
- Работает локально, не требует внешних API.
Нет, модель уже обучена (pretrained) на огромных текстовых данных и умеет понимать смысл фраз на многих языках, в том числе на русском. Ты просто используешь её как инструмент: подаёшь текст — получаешь вектор. Для 99% интернет-магазинов стандартная модель работает отлично «из коробки».
Модель обучена на больших датасетах (книги, статьи, диалоги и т.д.), которые подготовили разработчики sentence-transformers. Она не знает ничего о твоих товарах заранее, но умеет понимать смысл любых текстов.
- Интернет нужен только при первом запуске, чтобы скачать модель (~90 МБ).
- После этого модель хранится локально и сервис работает полностью оффлайн.
- Все вычисления происходят на твоём сервере, данные никуда не отправляются.
- Все товары из базы превращаются в векторы (эмбеддинги) с помощью ИИ-модели.
- Запрос пользователя тоже превращается в вектор.
- Сравниваются векторы — находятся товары, которые ближе всего по смыслу к запросу (даже если слова не совпадают).
Можно, но для большинства магазинов это не требуется. Если у тебя очень специфические товары или сленг, можно дообучить модель, но это сложнее и требует много данных и вычислительных ресурсов.
Создайте файл train/data/pairs.jsonl с примерами:
{"query": "король дрифта", "positive": "DRIFT KING Дрифт-легенда R32: Аромат скорости и адреналина."}
{"query": "золотая классика", "positive": "GOLDEN BEAST Золотая классика: Аромат власти и совершенства."}
{"query": "аромат вишни", "positive": "Drift Charm Cherry Подвесной ароматизатор с ароматом вишни."}
Каждая строка — отдельный JSON-объект с полями query и positive.
Выполните:
python train/train_model.py
После завершения обучения дообученная модель будет сохранена в папке train/model_finetuned.
В файле app/search_engine.py замените строку:
self.model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
на
self.model = SentenceTransformer('train/model_finetuned')
Теперь поиск будет работать на вашей дообученной модели!
- Установите зависимости:
pip install -r requirements.txt-
Укажите параметры подключения к MySQL в
config.py. -
Запустите сервер:
uvicorn main:app --reload- Укажите параметры подключения к MySQL в
config.py(должны быть доступны из контейнера). - Соберите и запустите сервис:
docker compose up --build- Сервис будет доступен на http://localhost:8000
Thank you so much for using my projects! If you have any questions, you can always ask me here:
If you want to thank me with a coin
TON: UQD-ZbaI-tHINZqu1Mg7GgFSCMm857jlvXJXLxSa1zx0JKGH