AI-система федеративного пошуку за кількома джерелами

Уявіть: оператор кол-центру обробляє запит клієнта і змушений перемикатися між Confluence, Jira, SharePoint та Outlook, щоб зібрати інформацію. У корпоративному контексті дані розмазані по десятках систем: Confluence для документації, Jira для задач, SharePoint для файлів, корпоративна пошта, CRM, з

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1440
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1264
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1002

Уявіть: оператор кол-центру обробляє запит клієнта і змушений перемикатися між Confluence, Jira, SharePoint та Outlook, щоб зібрати інформацію. У корпоративному контексті дані розмазані по десятках систем: Confluence для документації, Jira для задач, SharePoint для файлів, корпоративна пошта, CRM, зовнішні бази — і кожна потребує свого інтерфейсу пошуку. Співробітник витрачає до 40% часу на пошук та перемикання між системами. Федеративний пошук з єдиним пошуковим рядком та ранжуванням результатів скорочує цей час у 2-3 рази. Ми проектуємо та впроваджуємо такі системи під ключ: від аналізу вимог до деплою на інфраструктуру клієнта. Наш досвід — понад 5 років в AI/ML, 15+ реалізованих проектів федеративного пошуку. Гарантуємо SLA за latency (p99 < 1 сек) та якістю результатів (NDCG@10 > 0.85).

Чому федеративний пошук складніший за звичайний пошук?

Причина — неоднорідність джерел. BM25-скор з Elasticsearch непорівнянний з векторною близькістю з Qdrant. Різний час відповіді: Confluence може відповісти за 100 мс, а зовнішній API — за 2 секунди. Потрібна асинхронна архітектура з таймаутами, нормалізація скорів, дедуплікація та ранжування. Все це — нетривіальні завдання MLOps.

Як працює гібридна архітектура?

У більшості enterprise-проектів використовуємо гібридний підхід: Confluence, SharePoint, Jira — через централізований індекс, зовнішні API та realtime-дані — через query-time federation.

Підхід Latency Актуальність даних Складність Підходить для
Централізований індекс 100–500 мс Затримка ~15–60 хв Висока (ETL) Великі обсяги, корпоративний пошук
Query-time federation 1–5 сек Realtime Середня API-джерела, малі обсяги
Гібридний 300–800 мс Критичне — realtime Висока Enterprise з різними вимогами

Гібридна архітектура забезпечує latency 300-800 мс, що в 2-5 разів швидше за pure query-time федерацію.

import asyncio from typing import Protocol, runtime_checkable from dataclasses import dataclass @dataclass class SearchResult: source: str doc_id: str title: str snippet: str url: str score: float metadata: dict @runtime_checkable class SearchConnector(Protocol): async def search(self, query: str, filters: dict, limit: int) -> list[SearchResult]: ... class FederatedSearchOrchestrator: def __init__(self, connectors: dict[str, SearchConnector]): self.connectors = connectors self.merger = ResultMerger() async def search( self, query: str, sources: list[str] = None, filters: dict = None, limit: int = 10 ) -> list[SearchResult]: active_connectors = { name: conn for name, conn in self.connectors.items() if sources is None or name in sources } # Паралельний запит до всіх джерел з таймаутом tasks = { name: asyncio.create_task( asyncio.wait_for( conn.search(query, filters or {}, limit * 2), timeout=3.0 # не чекаємо повільні джерела довше 3 сек ) ) for name, conn in active_connectors.items() } results_by_source = {} for name, task in tasks.items(): try: results_by_source[name] = await task except asyncio.TimeoutError: results_by_source[name] = [] # джерело не відповіло except Exception as e: results_by_source[name] = [] return self.merger.merge_and_rank(results_by_source, limit) 

Як виконується дедуплікація та переранжування?

Головна технічна проблема федеративного пошуку — нормалізація скорів з різних джерел. BM25-скор з Elasticsearch непорівнянний з cosine similarity з Qdrant. Ми використовуємо CrossEncoder для фінального ранжування та косинусну близькість ембедингів для дедуплікації. Докладніше про CrossEncoder можна прочитати в документації.

from sentence_transformers import CrossEncoder import numpy as np class ResultMerger: def __init__(self): self.reranker = CrossEncoder( "cross-encoder/ms-marco-MiniLM-L-6-v2", max_length=512 ) def merge_and_rank( self, results_by_source: dict[str, list[SearchResult]], limit: int ) -> list[SearchResult]: all_results = [] for source, results in results_by_source.items(): all_results.extend(results) if not all_results: return [] # Дедуплікація за контентом (cosine similarity ембедингів) all_results = self._deduplicate(all_results, threshold=0.92) # Нормалізуємо скори всередині кожного джерела (min-max) for source in results_by_source: source_results = [r for r in all_results if r.source == source] if len(source_results) > 1: scores = [r.score for r in source_results] min_s, max_s = min(scores), max(scores) for r in source_results: r.score = (r.score - min_s) / (max_s - min_s + 1e-9) return sorted(all_results, key=lambda x: x.score, reverse=True)[:limit] 

