Разработка с помощью 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.
1. Постановка задачи и выбор инструментов
1.1. Зачем это все нужно?
Есть такая замечательная штука, которую придумали для "обучения" нейросетей, которая называется Embeddings. Как правильно подсказали в комментариях, это не совсем обучение, но выглядит именно так.
Embeddings — это векторное представление текстовых данных. Они используются для того, чтобы потом можно было из вопроса пользователя получить векторное представление (наборы чисел). Интересно то, что если потом и из вопроса получить Embeddings, то окажется, что векторное представление вопроса и наиболее релевантных ответов будут максимально близко находятся друг к другу.
Если выбрать N‑записей, которые будут максимально близко к вопросу и извлечь релевантный текст этих записей, а потом скормить все это богатство уже модели AI (например, GPT-4), но с вопросом пользователя и в контекст подкинуть те N‑записей, что мы нашли, то нейросеть подготовит хороший ответ на вопрос пользователя. Схема примерно следующая:

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

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

1.2. Как работает RAG
Retrieval (извлечение)
Модель получает запрос и обращается к базе данных (чаще всего с эмбеддингами) для поиска релевантных документов или фрагментов текста.Augmentation (обогащение)
Найденная информация добавляется к исходному запросу.Generation (генерация ответа)
Языковая модель (например, GPT-4) использует расширенный контекст (вопрос + найденные документы), чтобы выдать точный и обоснованный ответ.
Это очень упрощенная формулировка и алгоритм. Очень хорошее описание RAG в статье Архитектура RAG: полный гайд.
1.3. Формализация требований: сила хорошего ТЗ
Итак, наша задача общими словами — это на первом этапе научиться получать текст из всего, что может понадобиться: 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‑ассистентов.
1.4. Почему Cursor и AI?
Cursor — современная IDE, ориентированная на интеграцию с AI‑моделями. В связке с Claude 4.0 и Gemini Pro 2.5 она позволяет:
быстро генерировать boilerplate‑код
получать архитектурные рекомендации
автоматизировать рутинные задачи (настройка Docker, Makefile, тестов)
проводить ревью и рефакторинг с помощью AI
Практический пример: Я использовал Cursor для генерации FastAPI‑контроллеров, интеграции с Uvicorn и Docker, а также для написания unit и integration‑тестов.
2. Архитектура решения: от идеи к коду
2.1. Общая структура проекта
Проект был организован по классическим принципам Python‑разработки:
app/ — исходный код (extractors, utils, main, config)
tests/ — тесты и тестовые данные
Makefile, Dockerfile, docker-compose.yml — автоматизация сборки и запуска
docs/TZ.md — живое техническое задание, обновляемое по мере развития проекта
Совет: Ведение актуального ТЗ в репозитории — залог прозрачности и воспроизводимости разработки. Это облегчает ревью, автоматизацию и масштабирование команды.
2.2. Ключевые архитектурные решения
Асинхронность и изоляция
Все ресурсоемкие операции (OCR, парсинг PDF, работа с архивами) выполняются вне основного event loop с помощью run_in_threadpool. Это позволяет обрабатывать большие файлы, не блокируя сервер, и масштабировать API горизонтально.
Безопасность
Fail‑closed: любые сомнительные файлы отклоняются.
Валидация MIME‑типов: ароверка соответствия расширения и содержимого.
Ограничения на размер и глубину архивов: защита от zip‑бомб и path traversal.
Изоляция временных файлов: использование контекстных менеджеров и автоматическая очистка.
Все параметры (порт, языки OCR, таймауты, лимиты) задаются через переменные окружения, что облегчает деплой и CI/CD.
API снабжен автогенерируемой Swagger‑документацией, что критично для интеграции с внутренними сервисами.
2.3. Пример реализации эндпоинта
@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) и защищает сервер от зависаний.
3. Тестирование: автоматизация, проблемы и решения
3.1. Автоматизация тестирования
В проекте реализованы:
Unit‑тесты для extractors и utils,
Integration‑тесты для API,
Legacy‑тесты с реальными файлами (через run_tests.sh).
Инструменты: pytest, httpx, pytest‑asyncio, pytest‑cov.
3.2. Проблемы и ограничения
Несмотря на автоматизацию, тесты не всегда покрывают все edge‑cases:
Некоторые форматы (например, архивы с вложенными файлами) сложно тестировать автоматически.
Генерация тестовых данных для всех поддерживаемых форматов требует времени и ручной работы.
Legacy‑тесты не всегда интегрируются с CI/CD и могут давать ложноположительные результаты.
Совет: для сложных форматов используйте property‑based testing (например, с помощью Hypothesis), а для интеграционных сценариев — мокайте внешние зависимости (LibreOffice, Tesseract).
3.3. Практические рекомендации по тестированию
Покрытие кода: Сейчас ~60% (контролируется через pytest‑cov).
Изоляция тестов: Каждый тест должен быть независимым и не оставлять временных файлов.
Воспроизводимость: Все тестовые данные должны храниться в репозитории, а результаты — игнорироваться через.gitignore.
CI/CD: Интегрируйте тесты в pipeline, чтобы не допускать регрессий.
4. Опыт работы с AI и Cursor: плюсы, минусы, лайфхаки
4.1. Как AI помогал (и мешал)
Я использовал Claude 4.0 в качестве основной нейросети. После создания проекта, просим его по файлу ТЗ реализовать функциональность. Если есть вопросы задать их нам перед началом.
Дальше AI набросал вполне годное API на Python и FastAPI. Я разобрал структуру созданного проекта и завел правила для курсора (Cursor Rules). В правилах не жестил, просто нашел шаблон, который нужен, и добавил от себя где искать основные файлы проекта. Это обязательный шаг. Нужен он для того, чтобы при каждом запросе нейросеть не исследовала проект с нуля, а использовала готовую информацию о том, как организован код и что разработчик от нее ждет.
После этого пошли уже улучшения, добавление новых файлов для поддержки и т. д.
Основной кейс использования такой:
Мне нужно реализовать по TZ.md такой‑то блок / возможность (пишем что нужно). Напиши код, при необходимости добавь тесты и обнови документацию.
Он пишет код.
Мы проверяем и находим какие‑то недочеты.
Просим исправить если находятся ошибки.
Повторяем до того момента, пока блок / возможность / фича / ошибка будут сделаны. Возможно правим что‑то самостоятельно.
Таких итераций было достаточно много.
Далее наступил момент, когда сделано немало и вроде как всё работает, но все равно страшно:) Например, а вдруг есть какие‑то проблемы с безопасностью. Когда код написан нейросетью и ты не уверен в его правильности, то необходимо все перепроверить. Каким образом? Просим другую нейросеть))) Я использовал Gemini 2.5 Pro.
Промпт:
Я написал исходный код в проекте. Файл ТЗ находится в папке docs. Проверь проект на соответствие ТЗ, дополнительно ты должен найти в коде ошибки, уязвимости, неточности, проблемы с производительностью и все то, что может вызвать проблемы на prodaction.
Далее было найдено несколько серьезных моментов, которые снова скармливаем Claude 4.0. Например, обработка архивов с path traversal, zip‑bomb, синхронная работа некоторых распаковщиков файлов, вместо асинхронной и еще парочка интересных моментов были найдены на этих моментах.
На все про все у меня ушло 2 дня (!) и получил готовый API. Я бы не поверил, если бы сам лично в этом не участвовал ?
Конечно то, что нейросеть не нашла больше проблем не значит что их нет. Надо самому проводить ревью и анализ кода.
Плюсы:
Быстрая генерация шаблонного кода (FastAPI, Docker, Makefile).
Автоматизация рутинных задач (валидация, логирование, обработка ошибок).
Генерация тестов и документации.
Минусы:
AI не всегда понимает специфику (например, обработка архивов с path traversal).
Требуется ручная доработка и ревью, особенно для сложных сценариев.
Иногда AI генерирует избыточный или неэффективный код (например, дублирует проверки).
Ну и куда же без ложки дегтя. Было и такое, что AI забывал контекст и делал не то и после того, как его поправляешь, он начинает писать и хвалить тебя:
Вы правы, я допустил ошибку …
Вы подняли очень важный вопрос! …
И т.д.
Выглядит это все забавно, но забавно это ровно до того момента, если ты увидел и нашел проблему. А если же нет, то это останется в проекте и возможно потом выстрелит в не самое подходящее время...
Совет: используйте AI как ассистента, а не как единственный источник истины. Всегда проводите ревью и тестирование вручную. Также не стоит одним промптом решать сразу несколько сложных вопросов. Это чревато тем, что это будет выполнено не очень качественно.
4.2. Практические лайфхаки
Cursor + Claude 4.0: Отлично подходит для генерации boilerplate и архитектурных решений.
Gemini Pro 2.5: Хорош для ревью и генерации тестов.
Промпт‑инжиниринг: Чем подробнее и структурированнее ваш запрос, тем качественнее результат. Не стесняйтесь давать AI примеры и контекст.
Интеграция с git: Используйте AI для генерации changelog и автоматического обновления документации.
4.3. Статистика и метрики
Время разработки: С помощью AI и Cursor MVP был реализован за 2 дня!
Покрытие тестами: 60% кода покрыто unit и integration тестами.
Производительность: Обработка PDF‑файла 10 МБ — менее 10 секунд на сервере с 4 CPU.
Заключение
Приступая к этому проекту при использовании Cursor, я совсем не ожидал, что проект будет реализован за такой короткий срок.
Главный вывод, который я сделал для себя: программист в случае использования AI‑инструментов — это как дирижер. Он может не уметь играть на каких‑то инструментах, но он должен хорошо понимать музыку и точно знать, что ему нужно получить от музыкантов. Если этого понимания нет, то ничего хорошего не выйдет.
Просьба к нейросети «напиши хорошую программу» вовсе не гарантирует, что понятие хорошего результата у AI и у вас будут одинаковыми ?

