AI и LLM сейчас на пике популярности. Но чаще всего их используют как инструменты, постоянно требующие времени и внимания. А что, если сделать из них «сотрудникAI и LLM сейчас на пике популярности. Но чаще всего их используют как инструменты, постоянно требующие времени и внимания. А что, если сделать из них «сотрудник

Нанимаем ChatGPT на работу или автоматизация бизнес-процессов

2026/02/17 11:31
31м. чтение
4c2640992dff43f06ae7fd78b4086b58.png

AI и LLM сейчас на пике популярности. Но чаще всего их используют как инструменты, постоянно требующие времени и внимания. А что, если сделать из них «сотрудников», которые сами автономно будут выполнять часть вашей работы?

В этой статье мы шаг за шагом создадим такого «сотрудника» на чистом OpenAI API и добьёмся его полной автономности. Он будет сам получать новые задачи, выполнять их и обрабатывать результаты. Мы научим его вести логи и отчеты, предупреждать о сбоях. По пути разберёмся с Batch API и Structured Outputs. А в конце поговорим про RAG, Fine-Tuning и MCP.

Статья написана на основании собственного опыта реализации и внедрения LLM в бизнес процессы. Будет полезна тем, кто хочет автоматизировать часть своей рабочей или личной рутины и базово владеет Python.

Этап 1. Выбор задачи и создание промпта

Шаг 1. Выбор задачи

Какие задачи лучше всего подходят для полной автоматизации? Условно их можно определить по трём критериям:

  1. Регулярность.
    Задача повторяется изо дня в день (неделю) и носит рутинный характер. Это именно тот тип работы, который вы без колебаний передали бы надёжному подрядчику.

  2. Вы доверяете LLM.
    Вы можете так сформулировать промпт и входные данные, что модель стабильно выдаёт корректный результат. И вы готовы принимать его «вслепую», без ручной проверки.

  3. Автоматическое получение и обработка данных.
    Сбор исходных данных и обработку ответов можно полностью автоматизировать — через SQL, API, парсинг или UI-автоматизацию.

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

Наша задача: Нам каждый день нужно переводить большие объемы описаний товаров с английского на русский. Можно было бы использовать готовый переводчик вроде Google Translate, но усложним задачу: нам нужен Instagram стиль — с эмодзи, яркий и продающий.

Допущения и упрощения

Всё, что мы будем делать, можно собрать в OpenAI Agent Builder, n8n, make.com и похожих инструментах. Но цель статьи — пройти путь вручную и понять, что происходит под капотом. Поэтому будем работать с чистым Python и OpenAI API.

Весь код из статьи доступен на GitHub: https://github.com/andrey7mel/Hiring-ChatGPT. Не забудьте установить свой ключ от OpenAI API в .env файле.

Шаг 2. Простой промпт в чате

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

Prompt_v1

Промпт
Переведи описание товара на русский язык в Instagram стиле с использованием emoji:

=====

New Balance Men's Fresh Foam X 1080 V14. If we only made one running shoe, it would be the Fresh Foam X 1080. The unique combination of reliable comfort and high performance offers versatility that spans from every day to race day.

  • Fresh Foam X midsole foam with approximately 3% bio-based content delivers our most cushioned Fresh Foam experience for incredible comfort. Bio-based content is made from renewable resources to help reduce our carbon footprint, enhancing these road running shoes.

  • These running shoes for women feature a gusseted tongue designed to help keep debris out

  • No-sew overlays

  • Synthetic and engineered mesh upper

  • Adjustable lace closure for a customized fit

====

Результат:


🚀 New Balance Мужские Fresh Foam X 1080 V14 🌟 Если бы у нас была только одна модель для бега, это были бы Fresh Foam X 1080. Уникальное сочетание надежного комфорта и высокой производительности 💪 становится универсальным как для повседневной носки, так и для спортивных забегов. 🏃‍♂️

🧬 Подошва Fresh Foam X с примерно 3% био-составом дарит невероятный комфорт. Био-состав из возобновляемых ресурсов помогает уменьшить углеродный след 🌿, улучшая эти беговые кроссовки.

👟 Эти кроссовки для женщин имеют язычок, защищающий от попадания мусора. Без швов - только стиль и комфорт! 💅 Верх из синтетики и инновационной сетки обеспечивает идеальный баланс.

🎯 Регулируемая шнуровка для индивидуальной посадки. ⛓️


Отлично — базовая возможность есть. Дальше переходим к критически важному этапу: оптимизации промпта.

По промпт-инжинирингу написано множество материалов (тут будут ссылки). Есть и специальные GPTs, которые помогают писать хорошие промпты. Также, с выходом ChatGPT-5 появился мощный инструмент для их оптимизации — Prompt Optimizer

Модифицируем наш промпт по лучшим практикам: добавим роль, описание задачи и контекста, примеры хороших текстов и нужный формат.

Модифицируем наш промпт по лучшим практикам: добавим роль, описание задачи и контекста, примеры хороших текстов и нужный формат.

Prompt_v2

Ты — эксперт по креативному контенту для Instagram. Переведи следующий текст на русский язык в стиле Instagram-поста для спортивного бренда

Твоя задача — создать привлекательный, живой и лёгкий для восприятия текст, используя эмодзи, энергичный тон и адаптированный стиль общения.
Адаптируй под Instagram-формат: сделай текст более эмоциональным, вдохновляющим, с акцентом на комфорт, силу, стиль и энергичность. Используй короткие абзацы, хештеги и в конце призыв к действию.

Пример текста:

======
Лето набирает обороты и градусы, а наш кроссовочный ассортимент – свежие цвета и силуэты 😎

