Невозможно получить число, которое никто не записал: OKF против векторной базы данных RAG.
Проверенный пакет OKF на основе базы знаний Bedrock с использованием векторной базы данных и статистики опросов: почему вычисленные показатели вообще невозможно получить.
Источники: You Can’t Retrieve a Number Nobody Wrote Down: OKF vs. Vector Databases for RAG Chatbots
У каждого проекта есть один и тот же этап, к которому он постоянно возвращается, и он заключается в следующем: собрать графики и извлечь прозу. Эта идея возникла в ходе общения с чат-ботом, который начал работу в обычном режиме. Дюжина документов CDC, включая описание опроса, справочник кодов, краткий отчет и PDF-файлы с описанием методологии, были загружены в базу знаний Bedrock в надежде, что обширный набор данных позволит получить качественные ответы.
Но этого не произошло. Причина кроется в самом распространенном недопонимании принципа генерации с использованием дополнительных данных: существует мнение, что чем больше документов, тем точнее ответы. Векторная база данных может возвращать только тот текст, который уже находится в ней. Для любого вопроса, на который ответ никогда не записывался, объем коллекции совершенно не имеет значения.
В этих двенадцати документах подробно описывались показатели диабета: что они означают, у кого брались ответы и как они кодируются. Ни в одном из них не было статистики, которую пользователь мог бы фактически запросить. Эти цифры рассчитываются на основе 29 522 строк данных опроса и отсутствуют ни в одном PDF-файле, поэтому никакие поиски их не выявят.
Это приводит к ещё более серьёзной ошибке. Люди считают, что как только тема упоминается в документах, RAG может ответить на любой вопрос по ней. На самом деле он может ответить только на те вопросы, чьи ответы приведены в отдельном абзаце. Всё, что требует расчётов, находится вне его возможностей.
Таким образом чат-бот был пересоздан. Изначально это было учебное приложение, объединяющее Amazon Bedrock Flow, AWS Amplify Gen 2 и Next.js, при пересоздании вместо поисковой системы был использован проверенный пакет в формате Open Knowledge Format (OKF). Для справедливого сравнения на тех же документах была также создана настоящая база знаний Bedrock, и обе версии тестировались напрямую по единственным важным критериям: верна ли ответ и насколько быстро он поступает?
После постановки ключевого вопроса база знаний выделила пять соответствующих переменных и точно указала ограничение: в документах отсутствуют фактически рассчитанные статистические данные. Она даже порекомендовала правильный метод анализа — взвешенное соотношение людей с одним признаком, у которых также присутствует другой, что именно и выполняется системой OKF во время сборки, но с ошибками, поскольку сама система не может этого сделать. Всё сводится к одному предложению: невозможно получить число, которое никто не записал. Сторона OKF ответила цифрой, рассчитанной на основе микроданных с учетом правильного определения контингента и соответствующих весов.
Как был организован тест
Конфигурация была специально симметричной. Claude Sonnet 4.5 генерировал ответы с обеих сторон, в регионе us-east-1, с использованием транспортного механизма SDK внутри процесса и идентичного системного промпта, используемого развернутым Lambda. Метод был описан ещё до получения каких-либо результатов; задокументированы все семь вопросов и каждая попытка ответа, причем сохраняются необработанные ответы. Важно учитывать фактор времени: инструментарий напрямую вызывает функции получения данных и Bedrock, тогда как реальное приложение сначала направляет запросы через AppSync и Lambda. Код OKF, находящийся на тестировании, — это реальный код приложения, а транспортный механизм — нет; поэтому сравнение времени выполнения относится к двум разным реализациям, измеренным одинаковым способом, и не отражает реальное время работы для пользователя в браузере.
Замена: один Lambda
Чат-бот Amplify предоставляет инструменты в виде данных Amplify; каждый из них представляет собой функцию Lambda, работающую на основе запросов GraphQL, и Bedrock Flow был одним из таких инструментов. Поэтому изменение касается второго инструмента — askOkf, который отвечает из проверенного пакета вместо Flow. Схема, фронтенд и процесс развертывания остаются прежними.
// amplify/functions/askOkf/handler.ts — the essence
export const handler: Schema["askOkf"]["functionHandler"] = async (event) => {
// in-process TF-IDF over the bundle
const hits = search(event.arguments.question, 3);
const top = hits[0];
// Grounded-or-refuse: below the score floor,
// nothing verified matches → refuse
// before ever calling the model.
if (!top || top.score < MIN_SCORE) {
return { answer: refusal().text, citation: "", grounded: false, mode };
}
// read the verified figure straight from frontmatter
if (mode === "extractive") {
// 0 model calls - sub-millisecond
const a = extractiveAnswer(hits);
return { answer: a.text, citation: a.citations[0] ?? "", grounded: true, mode };
}
// generative: ground Claude on the ONE retrieved concept,
// safety-prompted grounded-or-refuse
const concept = top.concept;
const context = `Concept: ${concept.label}\nSource: ${conceptSource(concept.frontmatter)}\n\n${concept.text}`;
const response = await bedrock.send(
new ConverseCommand({
modelId: env.MODEL_ID,
// grounded-or-refuse; declines medical-advice intent
system: [{ text: SYSTEM_PROMPT }],
messages: [{ role: "user", content: [{ text: `Verified concept:\n${context}\n\nQuestion: ${question}` }] }],
inferenceConfig: { maxTokens: 400, temperature: 0 },
})
);
const text = response.output?.message?.content?.[0]?.text ?? "";
return { answer: `${text}\n\nSource: ${citation}`, grounded: true, mode };
};
Внутри обработчика функция search() сканирует четыре проверенных файла в формате Markdown, входящих в состав пакета Lambda. В процессе не используется никакая векторная база данных, никакие сервисы генерации эмбеддингов, а также не происходит никаких сетевых запросов. Учитываются только те данные, которые выдержали проверку, то есть те, по которым был проведен анализ и проверка результата. Заманчиво неверный показатель — невзвешенная ставка инсулина для всей выборки в размере 3,66% — отсутствует во всех этих файлах, поэтому его невозможно предоставить.
Для выполнения задачи используются два пути, и база тестирования оценивает оба из них. В экстрактивном пути данные из проверенных источников считываются из раздела frontmatter без каких-либо вызовов моделей. В генеративном пути производится один вызов функции Converse.
Базовая версия: настоящий векторный RAG
Противник должен был быть сильным. Речь идет о настроенной базе знаний Bedrock на S3 Vectors, содержащей настоящие материалы CDC 2023 NHIS: описание опроса, кодовый справочник для взрослых, отчеты об обзоре и методологии, техническую записку по импутации и инструкцию README для парных весов. Способный инженер построил бы именно такую систему. Поскольку модель идентична, единственной переменной остается место происхождения ответа — хранилище векторов или проверенный пакет внутри функции.
Было загружено тринадцать файлов, и десять из них были индексированы. Все три сбоя касались архивов формата .zip, которые Bedrock отклоняет, причем это были именно необработанные микроданные. Кажется, что это создаёт лазейку, позволяющую спасти векторную базу данных, но на самом деле это не так. Все документы, описывающие переменные диабета, были индексированы без проблем. Отсутствуют необработанные строки, и поиск среди них в любом случае не мог бы дать эти показатели, поскольку процент, рассчитанный с учётом весов опроса для 29 522 записей с использованием шаблона пропусков, представляет собой вычисление, а не отрывок текста. Невозможно добраться до результата путём его разбиения на части.
Ещё одно честное замечание: векторные решения оказались дешёвым вариантом. На подготовку дюжины документов и базы знаний ушли минуты. Работа с OKF требовала реальных усилий: необходимо было сформулировать концепции и провести анализ микроданных для проверки каждой цифры. Считать, что высокая скорость поиска означает гарантированную точность, — это собственное заблуждение. Дешёвое решение и высокая точность — это разные проблемы, и именно простота использования является причиной сохранения векторной базы данных, а не её устранения.
Точность
Набор вопросов включал три вопроса с числовыми ответами, уже проверенными на точность, три тестовых вопроса и один вопрос о методологии. Оценки присуждались по заранее утверждённой шкале: по 30 попыток на каждый числовой вопрос и по 2 на каждый тестовый вопрос; все результаты фиксировались. При решении всех трёх числовых вопросов векторная система RAG не смогла в任何 одной из попыток дать верный ответ.
Задержка
При решении задач с 30 попытками каждая (предварительные запуски — это попытки с 2 по 30) было установлено, что генеративный путь OKF работает в 1,4–2,4 раза быстрее, поскольку он исключает шаг поиска в сети и использует гораздо меньший контекст. Экстрактивный путь работает практически мгновенно, так как модель вообще не вызывается. Следует обращать внимание на диапазон значений, а не на среднее значение: разница наибольшая для инсулина — около 2,4 раза, а наименьшая — для возраста — около 1,4 раза; в этом случае значения почти совпадают, поэтому строки с данными по отдельным задачам представляют собой конечный результат, а не единый общий коэффициент. В любом случае скорость не является ключевым критерием. Время работы базы знаний — 3,3–3,7 секунды, что считается приемлемым, причем она уступает по точности, а не по времени.
Результаты исследования: поиск против обработки
Во всех испытаниях векторный RAG не смог предоставить ни одной из проверенных цифр, и плохая инженерная реализация здесь не является причиной. Эти числа просто отсутствуют в документах. Значение 31,96%, полученное с учетом результатов опросов, рассчитано на основе микроданных с использованием правильной выборки и весов, но оно отсутствует ни в одном PDF-файле. Система поиска может возвращать только уже существующий текст. OKF может дать ответ, поскольку цифра была рассчитана и проверена заранее, тогда как в базе знаний нет ничего, что можно было бы извлечь.
Обратите внимание, почему база знаний терпит неудачу: она говорит, что не может найти процент в документах, и не выдумывает числа. Это честно, и это делает аргумент еще более убедительным. Даже хорошо настроенный и правильно построенный векторный RAG по своей структуре не способен ответить на вопросы, связанные с расчетными статистическими данными, содержащимися в документации.
Здесь существуют еще два заблуждения.
- Фиксация на реальных данных не гарантирует точности. Эта база знаний отказывается предоставлять ложные данные, но это связано с хорошими стандартными настройками, а не с особенностями самого метода RAG. Если использовать более активную модель или документ-краткое изложение, в котором случайно присутствует частота вхождения без учета весов, это может привести к предоставлению уверенно неверного числа.
- Цитата мало что доказывает. Ссылка на источник указывает лишь на то, что документ был загружен, но не на то, что ответ выведен из него. Цитата в формате OKF — это что-то другое, поскольку она указывает на конкретную цифру, рассчитанную на основе данных и проверенную во время сборки, а не на текст, находящийся рядом с похожим предложением.
Лучшие подсказки и дополнительные фрагменты текста не помогут решить эту проблему. Решение заключается в том, чтобы прекратить получение этих чисел и не использовать их в дальнейшем.
Ограничения и компромиссы OKF
OKF не является универсальным движком поиска ответов, и тесты показывают, на чем он останавливается.
Он отвечает на вопрос «сколько», а не «почему». Что касается качественного вопроса о том, как взвешивание опроса влияет на распространённость, вектор RAG дал подробный и обоснованный ответ, взятый непосредственно из описания опроса, тогда как набор OKF из четырёх концепций мог предложить лишь связанную с этим цифру. Набор проверенных данных точен в отношении вычисленной статистики, но молчалив по поводу описательной информации. Это граница, а не недостаток, и она напрямую указывает на архитектуру ниже.
Быстрота означает отсутствие оценок. Метод извлечения данных отвечает менее чем за миллисекунду, но при запросе медицинских советов он просто возвращает значение "31,96%", поскольку не может понять, чего именно хочет пользователь. Метод генерации отказывается давать советы и предоставляет статистические данные с явным предупреждением о том, что они ничего не говорят о ситуации конкретного человека. Такая способность к различению требует дополнительных вычислений, занимающих около двух секунд. Считайте метод мгновенного ответа и метод, учитывающий намерение пользователя, отдельными инструментами и отчитывайтесь о обоих без их слияния.
Дополнение: третий инструмент
Эти ограничения приводят к одному выводу. OKF обеспечивает проверенный слой данных, а векторная база данных хорошо справляется с качественным, повествовательным уровнем информации, до которого OKF не может достучаться. Разумный подход заключается в использовании обоих инструментов как отдельных средств, из которых агент может выбирать.
Агент, основанный на фактах, уже использует два инструмента в этом духе: оба они проверены, работают в реальном времени и ограничены агрегатами — поиск концепций (search_okf) и запрос к агрегатам из списка разрешенных (analyze_rows). Каждый из них возвращает только то, что может подтвердить. База знаний Bedrock становится третьим инструментом, явно обозначенным как непроверенный текст. Затем агент предлагает проверенные цифры при вопросах о числах, основанный на фактах текст для объяснений и отказ, когда ни то, ни другое не применимо, при этом он тщательно разделяет эти три элемента.
Такое разделение также является рациональным использованием усилий: несколько минут на работу с базой знаний, несколько часов — на обработку проверенных данных. Получайте тексты дешево и вкладывайте усилия только там, где цифры должны быть точными: не компилируйте то, что можно бесплатно получить путем поиска, и не ищите то, что требует проверки.
Предварительный просмотр связанного результата
Если объединить четыре функции в одного агента (проверка, вычисления, получение данных и работа в реальном времени), возникает естественный вопрос: сохраняют ли более крупные модели порядок между этими функциями? Трем моделям показали поддельный заголовок новости с вымышленной статистикой, и все три из девяти проб воспроизвели это число, назвав его непроверенным утверждением третьей стороны. Однако информация о здоровье, созданная специально, всё равно доходила до читателя. Только проверка происхождения данных, реализованная в коде, смогла этому помешать во всех девяти случаях. Выбранная модель не оказала никакого влияния на уровень безопасности.
Это меняет восприятие данного критерия оценки. Проверенный набор данных предоставляет правильное число, что уже составляет половину задачи. Вторая половина заключается в том, чтобы не допустить распространения неверных данных под одинаковым обозначением, и это зависит от кода, а не от модели.
Работа в реальном времени и независимая проверка
Ничто из этого не осталось на ноутбуке. Функция askOkf была запущена в реальной среде Amplify (Cognito, AppSync, Lambda) и ответила: «В настоящее время 31,96% людей принимают инсулин», приведя соответствующую цитату, при этом отклонив вопрос о медицинских рекомендациях, действуя под подлинной ролью IAM. До этого независимая группа по безопасности проанализировала исходный код и сообщила, что условия выполнены (contract-satisfied): запрос требует аутентификации, разрешение bedrock:InvokeModel имеет принцип минимальных привилегий и ограничено одной моделью, внедрять что-либо невозможно, а каждый запрос ограничен одним вызовом модели.
Примечание по моделям: Bedrock только что отнес Claude 3 Sonnet к категории устаревших моделей, поэтому как OKF Lambda, так и тестовая среда используют Claude Sonnet 4.5. Именно идентичность моделей с обеих сторон обеспечивает справедливость сравнения.
Вывод
База данных векторов — это оптимальный выбор для решения открытых, качественных вопросов. Когда чат-боту необходимо указать конкретное число, такое как уровень распространенности, показатель KPI, сумма дохода или порог соответствия стандартам, использование методов поиска является неправильным подходом, поскольку надежная версия этого числа была рассчитана, но никогда не записана в прозе. Технология RAG либо пропустит его, что честно, либо выдумает его, что недопустимо. OKF рассчитывает число, проверяет его по исходным данным при создании и передает его: четыре файла в формате Markdown в Lambda, ничего не нужно настраивать, и это доступно во всех тестовых версиях.
Проблемой не было количество документов — проблемой было отсутствие числа, и дальнейшее пополнение базы данных не поможет его получить. Составьте собственные цифры.