Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Оптимизация диалогов ClickHouse Assistant с помощью семантического слоя

Агента чата ClickHouse Assistant можно настроить так, чтобы он учитывал вашу бизнес-логику, структуры данных и специфику предметной области с помощью AGENTS.md — специального сохраненного запроса, который служит семантическим слоем поверх системного промпта агента.

Создав файл AGENTS.md, вы можете задать пользовательские инструкции, которые добавляются в начало каждого диалога и помогают направлять генерацию SQL-запросов и анализ данных с учетом уникальных требований, расчетов и принятых в вашей организации соглашений.

Как это работает

Когда вы сохраняете запрос с именем "AGENTS.md" (с учетом регистра) в Cloud Console:

  1. Агент чата ClickHouse Assistant автоматически загружает этот файл при отправке сообщения
  2. Содержимое помещается в структурированный тег content и добавляется в системный промпт агента
  3. Эти инструкции применяются ко всем диалогам ClickHouse Assistant chat в этом сервисе

Создание AGENTS.md

Создайте сохраненный запрос

  1. В Cloud Console создайте новый запрос
  2. Назовите его строго так: "AGENTS.md" (с учетом регистра)
  3. Введите свои пользовательские инструкции в редакторе текста запроса (это не SQL)
  4. Сохраните запрос

Добавьте свои инструкции

Структурируйте инструкции, используя четкий и практичный язык. Включите:

  • Бизнес-правила и расчеты
  • Рекомендации по структуре данных
  • Терминологию предметной области
  • Распространенные шаблоны запросов
  • Правила оптимизации производительности

Лучшие практики

Относитесь к контексту как к ограниченному ресурсу

Контекст ценен — каждый токен расходует «бюджет внимания» агента. Подобно людям с ограниченной рабочей памятью, языковые модели работают хуже по мере увеличения контекста. Это значит, что нужно находить как можно меньший набор наиболее информативных токенов, который максимизирует вероятность желаемого результата.

Найдите правильный уровень детализации

Соблюдайте баланс между двумя крайностями:

  • Слишком конкретно: Жёстко заданная хрупкая логика if-else, которая делает систему уязвимой и усложняет поддержку
  • Слишком расплывчато: Высокоуровневые рекомендации, которые не дают конкретных ориентиров или ошибочно предполагают общий контекст

Оптимальный уровень детализации должен быть достаточно конкретным, чтобы эффективно направлять поведение, и при этом достаточно гибким, чтобы модель могла применять надёжные эвристики. Начните с минимального промпта на лучшей доступной модели, а затем добавляйте чёткие инструкции с учётом выявленных сбоев.

Структурируйте текст по разделам

Используйте XML-теги или заголовки Markdown, чтобы создать отдельные, удобные для быстрого просмотра разделы:

<background_information>
Context about your data and domain
</background_information>

<calculation_rules>
Specific formulas and business logic
</calculation_rules>

<tool_guidance>
How to use specific ClickHouse features
</tool_guidance>

Приводите разнообразные, эталонные примеры

Примеры говорят лучше тысячи слов. Вместо того чтобы пытаться уместить в промпт все возможные пограничные случаи, подберите компактный, но разнообразный набор примеров, который наглядно передаёт ожидаемое поведение.

Минимум, но достаточно

  • Включайте только действительно нужные инструкции
  • Будьте кратки — слишком большой контекст снижает качество из-за «деградации контекста»
  • Удаляйте устаревшие или редко используемые правила
  • Давайте достаточно информации, чтобы направлять нужное поведение

Пример: Вычисляемые метрики на основе сырых данных

Указывайте агенту, если для метрик требуются специальные вычисления, а не прямой доступ к столбцам:

<metric_calculations>
ВАЖНО: "active_sessions" — это НЕ столбец. Его необходимо вычислить.

Для вычисления активных сеансов:
COUNT(DISTINCT session_id || '|' || user_id) AS active_sessions

Это подсчитывает уникальные комбинации идентификаторов сеанса и пользователя.

Когда пользователь запрашивает "active sessions" или "session count", всегда используйте следующую формулу:
SELECT
    date,
    COUNT(DISTINCT session_id || '|' || user_id) AS active_sessions
FROM events
GROUP BY date;

</metric_calculations>

Пример: Правила бизнес-логики

Определите вычисления и категории, характерные для предметной области:

<business_rules>
Revenue Calculation:
- Exclude refunded transactions: WHERE transaction_status != 'refunded'
- Apply regional tax rates using CASE expressions
- Use MRR for subscriptions:
  SUM(CASE
    WHEN billing_cycle = 'monthly' THEN amount
    WHEN billing_cycle = 'yearly' THEN amount / 12
    ELSE 0
  END) AS mrr

Traffic Source Classification:
Use CASE expression to categorize:
CASE
  WHEN traffic_source IN ('google', 'bing', 'organic') THEN 'Organic Search'
  WHEN traffic_source IN ('facebook', 'instagram', 'social') THEN 'Social Media'
  WHEN traffic_source = 'direct' THEN 'Direct'
  ELSE 'Other'
END AS source_category

Customer Segmentation:
- Enterprise: annual_contract_value >= 100000
- Mid-Market: annual_contract_value >= 10000 AND annual_contract_value < 100000
- SMB: annual_contract_value < 10000

Always include these categorizations when generating traffic or revenue reports.
</business_rules>

Пример: особенности структуры данных

Описывайте нестандартные форматы данных или решения, унаследованные от устаревшей схемы:

<data_structure_notes>
The user_status column uses numeric codes, not strings:
- 1 = 'active'
- 2 = 'inactive'
- 3 = 'suspended'
- 99 = 'deleted'

When filtering or displaying user status, always use:
CASE user_status
  WHEN 1 THEN 'active'
  WHEN 2 THEN 'inactive'
  WHEN 3 THEN 'suspended'
  WHEN 99 THEN 'deleted'
END AS status_label

The product_metadata column contains JSON strings that must be parsed:
SELECT
    product_id,
    JSONExtractString(product_metadata, 'category') AS category,
    JSONExtractInt(product_metadata, 'inventory_count') AS inventory
FROM products;
</data_structure_notes>

Пример: терминология предметной области

Сопоставьте бизнес-термины с технической реализацией:

<terminology>
When users refer to "conversions", they mean:
- For e-commerce: transactions WHERE transaction_type = 'purchase'
- For SaaS: subscriptions WHERE subscription_status = 'active' AND first_payment_date IS NOT NULL

"Churn" is calculated as:
COUNT(DISTINCT user_id) WHERE last_active_date < today() - INTERVAL 90 DAY
AND previous_subscription_status = 'active'

"DAU" (Daily Active Users) means:
COUNT(DISTINCT user_id) WHERE activity_date = today()

"Qualified leads" must meet ALL criteria:
- lead_score >= 70
- company_size >= 50
- budget_confirmed = true
- contact_role IN ('Director', 'VP', 'C-Level')
</terminology>
Navigation