Ну а если без прелюдий, ловите подборку с новинками недели, в которой вы найдете новые расцветки Vans Knu Skool, «Данков», «Мото» и многое другое.

Если нужна помощь в быстром оформлении заказа, подборе размера или модели, будем рады помочь в директе 🤍

======

В ответ напиши готовый текст для публикации в Instagram

Текст для перевода и адаптации:

New Balance Men's Fresh Foam X 1080 V14. If we only made one running shoe, it would be the Fresh Foam X 1080. The unique combination of reliable comfort and high performance offers versatility that spans from every day to race day.

  • Fresh Foam X midsole foam with approximately 3% bio-based content delivers our most cushioned Fresh Foam experience for incredible comfort. Bio-based content is made from renewable resources to help reduce our carbon footprint, enhancing these road running shoes.

  • These running shoes for women feature a gusseted tongue designed to help keep debris out

  • No-sew overlays

  • Synthetic and engineered mesh upper

  • Adjustable lace closure for a customized fit

Результат:

🔥 New Balance 1080 V14 — когда одной пары достаточно! 🔥

Если бы мы делали только одну беговую модель — это была бы ОНА. Fresh Foam X 1080 V14 — про максимум комфорта, производительность и универсальность 💥
Тренировка, марафон или повседневная суета — эта пара справится со всем 🏃‍♂️⚡

💡 Максимальная амортизация Fresh Foam X — мягко, как облако
🌱 3% био-компонентов — бегай с заботой о планете
🚀 Дышащая сетка и бесшовные вставки — никакого лишнего
🎯 Регулируемая шнуровка и язычок-защита — твой идеальный фит

1080 V14 — это стиль, сила и скорость в каждом шаге 🖤

Проверь новинку в нашем профиле и пиши в директ — поможем с выбором размера и не только 🙌

#NewBalance #FreshFoamX #NB1080V14 #RunYourWay #БегЭтоСвобода #МужскойСтиль #КомфортНаМаксималках

👉 Жми на ссылку в био и будь первым, кто выведет бег на новый уровень

Шаг 3. Доступ к OpenAI API и бесплатные токены

На первом шаге мы работали в обычной версии ChatGPT. Теперь переезжаем в API — он даёт больше контроля над моделью и подходит для автоматизации.

API оплачивается отдельно: вы платите за каждый запрос. Получить бесплатные кредиты и гранты можно здесь: https://platform.openai.com/settings/organization/billing/credit-grants

Дополнительно можно получать ежедневные бесплатные токены, если вы согласитесь делиться своими запросами с OpenAI: https://help.openai.com/en/articles/10306912-sharing-feedback-evals-and-api-data-with-openai

Когда доступ настроен, удобнее всего начать эксперименты в Playground: https://platform.openai.com/chat/edit?models=gpt-5-chat-latest

Шаг 4. Выбор модели и настройка параметров

В отличие от веб-версии, в API мы сами выбираем модель и её поведение. В целом логика простая: для простых рутинных задач подойдут обычные (не reasoning) модели, для сложных многошаговых задач — reasoning-модели.

Для обычных моделей важны параметры:

  • Temperature — управляет вариативностью текста. 0.0–0.3 даёт стабильные и предсказуемые ответы, 0.7–1.0 — более креативные и «живые» формулировки.

  • Max tokens — максимум длины ответа в токенах. Слишком низкое значение обрежет текст, слишком высокое — лишь повысит стоимость и задержку.

  • Top P — «nucleus sampling»: доля наиболее вероятных слов, из которых модель выбирает. При 1.0 ничего не отсекается; при 0.8–0.95 модель игнорирует «длинный хвост» редких слов, ответы становятся чуть стабильнее.

У reasoning-моделей появляются дополнительные настройки:

  1. Text format — формат финального ответа. По умолчанию — обычный текст. Если нужен Markdown или другая разметка, это нужно явно указать в запросе: GPT-5 по умолчанию не форматирует ответы в Markdown ради совместимости с приложениями без рендера.

  2. Reasoning effort — «усилие на рассуждение». Низкие значения дают быстрый и дешёвый ответ, высокие — более глубокий разбор многошаговых задач, больше инструментальных вызовов и контекста.

  3. Verbosity — длина финального ответа (не внутренних рассуждений). Меньше — короче, больше — подробнее.

  4. Summary — краткое описание того, что модель делает/сделала. Удобно в агентных сценариях: план действий, промежуточные апдейты, короткая выжимка результата.

Шаг 5. Адаптируем промпт для API

В API промпт описывается структурой из трёх блоков:

— System — «устав» и роль модели: язык, тон, формат, запреты. Это самый приоритетный слой.
— Prompt messages — история переписки, в том числе примеры вопросов и ответов.
— Chat message — конкретные входные данные для текущего вызова.

Если конфликтуют Prompt и Chat — побеждает Chat. Если что-то противоречит System — побеждает System.

Адаптируем наш промпт:

Prompt_v3

System message

Ты — эксперт по креативному контенту для Instagram. Переведи следующий текст на русский язык в стиле Instagram-поста для спортивного бренда

Твоя задача — создать привлекательный, живой и лёгкий для восприятия текст, используя эмодзи, энергичный тон и адаптированный стиль общения.

Адаптируй под Instagram-формат: сделай текст более эмоциональным, вдохновляющим, с акцентом на комфорт, силу, стиль и энергичность. Используй короткие абзацы, хештеги и в конце призыв к действию. В ответ напиши готовый текст для публикации в Instagram, без комментариев и дополнительного текст

Пример хорошего текста:

Лето набирает обороты и градусы, а наш кроссовочный ассортимент – свежие цвета и силуэты 😎

Ну а если без прелюдий, ловите подборку с новинками недели, в которой вы найдете новые расцветки Vans Knu Skool, «Данков», «Мото» и многое другое.

