Как я создал Text Extract API для RAG за 2 дня с помощью AI и Cursor: подробный кейс

Разработка с помощью AI‑инструментов меняет подход к созданию ПО. Я сам убедился в этом на практике: всего за два дня мне удалось создать Text Extract API для RAG, используя Claude 4.0, Gemini Pro 2.5 и IDE Cursor. Этот эксперимент показал, что нейросети — уже не просто хайп, а мощный ассистент, способный значительно ускорить процесс разработки.

Наша команда занимается созданием ПО для IT‑специалистов — программу «Управление IT‑отделом 8». В ней есть блок для работы с заявками от клиентов и обширная база знаний. Возникла идея: интегрировать нейросети для автоматической обработки тикетов. Кейс прост:

Прилетает тикет от клиента > Нейросеть смотрит в базу знаний и готовит ответ > IT‑специалист либо использует ответ нейросети, либо нейросеть отвечает автоматически.

Для реализации такого функционала необходимо обучить AI‑модель на нашей базе знаний, а это требует качественного извлечения текста из различных документов. Эта статья посвящена первому этапу этого процесса — созданию API для извлечения текстовых данных из файлов любых форматов, что критически важно для эффективной работы с Retrieval‑Augmented Generation (RAG).

Для тех, кто хочет сразу увидеть результат, вот ссылка на GitHub.

Постановка задачи и выбор инструментов

Зачем это все нужно?

Есть такая замечательная штука, которую придумали для обучения нейросетей, которая называется Embeddings.

Embeddings — это векторное представление текстовых данных. Они используются для того, чтобы потом можно было из вопроса пользователя получить векторное представление (наборы чисел). Интересно то, что если потом и из вопроса получить Embeddings, то окажется, что векторное представление вопроса и наиболее релевантных ответов будут максимально близко находятся друг к другу.

Если выбрать N‑записей, которые будут максимально близко к вопросу и извлечь релевантный текст этих записей, а потом скормить все это богатство уже модели AI (например, GPT-4), но с вопросом пользователя и в контекст подкинуть те N‑записей, что мы нашли, то нейросеть подготовит хороший ответ на вопрос пользователя. Схема примерно следующая:

Упрощенная схема работы с базой знаний AI

Зачем такие сложности и почему сразу не спросить нейросеть и задать ей тот вопрос, который задал клиент? Дело в том, что нейросеть может ничего не знать о каких‑то специфических вещах. Ну например, на предприятии есть какой‑нибудь регламент и вопрос прилетает именно по этому регламенту. Что в таком случае ответит нейросеть? Правильно, ерунду…Мемчик

Поэтому общая схема ответа на вопрос пользователя по базе знаний с использованием AI будет такой:

Упрощенная схема ответа на вопрос пользователя по базе знаний Embeddings AI

Как работает RAG

  1. Retrieval (извлечение)
    Модель получает запрос и обращается к базе данных (чаще всего с эмбеддингами) для поиска релевантных документов или фрагментов текста.

  2. Augmentation (обогащение)
    Найденная информация добавляется к исходному запросу.

  3. Generation (генерация ответа)
    Языковая модель (например, GPT-4) использует расширенный контекст (вопрос + найденные документы), чтобы выдать точный и обоснованный ответ.

Это очень упрощенная формулировка и алгоритм. Очень хорошее описание RAG в статье Архитектура RAG: полный гайд.

Формализация требований: сила хорошего ТЗ

Итак, наша задача общими словами — это на первом этапе научиться получать текст из всего, что может понадобиться: docx, xlsx, pdf, png, jpg, doc, xls, zip, rar, 7z …

Если картинка, нужно распознать на ней текст, если офисный документ — достать текст оттуда, таблицу прочитать так, чтобы поняла текстовая модель, архивы распаковать и достать оттуда все вложенные файлы и с ними сделать то же самое. Фронт работы огромный.

Я начал с самого главного. С написания подробного технического задания (ТЗ). Есть такая прибаутка у аналитиков: «Без ТЗ результат ХЗ». При вайб‑кодинге с нейросетью, как я понял, это истина на 100% :)

