Одна функция, которая заменила аналитика. Claude.. Claude. excel.. Claude. excel. llm.. Claude. excel. llm. pandas.. Claude. excel. llm. pandas. python.. Claude. excel. llm. pandas. python. автоматизация.. Claude. excel. llm. pandas. python. автоматизация. данные.. Claude. excel. llm. pandas. python. автоматизация. данные. искусственный интеллект.. Claude. excel. llm. pandas. python. автоматизация. данные. искусственный интеллект. Машинное обучение.

Алексей — финансовый директор. Умный, занятой, не любящий ждать. Каждый понедельник он открывает Excel с продажами за прошлую неделю и задаёт вопросы.

Но Excel — не собеседник. Алексей идёт к аналитику.

Аналитик строит сводную, ищет причины, пишет письмо. Иногда это занимает полдня. Иногда — до вторника.

Я посчитал: среднее время от вопроса Алексея до ответа было 2 часа 17 минут. Сейчас — 4 минуты 30 секунд. Алексей пишет вопрос в чат, получает ответ с цифрами и объяснением.

Расскажу, как это работает. Без BI-систем, без баз данных, без аналитика в цепочке — просто Python и Claude API.

Что за задача

Типичный файл финансового отдела: CSV или Excel с колонками — дата, категория, менеджер, сумма, регион. 3000–50 000 строк. Обновляется раз в день или раз в неделю.

Вопросы бывают двух видов.

Простые: «Какой итог за февраль по Москве?»

Сложные: «Почему в феврале минус 15% к январю — это сезон или конкретные менеджеры провалились?»

На простые Excel справляется. На сложные — нет: нужно копать, сравнивать, делать вывод. Вот здесь и нужен аналитик. Или — Claude.

Архитектура за 5 минут

Excel/CSV → pandas → Claude API → текстовый ответ с цифрами
Одна функция, которая заменила аналитика - 1

Без векторных баз, без SQL, без инфраструктуры. Файл читается, данные готовятся для контекста, задаётся вопрос — получается ответ.

Полный код — ~75 строк.

Код

import anthropic
import pandas as pd
import json
from pathlib import Path


def get_table_summary(df: pd.DataFrame) -> dict:
    """Статистика по таблице — используется для больших файлов."""
    summary = {
        "shape": {"rows": df.shape[0], "cols": df.shape[1]},
        "columns": list(df.columns),
        "dtypes": df.dtypes.astype(str).to_dict(),
        "null_counts": df.isnull().sum().to_dict(),
        "numeric_stats": {},
    }
    for col in df.select_dtypes(include="number").columns:
        summary["numeric_stats"][col] = {
            "min": float(df[col].min()),
            "max": float(df[col].max()),
            "mean": round(float(df[col].mean()), 2),
            "sum": float(df[col].sum()),
        }
    return summary


def prepare_data_for_context(df: pd.DataFrame, max_rows: int = 200) -> str:
    """
    Маленькие таблицы — целиком.
    Большие — статистика + случайная выборка 50 строк.
    """
    if len(df) <= max_rows:
        return df.to_csv(index=False)

    summary = get_table_summary(df)
    sample = df.sample(min(50, len(df)), random_state=42)
    return (
        f"ТАБЛИЦА БОЛЬШАЯ ({len(df)} строк) — даю статистику и случайную выборку.nn"
        f"СТАТИСТИКА:n{json.dumps(summary, ensure_ascii=False, indent=2, default=str)}nn"
        f"СЛУЧАЙНАЯ ВЫБОРКА (50 строк из {len(df)}):n{sample.to_csv(index=False)}"
    )


def fix_column_types(df: pd.DataFrame) -> pd.DataFrame:
    """
    Фикс типов для выгрузок из 1С и других систем:
    пробелы как разделители тысяч, запятые вместо точек в числах.
    """
    for col in df.columns:
        col_lower = col.lower()
        if any(x in col_lower for x in ["дата", "date", "период", "месяц"]):
            try:
                df[col] = pd.to_datetime(df[col], dayfirst=True)
            except Exception:
                pass
        elif df[col].dtype == object:
            cleaned = (
                df[col]
                .astype(str)
                .str.replace(r"s", "", regex=True)
                .str.replace(",", ".")
            )
            try:
                df[col] = pd.to_numeric(cleaned)
            except (ValueError, TypeError):
                pass
    return df