Если нужна помощь в быстром оформлении заказа, подборе размера или модели, будем рады помочь в директе 🤍

Chat message

New Balance Men's Fresh Foam X 1080 V14. If we only made one running shoe, it would be the Fresh Foam X 1080. The unique combination of reliable comfort and high performance offers versatility that spans from every day to race day.

Fresh Foam X midsole foam with approximately 3% bio-based content delivers our most cushioned Fresh Foam experience for incredible comfort. Bio-based content is made from renewable resources to help reduce our carbon footprint, enhancing these road running shoes.

These running shoes for women feature a gusseted tongue designed to help keep debris out

No-sew overlays

Synthetic and engineered mesh upper

Adjustable lace closure for a customized fit

Результат

🔥 Бег — это свобода, а свобода начинается с правильной пары кроссовок. Встречайте New Balance Fresh Foam X 1080 V14 — модель, которая создана, чтобы быть №1 в твоём спортивном арсенале 🚀

👟 Максимальный комфорт благодаря амортизации Fresh Foam X 🌱 Экологичный подход: пена с био-компонентами снижает углеродный след 💨 Лёгкий и дышащий верх из сетки + бесшовные вставки для идеальной посадки 🔒 Регулируемая шнуровка и язычок, который защищает от попадания мусора

Эта пара одинаково уверенно чувствует себя и на ежедневных пробежках, и на старте гонки 🏃‍♂️💨

Стиль + комфорт + производительность = твой новый уровень.

#NewBalance #FreshFoamX #RunYourWay #КомфортВСкорости #NB1080

⚡️ Готов прокачать свои пробежки? Пиши нам в директ и подбери свою пару уже сегодня!

Получилось! В Playground мы можем сразу скопировать код с нашими параметрами: (три точки наверху) - Code

Этап 2. Автоматическое получение, обработка и сохранение данных

Шаг 6. Автоматическое получение данных

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

В реальных проектах почти все данные живут в базах — обычно SQL-подобных. Идеальный сценарий: у вас есть прямой доступ к базе, где хранятся описания товаров.

Если доступа нет, данные придётся «добывать» обходными путями:

  • Парсинг веб-интерфейса. Можно использовать Selenium и дальше отправлять данные в ChatGPT. Пример:
    https://fatehaliaamir.medium.com/build-a-linkedin-scraper-using-selenium-and-openais-gpt-4o-mini-d0f5a61e9902

  • Загрузка сохранённых страниц. Сохраняем страницы в pdf/html, отправляем их в модель и просим вытащить нужные поля. Либо пользуемся готовыми парсерами вроде firecrawl.

  • Вызовы API сайта. Если у веб-приложения есть внутренний API, можно «подсмотреть» запросы (часто с учётом cookies) и вызывать их напрямую.

  • Нативные приложения. Тут пригодится UI-автоматизация: Power Automate Desktop, AutoHotkey, pywinauto, UiPath и аналогичные инструменты.

  • Отдельно отмечу Computer / Browser Use-системы. Перспективное направление, но пока нестабильное и требующее постоянного доступа к рабочим машинам и внутренним системам.

Вариантов много и они сильно зависят от вашей ситуации. В примере дальше считаем, что у нас есть доступ к SQL-базе.

Напишем SQL-запрос, который вытаскивает описания товаров, ещё не помеченные как переведённые. Если вы не чувствуете себя уверенно в Python или SQL, можно описать задачу текстом и попросить ChatGPT сгенерировать код — современные модели с таким справляются очень хорошо.

Код fetch_texts_to_translate

def fetch_texts_to_translate(): """Fetch untranslated products from the database and save them to a CSV file.""" try: conn = mysql.connector.connect( host='localhost', port=3306, database='my_database', user='my_user', password='my_password', ) # Use context manager to ensure the connection is properly closed with conn: with conn.cursor() as cursor: query = "SELECT id, text FROM products WHERE translated = 0" cursor.execute(query) rows = cursor.fetchall() if not rows: print("No products to translate were found.") return df = pd.DataFrame(rows, columns=['id', 'text']) df.to_csv('texts_to_translate.csv', index=False) print(f"Saved {len(df)} records to texts_to_translate.csv") except Error as e: # Database-related errors print(f"Database error while fetching texts to translate: {e}") except Exception as e: # Any other unexpected errors print(f"Unexpected error while fetching texts to translate: {e}")

В результате у нас появляется файл texts_to_translate.csv с ID и текстами, которые нужно перевести.

Шаг 7. Перевод через OpenAI API

Теперь осталось научить модель переводить эти тексты. Для этого пишем скрипт, который:

  • читает texts_to_translate.csv,

  • отправляет каждый текст в LLM с нашим промптом,

  • сохраняет результаты в translated_texts.csv.

Код translate_texts

def translate_texts(input_csv="art_h_gpt/texts_to_translate.csv", output_csv="art_h_gpt/translated_texts.csv", sleep_seconds=1.2): """Read texts from CSV, translate them with OpenAI, and save the result to a new CSV.""" df = pd.read_csv(input_csv) if df.empty: print(f"No rows found in {input_csv}. Nothing to translate.") return translated_texts = [] for idx, row in df.iterrows(): user_content = str(row["text"]) product_id = row["id"] try: # Send the request to OpenAI for translation and creative adaptation response = client.responses.create( model="gpt-5-chat-latest", instructions=system_prompt, input=user_content, temperature=0.9, # More creativity top_p=0.95, # Limit to most likely words max_output_tokens=4096, ) translated = response.output_text.strip() except Exception as e: # In a real production setup you might want to log this instead of printing print(f"Error translating product id {product_id}: {e}") translated = "" translated_texts.append(translated) # A small pause between requests to reduce the chance of hitting rate limits time.sleep(sleep_seconds) df["translated_text"] = translated_texts df.to_csv(output_csv, index=False) print(f"Saved {len(df)} translated records to {output_csv}")

