DuckDB для локального аудита ИИ-выгрузки: пять запросов до отчёта
Модель подготовила отчёт по продажам, и график выглядит убедительно: выручка растёт, возвраты снижаются. Но до обсуждения выводов нужно ответить на более скучный вопрос: все ли заказы попали в файл и не посчитали ли одну строку дважды? DuckDB полезен как локальный проверочный слой. Он читает CSV и Parquet непосредственно из SQL-запроса, поэтому небольшую проверку можно выполнить на компьютере, не загружая весь набор в чат. Это не «нейросеть для аналитики» в привычном смысле. Это инструмент, который помогает установить, на каких данных вообще построен ответ нейросети.
Что проверяем на практике
Возьмём обезличенную таблицу заказов с полями order_id, order_date, shop_id, amount, status. ИИ сообщил месячную выручку и средний чек. Перед тем как доверять этому числу, запишите пять контрольных вопросов. Сколько в файле строк? Сколько уникальных заказов? Есть ли пустые даты и суммы? Как распределены статусы? Совпадает ли сумма утверждённых заказов с контрольной суммой исходной системы? Последний пункт важнее остальных: даже идеально написанный запрос к обрезанному файлу даст аккуратный, но неполный результат.
Установите официальный клиент DuckDB для своей системы и работайте с копией файла. В его командной строке можно обратиться к CSV через read_csv('orders.csv'). Сначала выполните SELECT count(*) FROM read_csv('orders.csv');. Это число сравнивают с количеством строк в экспортном журнале, а не с обещанием модели. Затем SELECT count(DISTINCT order_id) FROM read_csv('orders.csv');. Если значения расходятся, это повод искать повторные строки либо составной ключ: некоторые системы записывают несколько товаров в одном заказе, и одинаковый order_id там нормален. Не удаляйте «дубликаты» до понимания структуры.
Для пропусков полезен запрос с подсчётом amount IS NULL и order_date IS NULL. Но пустое поле может быть нулевой суммой, отменой или дефектом экспорта; SQL не знает бизнес-правила. Отдельно посчитайте количество записей по status и посмотрите на редкие значения. Если у части строк вместо «paid» написано «payed», отчёт мог отбросить их фильтром. Группировка по статусу делает проблему видимой, но решение об объединении вариантов принимает человек. В обзоре OpenRefine описан удобный визуальный способ такой очистки.
Пятый запрос — сумма по утверждённым операциям. До него уточните, что считается выручкой: оплаченный заказ, заказ после возврата или отгрузка? Не вставляйте произвольно WHERE status = 'paid', если исходная система использует два оплаченных статуса. Запишите правило словами и сравните число с независимым отчётом. Если расхождение есть, разложите его по дням и филиалам. Такой «разрез» помогает найти конкретный провал, а не спорить о целой месячной сумме. Для каждой спорной группы возьмите несколько строк и вернитесь к первичным документам.
Почему автоопределение типов требует внимания
Документация DuckDB описывает определение настроек CSV по образцу файла. Это ускоряет старт, но не гарантирует правильную трактовку каждого столбца. Код магазина 0012 может выглядеть числом, а дата в неоднозначном формате — быть истолкована неправильно. Сначала просмотрите схему, которую увидел клиент, и крайние записи. При необходимости задайте типы явно, особенно для идентификаторов и денежных полей. Не округляйте сумму с плавающей точкой только ради совпадения с ожиданием. Деньги и правила округления должны быть определены в исходном процессе.
Для большого массива можно перейти на Parquet, который хранит схему и позволяет эффективнее читать выборочные столбцы. Но не меняйте формат в середине расследования без сохранённой копии и сравнения контрольных чисел. В сравнении CSV и Parquet разобрано, в какой задаче проще текстовый файл, а где нужен столбцовый формат. Никакое ускорение запроса не компенсирует потерянную строку или неверную трактовку поля.
Когда локальный аудит недостаточен
SQL проверяет структуру и арифметику, но не исправляет смысл. Если ИИ причислил просьбу о возврате к успешной продаже, таблица останется технически чистой. Поэтому для классифицированных моделью строк нужна отдельная ручная выборка. Сохраните исходный текст, ответ модели, правильный класс и причину исправления. Проверьте не только случайные случаи, но и те, где цена ошибки выше: крупные суммы, спорные статусы, пустые объяснения. Если обнаружилась ошибка в логике отчёта, исправьте запрос и повторно выполните все контрольные проверки, а не меняйте итог вручную.
Ограничение «локально» тоже не следует преувеличивать. DuckDB может работать с файлами на компьютере, но расширения и внешние источники данных добавляют сетевые возможности. Для конфиденциального набора не включайте ненужные интеграции, храните копию в разрешённой папке и не отправляйте полный вывод в чат ради объяснения одного расхождения. Подготовьте маленькую обезличенную выборку. В гайде о проверке ответа ИИ есть общий принцип: проверять не уверенность формулировки, а происхождение чисел.
Вывод
DuckDB стоит использовать как быстрое местное сито перед публикацией аналитического вывода: пять простых проверок обнаружат пропуск, неожиданный статус и расхождение суммы раньше, чем красивый график отправится руководителю. Но результат запросов нужно сверять с первичной системой и реальными правилами расчёта. Модель может написать SQL, а человек должен знать, какую задачу этот SQL решает и какие данные он не видит.
FAQ
Нужно ли загружать CSV в отдельную базу?
Для начальной проверки нет: DuckDB умеет читать файл прямо в запросе. Постоянную таблицу создают, когда она действительно нужна процессу.
Разница между строками и уникальными заказами всегда ошибка?
Нет. Заказ может занимать несколько строк по товарам. Сначала выясните уровень детализации файла.
Можно ли поручить модели написать все проверки?
Можно попросить черновик запросов, но допустимые статусы, контрольную сумму и определение выручки должен задать владелец данных.
Почему локальный инструмент всё равно требует политики доступа?
Файл остаётся чувствительным независимо от места выполнения запроса. Ограничьте права к папке, журналам и экспортам результатов.