Что такое конверсационный поиск?
Обычный поиск — 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 изменит работу с документами в вашей компании. Свяжитесь с нами для бесплатной оценки проекта.







