Практические замечания: Часть II — Когда RAG не возвращает ничего
Пошаговое руководство по практическим заметкам: Часть II — когда RAG не возвращает ничего: контракты, проверки и слоты для вставки кода для команд, использующих эту схему.
Используйте это как переработанную версию идей из раздела «Часть II — Когда RAG не возвращает данных» для операторов: четкие этапы, упорядоченные блоки кода и записи о восстановлении, сохраняющиеся при передаче задач.
Как отлаживать и устранять проблему пустых результатов поиска в системах ИИ
Метод отладки работает наилучшим образом, если рассматривать его как измеримую структуру. Сначала соберите один эталонный пример, один случай сбоя и записи о возврате к предыдущему состоянию, прежде чем расширять объем работ. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, которое операторы могут проверять, не читая весь код. Разделяйте политику разбиения данных на части и политику поиска. Изменение одной из них не должно приводить к переписыванию другой при изменении показателей качества.
1. Начните с индексации и эмбеддингов
Этап «1. Начало с индексации» работает наилучшим образом, если рассматривать его как измеримую характеристику. Соберите один идеальный пример обработки данных, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Документируйте одновременно успешный и восстановительный сценарии работы. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не этапом последующей доработки. Разделяйте политику разбиения данных на части и политику их извлечения; изменение одной не должно приводить к переписыванию другой при смене показателей качества.
2. Проверка пороговых значений, семантики оценок и фильтров
Этап оценки двух порогов проверки работает наилучшим образом, если рассматриваться как измеримая величина. Соберите один идеальный пример выполнения, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объема работ. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. Когда какой-либо шаг срабатывает некорректно, причина сбоя должна указывать на конкретную ответственность, а не на запутанную цепочку операций. Разделяйте политику разбиения данных на части и политику их извлечения. Изменение одной из них не должно приводить к переписыванию другой при изменении показателей качества.
results = vector_store.search(query_embedding, top_k=10)
for r in results:
print(r.score, r.metadata.get('source'))
3. Переписывание запросов и качество частей данных
Этап переписывания запросов с использованием трёх проверок работает наилучшим образом, если рассматривать его как измеримую структуру. Соберите один идеальный пример выполнения, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия соответствующим документам, определите критерии успешного выполнения и не соглашайтесь на молчаливое частичное завершение работы. Разделяйте политику разбиения данных на части и политику их поиска. Изменение одной из них не должно принуждать к переписыванию другой при изменении показателей качества.
4. Использование гибридного поиска для улучшения точности воспроизведения
Этап гибридного поиска «4 Use» работает наилучшим образом, когда его рассматривают как измеримую характеристику. Соберите один идеальный пример обработки запроса, один случай сбоя и запись о возврате к предыдущему состоянию до расширения объёма работ. Записывайте временные показатели, а также стоимость токенов или запросов рядом с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные счёты при переходе от демо-среды к общедоступным средам. Разделяйте политику разбиения данных на части и политику поиска. Изменение одной из них не должно приводить к переписыванию другой при изменении показателей качества. Этап гибридного поиска «4 Use» работает наилучшим образом, когда его рассматривают как измеримую характеристику. Соберите один идеальный пример обработки запроса, один случай сбоя и запись о возврате к предыдущему состоянию до расширения объёма работ. Документируйте одновременно успешный и восстановительный пути обработки запросов. Попытки повторной обработки, проверка человеком и обработка неработоспособных сообщений являются частью продукта, а не этапами последующей доработки.
5. Проводить широкий поиск, затем переориентировать результаты
На этапе «5. Получение данных в широком формате» необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг, исходя из известной точки контроля, без необходимости угадывать скрытое состояние. Лучше использовать небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага причина должна быть связана с конкретной функцией, а не с запутанной структурой обработки данных. Указывайте те части текста, на которых основан ответ. Без цитат операторы не смогут отличить вымысел от проблем с индексацией.
6. Расширение запроса и создание явного пути резервного варианта
На этапе 6 «Расширение запроса» необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Рассматривайте этот этап как контракт между входными данными и проверенными результатами. Дайте названия создаваемым элементам, определите критерии успеха и не допускайте молчаливого частичного завершения работы. Указывайте те фрагменты текста, которые легли в основу ответа. Без цитат операторы не смогут отличить галлюцинации от пробелов в индексации.
docs = retrieve(query)
if not useful(docs): docs = retrieve(expand(query), hybrid=True)
if not useful(docs): return ask_for_clarification_or_no_answer()
7. Более устойчивая архитектура производства
На этапе 7 A More Resilient необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Записывайте время выполнения и стоимость токенов или запросов рядом с функциональными результатами. Отображение стоимости заранее предотвращает неожиданные счета при переходе с демо-среды в общедоступные среды. Указывайте конкретные фрагменты текста, на которых основан ответ. Без цитат операторы не смогут отличить галлюцинации от пробелов в индексации. На этапе 7 A More Resilient необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Документируйте одновременно успешный сценарий работы и сценарий восстановления. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.
8. Сделать процесс получения данных видимым
При работе над этапом «Сделать процесс получения данных видимым» сначала запишите условия работы: необходимые входные данные, сигнал о успехе и последствия частичной неудачи. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Предпочитайте небольшие, тестируемые модули большим скриптам. Если какой-то шаг не сработает, причина должна быть связана с конкретной функцией, а не с запутанной цепочкой операций. Оцените уровень воспроизведения ответов на фиксированном наборе вопросов перед настройкой подсказок. Частая смена подсказок редко помогает улучшить качество получения данных.
log({
'query': query, 'rewritten': rewritten_query, 'filters': filters,
'candidate_count': len(raw_results), 'scores': scores,
'selected_chunk_ids': selected_ids, 'fallback': fallback_stage
})
Чек-лист операционной деятельности
При работе над этапом чек-листа операционной деятельности сначала запишите условия работы: необходимые входные данные, сигнал о успехе и последствия частичной неудачи. Такой чек-лист поможет сохранять честность при последующих изменениях кода.
Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код.
Измеряйте показатель воспроизводимости на фиксированном наборе вопросов перед настройкой подсказок. Частая смена подсказок редко помогает улучшить слабую систему поиска.
Фиксируйте версии зависимостей и записывайте хэш изображения, использованного для демонстрации. Воспроизводимость важнее коллективного опыта.
Документируйте как успешный, так и восстановительный сценарии работы. Повторные попытки, проверка человеком и обработка неработающих сообщений являются частью продукта, а не последующими улучшениями.
Измеряйте показатель воспроизводимости на фиксированном наборе вопросов перед настройкой подсказок. Частая смена подсказок редко помогает улучшить слабую систему поиска.
Перед внедрением стека заморозьте версии, сделайте копию «золотого» отчета для критической цепочки операций и уточните шаги возврата к предыдущему состоянию. В совместных средах необходимы ограничения на частоту запросов, проверки принадлежности пользователя и четко определенный ответственный за обновление секретов. Лучше выбирать надежность, даже если она кажется скучной, чем умные одноразовые демонстрации.
Примечание для 429668e62b58: не храните ключи поставщика в репозитории, установите лимит токенов на одну сессию и сохраняйте отчеты рядом с фикстчерами для оценки, чтобы последующие замены моделей можно было сравнивать.
Для этапа 0 по усилению безопасности определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Храните конфигурацию вне кода приложения: файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, которое операторы могут проверять, не читая весь граф составляющих.
Деталь усиления безопасности 0/735: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменение на основе фиксированного набора вопросов, а не на основе единичных примеров.
При работе над первым этапом записи по усилению безопасности сначала запишите контракт: необходимые входные данные, сигнал успешного выполнения и что происходит при частичной неудаче. Такой чек-лист помогает сохранять честность последующих изменений в коде. Предпочитайте небольшие, проверяемые единицы кода вместо обширных скриптов. Когда какой-то шаг терпит неудачу, причина должна указывать на конкретную ответственность, а не на запутанную цепочку операций.
Деталь усиления безопасности 1/735: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменение на основе фиксированного набора вопросов, а не на основе единичных примеров.
Этап 2 процедуры усиления безопасности работает наилучшим образом, если рассматривать его как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Записывайте время выполнения операций, стоимость токенов или запросов вместе с функциональными результатами. Отслеживание затрат на раннем этапе помогает избежать неожиданных счетов при переходе от демо-среды к общедоступным средам.
Подробности усиления безопасности 2/735: измерьте время выполнения операций, класс ошибок и расход токенов для данной записи, затем решите, следует ли сохранять изменения, опираясь на установленный набор критериев, а не на единичные примеры.