Отлично, мы реализовали работу с OpenAI API

Шаг 8. Обработка полученных данных

Дальше нужно вернуть переводы во внутреннюю систему или базу. Как и на втором шаге, используем любой удобный для вас способ автоматизации:

  • прямой SQL-доступ к базе,

  • вызовы API вашей внутренней системы,

  • UI-автоматизацию с вводом текста в нужные поля.

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

save_translations_to_db

def save_translations_to_db(csv_path="translated_texts.csv"): """Update product translations in the database based on the CSV file.""" df = pd.read_csv(csv_path) if df.empty: print(f"No rows found in {csv_path}. Nothing to update.") return try: conn = mysql.connector.connect( host='localhost', port=3306, database='my_database', user='my_user', password='my_password', ) with conn: with conn.cursor() as cur: # Iterate over all products and update their translations in the database for idx, row in df.iterrows(): cur.execute( "UPDATE products " "SET translated_text = %s, translated = 1 " "WHERE id = %s", (row["translated_text"], int(row["id"])), ) # Commit changes only if all updates succeeded conn.commit() print(f"Updated {len(df)} rows in the database.") except Error as e: print(f"Database error while saving translations: {e}") except Exception as e: print(f"Unexpected error while saving translations: {e}")

Готово, у нас есть рабочие скрипты. Осталось настроить их автоматический запуск.

Шаг 9. Автоматический запуск

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

Но сервер есть не у всех, поэтому сделаем проще: настроим расписание на обычном компьютере c Windows — домашнем или рабочем. Важно только, чтобы он был включён в нужное время. Настроим запуск каждый день в 11:00.

Порядок действий:

1) Создаём в этой же папке файл run_all.bat, который последовательно запускает все три скрипта. Не забудьте поменять адрес папки со скриптами на первой строке.

run_all.bat

cd C:\app\translate call .venv\Scripts\activate.bat python extract_texts_from_db.py python openai_text_translator.py python save_translations_to_db.py

2) Создаем скрипт create_local_task.ps1 для автозапуска:

create_local_task.ps1

$ErrorActionPreference = 'Stop' # Name of the Scheduled Task $TaskName = "TranslateTask" # Full path to the batch file that should be executed by the task. $BatPath = "C:\app\translate\run_all.bat" # Run the task under the currently logged-on user. $UserId = "$env:UserDomain\$env:UserName" try { # Define the action: run the specified batch file. $action = New-ScheduledTaskAction ` -Execute $BatPath # Define a single trigger: run every day at 11:00. $triggers = @( New-ScheduledTaskTrigger -Daily -At 11:00 ) # Run the task only when the user is logged on (Interactive logon). $principal = New-ScheduledTaskPrincipal ` -UserId $UserId ` -LogonType Interactive ` -RunLevel Limited # Task settings: allow run on battery, wake the computer if needed, etc. $settings = New-ScheduledTaskSettingsSet ` -StartWhenAvailable ` -AllowStartIfOnBatteries ` -DontStopIfGoingOnBatteries ` -WakeToRun # Register or update the Scheduled Task. Register-ScheduledTask ` -TaskName $TaskName ` -Action $action ` -Trigger $triggers ` -Principal $principal ` -Settings $settings ` -Force Write-Host "Scheduled task '$TaskName' has been created or updated successfully." -ForegroundColor Green } catch { Write-Error "Failed to register scheduled task '$TaskName'. Details: $_" exit 1 }

3) Открываем папку с нашими скриптами (C:\app\translate), зажимаем Shift, кликаем правой кнопкой в пустое место в папку и выбираем Open PowerShell Window Here

4) Выполняем команду - .\create_local_task.ps1

В результату выполнения у вас должно отобразиться:

08145191fed27dd6abe163898ce9a268.png

Проверить статус задачи можно командой:
Get-ScheduledTaskInfo -TaskName RunColorsScript

Если задача уже не актуальна, можно удалить ее:
Unregister-ScheduledTask -TaskName RunColorsScript

Если вы сделали много задач, то можно посмотреть список всех задач (исключая системные от Microsoft):
Get-ScheduledTask | Where-Object { $_.TaskPath -notlike "\Microsoft\*" }

Шаг 10. Автоматический запуск в режиме администратора

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

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

Чтобы избавиться от этой зависимости, нужны права администратора. В этом случае мы можем создать задачу, которая будет выполняться всегда — в указанное время, даже если:

  • никто не вошёл в систему;

  • компьютер только что перезагрузился;

  • Нет активной пользовательской сессии.

Напишем код для создания админкой задачи:

create_admin_task.ps1

$ErrorActionPreference = 'Stop' # Name of the Scheduled Task $TaskName = "TranslateTaskAdmin" # Full path to the batch file that should be executed by the task. $BatPath = "C:\app\translate\run_all.bat" # Run the task under the currently logged-on user. $UserId = "$env:UserDomain\$env:UserName" try { # Define the action: run the specified batch file. $action = New-ScheduledTaskAction ` -Execute $BatPath # Define a single trigger: run every day at 11:00. $triggers = @( New-ScheduledTaskTrigger -Daily -At 11:00 ) # Principal: S4U without password, with highest privileges $principal = New-ScheduledTaskPrincipal ` -UserId $UserId ` -LogonType S4U ` -RunLevel Highest # Task settings: allow run on battery, wake the computer if needed, etc. $settings = New-ScheduledTaskSettingsSet ` -StartWhenAvailable ` -AllowStartIfOnBatteries ` -DontStopIfGoingOnBatteries ` -WakeToRun ` -ExecutionTimeLimit (New-TimeSpan -Minutes 30) # Register or update the Scheduled Task. Register-ScheduledTask ` -TaskName $TaskName ` -Action $action ` -Trigger $triggers ` -Principal $principal ` -Settings $settings ` -Force Write-Host "Scheduled task '$TaskName' has been created or updated successfully." -ForegroundColor Green } catch { Write-Error "Failed to register scheduled task '$TaskName'. Details: $_" exit 1 }

