Чому 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-інженерів.