Порівняння підходів до дедуплікації:

Метод Точність Швидкість Використання
Embedding cosine (CrossEncoder) 95% 10-50 мс на пару Фінальне ранжування
Косинусна близькість ембедингів 85% 1-5 мс Попередня дедуплікація
Текстове співпадіння (Shingles) 70% <1 мс Швидка фільтрація
Типові проблеми та їх вирішення
  • Різні швидкості відповіді джерел: таймаут 3 секунди для кожного, як у коді вище.
  • Дрейф скорів після оновлення індексу: вирішуємо перенавчанням нормалізації раз на місяць.
  • Відсутність ембедингів у деяких джерелах: використовуємо гібридний пошук + промпт для LLM.

Конектори під конкретні джерела

class ConfluenceConnector: async def search(self, query: str, filters: dict, limit: int) -> list[SearchResult]: # Гібридний пошук: vector store (Qdrant) для семантики # + Confluence REST API для актуальності vector_results = await self.vector_store.asimilarity_search(query, k=limit) return [self._to_result(r) for r in vector_results] class JiraConnector: async def search(self, query: str, filters: dict, limit: int) -> list[SearchResult]: # JQL з text search jql = f'text ~ "{query}" ORDER BY updated DESC' if filters.get("project"): jql = f'project = {filters["project"]} AND ' + jql issues = self.jira.search_issues(jql, maxResults=limit) return [self._issue_to_result(i) for i in issues] class EmailConnector: async def search(self, query: str, filters: dict, limit: int) -> list[SearchResult]: # Пошук через Microsoft Graph API або IMAP results = await self.graph_client.search_messages( query=query, top=limit, select=["subject", "bodyPreview", "from", "receivedDateTime"] ) return [self._email_to_result(r) for r in results] 

Кейс: страхова компанія, 600 співробітників. 6 джерел: SharePoint (180K документів), Jira, Outlook, внутрішня СЕД, база прецедентів, регуляторна база ЦБ (зовнішній API). До впровадження оператор КЦ перемикався між 4–5 вкладками при обробці запиту клієнта. Після — один пошуковий інтерфейс з результатами з усіх джерел. Середній час обробки запиту: 4,2 хв → 1,8 хв. Джерело «Регуляторна база» через query-time federation — latency 800 мс, що прийнятно для даного сценарію. Економія часу склала понад 100 годин на місяць на відділ, що дозволило скоротити штат на 2 FTE.

Персоналізація джерел за роллю

Різним ролям показуємо релевантні джерела за замовчуванням. Для маршрутизації запитів використовуємо LangChain Expression Language (LCEL), що спрощує конфігурацію правил.

ROLE_SOURCE_CONFIG = { "developer": ["jira", "confluence", "gitlab", "stackoverflow-internal"], "hr": ["confluence", "email", "hr-system", "orgchart"], "lawyer": ["contracts-db", "sharepoint", "email", "regulations"], "support": ["confluence", "jira", "email", "crm", "knowledge-base"], } 

Що входить у реалізацію

  • Прототип з 2–3 джерелами за 4–6 тижнів.
  • Архітектурна документація та специфікація API.
  • Розробка конекторів для кожного джерела.
  • Модуль дедуплікації та ранжування (CrossEncoder).
  • Панель моніторингу якості та latency (MLOps).
  • Навчання команди та 1 місяць підтримки після запуску.

Терміни: 2–3 джерела, пілот: 4–6 тижнів; повна федерація 6–8 джерел: 3–4 місяці. Вартість розраховується індивідуально, окупається за рахунок скорочення трудозатрат співробітників.

Як ми гарантуємо якість?

Використовуємо сертифіковані моделі (CrossEncoder на RoBERTa), проводимо A/B-тестування ранжування до деплою. Впроваджуємо моніторинг дрейфу якості ембедингів та автоматичний перерахунок нормалізації. Гарантуємо NDCG@10 не нижче 0.85 після налаштування.

Оцінимо ваш проект — зв'яжіться з нами для консультації. Замовте пілот за 4-6 тижнів, і ми покажемо, як федеративний пошук прискорює роботу ваших співробітників. Отримайте демо-доступ до працюючого прототипу.