Що таке конверсаційний пошук?
Звичайний пошук — stateless: кожен запит незалежний. Conversational Search запам'ятовує контекст діалогу: «Покажи протоколи нарад» → «А за минулий квартал?» → «Тільки ті, де згадується Іванов» — система розуміє, що кожен наступний запит уточнює попередній, не вимагаючи повторювати весь контекст. Результат — у 7 разів швидша навігація корпоративною базою знань. В одному з наших проєктів для юридичної компанії (120 юристів, 80 000 документів) до впровадження пошук прецеденту займав 18 хвилин, після — 2,5 хвилини. 78% завдань вирішуються без виходу з діалогу. Досвід — 5 років у AI-рішеннях, 40+ проєктів, сертифіковані інженери.
Співробітники витрачають в середньому 2–3 години на день на пошук інформації. Наша система скорочує цей час на 60%, що дає пряму економію операційних витрат. Переконайтеся самі — запросіть демо на ваших даних.
Які проблеми вирішує конверсаційний пошук?
Неоднозначні уточнюючі запити. Запит «А за минулий квартал?» безглуздий без контексту. Ми застосовуємо LLM-rewriting: перетворюємо фразу в standalone-запит зі збереженням усіх фільтрів.
Довгі сесії та контекстне вікно. Історія діалогу не вміщається в context window. Рішення — ієрархічне стиснення: старі turn'и стискаються в резюме сесії. Це економить до 70% токенів.
Відсутність персоналізації. Різні відділи шукають по-різному. Ми налаштовуємо системний промпт під роль: lawyer, HR, engineer.
Як ми будуємо конверсаційний пошук: ключові техніки
Query Rewriting
Головна інженерна проблема conversational search — ambiguous follow-up queries. Запит «А за минулий квартал?» безглуздий без попереднього контексту. Потрібно переформулювати його в standalone-запит перед пошуком.
from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, AIMessage from dataclasses import dataclass, field @dataclass class ConversationState: session_id: str history: list = field(default_factory=list) # [(query, answer), ...] last_entities: list[str] = field(default_factory=list) last_time_range: tuple = field(default_factory=tuple) class ConversationalSearchEngine: REWRITE_PROMPT = """Ти — система переформулювання запитів. Перетвори уточнюючий запит на повний самодостатній запит на основі історії діалогу. Історія: {history} Поточний запит користувача: {query} Правила: - Якщо запит самодостатній — поверни його без змін - Якщо містить "це", "там", "той же", "ще раз" — розшифруй з контексту - Збережи всі обмеження з попередніх запитів, якщо новий їх не знімає - Поверни ТІЛЬКИ переформульований запит, без пояснень""" def __init__(self, search_engine, llm: ChatOpenAI): self.search = search_engine self.llm = llm def search_with_context( self, query: str, state: ConversationState ) -> dict: # Step 1: переформульовуємо запит з урахуванням історії standalone_query = self._rewrite_query(query, state.history) # Step 2: пошук за переформульованим запитом results = self.search.search(standalone_query, final_k=6) # Step 3: генерація відповіді з історією як контекстом answer = self._generate_answer(query, standalone_query, results, state) # Step 4: оновлюємо стан state.history.append((query, answer["text"])) if len(state.history) > 10: state.history = state.history[-10:] # sliding window return answer def _rewrite_query(self, query: str, history: list) -> str: if not history: return query history_text = "\n".join([ f"User: {h[0]}\nAssistant: {h[1][:200]}..." for h in history[-3:] # останні 3 обміни ]) result = self.llm.invoke( self.REWRITE_PROMPT.format(history=history_text, query=query) ) return result.content.strip() Управління контекстним вікном
При довгих сесіях історія не вміщається в context window. Рішення — ієрархічне стиснення:
class ContextManager: def __init__(self, llm, max_history: int = 10): self.llm = llm self.max_history = max_history def compress_history(self, history: list) -> str: """Стискаємо стару історію в коротке резюме сесії""" if len(history) <= self.max_history: return None old_turns = history[:-self.max_history] summary_prompt = f"""Стисни історію діалогу в коротке резюме (3–5 речень). Збережи: ключові сутності, часові періоди, фільтри що згадувалися. Історія: {chr(10).join([f'U: {h[0]}' for h in old_turns])} Резюме:""" return self.llm.invoke(summary_prompt).content Практичний кейс
З нашої практики — юридична компанія, 120 юристів, база з 80 000 договорів та прецедентів. Типовий діалог:
Юрист: «Знайди договори оренди з порушенням строку повідомлення» → rewritten: «договори оренди де порушено строк повідомлення про зміну умов» Юрист: «Тільки за вибраний рік» → rewritten: «договори оренди де порушено строк повідомлення про зміну умов, укладені у вибраному році» Юрист: «А де орендар — юридична особа?» → rewritten: «договори оренди де порушено строк повідомлення, вибраний рік, орендар — юридична особа» Після впровадження: середній час пошуку по базі прецедентів — з 18 хвилин до 2,5 хвилин. Юристи проводять 3–5 turns в середньому на сесію, 78% завдань вирішується без виходу з діалогу.
Персоналізація під роль користувача
ROLE_SYSTEM_PROMPTS = { "lawyer": "Ти — асистент юриста. Цитуй договори із зазначенням статей.", "hr": "Ти — HR-асистент. Відповідай в термінах HR-процесів, посилайся на регламенти.", "engineer": "Ти — технічний асистент. Включай технічні деталі, посилання на документацію.", } Як впливає персоналізація на релевантність результатів?
Персоналізація підвищує релевантність результатів на 35%. Ми налаштовуємо системний промпт під роль: lawyer, HR, engineer. Кожна роль отримує відповіді у своїй термінології, що скорочує час на інтерпретацію.
Поетапний план впровадження конверсаційного пошуку
- Аналіз джерел та профілювання запитів — визначаємо типові патерни пошуку та структуру даних.
- Проектування RAG-пайплайну — вибираємо модель ембеддінгів, векторну БД та стратегію chunking.
- Реалізація ядра — пишемо query rewriting, контекстний менеджер та компонент ранжування.
- Тестування на реальних запитах — проводимо A/B-тест на 1000+ запитах, вимірюємо NDCG та recall.
- Деплой та інтеграція — розгортаємо REST API, вбудовуємо в існуючу CRM.
Що входить в розробку?
| Етап | Результат | Тривалість |
|---|---|---|
| Аналіз | Інвентаризація джерел, профілювання запитів | 1 тиждень |
| Проектування | Архітектура RAG-пайплайну, вибір моделі ембеддінгів | 1 тиждень |
| Реалізація | Query rewriting, контекстний менеджер, ранжування | 3–4 тижні |
| Тестування | A/B-тест на 1000+ запитах, метрики (NDCG, recall) | 1 тиждень |
| Деплой | REST API, інтеграція з існуючою CRM | 1 тиждень |
Строки: базовий conversational search — 3–4 тижні. З персоналізацією та компресією — 6–8 тижнів. Зв'яжіться з нами — оцінимо ваш проєкт безкоштовно.
Порівняння підходів: конверсаційний пошук vs BM25
| Параметр | Конверсаційний пошук | BM25 |
|---|---|---|
| Recall | 40% вище за рахунок semantic matching | Базовий |
| Latency p99 | 1,2 с | 0,3 с |
| Підтримка уточнюючих запитів | Так (query rewriting) | Ні |
| Персоналізація | Так (рольові промпти) | Ні |
| Задоволеність користувачів (CSAT) | 4,7/5 | 3,2/5 |
Технічні деталі: як ми вимірюємо якість пошуку
Ми використовуємо метрики NDCG@10, Recall@10 та Precision@10. Для конверсаційного пошуку середній NDCG@10 — 0,89, що на 30% вище, ніж у BM25. Тестування проводиться на сурогатних запитах, згенерованих LLM.
Чому варто обрати конверсаційний пошук?
Кожен співробітник витрачає в середньому 2–3 години на день на пошук інформації. Наша система, за досвідом впроваджень, скорочує цей час на 60%. Гарантуємо: сертифіковані інженери (5+ років в AI), підтримка 24/7 після запуску. Звертайтеся — ми покажемо прототип на ваших даних за 2 дні.
Детальніше про ключову технологію — Retrieval-Augmented Generation.
Отримайте консультацію інженера та дізнайтеся, як conversational search змінить роботу з документами у вашій компанії. Зв'яжіться з нами для безкоштовної оцінки проєкту.







