0Pricing
AI Agents · Урок

Инструменты агентов на основе Pandas

Определения инструментов для операций read_csv, groupby, merge и describe.

«Инструменты агентов на основе Pandas» — бесплатный урок AI Agents на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Agents, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Agents содержит 4 уроков всего.

Инструменты pandas для агентов данных

Вместо генерации произвольного кода можно предоставить агенту данных набор чётко определённых инструментов pandas. Каждый инструмент выполняет конкретную операцию над данными и возвращает структурированный результат.

Такой подход безопаснее и предсказуемее свободной генерации кода: агент выбирает инструменты и выстраивает их в цепочку, а не пишет код с нуля.

Инструмент: read_csv

Отправная точка любого сеанса анализа данных. read_csv загружает CSV-файл в память и возвращает описание его размера и столбцов, чтобы агент понимал, с какими данными работает.

import pandas as pd
from typing import Optional

# In-memory dataframe store (shared across tool calls in one session)
dataframes = {}

def read_csv(path: str, df_name: str = 'df') -> dict:
    '''Load a CSV file and return schema info.'''
    df = pd.read_csv(path)
    dataframes[df_name] = df
    return {
        'df_name': df_name,
        'rows': len(df),
        'columns': list(df.columns),
        'dtypes': df.dtypes.astype(str).to_dict(),
        'sample': df.head(3).to_dict(orient='records'),
        'null_counts': df.isnull().sum().to_dict()
    }

# Agent usage:
result = read_csv('orders.csv', 'orders')
print(f"Loaded {result['rows']} rows, columns: {result['columns']}")

Инструмент: filter_dataframe

Фильтрует строки на основе строки-условия. Условие вычисляется для таблицы данных с помощью df.query(), которая поддерживает безопасное подмножество выражений pandas.

def filter_dataframe(df_name: str, condition: str, result_name: str = None) -> dict:
    '''Filter rows matching condition. Returns filtered dataframe info.'''
    df = dataframes.get(df_name)
    if df is None:
        return {'error': f'Dataframe {df_name!r} not found. Call read_csv first.'}

    try:
        filtered = df.query(condition)
        store_name = result_name or f'{df_name}_filtered'
        dataframes[store_name] = filtered
        return {
            'df_name': store_name,
            'rows_before': len(df),
            'rows_after': len(filtered),
            'sample': filtered.head(3).to_dict(orient='records')
        }
    except Exception as e:
        return {'error': f'Filter error: {e}'}

# Example: filter orders from 2024
result = filter_dataframe('orders', 'order_date >= "2024-01-01"', 'orders_2024')
print(f"Filtered to {result['rows_after']} rows")

Инструмент: groupby_aggregate

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

def groupby_aggregate(df_name: str, group_column: str,
                      agg_column: str, agg_func: str) -> dict:
    '''Group by column and aggregate. agg_func: sum, mean, count, min, max, median'''
    df = dataframes.get(df_name)
    if df is None:
        return {'error': f'Dataframe {df_name!r} not found'}

    VALID_FUNCS = {'sum', 'mean', 'count', 'min', 'max', 'median', 'std'}
    if agg_func not in VALID_FUNCS:
        return {'error': f'Invalid agg_func. Choose from: {VALID_FUNCS}'}

    try:
        result = df.groupby(group_column)[agg_column].agg(agg_func).reset_index()
        result.columns = [group_column, f'{agg_column}_{agg_func}']
        result = result.sort_values(f'{agg_column}_{agg_func}', ascending=False)
        return {
            'result': result.head(20).to_dict(orient='records'),
            'total_groups': len(result)
        }
    except Exception as e:
        return {'error': str(e)}

# Agent call: total revenue by product category
print(groupby_aggregate('orders', 'category', 'revenue', 'sum'))

Инструмент: merge_dataframes

Объединяет две таблицы данных по общему ключу. Это позволяет агенту объединять данные из нескольких файлов — например, соединять заказы с таблицей клиентов, чтобы получить имена клиентов.

def merge_dataframes(df1_name: str, df2_name: str,
                     on: str, how: str = 'inner',
                     result_name: str = 'merged') -> dict:
    '''Join two dataframes on a key column.'''
    df1 = dataframes.get(df1_name)
    df2 = dataframes.get(df2_name)
    if df1 is None:
        return {'error': f'{df1_name!r} not found'}
    if df2 is None:
        return {'error': f'{df2_name!r} not found'}

    VALID_HOW = {'inner', 'left', 'right', 'outer'}
    if how not in VALID_HOW:
        return {'error': f'Invalid join type. Choose from: {VALID_HOW}'}

    try:
        merged = df1.merge(df2, on=on, how=how)
        dataframes[result_name] = merged
        return {
            'df_name': result_name,
            'rows': len(merged),
            'columns': list(merged.columns),
            'sample': merged.head(3).to_dict(orient='records')
        }
    except Exception as e:
        return {'error': str(e)}

