Маркетингова команда витрачає 4 години на один запит до даних. Два аналітики завалені тікетами, а бізнес чекає на звіти. Така ситуація знайома багатьом. Ми вирішили її для e-commerce проєкту за допомогою AI Data Analyst — цифрового співробітника та AI-агента, який сам генерує SQL, виконує запити, будує графіки та дає інтерпретацію. Все природною мовою. Жодних шаблонних дашбордів — довільне питання перетворюється на відповідь за хвилини. Цифровий аналітик відповідає у 120 разів швидше за ручний аналіз і знижує витрати на аналітику на 60%. Економія бюджету на аналітику досягає 60%, а типовий проєкт окупається за 2–3 місяці.
Які проблеми вирішує AI Data Analyst?
Ad-hoc запити без участі аналітика
Ручна аналітика буксує на типових питаннях: «скільки замовлень учора?», «який retention когорти?», «топ продуктів за виручкою». BI-дашборди покривають 20% потреб, решта — ad-hoc. AI Data Analyst бере на себе 80% повторюваних ad-hoc, звільняючи аналітиків для глибинних досліджень.
Автоматична звітність за розкладом
Щоденні дайджести, щотижневі когортні звіти, моніторинг сезонності — налаштовується один раз і працює за кроном. Без участі людини.
Виявлення аномалій у реальному часі
Падіння конверсії, аномальне зростання error rate, різкий стрибок повернень — система б'є тривогу з інтерпретацією причини. LLM пояснює, що сталося і наскільки критично. Згідно з дослідженням Text-to-SQL на Spider dataset, точність генерації SQL з першої спроби досягає 81%.
Як AI Data Analyst вирішує проблему ad-hoc аналітики?
Цифровий аналітик отримує питання російською або англійською, перетворює його на SQL-запит до вашої бази, завантажує дані, візуалізує та пише висновки. На відміну від BI-інструментів з фіксованими дашбордами, він працює з довільними запитами — жодних обмежень.
Text-to-SQL ядро
Приклад реалізації DataAnalystAgent
from openai import AsyncOpenAI from typing import Optional import pandas as pd import json client = AsyncOpenAI() class SQLGenerator: def __init__(self, schema: dict): """ schema: { "table_name": { "columns": [{"name": "...", "type": "...", "description": "..."}], "description": "...", "relationships": [...] } } """ self.schema = schema self.schema_context = self._format_schema() def _format_schema(self) -> str: parts = [] for table, info in self.schema.items(): cols = ", ".join( f"{c['name']} {c['type']} -- {c.get('description', '')}" for c in info["columns"] ) parts.append(f"-- {info.get('description', '')}\nCREATE TABLE {table} ({cols});") return "\n\n".join(parts) async def generate_sql(self, question: str) -> dict: response = await client.chat.completions.create( model="gpt-4o", messages=[{ "role": "system", "content": f"""Ти — аналітик даних. Генеруй тільки SELECT-запити. Схема бази даних: {self.schema_context} Правила: - Завжди використовуй явні JOIN (не implicit) - Для часових рядів — GROUP BY дата з потрібною гранулярністю - Якщо питання неоднозначне — вибери найбільш вірогідну інтерпретацію та вкажи допущення - Поверни JSON: {{"sql": "...", "assumption": "...", "chart_type": "bar|line|pie|table"}}""" }, { "role": "user", "content": question, }], response_format={"type": "json_object"}, ) return json.loads(response.choices[0].message.content) class DataAnalystAgent: def __init__(self, db_connection, schema: dict): self.db = db_connection self.sql_gen = SQLGenerator(schema) async def answer(self, question: str) -> dict: """Повний цикл: питання → SQL → дані → інтерпретація""" # Генерація SQL sql_result = await self.sql_gen.generate_sql(question) sql = sql_result["sql"] # Виконання запиту try: df = await asyncio.get_event_loop().run_in_executor( None, pd.read_sql, sql, self.db ) except Exception as e: # Спроба виправити SQL fixed = await self.fix_sql_error(sql, str(e)) df = await asyncio.get_event_loop().run_in_executor( None, pd.read_sql, fixed, self.db ) # Інтерпретація результату interpretation = await self.interpret_results(question, df) return { "question": question, "sql": sql, "data": df.to_dict("records")[:100], "summary": df.describe().to_dict() if len(df) > 0 else {}, "interpretation": interpretation, "chart_type": sql_result.get("chart_type", "table"), "assumption": sql_result.get("assumption"), } async def interpret_results(self, question: str, df: pd.DataFrame) -> str: if df.empty: return "Запит не повернув даних. Перевірте умови фільтрації." stats = df.describe().to_string() if df.select_dtypes(include="number").shape[1] > 0 else "" sample = df.head(10).to_string() response = await client.chat.completions.create( model="gpt-4o", messages=[{ "role": "system", "content": "Інтерпретуй результати запиту для бізнес-аудиторії. Виділи ключові інсайти, аномалії, тренди. Конкретні числа." }, { "role": "user", "content": f"Питання: {question}\nСтатистика:\n{stats}\nПриклад даних:\n{sample}", }], ) return response.choices[0].message.content Автоматизована аналітика
class AutomatedReportingSystem: """Система автоматичних аналітичних звітів""" REPORT_SCHEDULE = { "daily_sales": { "cron": "0 8 * * *", "questions": [ "Виручка за вчора vs тиждень тому", "Топ-10 продуктів за виручкою за вчора", "Аномалії в транзакціях за вчора", ], "recipients": ["[email protected]", "[email protected]"], }, "weekly_cohort": { "cron": "0 9 * * 1", "questions": [ "Retention когорт за останні 8 тижнів", "LTV за каналами залучення", "Churn rate за тиждень vs попередні 4 тижні", ], "recipients": ["[email protected]"], }, } async def generate_scheduled_report(self, report_name: str) -> str: config = self.REPORT_SCHEDULE[report_name] analyst = DataAnalystAgent(self.db, self.schema) sections = [] for question in config["questions"]: result = await analyst.answer(question) chart = await self.create_visualization(result) sections.append({ "question": question, "interpretation": result["interpretation"], "chart_url": chart, }) return await self.format_report(report_name, sections) Алерти на аномалії
class AnomalyDetector: async def detect_and_alert(self) -> list[dict]: """Щоденне виявлення статистичних аномалій у ключових метриках""" metrics_to_monitor = [ {"name": "daily_revenue", "query": "SELECT SUM(amount) FROM orders WHERE date = CURRENT_DATE"}, {"name": "conversion_rate", "query": "..."}, {"name": "api_error_rate", "query": "..."}, ] alerts = [] for metric in metrics_to_monitor: current_value = await self.db.fetchval(metric["query"]) historical = await self.db.fetch(metric["history_query"]) mean = statistics.mean(historical) stdev = statistics.stdev(historical) z_score = (current_value - mean) / stdev if stdev > 0 else 0 if abs(z_score) > 2.5: # Запитуємо у LLM інтерпретацію аномалії interpretation = await self.interpret_anomaly(metric, current_value, mean, z_score) alerts.append({ "metric": metric["name"], "current": current_value, "expected_range": (mean - 2 * stdev, mean + 2 * stdev), "z_score": z_score, "interpretation": interpretation, }) return alerts Порівняння BI-дашбордів і AI Data Analyst
| Критерій | BI-дашборди | AI Data Analyst |
|---|---|---|
| Тип запитів | Завчасно визначені | Довільні ad-hoc |
| Час відповіді на нове питання | Дні (потрібен розробник) | Секунди-хвилини |
| Гнучкість | Фіксовані фільтри | Природна мова |
| Інтерпретація | Тільки числа | AI-висновки та інсайти |
| Автоматичні звіти | Потребують налаштування | Створюються за кроном |
Обмеження прямого виклику GPT-4
Прямий виклик GPT-4 з питанням «скільки замовлень учора?» — погана ідея. Модель не знає вашої схеми: таблиці, типи, зв'язки. Вона вигадає назви, згенерує невалідний SQL і буде галюцинувати інтерпретацію. AI Data Analyst обгортає LLM в кастомний пайплайн: скелет схеми (імена таблиць, колонок, типи) подається в system prompt, запит виконується в реальній БД, помилки ловляться і виправляються повторним викликом з текстом помилки. Це дає ті самі 81% коректних з першої спроби.
Крім того, ми використовуємо Retrieval-Augmented Generation (RAG) — якщо схема велика (50+ таблиць), підвантажуємо лише релевантні за запитом. Це знижує токенну вартість і покращує якість.
З нашої практики: e-commerce з 15 ad-hoc запитами на день
Наш клієнт — маркетингова команда з 5 осіб. Вони надсилали 15–20 питань аналітикам, відповідь займала в середньому 4 години. Ми розгорнули AI Data Analyst на PostgreSQL з 12 таблицями (замовлення, клієнти, продукти, трафік). Результати:
- Середній час відповіді впав з 4 годин до 2 хвилин.
- Правильність SQL з першої спроби — 81% (решта виправляються автоматично).
- Аналітики переключилися на комплексний аналіз та експерименти.
- Команда оцінила задоволеність на 4.3/5.0.
- Економія бюджету на аналітику склала 60%, проєкт окупився за 2 місяці.
Ми на ринку більше 5 років, реалізували 30+ AI-проєктів, тому гарантуємо якість.
Як ми впроваджуємо AI Data Analyst?
- Аудит джерел даних — опис схем, типів, зв'язків, типових запитів.
- Створення скелету схеми — форматування для system prompt, визначення семантики.
- Prompt engineering — налаштування правил генерації SQL, формату виведення, інтерпретації.
- Інтеграція з каналом — Slack, Teams, Telegram або веб-інтерфейс.
- Запуск та ітерація — тестування на реальних запитах, доопрацювання авто-виправлень.
Скільки часу займає кожен етап?
| Етап | Термін |
|---|---|
| Text-to-SQL під вашу схему | 1–2 тижні |
| Автоматичні звіти та візуалізації | 1–2 тижні |
| Slack/Teams інтеграція | 1 тиждень |
| Anomaly detection | 1 тиждень |
| Разом | 4–6 тижнів |
Що входить в результат
- Документація — опис архітектури, схеми, інструкції з експлуатації.
- Доступ до вихідного коду — повністю прозора реалізація у вашому репозиторії.
- Навчання команди — 2–3 робочих дні для аналітиків та інженерів.
- Підтримка після запуску — 2 тижні on-call, виправлення багів, доналаштування.
- Гарантія якості — точність SQL не нижче 80%, стабільна інтеграція, робота алертів.
Зв'яжіться з нами — розкажемо, як AI Data Analyst скоротить час аналітики у вашій компанії та зекономить бюджет. Замовте безкоштовне демо та оцініть результат на своїх даних.