Далее нужно:

  1. Запустить PowerShell от имени администратора.

  2. Перейти в папку проекта - cd C:\app\translate

  3. Выполнить скрипт - .\create_admin_task.ps1

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

Этап 3. Улучшаем скрипт

Шаг 11. Запись логов в файл

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

Код log

def log(message): """Print message to console and save it to a daily log file.""" timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") line = f"{timestamp} {message}" # print to console print(line, flush=True) # ensure log directory exists log_dir = Path(LOG_DIR) log_dir.mkdir(parents=True, exist_ok=True) # daily file name, e.g. app_20250215.log filename = f"app_{datetime.now().strftime('%Y%m%d')}.log" filepath = log_dir / filename # append log line to file with filepath.open("a", encoding="utf-8") as f: f.write(line + "\n")

Теперь все логи попадают в файл с датой запуска скрипта. Если что-то пошло не так, можно быстро открыть лог и увидеть, на каком шаге произошла ошибка.

Шаг 12. Отчёты в Google Таблицах

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

Писать отчёты просто в файл неудобно: нам нужен постоянный доступ к компьютеру. Удобнее вести отчётность в Google Таблицах — тогда статистика всегда под рукой, с любого устройства. Альтернатива — телеграм-бот, который регулярно присылает отчеты.

Напишем функцию, которая добавляет запись в Google Таблицу:

Код publish_google_sheet_log