# Join orders with customers on customer_id
print(merge_dataframes('orders', 'customers', on='customer_id'))

Инструмент: describe_dataframe

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

def describe_dataframe(df_name: str) -> dict:
    '''Return statistical summary and data quality info.'''
    df = dataframes.get(df_name)
    if df is None:
        return {'error': f'Dataframe {df_name!r} not found'}

    # Numeric stats
    numeric_cols = df.select_dtypes(include='number').columns.tolist()
    stats = {}
    for col in numeric_cols:
        s = df[col].describe()
        stats[col] = {
            'min':    round(float(s['min']), 4),
            'max':    round(float(s['max']), 4),
            'mean':   round(float(s['mean']), 4),
            'median': round(float(df[col].median()), 4),
            'std':    round(float(s['std']), 4),
            'nulls':  int(df[col].isnull().sum())
        }

    # Categorical columns summary
    cat_cols = df.select_dtypes(include='object').columns.tolist()
    cat_stats = {
        col: {
            'unique_values': df[col].nunique(),
            'top_3': df[col].value_counts().head(3).to_dict()
        }
        for col in cat_cols
    }

    return {'numeric': stats, 'categorical': cat_stats, 'total_rows': len(df)}

Инструмент: sort_and_top_n

Возвращает первые N строк, отсортированные по столбцу. Полезен для вопросов вроде «какие клиенты лидируют», «какие товары лучшие» или «какова наибольшая выручка».

def sort_and_top_n(df_name: str, sort_column: str,
                   n: int = 10, ascending: bool = False) -> dict:
    '''Return top N rows sorted by column.'''
    df = dataframes.get(df_name)
    if df is None:
        return {'error': f'{df_name!r} not found'}
    if sort_column not in df.columns:
        return {'error': f'Column {sort_column!r} not found. Available: {list(df.columns)}'}

    sorted_df = df.sort_values(sort_column, ascending=ascending)
    top = sorted_df.head(n)

    return {
        'rows': top.to_dict(orient='records'),
        'total_rows_in_df': len(df),
        'sort_column': sort_column,
        'sort_order': 'ascending' if ascending else 'descending'
    }

# Top 5 orders by total value
print(sort_and_top_n('orders', 'total_amount', n=5))

Инструмент: pivot_table

Создаёт сводную таблицу — перекрёстную таблицу двух категориальных столбцов с агрегированным значением. Идеально подходит для вопросов о выручке по регионам в разрезе категорий товаров.

def pivot_table(df_name: str, index: str, columns: str,
                values: str, aggfunc: str = 'sum') -> dict:
    '''Create a pivot table.'''
    df = dataframes.get(df_name)
    if df is None:
        return {'error': f'{df_name!r} not found'}

    VALID_FUNCS = {'sum', 'mean', 'count', 'min', 'max'}
    if aggfunc not in VALID_FUNCS:
        return {'error': f'Invalid aggfunc. Choose from: {VALID_FUNCS}'}

    try:
        pivot = df.pivot_table(
            index=index, columns=columns,
            values=values, aggfunc=aggfunc,
            fill_value=0
        )
        # Convert to nested dict for JSON serialization
        result = pivot.round(2).to_dict()
        return {
            'pivot': result,
            'index': index,
            'columns': columns,
            'values': values,
            'aggfunc': aggfunc
        }
    except Exception as e:
        return {'error': str(e)}

Инструмент: calculate_metric

Вычисляет отдельный бизнес-показатель — рост выручки, коэффициент конверсии или уровень оттока — на основе существующих столбцов таблицы данных. Это точнее, чем просить LLM написать выражение pandas.

def calculate_metric(df_name: str, metric: str, params: dict = None) -> dict:
    '''Calculate a named business metric from the dataframe.'''
    df = dataframes.get(df_name)
    if df is None:
        return {'error': f'{df_name!r} not found'}

    params = params or {}
    try:
        if metric == 'conversion_rate':
            total_col = params.get('total_column', 'total')
            converted_col = params.get('converted_column', 'converted')
            rate = df[converted_col].sum() / df[total_col].sum() * 100
            return {'metric': 'conversion_rate', 'value': round(rate, 2), 'unit': '%'}

        elif metric == 'average_order_value':
            revenue_col = params.get('revenue_column', 'revenue')
            count_col = params.get('count_column', 'order_count')
            aov = df[revenue_col].sum() / df[count_col].sum()
            return {'metric': 'average_order_value', 'value': round(aov, 2)}

        else:
            return {'error': f'Unknown metric: {metric}'}

    except Exception as e:
        return {'error': str(e)}

