Работа с файловым API: Загрузка и анализ больших документов (PDF, CSV)

45 минут Урок 9

Введение: Почему контекстного окна недостаточно?

Добро пожаловать во второй модуль. Сегодня мы поговорим о фундаментальной проблеме, с которой сталкивается каждый разработчик LLM-приложений: работа с большими данными.

Раньше, если вам нужно было проанализировать длинный PDF-отчет или большую таблицу CSV, вы, вероятно, прибегали к сложной эквилибристике. Вы извлекали текст (используя PyPDF2 или подобные библиотеки), разбивали его на чанки (chunking), создавали эмбеддинги и использовали векторные базы данных (RAG). Это рабочий подход, но у него есть недостатки: потеря контекста на стыке чанков, потеря форматирования, игнорирование изображений и графиков внутри документа.

Gemini меняет правила игры. Благодаря огромному контекстному окну и специальному File API, мы можем загружать документы целиком. Модель «видит» документ так же, как и человек: с заголовками, сносками, диаграммами в PDF и сложной структурой данных в CSV. Но просто отправить 500 МБ текста в промпт — это неэффективно и дорого. Именно здесь на сцену выходит File API.

Что такое File API и как это работает?

File API в экосистеме Gemini — это промежуточное хранилище. Когда вы отправляете файл, он не попадает сразу в промпт. Процесс выглядит так:

  1. Загрузка (Upload): Вы отправляете файл на серверы Google. Ему присваивается уникальный URI.
  2. Обработка (Processing): Система анализирует файл. Для PDF происходит OCR и разбор структуры, для видео — нарезка кадров и анализ аудиодорожки. Это занимает время (от секунд до минут).
  3. Инференс (Inference): Вы обращаетесь к модели, передавая ей не «сырой» файл, а его file_uri. Модель подтягивает уже обработанные данные из кэша.
  4. Удаление (Cleanup): Файлы временные. По умолчанию они живут 48 часов, но хорошим тоном считается удалять их сразу после использования.

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

python
import os
import time
import google.generativeai as genai

# Настройка API ключа
# В реальном проекте используйте переменные окружения!
genai.configure(api_key=os.environ["GEMINI_API_KEY"])

def upload_and_monitor(file_path, display_name=None):
    """
    Загружает файл и ожидает завершения его обработки.
    """
    print(f"Начинаю загрузку файла: {file_path}...")
    
    # 1. Загрузка файла
    sample_file = genai.upload_file(
        path=file_path,
        display_name=display_name
    )
    
    print(f"Файл загружен: {sample_file.display_name} ({sample_file.uri})")
    
    # 2. Ожидание обработки (Polling)
    # Важный этап: нельзя использовать файл, пока state != ACTIVE
    while sample_file.state.name == "PROCESSING":
        print("Обработка файла... ждем 5 секунд")
        time.sleep(5)
        sample_file = genai.get_file(sample_file.name)
        
    if sample_file.state.name == "FAILED":
        raise ValueError("Не удалось обработать файл.")
        
    print(f"Файл готов к использованию! Состояние: {sample_file.state.name}")
    return sample_file

Работа с PDF: Мультимодальность в действии

PDF — это самый сложный формат. Это не просто текст, это визуальное представление. Традиционные парсеры часто ломаются на двухколоночной верстке или путают подписи к графикам с основным текстом.

Gemini, используя свои мультимодальные возможности, воспринимает PDF визуально и текстуально одновременно. Если в вашем финансовом отчете есть круговая диаграмма, модель не просто прочитает цифры рядом, она «увидит» сектора диаграммы.

Практический кейс: Анализ контрактов

Представьте, что у вас есть 50-страничный договор аренды. Вы хотите найти все пункты, касающиеся штрафов за просрочку, и сравнить их с законодательством. Загружая файл через File API, вы можете попросить модель сделать именно это, ссылаясь на конкретные страницы.

python
# Представим, что у нас есть файл 'contract.pdf'
# Используем функцию, которую мы написали выше
pdf_file = upload_and_monitor("contract.pdf", display_name="Contract 2024")

# Инициализация модели (используем модель с поддержкой большого контекста)
# Gemini 1.5 Pro или более новые версии Gemini 3 идеально подходят
model = genai.GenerativeModel("gemini-1.5-pro-latest")

# Формируем запрос
prompt = """
Проанализируй этот документ.
1. Какова общая сумма контракта?
2. Найди все условия расторжения договора.
3. Если есть графики платежей, представь их в виде таблицы Markdown.
"""

# Передаем файл как часть контента
response = model.generate_content([prompt, pdf_file])

print(response.text)
Упражнение

Напишите скрипт, который загружает PDF-файл (например, инструкцию к бытовой технике), дожидается его обработки и затем спрашивает у модели: «Как устранить неисправность, если мигает красный индикатор?». Не забудьте обработать возможные ошибки загрузки.

CSV и Code Execution: Анализ данных без галлюцинаций

Теперь перейдем к CSV. Загружать CSV как текст в промпт — плохая идея для больших датасетов. Модели могут «потеряться» в рядах цифр или начать выдумывать (галлюцинировать) результаты вычислений. LLM — это гуманитарии, а не калькуляторы.

Однако, в Gemini 3 API есть мощная связка: File API + Code Execution.

Когда вы загружаете CSV и включаете инструмент code_execution, происходит магия. Модель не пытается посчитать среднее значение в уме. Она:

  • Понимает, что это файл данных.
  • Пишет код на Python (используя Pandas) для чтения этого файла.
  • Выполняет этот код в безопасной песочнице.
  • Возвращает вам точный результат вычислений.

Это превращает Gemini в полноценного аналитика данных.

python
# Загружаем датасет продаж
csv_file = upload_and_monitor("sales_data_2024.csv", display_name="Sales Q1")

# Включаем инструмент выполнения кода
model_with_tools = genai.GenerativeModel(
    model_name="gemini-1.5-pro-latest",
    tools="code_execution" # <-- Ключевой момент
)

analysis_prompt = """
Используя данные из файла:
1. Построй график продаж по месяцам (опиши тренд).
2. Рассчитай средний чек заказа.
3. Какая категория товаров самая прибыльная?
"""

# Модель сама напишет код для pd.read_csv(file_uri) и выполнит его
response = model_with_tools.generate_content([analysis_prompt, csv_file])

# Мы можем даже посмотреть код, который написала модель
for part in response.parts:
    if part.executable_code:
        print("--- Сгенерированный Python код ---")
        print(part.executable_code.code)
    if part.text:
        print("--- Ответ ---")
        print(part.text)

Управление жизненным циклом файлов

File API предоставляет хранилище объемом до 20 ГБ на проект. Хотя файлы удаляются автоматически через 48 часов, профессиональный разработчик должен управлять мусором (Garbage Collection) самостоятельно. Это вопрос гигиены разработки и безопасности данных.

API предоставляет методы для листинга всех загруженных файлов и их принудительного удаления. Это особенно важно, если вы строите агента, который обрабатывает сотни документов в день.

python
def cleanup_old_files():
    """
    Удаляет все файлы, созданные через API.
    Внимание: удалит все файлы в проекте!
    """
    print("Начинаем очистку хранилища...")
    files = genai.list_files()
    count = 0
    for f in files:
        print(f"Удаление {f.display_name} ({f.name})...")
        genai.delete_file(f.name)
        count += 1
    print(f"Удалено файлов: {count}")

# Вызывать с осторожностью!
# cleanup_old_files()
Вопрос

Почему необходимо проверять состояние файла (file.state) после загрузки через upload_file?

Заключение

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

Ключевые выводы:

  • Большие документы загружаем через upload_file, а не через текст base64.
  • Всегда ждем смены статуса на ACTIVE.
  • Для точных вычислений в CSV используем code_execution.
  • Не забываем удалять файлы после работы.

В следующем уроке мы рассмотрим, как кэшировать контекст (Context Caching), чтобы работа с одними и теми же файлами стала дешевле и быстрее.