def ask_about_data(file_path: str, question: str) -> str:
    path = Path(file_path)
    if path.suffix.lower() == ".csv":
        df = pd.read_csv(path)
    else:
        df = pd.read_excel(path)

    df = fix_column_types(df)
    data_context = prepare_data_for_context(df)

    prompt = f"""Ты аналитик данных. Перед тобой данные из таблицы.

ДАННЫЕ:
{data_context}

ВОПРОС:
{question}

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

    client = anthropic.Anthropic()
    message = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=2048,
        messages=[{"role": "user", "content": prompt}]
    )
    return message.content[0].text


if __name__ == "__main__":
    answer = ask_about_data(
        "sales_february_2026.xlsx",
        "Почему в феврале падение 15% к январю? Это сезон или конкретные менеджеры?"
    )
    print(answer)
Одна функция, которая заменила аналитика - 2

Как выглядит диалог

Файл: выгрузка продаж за январь–февраль 2026, 4 200 строк, 7 менеджеров, 3 региона.

Вопрос Алексея: «Почему в феврале минус 15% к янв��рю — это сезон или менеджеры?»

Ответ за 4 секунды:

Падение в феврале — 14,8% к январю (январь: 8 340 000 ₽, февраль: 7 104 000 ₽).

Разбивка по менеджерам:
— Иванова: −3% (в норме, сезонный паттерн)
— Петров: −8% (небольшое снижение)
— Сидоров: −41% (критическое падение: 1 820 000 → 1 070 000 ₽)
— Козлова: −2% (стабильно)
— Остальные: ±5% (в пределах нормы)

Вывод: 78% общего падения объясняется Сидоровым — у него провал именно
в Московском регионе (−52%). Остальные менеджеры держатся.
Это не сезон — это точечная проблема.

Рекомендую: уточнить у Сидорова по сделкам в Москве в феврале.
Одна функция, которая заменила аналитика - 3

Алексей сразу идёт к Сидорову. Не ждёт аналитика, не строит сводную сам.

Где грабли

1. Галлюцинации в цифрах

Первую неделю я принимал все ответы за правду. На второй — заметил расхождение.

В одном анализе Claude написал сумму 1 234 500 ₽. В таблице стояло 1 243 500 ₽. Разница 9 000 — копейки в процентах, но неприятно. Добавил в промпт: «Каждую цифру сверяй с данными. Если не уверен — пиши “требует проверки”.»

Стало лучше. Но не идеально — на больших выборках Claude иногда считает агрегаты с погрешностью ±1–2%. Для оперативного анализа ок, для бухгалтерии — нет.

2. Контекстное окно

Таблица на 50 000 строк в контекст не лезет. Поэтому prepare_data_for_context — она режет большие файлы до статистики + случайная выборка.

Минус очевидный: на случайной выборке можно пропустить аномалию. Если у вас 100 строк и одна из них — ключевой выброс, а она не попала в выборку — Claude её не увидит.

Решение на практике: для файлов > 5 000 строк я сначала прошу «дай общую статистику», потом «посмотри конкретно за февраль» — уже меньше данных, влезает целиком.

3. Форматы из 1С

Это отдельная боль. Выгрузки из 1С и многих российских систем выглядят так:

1 234 567,89  ← пробел как разделитель тысяч, запятая как десятичная
Одна функция, которая заменила аналитика - 4

pandas читает это как строку. fix_column_types как раз это и фиксит — убирает пробелы, меняет запятую на точку.

Но бывают сюрпризы: в одной выгрузке даты шли как «Январь 2026», в другой — «01.2026», в третьей — числом 202601. Первые два pd.to_datetime ест, третий — нет.

Пришлось добавить отдельный обработчик для числовых дат.

4. Название колонок

Никто в мире не называет колонки одинаково. В одном файле «Сумма продаж», в другом «Выручка», в третьем «Revenue_RUB». Claude справляется с интерпретацией — это его сильная сторона. Но иногда путается, если колонок много и названия перекрываются.

Помогает: в начале диалога один раз спросить «Какие колонки есть в таблице и что они значат?» — получить описание, потом задавать вопросы.

Ограничения — честно

Не подходит для:

  • Таблиц > 50 000 строк без предобработки

  • Точной бухгалтерии (нужна проверка цифр)

  • Сложных join’ов между несколькими файлами (теоретически можно, но громоздко)

  • Real-time данных — придётся перечитывать файл каждый раз

Подходит для:

  • Оперативного анализа: «что происходит прямо сейчас»

  • Вопросов «почему» — когда нужен вывод, а не просто цифры

  • Нерегулярных запросов — тех, под которые не строят дашборды

  • Людей, которые не умеют в Excel pivot tables

Что дальше

Алексей теперь спрашивает сам. Аналитик занимается более сложными задачами.

Следующий шаг — веб-интерфейс: загрузи файл, задай вопрос, получи ответ. Без Python, без терминала. Это уже другая история.


А у вас есть такая задача — перевести данные из «немых» таблиц в диалог? Как решаете вопрос “переводчика” между данными и нужным человеком?


Сергей Цветков. AI-автоматизация бизнес-процессов. 15 лет в IT, 30+ AI-проектов.

Автор: sergei_ai

Источник

Rambler's Top100