Подготовил промпт в Google Gemini. Попросил ТЗ для извлечения текста:

Роль:
Ты — эксперт по составлению технических заданий (ТЗ).
Твоя задача:
Задавать уточняющие вопросы для формирования четкого ТЗ. Формулировать структурированное ТЗ на основе ответов. Проверять ТЗ на полноту и корректность, уточняя недостающие детали.
Контекст:
Входные данные:
Мне нужно простое API для извлечения текста из файлов различных форматов.
Изображения с OCR:.jpg,.jpeg,.png,.tiff,.tif,.bmp,.gif (распознавание на русском и английском)
Текстовые файлы:.txt
HTML документы:.html,.htm
Markdown файлы:.md,.markdown
Обработка через textract
Документы:.doc,.docx,.pdf,.rtf,.odt
Таблицы:.csv,.xls,.xlsx,.ods
Презентации:.pptx,.ppt
Электронные книги:.epub
Email:.eml,.msg
Данные:.json
Markdown:.md,.markdown
Выходные данные:
Готовое ТЗ в структурированном формате.
Проверка и уточнение ТЗ для исключения двусмысленностей.
Цель:
Создать ТЗ, которое:
Полностью описывает задачу или проект.
Учитывает все ключевые аспекты (функционал, ограничения, технологии).
Легко понимается разработчиками и другими участниками команды.
Ограничения:
Все требования должны быть изложены четко и без двусмысленностей.
Если пользователь не отвечает на вопросы, использовать значения по умолчанию.
Параметры генерации:
Формат вывода:
Черновик ТЗ → Проверка → Итоговое ТЗ.
Дополнительно:
Рекомендации по улучшению ТЗ.
Примеры типовых решений для сложных случаев.

В результате после общения с нейросетью и кучи правок, я получил отличное ТЗ для разработки.
Вот что получил в итоге:

  • Поддерживаемые форматы (PDF, DOCX, изображения,архивы, исходный код и др.)

  • Требования к безопасности (валидация MIME‑типов, защита от zip‑бомб, fail‑closed по умолчанию)

  • Нефункциональные параметры (таймауты, максимальный размер файлов, асинхронность)

  • Структуру API и примеры ответов

  • Требования к тестированию и инфраструктуре (Docker, Makefile, CI/CD).

Конечно, в процессе разработки ТЗ редактировалось, но сама суть дальше уже почти не менялась.

Совет: чем подробнее и структурированнее ТЗ, тем проще автоматизировать разработку и ревью, особенно если вы планируете использовать AI‑ассистентов.

Почему Cursor и AI?

Cursor — современная IDE, ориентированная на интеграцию с AI‑моделями. В связке с Claude 4.0 и Gemini Pro 2.5 она позволяет:

  • быстро генерировать boilerplate‑код

  • получать архитектурные рекомендации

  • автоматизировать рутинные задачи (настройка Docker, Makefile, тестов)

  • проводить ревью и рефакторинг с помощью AI

Практический пример: Я использовал Cursor для генерации FastAPI‑контроллеров, интеграции с Uvicorn и Docker, а также для написания unit и integration‑тестов.

Архитектура решения: от идеи к коду

Общая структура проекта

Проект был организован по классическим принципам Python‑разработки:

  • app/ — исходный код (extractors, utils, main, config)

  • tests/ — тесты и тестовые данные

  • Makefile, Dockerfile, docker-compose.yml — автоматизация сборки и запуска

  • docs/TZ.md — живое техническое задание, обновляемое по мере развития проекта

Совет: Ведение актуального ТЗ в репозитории — залог прозрачности и воспроизводимости разработки. Это облегчает ревью, автоматизацию и масштабирование команды.

Ключевые архитектурные решения

Асинхронность и изоляция

Все ресурсоемкие операции (OCR, парсинг PDF, работа с архивами) выполняются вне основного event loop с помощью run_in_threadpool. Это позволяет обрабатывать большие файлы, не блокируя сервер, и масштабировать API горизонтально.

