TGViewer
Лёха ведет дневник Лёха ведет дневник @alexs_journal · 1.07K subscribers
Post #142 1.24K
[Часть2] Как я строил AI-аналитика для данных о третичных продажах

Агент, если по-простому — это LLM с набором инструментов, который итеративно решает задачу.
На каждом шаге он решает, какой инструмент вызвать, с какими параметрами, и что делать с результатом.
Цикл продолжается, пока агент не соберёт достаточно данных для ответа.

Tools: как агент работает с данными
run_sql — основной инструмент

Принимает произвольный SELECT-запрос, прогоняет через guardrails (об этом ниже), выполняет в ClickHouse, возвращает результат в виде таблицы.
Если запрос упал с ошибкой — агент видит текст ошибки и может исправить SQL и попробовать снова.

get_reference_values — инструмент разведки данных.
Прежде чем строить сложный запрос, агент может спросить:
«Какие значения есть в столбце subcategory для category = 'Мясная гастрономия'

Технически tool делает
SELECT DISTINCT field 
FROM ai.sellout_sales
WHERE ...
ORDER BY field
LIMIT 50

и возвращает список значений.

Но вызвать его можно только для 20 разрешённых полей (whitelist: category, subcategory, group_name, brand, producer, client, region, city и другие справочные поля).
Это защита — нельзя разведать, например, конкретные store_addr или ean.

Зачем это нужно? Пример: пользователь спрашивает «продажи в Дикси по творогу».
Агент вызывает
get_reference_values(
field='subcategory',
filter_clause="category = 'Молочная гастрономия'"
)

видит в ответе Творожная группа (а не Творог), и строит SQL с правильным фильтром. Без этого шага LLM с высокой вероятностью напишет subcategory = 'Творог' и получит 0 строк.

Системный промпт: 300 строк контекста для LLM
Промпт агента — это не просто «ты аналитик, пиши SQL»
Это 300 строк структурированных инструкций, разбитых на блоки:

- Роль и workflow из 5 шагов:
классификация запроса → уточнение у пользователя → разведка данных → SQL-запросы → анализ и выводы.

Если пользователь написал «привет» вместо аналитического вопроса — агент вежливо объясняет возможности и предлагает 5 конкретных примеров запросов.

- Полная схема таблицы — все 53 поля с типами и семантикой.
Агент знает, что salesvalueVAT — это выручка с НДС (и что именно её нужно использовать, потому что salesvalue для ряда сетей равен нулю).
Знает, что reg_price_report содержит много нулей и для расчёта средней цены нужна формула средневзвешенной: sum(salesvalueVAT) / nullIf(sum(sales_weight_kg), 0).

- Справочники и маппинги — точные значения client по каждой сети с учётом регистра ('Пятёрочка' vs 'МАГНИТ' vs 'Ашан'),
маппинг пользовательских терминов на поля ("творог" → subcategory = 'Творожная группа'),
иерархии (chain -> client -> store_code_uni).

- Подсказки для сложных запросов — паттерны SQL для типовых аналитических задач: сегментация через ntile(),
тренды через lagInFrame(),
pivot-матрицы через условную агрегацию (sumIf/avgIf),
расчёт индексов цен YoY с CTE.
И явные предупреждения: linearRegression в ClickHouse не существует - не выдумывай.

По сути, промпт — это сжатая документация по данным и по паттернам ClickHouse SQL, которую аналитик-человек держит в голове после месяцев работы с этой базой.

SQL Guardrails: безопасность на уровне валидации

Давать LLM возможность писать произвольный SQL — мощно, но опасно. Каждый запрос проходит через validate_select_sql() до обращения к базе:

- Разрешён только SELECT или WITH ... SELECT.
- Запрещены множественные statements (защита от SELECT 1; DROP TABLE).
- Denylist опасных ключевых слов: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE.
- Автоматическое добавление SETTINGS max_execution_time=45 — защита от тяжёлых запросов к 552 млн строк.
- Отдельный read-only пользователь ClickHouse (agent) с правами только на SELECT по ai.*.

Невалидный SQL блокируется, а агент получает сообщение SQL_VALIDATION_ERROR: ... с инструкцией исправить запрос.
Тот же механизм работает для SQL_EXECUTION_ERROR — если ClickHouse вернул ошибку (несуществующий столбец, синтаксическая ошибка), агент видит текст и пробует переписать запрос.

Если интересно — могу поделиться системным промптом к агенту.

@alexs_journal
  • 🔥 16
  • ❤ 6
  • 👍 4
More from @alexs_journal
  1. Sep 17, 2026Представляю вашему вниманию Hub Defence! Игра в жанре Tower Defence о том, как Валера Кова…
  2. Sep 13, 2026Post #157
  3. Sep 4, 2026Дарим подписку на hub Условия простые, напишите ваш кейс в комментариях под этим постом. Р…
  4. Aug 11, 2026Первый выпуск начинается со спора самих ведущих ИИ —начало конца творческих профессий ИИ —…
  5. Aug 7, 2026Продолжаю рассказ про то, как у меня устроен Obsidian, как я использую методику GTD, настр…
  6. Jul 29, 2026Post #153
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →