Почему ad-hoc запросы тормозят аналитику
Бизнес-пользователь хочет увидеть топ-10 продаж по категориям за последнюю неделю. Традиционный путь: запрос аналитику, уточнение требований, ожидание в очереди. Ответ приходит через пару дней. Text-to-Code решает иначе. LLM превращает вопрос на русском в код Python или SQL. Затем выполняет его и возвращает результат с визуализацией. Всё это занимает секунды. Согласно Gartner, доля NLQ-запросов вырастет до 60% в ближайшие годы.
Недавно мы внедрили Text-to-Code для ритейл-сети с 500 магазинами. Раньше на запрос 'покажи средний чек по регионам за прошедший месяц' уходило 2 дня. Теперь ответ приходит за 15 секунд. Аналитики переключились на сложные задачи, а бизнес-пользователи получили самообслуживание. За 5 лет работы мы реализовали более 50 проектов AI-аналитики.
Как Text-to-Code ускоряет работу с данными
Классическая BI требует заранее спроектированных дашбордов. Каждый новый вопрос — 1–3 дня на согласование и разработку. Text-to-Code сокращает это до 10–30 секунд. Аналитики тратят на рутину на 70% меньше времени. Бизнес-пользователи получают самообслуживание для 80% стандартных запросов. Text-to-Code в 10–50 раз быстрее традиционных BI-запросов.
| Критерий | Классическая BI | Text-to-Code (наша система) |
|---|---|---|
| Время на новый запрос | 1–3 дня | 10–30 секунд |
| Необходимость SQL/Python | Да | Нет (вопрос на естественном языке) |
| Адаптация к изменению данных | Ручная перестройка дашбордов | Автоматическая через schema retrieval |
| Масштабируемость (100+ запросов/день) | Ограничена штатом аналитиков | Практически безгранична (sandbox) |
Почему безопасность кода — главный риск?
Главный риск Text-to-Code — вредоносный или некорректный код. Наша изоляция строится на трёх уровнях:
- Sandbox-контейнер: выполнение в изолированном окружении с ограниченным доступом к файловой системе и сети. Используем Docker или gVisor.
- Whitelist модулей: разрешены только pandas, numpy, plotly и встроенные функции Python. Запросы на импорт сторонних библиотек блокируются.
- Валидация результата: типы выходных данных проверяются, код логируется для аудита.
Пример конфигурации Docker-контейнера для изоляции кода:
version: '3.8'
services:
sandbox:
image: python:3.11-slim
command: tail -f /dev/null
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
volumes:
- ./data:/data:ro
environment:
- PYTHONDONTWRITEBYTECODE=1
deploy:
resources:
limits:
cpus: '1'
memory: 2G
Реализация на примере AIDataAnalyst
from anthropic import Anthropic
import pandas as pd
import io
class AIDataAnalyst:
def __init__(self, dataframes: dict[str, pd.DataFrame]):
self.dfs = dataframes
self.llm = Anthropic()
self.schema = self._build_schema()
def _build_schema(self) -> str:
schema_parts = []
for name, df in self.dfs.items():
schema_parts.append(f"Table: {name}")
schema_parts.append(f"Shape: {df.shape[0]} rows x {df.shape[1]} columns")
schema_parts.append("Columns:")
for col in df.columns:
dtype = str(df[col].dtype)
n_unique = df[col].nunique()
sample = str(df[col].dropna().head(3).tolist())
schema_parts.append(f" - {col} ({dtype}, {n_unique} unique): {sample}")
schema_parts.append("")
return '\n'.join(schema_parts)
def analyze(self, question: str) -> dict:
"""Анализ данных по вопросу на естественном языке"""
system_prompt = f"""You are a data analyst. You have access to these dataframes:
{self.schema}
Write Python code using pandas to answer the user's question.
The dataframes are available as: {list(self.dfs.keys())}
Return ONLY the Python code, no explanations. Use variable 'result' for the final result."""
response = self.llm.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
system=system_prompt,
messages=[{"role": "user", "content": question}]
)
code = response.content[0].text.strip()
if code.startswith("```python"):
code = code[9:-3].strip()
result = self._execute_safely(code)
# Генерация объяснения
explanation = self._generate_explanation(question, result, code)
return {
'question': question,
'code': code,
'result': result,
'explanation': explanation
}
def _execute_safely(self, code: str) -> any:
"""Безопасное выполнение сгенерированного кода"""
import builtins
# Разрешённые функции
safe_globals = {
'__builtins__': {
'len': builtins.len, 'range': builtins.range,
'list': builtins.list, 'dict': builtins.dict,
'str': builtins.str, 'int': builtins.int,
'float': builtins.float, 'print': builtins.print,
'sorted': builtins.sorted, 'sum': builtins.sum,
'min': builtins.min, 'max': builtins.max,
'round': builtins.round, 'abs': builtins.abs,
},
'pd': pd,
'np': __import__('numpy'),
}
# Добавление датафреймов
safe_globals.update(self.dfs)
local_vars = {}
exec(code, safe_globals, local_vars)
return local_vars.get('result')
def _generate_explanation(self, question: str, result, code: str) -> str:
result_str = str(result)[:2000] if result is not None else "No result"
response = self.llm.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=300,
messages=[{
"role": "user",
"content": f"""Question: {question}
Analysis result: {result_str}
Provide a clear 2-3 sentence business explanation of this result."""
}]
)
return response.content[0].text
Как автоматическая визуализация выбирает график?
class AutoVisualizer:
def create_chart(self, data, question: str) -> str:
"""Автоматический выбор и создание визуализации"""
chart_type = self._suggest_chart_type(data, question)
import plotly.express as px
if isinstance(data, pd.DataFrame):
if chart_type == 'bar':
fig = px.bar(data, x=data.columns[0], y=data.columns[1],
title=question[:80])
elif chart_type == 'line':
fig = px.line(data, x=data.columns[0], y=data.columns[1:],
title=question[:80])
elif chart_type == 'scatter':
fig = px.scatter(data, x=data.columns[0], y=data.columns[1],
title=question[:80])
elif chart_type == 'pie':
fig = px.pie(data, names=data.columns[0], values=data.columns[1],
title=question[:80])
return fig.to_html(include_plotlyjs='cdn', full_html=False)
return None
Что входит в разработку AI-системы?
Мы предоставляем полный комплект документации и артефактов:
- Model card — спецификация выбранной LLM, параметры инференса, версии библиотек;
- Конфигурационные файлы — Docker Compose, переменные окружения, скрипты развертывания;
- Интерактивный Playbook — описание всех компонентов и инструкции по настройке;
- Нагрузочное тестирование — отчёт с латентностью p50/p99, FLOPS, GPU utilization при пиковых нагрузках;
- Обучение команды — 2-3 сессии по эксплуатации и дообучению модели;
- Пост-релизная поддержка — 30 дней инцидент-менеджмента и доработок.
Сравнение моделей для Text-to-Code:
| Модель | Латенция (p99) | Токенов на запрос | Поддержка русского |
|---|---|---|---|
| Claude 3.5 Sonnet | 1.2 с | 150-300 | Отличная |
| GPT-4o | 1.5 с | 200-400 | Хорошая |
| LLaMA 3 70B | 2.0 с | 180-350 | Средняя |
| Qwen 2.5 72B | 1.8 с | 160-320 | Отличная |
Этапы работы и ориентировочные сроки
- Аналитика (2–3 дня): разбираем ваши данные, определяем типовые запросы, выбираем LLM и архитектуру.
- Проектирование (3–5 дней): схема RAG, sandbox, pipeline код-генерации.
- Реализация (7–10 дней): интеграция LLM, написание компонентов, визуализации.
- Тестирование (3–5 дней): юнит-тесты, нагрузочное тестирование, проверка безопасности.
- Деплой (2–3 дня): развертывание на вашей инфраструктуре или в облаке, передача документации.
Ориентировочный срок — от 17 до 26 дней. Стоимость рассчитывается индивидуально после аудита данных и требований. Гарантируем безопасность выполнения кода и конфиденциальность данных. Опыт работы с чувствительными данными подтверждён сертификатами. Получите консультацию — свяжитесь с нами для оценки вашего проекта. Закажите бесплатный аудит ваших данных.