Регистрация инструментов в агенте на базе LLM

Зарегистрируйте все инструменты pandas в агенте на базе LLM, используя формат вызова функций OpenAI. Агент решает, какой инструмент вызвать, основываясь на вопросе пользователя.

tools = [
    {
        'type': 'function',
        'function': {
            'name': 'read_csv',
            'description': 'Load a CSV file for analysis',
            'parameters': {
                'type': 'object',
                'properties': {
                    'path': {'type': 'string', 'description': 'Path to CSV file'},
                    'df_name': {'type': 'string', 'description': 'Name to reference this dataframe'}
                },
                'required': ['path']
            }
        }
    },
    {
        'type': 'function',
        'function': {
            'name': 'groupby_aggregate',
            'description': 'Group data by a column and compute sum, mean, count, min, max, or median',
            'parameters': {
                'type': 'object',
                'properties': {
                    'df_name':      {'type': 'string'},
                    'group_column': {'type': 'string'},
                    'agg_column':   {'type': 'string'},
                    'agg_func':     {'type': 'string', 'enum': ['sum', 'mean', 'count', 'min', 'max', 'median']}
                },
                'required': ['df_name', 'group_column', 'agg_column', 'agg_func']
            }
        }
    }
]

if __name__ == '__main__':
    print('Registered tools:')
    for t in tools:
        fn = t['function']
        print(f"  - {fn['name']}: {fn['description']}")

Объединение нескольких инструментов в цепочку

Для сложных вопросов требуется объединять несколько инструментов в цепочку. Агент вызывает их последовательно, используя результат одного инструмента как входные данные для следующего. Результат каждого инструмента возвращается агенту до следующего вызова.

import json
import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

TOOL_MAP = {
    'read_csv': read_csv,
    'filter_dataframe': filter_dataframe,
    'groupby_aggregate': groupby_aggregate,
    'describe_dataframe': describe_dataframe,
    'merge_dataframes': merge_dataframes,
    'sort_and_top_n': sort_and_top_n
}

def run_data_agent(question, data_paths):
    messages = [
        {'role': 'system', 'content': f'You are a data analyst. Available data: {data_paths}'},
        {'role': 'user', 'content': question}
    ]

    for _ in range(10):  # max 10 tool calls
        response = client.chat.completions.create(
            model='gpt-4o', messages=messages, tools=tools
        )
        msg = response.choices[0].message

        if not msg.tool_calls:
            return msg.content  # final answer

        messages.append(msg)
        for call in msg.tool_calls:
            fn = TOOL_MAP[call.function.name]
            args = json.loads(call.function.arguments)
            result = fn(**args)
            messages.append({'role': 'tool', 'tool_call_id': call.id,
                             'content': json.dumps(result)})

    return 'Max tool calls reached'

Проверка знаний

В чём главное преимущество предоставления агенту данных инструментов pandas по сравнению с использованием шаблона интерпретатора кода?

Повторение: инструменты агента данных на основе pandas

Инструменты pandas предоставляют агенту данных безопасные и чётко определённые операции: read_csv, filter_dataframe, groupby_aggregate, merge_dataframes, describe_dataframe, sort_and_top_n и pivot_table.

Каждый инструмент проверяет входные данные, корректно обрабатывает ошибки и возвращает структурированные результаты. Зарегистрируйте инструменты в формате вызова функций OpenAI, и агент автоматически объединит вызовы инструментов в цепочку, чтобы отвечать на сложные многоэтапные вопросы о данных.

Часто задаваемые вопросы

Урок «Инструменты агентов на основе Pandas» бесплатный?

Да — полный текст урока «Инструменты агентов на основе Pandas» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Agents, подпишись на CoddyKit PRO. Курс AI Agents содержит 4 уроков всего.

Чему я научусь в уроке «Инструменты агентов на основе Pandas»?

Определения инструментов для операций read_csv, groupby, merge и describe. Ты практикуешь AI Agents с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать AI Agents?

Предыдущий опыт не требуется. AI Agents на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Инструменты агентов на основе Pandas»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке AI Agents?

Да. Каждый урок AI Agents включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблон интерпретатора кода для анализа данных
  2. Инструменты агентов на основе Pandas
  3. Автоматическая генерация диаграмм и визуализаций
  4. Агенты для статистических сводок
← Назад к AI Agents