Most teams build their first retrieval system the same way: slice every document into fixed 512-token chunks, push them into a vector database, and hope the embedding model does the hard work. That hope gets you through a demo. It does not survive contact with real users.
In production, a legal contract falls apart when you sever a liability clause from its exceptions. API documentation turns useless when a code sample gets detached from its function signature. A customer support thread becomes noise when you rip a single complaint out of its conversational history. The problem is rarely the language model sitting at the end of the pipeline. The problem is what you feed it.
We learned this the hard way. Our initial retrieval layer looked standard but behaved inconsistently. So we rebuilt it around a simple idea: treat retrieval as measured infrastructure, not magic. Here is exactly what changed, and how we pushed recall to 95 percent while cutting the 95th-percentile latency from 850 ms to 320 ms.
The Fixed-Chunk Trap
Uniform token counts are easy to code and easy to explain. That convenience masks a basic truth: documents have structure. When you ignore that structure, you destroy signal.
Consider a ten-page master service agreement. A fixed 512-token slice will land mid-obligation, splitting a clause from the very cap table that limits it. The retrieval step then returns half a thought. The generator hallucinates the rest. In API documentation, a chunk that is too large dilutes the embedding with boilerplate headers, burying the specific method a developer needs. In support tickets, a fixed window treats a conversation as a bag of sentences, stripping away the back-and-forth that reveals what actually failed.
We stopped treating chunk size as a hyperparameter we guessed. We started treating it as a mapping exercise between the document type and the information architecture inside it.
Match Your Chunking to the Data
The fix is not one perfect chunk size. The fix is three distinct strategies tuned to three distinct data shapes.
Legal documents now go through recursive splitting. The algorithm first looks for the largest natural boundaries—sections, then subsections, then numbered clauses—and only falls back to smaller splits when necessary. This keeps a termination clause attached to its survival conditions. The retrieval step sees complete logical units, which sharply reduces the model’s temptation to invent missing exceptions.
API and code documentation get structure-aware chunking. Markdown headers, code fences, and parameter tables are parsed as atomic units. We do not split inside a code block. We keep docstrings adjacent to their signatures. The result is that a query for a specific class method retrieves the full context a developer needs: the description, the typed parameters, and the working example.
Support and conversational data use semantic chunking. Instead of counting tokens, we look for shifts in topic or intent. If a customer describes a bug in message three and pastes a stack trace in message seven, we chunk by meaning, not by message index. The retrieval layer then returns the full arc of the problem rather than a orphaned sentence.
Why Vector Search Alone Fails
Even perfect chunks die in a pure vector search. Dense embeddings excel at capturing meaning and synonymy, but they are notoriously fuzzy on exact strings. If an engineer searches for the precise error code ERR_CONNECTION_REFUSED, vector similarity might return a dozen conceptual neighbors and miss the exact match buried at rank fourteen.
Keyword search with BM25 has the opposite problem. It finds exact tokens but misses semantic intent. A user asking “why is my database down” will never match a document that says “troubleshooting connection timeouts.”
We now run both. Vector and keyword results are fed into Reciprocal Rank Fusion, which blends the two ranked lists without requiring calibrated scores. The fused list is then passed through a cross-encoder reranker. The reranker is slower than the initial retrieval, but it is far more precise because it judges query-document relevance directly rather than through compressed embeddings. That hybrid pipeline alone lifted our recall by 15 percent.
Fixing Bad Queries Before They Hit the Index
Пользователи не пишут идеальные поисковые запросы. Они вставляют усеченные строки логов. Они пишут «всё сломалось». Они используют жаргон, который никогда не встречался в вашей документации. Если вы доверяете сырому запросу, вы доверяете шуму.
Теперь мы расширяем каждый входящий запрос до трех-пяти вариаций перед отправкой в слой поиска (retrieval layer). Одна вариация может быть прямым парафразом. Другая — гипотетическим идеальным заголовком документа. Третья — очищенной от разговорного мусора и содержащей только технические ключевые слова. Каждый вариант проходит эмбеддинг и поиск. Затем мы удаляем дубликаты и объединяем пулы кандидатов.
Это не бесплатно. Эти дополнительные вызовы эмбеддингов стоят денег и добавляют несколько миллисекунд. Но эффект на полноту поиска (recall) был колоссальным: мы перешли с 78% до 96%, расширяя запросы перед поиском. Поскольку более качественный поиск сужает окно генерации и дает модели правильный контекст, в конечном итоге мы сэкономили деньги на этапе генерации. Чуть более дорогой этап поиска обходится дешевле, чем долгий этап генерации с галлюцинациями.
Хватит гадать. Начните искать.
Когда мы внедрили правильное разбиение на чанки (chunking), гибридный поиск и расширение запросов, мы всё равно столкнулись с комбинаторным хаосом. Размер чанка, перекрытие чанков, глубина поиска top-k, пороги реранкера и веса слияния — всё это взаимосвязано. Ручной поиск по сетке (grid search) занял бы недели и всё равно привел бы нас к локальному максимуму.
Мы перешли к байесовской оптимизации для исследования этого пространства. Вместо того чтобы исчерпывающе тестировать каждую комбинацию, алгоритм поиска поддерживает «убеждение» о том, какие конфигурации с большой вероятностью покажут хороший результат, и постепенно сужает область поиска до наиболее перспективных регионов.
Результатом является не одна идеальная настройка, а фронт Парето из вариантов выбора. С одной стороны, у нас есть облегченная конфигурация, оптимизированная для нашего высокопроизводительного эндпоинта API поддержки: быстрый вывод, умеренная полнота поиска и минимально возможная задержка. С другой стороны, у нас есть агрессивная конфигурация для юридической экспертизы: более глубокий поиск, более тяжелый реранкинг и более плотное перекрытие чанков — мы жертвуем миллисекундами ради тщательности. Поскольку этот фронт явно определен, мы можем выбрать подходящую точку для конкретного продукта, а не пытаться найти решение, подходящее всем.
Как это выглядит в цифрах
Эти изменения превратили хрупкий прототип в измеримый производственный конвейер.
Полнота поиска (Recall at ten) выросла с 78% до 95%. Это означает, что если правильный ответ существует в нашем корпусе, мы находим его девятнадцать раз из двадцати.
Задержка (latency) на 95-м перцентиле снизилась с 850 мс до 320 мс. Гибридный стек на бумаге кажется более тяжеловесным, но более умное индексирование, компактные реранкеры и возможность выдавать агрессивные чанки только при необходимости сделали всю систему быстрее.
Уровень галлюцинаций — отслеживаемый людьми-аннотаторами на выделенном «золотом» наборе данных — упал с 12% до 3%. Когда модель получает полный и релевантный контекст, она перестает выдумывать факты.
Стоимость одного запроса снизилась с $0.008 до $0.005. Улучшенный поиск означает более короткие и сфокусированные промпты для LLM и меньше попыток исправления ошибок. Дополнительные затраты на эмбеддинги при расширении запросов нивелируются экономией на генерации.
Создайте «золотой» набор данных и относитесь к поиску как к коду
Если вы извлечете из этого один урок, то пусть это будет дисциплина измерений. Мы создали небольшой «золотой» набор данных из реальных вопросов и проверенных мест расположения ответов. Прежде чем любое изменение попадет в продакшн, оно проверяется на этом наборе данных. Полнота поиска и задержка отслеживаются в реальном времени, а не «на глаз» в ноутбуке.
Поиск — это не исследовательское демо. Это инфраструктура. Он заслуживает юнит-тестов, регрессионных бенчмарков и автоматической оптимизации, так же как и весь остальной ваш стек. Разбивайте на чанки по структуре документа, а не по суевериям относительно количества токенов. Сочетайте векторный и ключевой поиск с реранкером. Расширяйте запросы, которые на самом деле пишут ваши пользователи. А затем позвольте алгоритму поиска крутить настройки вместо вашей интуиции.
Описанный нами конвейер не является теоретическим. Вы можете прочитать оригинальный материал здесь, а если вы хотите обсудить инженерию поиска с сообществом, которому это не безразлично, группа GyaanSetu AI открыта для общения.