Безопасность

  • Fail‑closed: любые сомнительные файлы отклоняются.

  • Валидация MIME‑типов: ароверка соответствия расширения и содержимого.

  • Ограничения на размер и глубину архивов: защита от zip‑бомб и path traversal.

  • Изоляция временных файлов: использование контекстных менеджеров и автоматическая очистка.

Все параметры (порт, языки OCR, таймауты, лимиты) задаются через переменные окружения, что облегчает деплой и CI/CD.

API снабжен автогенерируемой Swagger‑документацией, что критично для интеграции с внутренними сервисами.

Пример реализации эндпоинта

@app.post("/v1/extract/")
async def extract_text(file: UploadFile = File(...)):
    # Валидация, обработка, логирование
    extracted_files = await asyncio.wait_for(
        run_in_threadpool(
            text_extractor.extract_text, content, safe_filename_for_processing
        ),
        timeout=settings.PROCESSING_TIMEOUT_SECONDS
    )
    return {"status": "success", "files": extracted_files}


Практический совет: используйте asyncio.wait_for для контроля таймаутов на уровне API — это позволяет возвращать понятные ошибки (504 Gateway Timeout) и защищает сервер от зависаний.

Тестирование: автоматизация, проблемы и решения

Автоматизация тестирования

В проекте реализованы:

  • Unit‑тесты для extractors и utils,

  • Integration‑тесты для API,

  • Legacy‑тесты с реальными файлами (через run_tests.sh).

Инструменты: pytest, httpx, pytest‑asyncio, pytest‑cov.

Проблемы и ограничения

Несмотря на автоматизацию, тесты не всегда покрывают все edge‑cases:

  • Некоторые форматы (например, архивы с вложенными файлами) сложно тестировать автоматически.

  • Генерация тестовых данных для всех поддерживаемых форматов требует времени и ручной работы.

  • Legacy‑тесты не всегда интегрируются с CI/CD и могут давать ложноположительные результаты.

Совет: для сложных форматов используйте property‑based testing (например, с помощью Hypothesis), а для интеграционных сценариев — мокайте внешние зависимости (LibreOffice, Tesseract).

Практические рекомендации по тестированию

  • Покрытие кода: Сейчас ~60% (контролируется через pytest‑cov).

  • Изоляция тестов: Каждый тест должен быть независимым и не оставлять временных файлов.

  • Воспроизводимость: Все тестовые данные должны храниться в репозитории, а результаты — игнорироваться через.gitignore.

  • CI/CD: Интегрируйте тесты в pipeline, чтобы не допускать регрессий.

Опыт работы с AI и Cursor: плюсы, минусы, лайфхаки

Как AI помогал (и мешал)

Я использовал Claude 4.0 в качестве основной нейросети. После создания проекта, просим его по файлу ТЗ реализовать функциональность. Если есть вопросы задать их нам перед началом.

Дальше AI набросал вполне годное API на Python и FastAPI. Я разобрал структуру созданного проекта и завел правила для курсора (Cursor Rules). В правилах не жестил, просто нашел шаблон, который нужен, и добавил от себя где искать основные файлы проекта. Это обязательный шаг. Нужен он для того, чтобы при каждом запросе нейросеть не исследовала проект с нуля, а использовала готовую информацию о том, как организован код и что разработчик от нее ждет.

После этого пошли уже улучшения, добавление новых файлов для поддержки и т. д.

Основной кейс использования такой:

  1. Мне нужно реализовать по TZ.md такой‑то блок / возможность (пишем что нужно). Напиши код, при необходимости добавь тесты и обнови документацию.

  2. Он пишет код.

  3. Мы проверяем и находим какие‑то недочеты.

  4. Просим исправить если находятся ошибки.

  5. Повторяем до того момента, пока блок / возможность / фича / ошибка будут сделаны. Возможно правим что‑то самостоятельно.

Таких итераций было достаточно много.