def publish_google_sheet_log(message): """ Insert a new log row at the TOP of the sheet. Column A = timestamp (local computer time) Column B = message """ if not GOOGLE_SHEET_ID or not SERVICE_ACCOUNT_JSON: raise RuntimeError("GOOGLE_SHEET_ID and SERVICE_ACCOUNT_JSON must be defined at the top of the file") try: creds = Credentials.from_service_account_file( SERVICE_ACCOUNT_JSON, scopes=[ "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive", ], ) service = build("sheets", "v4", credentials=creds) sheets = service.spreadsheets() timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Step 1: Shift existing rows down by 1 (insert a new top row) insert_request = { "insertRange": { "range": { "sheetId": 0, # works if the sheet uses the first tab (ID = 0) "startRowIndex": 0, "endRowIndex": 1 }, "shiftDimension": "ROWS" } } sheets.batchUpdate( spreadsheetId=GOOGLE_SHEET_ID, body={"requests": [insert_request]}, ).execute() # Step 2: write timestamp and message to A1 / B1 row_data = [[timestamp, message]] sheets.values().update( spreadsheetId=GOOGLE_SHEET_ID, range="A1:B1", valueInputOption="RAW", body={"values": row_data}, ).execute() except Exception as e: print(f"Error while publishing log to Google Sheets: {e}")

Для работы этой функции вам понадобится сервис аккаунт (это как API ключ для доступа к ресурсам Google)

Как получить service-account.json
  • Откройте Google Cloud Console по ссылке https://console.cloud.google.com и войдите под тем аккаунтом, где находится ваша таблица.

  • Создайте проект, если у вас его ещё нет. В верхней части нажмите на выбор проекта, выберите “New Project”, задайте любое имя и создайте проект.

  • Теперь включите нужные API. Откройте раздел “APIs & Services”, затем “Library”. Найдите и включите Google Sheets API.

  • После этого создайте сервисный аккаунт. Откройте “APIs & Services”, затем “Credentials”, нажмите “Create credentials” и выберите “Service account”. Задайте имя, например “sheets-logger”. Нажмите “Create”.

  • Теперь нужно получить JSON-ключ. Перейдите в раздел “IAM & Admin”, затем “Service Accounts”. Откройте созданный сервисный аккаунт, перейдите во вкладку “Keys”, нажмите “Add key” и выберите “Create new key”, затем формат JSON. У вас скачается файл. Это и есть ваш service-account.json. Положите рядом с вашими скриптами.

  • Далее нужно выдать этому аккаунту доступ к таблице. Откройте свою Google таблицу, нажмите “Share” и добавьте туда email сервисного аккаунта. Он выглядит примерно так: [email protected]. Дайте ему доступ уровня Editor (Редактор).

  • После этого ваш сервисный аккаунт сможет записывать данные в Google Sheets

Шаг 13. Push-уведомления в Telegram

Мы с вами настроили два типа логирования:

  1. Технические логи (файлы): Подробная «история болезни», которая хранится локально на вашем компьютере.

  2. Менеджерские отчеты: Удобная выжимка результатов.

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

Но что, если вы забудете туда заглянуть? А именно сегодня у вас отключится интернет или сменится пароль от базы данных? Скрипт упадет, работа встанет, а вы узнаете об этом только через неделю, когда руки дойдут до проверки отчетов.

В критических ситуациях нам нужен принцип Push. Система сама должна «толкнуть» нас и сообщить о проблеме. Реализуем это через Telegram-бота.

Нам не нужны сложные библиотеки для ботов. Telegram API позволяет отправлять сообщения простым https-запросом. Для этого нам нужен только ключ от бота и адрес чата:

Создаем бота и получаем API Token:

  • Откройте в Telegram бота @BotFather.

  • Напишите команду /newbot.

  • Придумайте имя и юзернейм (должен заканчиваться на bot).

  • Получите API Token. Сохраните его.

Узнаем Chat ID (Куда отправлять):

  • Личные сообщения: Найдите своего бота в поиске и обязательно нажмите Start (или напишите /start). Без этого бот не сможет вам писать.

  • Группа: Если хотите уведомления в общий чат, добавьте туда бота.

  • Чтобы узнать ID чата, перешлите любое сообщение из этого чата боту @userinfobot (или @getmyid_bot). Он пришлет вам Chat ID.

Код отправки сообщений в Telegram

def send_telegram_message(message): """ Send a message to Telegram bot. """ if not BOT_TOKEN or not CHAT_ID: raise RuntimeError("BOT_TOKEN and CHAT_ID must be defined at the top of the file") try: url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage" data = { 'chat_id': CHAT_ID, 'text': message } response = requests.post(url, data=data) response.raise_for_status() return True except Exception as e: print(f"Error while sending message to Telegram: {e}") return False

Далее модифицируем наш основной скрипт. Мы обернем выполнение задачи в блок try-except и в случае ошибки отправим сообщение в телеграмм. Если все хорошо — вы листаете отчеты в Google Таблицах за обедом. Если что-то сломалось — вы получите сообщение и сможете отреагировать.

Шаг 14. Structured outputs - шаблон ответа

До этого момента мы просили модель просто «вернуть текст». Но LLM это генератор следующего токена с определенной вероятностью. Это создает «шумы»: иногда модель может добавить в начале фразы вроде «Вот ваш перевод:», сломать верстку или допустить синтаксическую ошибку в данных (например, забыть закрывающую скобку).

Нам нужна гарантия, что мы всегда получим чистые данные, готовые для записи в базу.

Для этого существует Structured Outputs. Эта функция позволяет жестко задать схему ответа. Мы как бы даем нашему сотруднику не пустой лист бумаги, а строгий бланк, где нужно заполнить конкретные поля.

Реализуем это с помощью библиотеки Pydantic. Мы опишем структуру поста (текст, хештеги) как класс, и модель будет обязана вернуть данные именно в этом виде.

Код Structured outputs

# --- Structured Outputs: output schema definition --- class InstagramTranslation(BaseModel): """Expected structured response from the model.""" instagram_text: str = Field( description="Final Instagram-ready post in Russian." ) hashtags: List[str] = Field( default_factory=list, description="List of relevant hashtags without the leading '#'.", ) #... # --- Structured Outputs: use responses.parse with a Pydantic schema --- response = client.responses.parse( model="gpt-5-chat-latest", instructions=system_prompt, input=user_content, temperature=0.9, # More creativity top_p=0.95, # Limit to most likely words max_output_tokens=4096, text_format=InstagramTranslation, ) # --- Structured Outputs: parsed is an InstagramTranslation instance --- parsed: InstagramTranslation = response.output_parsed translated = parsed.instagram_text.strip() tags = " ".join( f"#{tag.strip()}" for tag in parsed.hashtags if isinstance(tag, str) and tag.strip() )

Отлично! Это поможет нам повысить стабильность в работе с LLM.

Шаг 15. Batch API - экономим 50%

Сейчас наш скрипт работает в Online (синхронном) режиме. Мы отправляем запрос и ждем ответа. Это удобно, когда результат нужен прямо сейчас, но это самый дорогой способ взаимодействия.

Если у вас тысячи запросов и нам не критично получить ответ моментально, существует Batch API.

Суть проста: мы собираем все запросы в один файл и отправляем его OpenAI. Запросы выполняются в течение 24 часов (обычно быстрее), используя свободные мощности серверов. А мы получаем скидку 50%.

При работе с Batch API важно учесть несколько моментов:

  1. Храните batch_id
    Каждая задача в Batch API имеет свой идентификатор. Его нужно сохранить , чтобы потом получить результаты

  2. Избегайте двойной обработки
    Если скрипт запускается чаще, чем раз в 24 часа, у вас могут одновременно висеть несколько еще не завершенных batch-задач. Нужно хранить в базе, какие элементы уже ушли в обработку, и не отправлять их повторно.

  3. Связывайте ответы с товарами через custom_id.
    У каждого запроса в .jsonl есть поле custom_id. Запишите туда ID товара или строки таблицы. Порядок ответов Batch API не гарантирует, поэтому на этапе разбора результатов вы смотрите на custom_id и по нему понимаете, к какому товару относится конкретный перевод.

Разобьем наш код работы с LLM на 2 части - создание и получение batch:

Код Batch API + Structured outputs

Создание Batch:

# --- Data Model (Structured Outputs) --- class InstagramTranslation(BaseModel): """ Schema for the structured response from OpenAI. """ instagram_text: str = Field( description="Final Instagram-ready post in Russian." ) hashtags: List[str] = Field( default_factory=list, description="List of relevant hashtags without the leading '#'." ) def get_batch_schema(): """ Generates the JSON schema required for the Batch API to enforce Structured Outputs. """ schema = InstagramTranslation.model_json_schema() return { "type": "json_schema", "json_schema": { "name": "InstagramTranslation", "strict": True, "schema": { "type": "object", "properties": schema["properties"], "required": list(schema["properties"].keys()), "additionalProperties": False } } } for _, row in df.iterrows(): pid = str(row["id"]) text = str(row["text"]) if pid in processed_ids: continue # Prepare the task for Batch API # We use 'custom_id' to track the product ID through the process task = { "custom_id": pid, "method": "POST", "url": "/v1/chat/completions", "body": { "model": "gpt-5-chat-latest", "messages": [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": text} ], "response_format": schema, "temperature": 0.9, "max_tokens": 4096 } } tasks.append(json.dumps(task)) new_ids.append(pid) if not tasks: logger.info("No new items to translate. All IDs are already in the database.") return # 3. Save tasks to a temporary JSONL file jsonl_filename = "batch_payload.jsonl" with open(jsonl_filename, "w", encoding="utf-8") as f: f.write("\n".join(tasks)) logger.info(f"Prepared {len(tasks)} tasks for upload.") # 4. Upload file to OpenAI try: batch_file = client.files.create( file=open(jsonl_filename, "rb"), purpose="batch" ) logger.info(f"File uploaded successfully. File ID: {batch_file.id}") # 5. Create the Batch Job batch_job = client.batches.create( input_file_id=batch_file.id, endpoint="/v1/chat/completions", completion_window="24h", metadata={"description": "Instagram Content Translation"} ) # 6. Register in Database db_helper.add_new_batch(batch_job.id, batch_file.id, new_ids) logger.info(f"Batch successfully created! Batch ID: {batch_job.id}") logger.info("Run 'retrieve_batch.py' later to check status and get results.") except Exception as e: logger.error(f"Failed to create batch: {e}")

Получение и сохранение:

def process_completed_batch(batch_id, output_file_id): """ Downloads the result file, parses the structured output, saves it to a CSV, and updates the database. """ logger.info(f"Downloading results for batch {batch_id}...") try: content_response = client.files.content(output_file_id) file_content = content_response.text except Exception as e: logger.error(f"Failed to download file content: {e}") return results = [] # Process the JSONL response line by line for line in file_content.strip().split('\n'): item = json.loads(line) custom_id = item['custom_id'] # This corresponds to our product ID response = item.get('response', {}) if response.get('status_code') == 200: raw_content = response['body']['choices'][0]['message']['content'] try: # Parse JSON string into Pydantic model data_dict = json.loads(raw_content) parsed_obj = InstagramTranslation(**data_dict) # Format hashtags with '#' hashtags_str = " ".join([f"#{tag}" for tag in parsed_obj.hashtags]) results.append({ "id": custom_id, "translated_text": parsed_obj.instagram_text, "hashtags": hashtags_str }) # Mark this specific item as completed in DB db_helper.mark_item_completed(custom_id) except Exception as e: logger.error(f"Parsing error for ID {custom_id}: {e}") else: logger.error(f"API Error for ID {custom_id}: {response}") # Save to a new CSV file if results: output_filename = DATA_DIR / f"results_{batch_id}.csv" pd.DataFrame(results).to_csv(output_filename, index=False) logger.info(f"Saved {len(results)} translated items to {output_filename}") # Mark batch as fully completed db_helper.update_batch_status(batch_id, "completed", output_file_id) else: logger.warning(f"Batch {batch_id} returned no valid results.") db_helper.update_batch_status(batch_id, "failed")

Этап 4. Дальнейшее развитие

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

Шаг 16. RAG — Доступ к корпоративной базе знаний

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

Но так бывает не всегда.

Представьте, что вы просите вашего нового сотрудника: «Ответь клиенту согласно нашей внутренней инструкции №42» или «Используй терминологию из технической документации к нашему новому станку».
Модель не знает этих документов. Их не было в интернете на момент ее обучения, или они являются вашей коммерческой тайной. Чтобы наш AI-сотрудник мог работать с вашими уникальными данными, ему нужно эти знания передать. Сделать это можно двумя способами.

Способ 1. Использование контекстного окна
Самый простой вариант — просто скопировать нужный документ и вставить его прямо в промпт (в сообщение System или User).
Пример: «Прочитай этот текст: [Текст инструкции]. А теперь ответь на вопрос...»
Это отлично работает, если ваши данные — это несколько страниц текста. Но если у вас техническая документация на 500 страниц или база знаний из тысяч товаров, этот метод не подойдет. Даже если огромное контекстное окно современных моделей вместит этот объем, такой запрос будет стоить дорого и обрабатываться долго.

Способ 2. RAG (Retrieval-Augmented Generation)
Здесь на сцену выходит RAG. Если говорить простыми словами, RAG — это технология, которая позволяет модели «подглядывать» в учебник перед тем, как дать ответ.

Это работает так:

  1. Вы берете ваши внутренние документы, инструкции или базы данных.

  2. Переводите их в специально подготовленный вид (обычно это база векторов или набор пар «вопрос-ответ/фрагмент текста»).

  3. Когда вы задаете модели вопрос, система сначала бежит в эту базу, находит там самые релевантные куски информации (те самые «шпаргалки»), которые нужны именно для этого вопроса.

  4. Эти найденные кусочки автоматически добавляются к вашему вопросу и отправляются в LLM.

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

Шаг 17. Fine-Tuning — отправляем сотрудника на курсы

Если RAG — это «шпаргалка» или «учебник», который мы даем сотруднику в руки, то Fine-Tuning — это обучение самого сотрудника, как курсы повышения квалификации или стажировка, после которой меняются привычки и поведение модели.

При дообучении вы берете эту готовую модель и показываете ей тысячи примеров в формате:

  1. Вводные данные: (Что спросил клиент)

  2. Идеальный ответ: (Как именно должен ответить наш сотрудник)

Модель смотрит на эти пары снова и снова и корректирует свои внутренние настройки (веса), чтобы в будущем отвечать именно в таком стиле, формате или тональности, даже без подробных инструкций в промпте.

Когда нужен Fine-Tuning, а когда RAG?

  • RAG нужен для ФАКТОВ. Если вам нужно, чтобы модель знала цены на вашем складе сегодня, содержание нового договора или последние новости — используйте RAG. Дообучать модель ради фактов бессмысленно: это дорого, долго, и знания устареют на следующий день.

  • Fine-Tuning нужен для ПОВЕДЕНИЯ и ФОРМЫ. Если вам нужно, чтобы модель всегда отвечала в стиле дореволюционного дворянина или идеально писала код на редком языке программирования — используйте Fine-Tuning.

Пример:
Если вы хотите, чтобы модель знала все законы РФ — это RAG (законы меняются, их много).
Если вы хотите, чтобы модель научилась думать и писать как опытный юрист с 20-летним стажем, используя профессиональные обороты речи — это Fine-Tuning.

Шаг 18. Своя модель на своем железе


Помимо гигантов вроде ChatGPT, существует огромный мир Open-Source моделей (Llama, Mistral, Qwen). Вы можете скачать такую модель, дообучить ее на своих данных и запустить локально на своем сервере. Ваши данные никуда не уходят, а модель работает полностью под вашим контролем, не требуя оплаты за каждый токен API.

Дообучение — это процесс более сложный и дорогостоящий, чем работа с промптами или RAG, поэтому прибегать к нему стоит, когда простые методы уже исчерпаны.

Шаг 19. LLM-конвейер

До сих пор мы рассматривали сценарий, где одна модель делает всё: и читает, и переводит, и форматирует. Но в реальном бизнесе мы редко поручаем одному человеку быть одновременно переводчиком, редактором, дизайнером и SMM-менеджером. Универсалы проигрывают узким специалистам.

Пытаясь запихнуть все инструкции в один огромный промпт, мы рискуем получить «кашу». Гораздо эффективнее построить конвейер (Pipeline), где результат работы одной модели становится входными данными для следующей. Например:

  1. Переводчик (Модель А): Получает сырой текст и делает черновой перевод. Её цель — просто сохранить смысл, не заботясь о красоте.

  2. Редактор (Модель B): Получает черновик от первой модели. В её промпте зашиты правила редполитики и Tone of Voice. Она не переводит, она критикует и улучшает. Если перевод плохой, она может вернуть его на доработку (Self-Correction).

  3. Дизайнер (Модель C): Читает готовый пост и генерирует промпт для Nano Banana, создает изображение для поста.

  4. SMM-менеджер (Скрипт-сборщик): Собирает финальный текст, картинку и хештеги, формирует JSON и через официальный API Инстаграма публикует пост.

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

  • Качество: Нескольо коротких, узкоспециализированных промптов всегда работают стабильнее, чем один гигантский.

  • Контроль: Вы можете внедрить этапы проверки. Например, «Редактор» может классифицировать контент на безопасность перед публикацией.

  • Экономия: Вам не всегда нужна самая умная и дорогая модель. Черновой перевод может делать быстрая и дешевая модель, а финальную «полировку» текста — дорогая.

Шаг 20. MCP и AI-Агенты — От жестких инструкций к свободе действий

Мы вручную написали Python-скрипты, которые подключаются к базе, вытаскивают товары по фиксированному SQL запросу, отправляют их в модель и сохраняют результат.

А что, если дать модели «ключи» от базы и позволить ей самой решать, как выполнять работу? Здесь начинается эра AI-агентов и MCP (Model Context Protocol). MCP — это стандарт, который соединяет AI-модели с вашими данными и инструментами. Вместо того чтобы писать SQL, мы могли бы настроить MCP-сервер для MySQL и просто сказать агенту: «Найди в базе непереведённые товары и переведи их». Агент сам подключился бы к базе, разобрался в структуре таблиц, нашёл строки с translated = 0, отправил тексты на перевод и записал результат обратно. Мы больше объясняем что сделать, а не как.

Но у такого подхода есть риски.

  1. Детерминированность.
    Скрипт — это поезд: 100 запусков → 100 одинаковых SQL-запросов. Агент с MCP — таксист: адрес один, но маршрут он выбирает сам. Сегодня «непереведённые товары» для него translated = 0, завтра — text_ru IS NULL, а послезавтра он может вообще решить удалить «старые» записи. Для задач, где важна точность до запятой (деньги, удаление данных), полная свобода агента опасна.

  2. Безопасность.
    У скрипта есть строго ограниченные права: он делает только то, что мы в него зашили. Агент с доступом к базе через MCP — это стажёр в серверной. Неправильно понятая команда может превратиться в реальный DROP TABLE.

Поэтому на практике используют гибридный подход. MCP остаётся «мостом» между моделью и системами, но агенту дают не доступ «делай любой SQL», а набор безопасных инструментов: «получить товар», «обновить перевод» и т.п. Агент решает, когда их вызывать, а что конкретно они делают, по-прежнему жёстко контролируется нашим кодом.

Заключение

Мы прошли весь путь — от простого диалога с моделью до полностью автономной системы, которая сама выполняет бизнес-задачи. Настроили модель через API, собрали рабочий промпт, написали скрипты для получения данных, обработки и сохранения результатов. Оптимизировали расходы с помощью Batch API, добавили логи и отчётность в Google Таблицах, сделали процесс устойчивым и воспроизводимым.

По сути, мы создали «виртуального сотрудника», который не требует контроля и работает по расписанию. Дальше можно развивать систему в сторону RAG, агентных сценариев, MCP и более продвинутых форм автоматизации — всё зависит от ваших задач!

Весь код доступен на GitHub: https://github.com/andrey7mel/Hiring-ChatGPT

НЕ РАСКРЫВАЙТЕ СПОЙЛЕР

Если вам интересны практические кейсы внедрения LLM в бизнес - подписывайтесь на канал: https://t.me/ai_for_business_tasks
P.S. Я предупреждал:)

Источник

Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу service@support.mexc.com для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.