В компании из 500 человек знания хранятся в 7–12 системах одновременно: Confluence, SharePoint, Jira, корпоративная почта, 1C, внутренние CRM, файловые сервера. Сотрудник тратит в среднем 2,5 часа в день на поиск информации — это не метафора, это данные McKinsey Global Institute. Ключевая проблема не в том, что данные есть, а в том, что найти их через обычный keyword-поиск невозможно: документ называется «Регламент_v3_final_FINAL2», а запрос — «как оформить командировку». Мы разрабатываем AI Enterprise Search — систему, которая решает эту проблему через семантическое понимание запроса и гибридный поиск по всем источникам одновременно.
Проблемы, которые решаем
Разрозненность данных — не единственная сложность. Даже если документ найден, он может быть неактуален или не соответствовать контексту. Типичные сценарии:
- Низкая точность keyword-поиска: артикул «A-123» ищется как обычное слово, без понимания, что это номер детали.
- Отсутствие контекста: запрос «бюджет на маркетинг» должен учитывать, что пользователь — руководитель отдела, а не стажёр.
- Нарушение безопасности: сотрудник видит документы, к которым не имеет доступа, если ACL не внедрён.
Почему AI Enterprise Search эффективнее обычного поиска?
Чистый векторный поиск хорошо работает на семантически похожих запросах, но плохо — на точных совпадениях: артикулах, именах, датах. Запрос «договор с ООО "Ромашка" от 12 марта» даст лучший результат через BM25, а «порядок действий при инциденте с утечкой данных» — через векторный поиск. Гибридный подход объединяет сильные стороны обоих методов.
| Тип поиска | Сильные стороны | Слабые стороны |
|---|---|---|
| Keyword (BM25) | Точные совпадения, артикулы, даты | Не понимает синонимы, контекст |
| Векторный (Embeddings) | Семантика, синонимы, обобщения | Плохо на редких терминах, "холодный старт" |
| Гибридный (наш) | Лучшее из двух миров, CrossEncoder реранкинг | Сложнее в реализации, требует тонкой настройки |
from qdrant_client import QdrantClient
from rank_bm25 import BM25Okapi
from sentence_transformers import SentenceTransformer, CrossEncoder
import numpy as np
class HybridSearchEngine:
def __init__(self):
self.dense_model = SentenceTransformer("intfloat/multilingual-e5-large")
self.reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")
self.qdrant = QdrantClient(url="http://localhost:6333")
self.bm25_index = None
self.doc_store = {}
def search(self, query: str, top_k: int = 20, final_k: int = 5) -> list[dict]:
# Dense search
query_emb = self.dense_model.encode(
f"query: {query}", # E5-формат
normalize_embeddings=True
)
dense_results = self.qdrant.search(
collection_name="enterprise_docs",
query_vector=query_emb.tolist(),
limit=top_k
)
# Sparse search (BM25)
bm25_scores = self.bm25_index.get_scores(query.lower().split())
top_bm25_ids = np.argsort(bm25_scores)[-top_k:][::-1]
# Merge результатов (RRF - Reciprocal Rank Fusion)
merged = self._reciprocal_rank_fusion(dense_results, top_bm25_ids)
# Cross-encoder reranking
pairs = [(query, self.doc_store[doc_id]["text"]) for doc_id in merged[:top_k]]
rerank_scores = self.reranker.predict(pairs)
reranked = sorted(
zip(merged[:top_k], rerank_scores),
key=lambda x: x[1],
reverse=True
)
return [self.doc_store[doc_id] for doc_id, _ in reranked[:final_k]]
def _reciprocal_rank_fusion(self, dense: list, sparse: list, k: int = 60) -> list:
scores = {}
for rank, item in enumerate(dense):
doc_id = item.id
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
for rank, doc_id in enumerate(sparse):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
return sorted(scores, key=scores.get, reverse=True)
Понимание запроса и генерация ответа
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
class EnterpriseSearchAssistant:
def __init__(self, search_engine: HybridSearchEngine):
self.search = search_engine
self.llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.1)
def answer(self, query: str, user_context: dict) -> dict:
# Расширение запроса для лучшего поиска
expanded_query = self._expand_query(query, user_context)
# Поиск по всем источникам
results = self.search.search(expanded_query, final_k=7)
if not results:
return {"answer": "Документы по вашему запросу не найдены.", "sources": []}
# Генерация ответа с цитатами
context = "\n\n".join([
f"[{i+1}] {r['title']} ({r['source']})\n{r['text'][:500]}"
for i, r in enumerate(results)
])
prompt = f"""Ответь на вопрос сотрудника на основе документов компании.
Используй только предоставленные документы. Цитируй источники [1], [2] и т.д.
Если ответ неполный — скажи об этом.
Вопрос: {query}
Документы:
{context}"""
answer = self.llm.invoke(prompt).content
return {
"answer": answer,
"sources": [{"id": i+1, "title": r["title"], "url": r["url"]}
for i, r in enumerate(results)]
}
Индексация источников
Для каждого источника — отдельный коннектор с инкрементальным обновлением:
| Источник | Коннектор | Частота индексации | Особенности |
|---|---|---|---|
| Confluence | REST API (spaces, pages) | Каждые 30 мин | Обработка разметки Confluence |
| SharePoint | Microsoft Graph API | Каждый час | Поддержка Word/PDF/PPTX |
| Jira | REST API | Каждые 15 мин | Тикеты + комментарии |
| IMAP/Exchange | Realtime (webhooks) | Только отправленные/полученные | |
| Файловый сервер | Inotify / polling | При изменении | PDF, DOCX, XLSX, TXT |
Кейс из практики: производственный холдинг, 1200 сотрудников. Индексировали 340 000 документов из Confluence, SharePoint и самописной СЭД. Время загрузки индекса — 18 часов (однократно). Регулярное обновление — дельта за 30 минут, ~200 документов, занимает 4 минуты. Средняя точность топ-3 ответов (оценка HR-командой по выборке 500 запросов): 78% релевантных результатов против 41% у прежнего Elasticsearch keyword-поиска. За счёт автоматизации поиска компания получила существенную экономию бюджета.
Как оценивается точность поиска?
Оценка проводится на реальных запросах сотрудников. Мы формируем выборку из 300–500 типовых вопросов, размечаем релевантные документы и считаем recall@k и precision@k. Ключевой инструмент — CrossEncoder, который ранжирует кандидатов и повышает точность топ-3 до 78%. Валидация выполняется заказчиком на его данных.
Как мы обеспечиваем безопасность корпоративных данных?
Критическая деталь enterprise-поиска — пользователь должен видеть только те документы, к которым у него есть доступ. Реализуется через metadata-фильтры в Qdrant:
# При поиске фильтруем по правам пользователя
results = qdrant.search(
collection_name="enterprise_docs",
query_vector=query_emb,
query_filter=Filter(
must=[
FieldCondition(
key="allowed_groups",
match=MatchAny(any=user_groups)
)
]
),
limit=20
)
Пример настройки прав доступа
ACL настраивается через метаданные документа: groups, roles, permissions. Векторная база Qdrant поддерживает filtering на уровне точек (documents), что гарантирует безопасность.Процесс работы
- Аналитика и аудит источников: выявляем, где хранятся данные, оцениваем объём и частоту изменений.
- Проектирование архитектуры: выбираем модель эмбеддингов, векторную БД, настраиваем пайплайн.
- Индексация данных: подключаем коннекторы, проводим пробную индексацию на 10% данных.
- Настройка поиска и реранжирования: оптимизируем параметры RRF, подбираем пороги для CrossEncoder.
- Интеграция UI и ботов: встраиваем поиск в веб-интерфейс, Slack-бота, API.
- Тестирование и отладка: проверяем на реальных запросах сотрудников, итеративно улучшаем.
- Деплой и мониторинг: разворачиваем в production, настраиваем логи и метрики (latency p99, recall).
Что входит в работу
- Документация архитектуры и инструкции по эксплуатации.
- Настроенные коннекторы ко всем источникам.
- Веб-интерфейс поиска и интеграция с корпоративным мессенджером.
- Обучение команды (2-3 воркшопа).
- Гарантийная поддержка 3 месяца после запуска.
Сроки и стоимость
- Пилот (1-2 источника, ~50 000 документов): 4–6 недель.
- Полная система (5–8 источников + UI): 3–4 месяца.
- Настройка ACL: +2–3 недели.
Стоимость рассчитывается индивидуально после аудита. В среднем инвестиции окупаются за 6–12 месяцев за счёт сокращения времени на поиск. Закажите пилотный проект — первый этап займёт не больше 2 дней на анализ.
Почему выбирают нас
- 5+ лет на рынке AI-решений для enterprise.
- 20+ проектов по внедрению семантического поиска в компаниях от 200 до 5000 сотрудников.
- Гарантия SLA 99.9% и точности поиска не ниже 75% по вашим критериям.
- Сертифицированные инженеры по MLOps и NLP.
Свяжитесь с нами, чтобы получить консультацию по вашему проекту и предварительную оценку за 2 дня.