Второй важный вывод. AI в текущем виде еще не так хорош. Но как мне кажется это только самое начало и этот инструмент точно займет свое место в корпоративной среде. Будущее уже наступило.
Современные инструменты — AI, Cursor — позволяют существенно ускорить и упростить разработку ПО, особенно для задач, связанных с обработкой неструктурированных данных. Однако автоматизация не отменяет необходимости в хорошем проектировании, тестировании и ревью.
Надеюсь, мой опыт будет полезен тем, кто планирует внедрять подобные решения в своих компаниях.
Если вы работаете с корпоративными данными, интегрируете RAG или строите внутренние API — не бойтесь экспериментировать с AI и современными IDE. Делитесь своим опытом, задавайте вопросы в комментариях и не забывайте про тесты и безопасность!
Планы на будущее
Этот кейс с созданием Text Extract API — лишь первый шаг на пути интеграции нейросетей в наши корпоративные решения. Лично я вижу большой потенциал в использовании RAG для повышения эффективности работы в нашем решении. Следующий шаг по плану включает интеграцию этого API в другой сервис, который станет основой для полноценного RAG‑решения. Этот будущий сервис сможет не только извлекать текст, но и проводить семантический поиск по базе знаний, формировать базы знаний из файлов и предоставлять контекст для нейросети и генерировать максимально релевантные ответы на заявки клиентов.
Это только начало большой работы, и я с нетерпением жду возможности поделиться новыми результатами и опытом в будущих статьях.
P. S. Если вам интересны детали реализации, архитектурные решения или примеры кода — пишите, с радостью поделюсь дополнительными материалами и отвечу на вопросы! Github проекта.
© 2025 ООО «СОФТОНИТ»
Комментарии (4)
Lyrkchan
08.07.2025 14:55Только в RAG всё же не происходит "обучение модели", это важный аспект.
К слову, я делал тоже самое, но кроме .zip и прочего, а для OCR я использовал кроме tesseract ещё simpletex api. Делал по заказу одного ху~.., кхм, "бизнесмена": по знакомству начал с ним работать, а спустя месяц работы он отказался оплачивать хоть сколько-то. Далее я забросил проект: очевидно ничего не скидывал этому существу, но всё равно обидно ведь в целом я пошёл на такое сомнительное рискованное сотрудничество из-за жёсткой нужды в деньгах. Кстати хабром я пользуюсь не особо давно, и уж тем более не пишу посты/комментарии. В общем мне хочется узнать: было бы интересно если бы я выложил полностью историю как меня нагрел недобизнесмен, фаундер одной переводческой компании? Было бы это легитимно? Я имею ввиду в рамках правил хабра. И я бы наверное даже указал конкретные имена, название компании и даже выложил бы переписку чтобы подпортить репутацию данному существу.
Diversus Автор
08.07.2025 14:55Хорошее замечание про обучение. Это действительно моя оговорка. Все выглядит так, что мы модель как будто бы обучили, но это не так. Мы просто подсовываем ей нужный контекст в момент вопроса пользователя. Вот и вся магия.
Что касается вашей ситуации, то тут сложно что-то комментировать.
bitrix24ru
Очень подробно изложил, делал подобное в начале года + данные до этого собирал. А если Авито не отдает телефон и пользователь звонит по телефону? Да и во сколько обошлось в целом?
Diversus Автор
Спасибо за обратную связь, но я не совсем понимаю о чем вы ))) В статье вообще нет упоминания Авито и телефонных звонков.
Что же касается финансового вопроса, то специально не считал. Но я думаю не так много 20$ Cursor и модели где то еще на 50. Это я прям с запасом взял, скорее всего меньше.