Далее наступил момент, когда сделано немало и вроде как всё работает, но все равно страшно:) Например, а вдруг есть какие‑то проблемы с безопасностью. Когда код написан нейросетью и ты не уверен в его правильности, то необходимо все перепроверить. Каким образом? Просим другую нейросеть))) Я использовал Gemini 2.5 Pro.

Промпт:

Я написал исходный код в проекте. Файл ТЗ находится в папке docs. Проверь проект на соответствие ТЗ, дополнительно ты должен найти в коде ошибки, уязвимости, неточности, проблемы с производительностью и все то, что может вызвать проблемы на prodaction.

Далее было найдено несколько серьезных моментов, которые снова скармливаем Claude 4.0. Например, обработка архивов с path traversal, zip‑bomb, синхронная работа некоторых распаковщиков файлов, вместо асинхронной и еще парочка интересных моментов были найдены на этих моментах.

На все про все у меня ушло 2 дня (!) и получил готовый API. Я бы не поверил, если бы сам лично в этом не участвовал

ChatGPT в «Управление IT-отделом 8»
Ассистент на основе ChatGPT готов помочь вам с любыми вопросами
Подробнее
Изображение автора статьи

Основатель и директор по развитию Софтонит. Практикующий руководитель разработки. Эксперт в области автоматизации техподдержки

Загрузка...
Поделитесь статьей
Рекомендуем почитать
Статьи Учет картриджей в Excel

Сегодня рассмотрим сквозной пример создания таблицы Excel для реализации учета картриджей на предприятии. На данном примере, Вы сможете почерпнуть для себя полезность автоматизации ведения учета.

Статьи Открытие задач при командной разработке в gitlab (github) в Управление IT-отделом 8

Часто при разработке с gitlab (github), в случае если используется собственная система учета задач, хочется открывать задания пользователей из репозитория gitlab по щелчку мыши и чтобы сразу открывалась задача источник. Мы в своей работе используем gitlab - для разработки и Управление IT-отделом 8 - для ведения списка заданий.
Давайте рассмотрим как настроить открытие задач gitlab в конфигурации. Для github это же можно настроить аналогично.

Статьи Собираем статистику печати пользователей

У Вас есть сервер печати на сервере Windows? Нужна статистика использования и печати на принтерах и МФУ? Необходимо определить наиболее активно используемые устройства, оценить нагрузку на них и принять своевременные решения по закупке расходных материалов, техническом обслуживании или даже замене на более экономичные и производительные?
Тогда эта статья для Вас!
Научимся собирать и анализировать статистику используя данные сервера печати, а так же посмотрим как работать с ними в конфигурации Управление IT-отделом 8.

Статьи Метод Любищева и учет времени по мотивам книги Даниила Гранина «Эта странная жизнь»

В статье рассмотрено как содержание книги Даниила Гранина «Эта странная жизнь», так и разработанная нами система учета времени по методу Любищева.
Мы внедрили функционал учета рабочего времени в мобильное приложение и десктопную версию конфигурации Управление IT-отделом 8.
И даже опробовали ее на себе! Что из этого получилось давайте рассмотрим подробнее и с какими трудностями мы столкнулись.

Статьи 1С синхронизация данных в Power BI с помощью интерфейса OData

Иногда появляется необходимость в расширении аналитических инструментов в организации с помощью различного ПО. Но, как объединить два абсолютно сторонних программных продукта в один механизм, который приносит максимальную пользу? Ответ есть, сегодня рассмотрим синхронизацию конфигурации "Управление IT-отделом 8" и Microsoft Power BI, используя канал OData. 

Опыт клиентов Как увеличить штат разработчиков используя Управление IT-отделом 8. Опыт компании «ВИТТА ЛАБ»

Заместитель технического директора компании «ВИТТА ЛАБ» Белых Александр, рассказал о своем опыте, как у него получилось увеличить штат разработчиков используя Управление IT-отделом 8. Мы с Александром познакомились на конференции Infostart Event 2022 в Санкт-Петербурге. «Пообщаться» затянулось и мы потом встречались несколько раз и говорили на темы, связанные с учетом в ИТ и не только. Кейс будет интересен ИТ-руководителям.

0 / 0