Почему Search-as-a-Service быстрее и дешевле собственной разработки поиска
Мы часто видим, как компании тратят месяцы на разработку поиска с нуля для каждого продукта: пишут свою векторизацию, городить реранжировку, настраивать инфраструктуру. Search as a Service — это готовая поисковая платформа с AI-слоем, которую мы подключаем через API или SDK. Наши инженеры с 10+ летним опытом в MLOps берут на себя всю инфраструктуру: от выбора embedding-модели до настройки гибридного поиска и реранжировки.
Типичный сценарий: у компании 5 продуктов, в каждом нужен поиск по каталогу, документам, контенту. Без платформы — 5 независимых реализаций, 5 раз настраивать индексы, 5 раз платить за GPU для embedding-модели. С нашей платформой — один shared сервис, разные индексы (tenants), единый API. Стоимость инфраструктуры снижается на 30–50% за счёт shared GPU, а время вывода поиска — с месяцев до недель.
Как работает многотенантность в поисковой платформе?
Каждый клиент получает изолированную среду: свою коллекцию в Qdrant (или другой векторной БД), собственные pipeline индексации и гибкие лимиты. Мы гарантируем, что данные разных заказчиков не смешиваются, а нагрузка равномерно распределяется через горизонтальное масштабирование.
from fastapi import FastAPI, Header, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional
import uuid
app = FastAPI(title="Search as a Service")
class IndexConfig(BaseModel):
name: str
embedding_model: str = "intfloat/multilingual-e5-large"
chunk_size: int = 512
chunk_overlap: int = 64
language: str = "ru"
reranker_enabled: bool = True
class SearchRequest(BaseModel):
query: str
index_name: str
filters: Optional[dict] = None
top_k: int = 10
mode: str = "hybrid" # "vector" | "keyword" | "hybrid"
generate_answer: bool = False
class SearchService:
def __init__(self):
self.tenant_indexes = {} # tenant_id → {index_name → index}
self.embedding_models = {} # model_name → loaded_model
self.reranker = self._load_reranker()
async def create_index(self, tenant_id: str, config: IndexConfig):
"""Создаёт изолированный индекс для тенанта"""
collection_name = f"{tenant_id}_{config.name}"
# Каждый тенант — отдельная коллекция в Qdrant
# с собственными payload-фильтрами
self.qdrant.create_collection(
collection_name=collection_name,
vectors_config=VectorParams(
size=self._get_vector_size(config.embedding_model),
distance=Distance.COSINE
)
)
return {"index_id": collection_name, "status": "created"}
async def search(
self,
tenant_id: str,
request: SearchRequest
) -> dict:
collection = f"{tenant_id}_{request.index_name}"
if request.mode == "hybrid":
results = await self._hybrid_search(
collection, request.query,
request.filters, request.top_k
)
elif request.mode == "vector":
results = await self._vector_search(
collection, request.query, request.top_k
)
else:
results = await self._keyword_search(
collection, request.query, request.top_k
)
if request.generate_answer and results:
answer = await self._generate_answer(request.query, results)
return {"results": results, "answer": answer}
return {"results": results}
SDK для команд-потребителей
Мы предоставляем Python SDK с минимальными зависимостями. Команды подключаются к платформе за 10 минут — без погружения в детали работы векторных БД и LLM.
# pip install search-platform-sdk
from search_platform import SearchClient
client = SearchClient(
api_key="sk-...",
base_url="https://search.internal.company.com"
)
# Индексация документов
client.index.upload(
index_name="product-catalog",
documents=[
{"id": "p001", "title": "Ноутбук Dell XPS", "description": "...",
"price": 89999, "category": "laptops"},
# ...
]
)
# Поиск
results = client.search(
index_name="product-catalog",
query="тонкий ноутбук для работы с видео",
filters={"price": {"lte": 100000}, "category": "laptops"},
top_k=5,
generate_answer=True
)
print(results.answer) # "На основе вашего запроса рекомендую..."
print(results.items) # список документов с релевантностью
Почему стоит выбрать Search-as-a-Service, а не самодельное решение?
Сравните: самостоятельная реализация требует найма команды ML-инженеров, выбора и обучения embedding-модели, настройки векторной БД, реранжировщика, балансировщика, мониторинга — 6–12 месяцев работы. Наша платформа даёт тот же функционал за 6–8 недель, в 4 раза быстрее, с гарантированным SLA 99.9% и latency P99 < 1 сек. Мы уже проверили архитектуру на нагрузке 2M документов и 12 продуктов — результат: 35% экономии на инфраструктуре, 4 дня на подключение команды через SDK.
| Характеристика | Самостоятельная разработка | Search-as-a-Service |
|---|---|---|
| Время внедрения | 6–12 месяцев | 6–8 недель |
| Стоимость инфраструктуры | высокая (отдельные GPU, несколько команд) | экономия до 35% за счёт shared GPU |
| SLA | ниже (без мониторинга и бэкапов) | 99.9% |
| Поддержка новых источников данных | требует доработок | плагины и SDK |
Кейс SaaS-компании: мигрировала со своих разрозненных Elasticsearch-инстансов на единую платформу. 3 команды подключились через SDK за 1 день (без понимания векторных баз и embedding-моделей). Стоимость инфраструктуры снизилась на 35% — существенная экономия. Среднее время ответа поиска: 280 мс P50, 650 мс P99 на корпусе 2M документов.
Rate limiting и мониторинг
Контролируем нагрузку динамическими лимитами по планам и логируем каждый запрос в TimescaleDB.
from fastapi_limiter import FastAPILimiter
from fastapi_limiter.depends import RateLimiter
import redis.asyncio as redis
# Лимиты по тенантам
TENANT_LIMITS = {
"free": "100/minute",
"pro": "1000/minute",
"enterprise": "unlimited"
}
@app.post("/search")
@limiter.limit(get_tenant_limit) # динамический лимит по плану
async def search_endpoint(
request: SearchRequest,
x_api_key: str = Header(...),
tenant = Depends(authenticate_tenant)
):
return await search_service.search(tenant.id, request)
Billing и usage tracking
Каждый поиск и каждый embedding-запрос логируются в TimescaleDB:
CREATE TABLE search_usage (
id BIGSERIAL PRIMARY KEY,
tenant_id TEXT NOT NULL,
index_name TEXT NOT NULL,
query_hash TEXT, -- хэш для анонимизации
mode TEXT,
latency_ms INTEGER,
result_count INTEGER,
answer_generated BOOLEAN,
tokens_used INTEGER, -- для LLM-ответа
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Гипертаблица TimescaleDB для эффективного time-range запросов
SELECT create_hypertable('search_usage', 'created_at');
Технические детали архитектуры индексации
Документы проходят чанкинг (разбиение на части по 512 токенов с перекрытием 64), векторизацию через embedding-модель, затем сохраняются в Qdrant с полными payload. Для каждого тенанта — отдельная коллекция. При гибридном поиске результаты объединяются через weighted sum с реранжировкой от cross-encoder.Что входит в работу
- Аудит текущей поисковой инфраструктуры (если есть) — анализ индексов, замеры latency, выявление узких мест.
- Проектирование multi-tenant архитектуры — выбор векторной БД (Qdrant, Pinecone, Weaviate), настройка изоляции, планирование ёмкости.
- Разработка API и SDK — RESTful API (FastAPI) и Python SDK с поддержкой гибридного поиска, реранжировки и генерации ответов на основе RAG с контролем галлюцинаций через few-shot prompting.
- Интеграция с существующими системами — кастомные коннекторы для CMS, ERP, DMS.
- Мониторинг и биллинг — дашборды Grafana, логи в TimescaleDB, система rate limiting по планам.
- Документация и обучение — полная документированная схема API, примеры кода, 2 часа онлайн-тренинга для команд.
- Поддержка и SLA — гарантия 99.9% uptime, реагирование на инциденты в течение 1 часа.
Процесс работы
- Аналитика — обсуждаем требования, профиль нагрузки, объём данных и желаемые метрики (P50/P99 latency).
- Проектирование — создаём архитектуру, выбираем стэк (embedding-модель, векторную БД, реранжировщик), проектируем схему тенантов.
- Реализация — разрабатываем API, SDK, пайплайн индексации, интеграционные тесты.
- Нагрузочное тестирование — на ваших данных (или синтетических) замеряем latency, throughput, определяем точки отказа.
- Деплой — разворачиваем на вашей инфраструктуре (AWS/GCP/on-prem) или нашей облачной площадке. Настраиваем мониторинг.
- Приёмка и обучение — демонстрация, передача документации, обучение команды.
SLA и параметры платформы
| Параметр | Значение |
|---|---|
| Latency P50 | < 300 мс |
| Latency P99 | < 1 сек |
| Доступность | 99.9% |
| Максимальный размер документа | 5 MB |
| Поддерживаемые форматы | PDF, DOCX, TXT, HTML, JSON |
| Языки | RU, EN, DE, FR, ES (multilingual-E5) |
| Максимум тенантов | Не ограничено (горизонтальное масштабирование) |
Сроки: базовая платформа (API + индексация + гибридный поиск) — 6–8 недель; с генерацией ответов, SDK и биллингом — 3–4 месяца. Свяжитесь с нами для точной оценки вашего проекта — мы рассчитаем стоимость и сроки под вашу задачу. Получите консультацию наших AI-инженеров.







