Интеграция SAP с ИИ: от прототипа к промышленному решению на ABAP

от автора

Привет, Хабр! Меня зовут Виктория Мохирева, я консультант SAP MM. Моя прошлая статья была посвящена тому, как с помощью локального класса и глобального API мы с командой «приручили» большую языковую модель для работы с пересортицей. И, как это часто бывает, с прототипа все только началось.

Мы пришли к тому, что ИИ начал выдавать разумные ответы и радовались этому, а впереди нас ждали новые вызовы:

  • Как отслеживать статусы отправки и получения данных?

  • Как не потерять данные при сбоях?

  • Как сделать систему масштабируемой?

  • И, главное — как не превратить эксперимент в «костыль»?

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

Редактор промптов 2.0: шаблоны, редактирование и контроль

Пользовательский опыт сосредоточен в нашем редакторе промптов. Мы его полностью переписали, для того чтобы он из «поля ввода данных» превратился в полноценный инструмент. 

1. Шаблоны из стандартных текстов SAP

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

Теперь:

ls_header-tdobject = 'ZPROMTTXT'. " объект текстаls_header-tdname = 'PROMT'. " имя текстаCALL FUNCTION 'READ_TEXT' ... " читаем из базы

Польза нашего нововведения:

  • Бизнес-аналитики могут редактировать промпты без вмешательства разработчика.

  • Поддержка разных шаблонов для разных процессов (закупки, продажи, претензии).

  • Локализация без перекомпиляции.

2. Режим «Только чтение» и редактирование

Сколько раз вы видели, как пользователь «улучшает» промпт, удаляет ключевые слова, но получает кашу из ответов ИИ? Такое встречается часто. Поэтому по умолчанию редактор находится в режиме set_readonly_mode( abap_true ).

Если нужно внести правки, то кнопка «EDIT» переключает режим: это просто и эффективно, и спасло нас от сотен инцидентов.

3. Очистка и загрузка шаблона заново

Кнопки CLEAR и TEMPLATE теперь стандартные.

  • CLEAR — очищает поле.

  • TEMPLATE — загружает актуальный шаблон из SO10.

После каждого действия мы вызываем cl_gui_cfw=>flush() для того, чтобы изменения отображались мгновенно. Пользователь видит результат и не думает, что система зависла.

Отправка запроса: двухуровневое логирование и контроль статуса

Как только пользователь нажимает «SEND», метод SEND_PROMPT_TO_AI выполняет три ключевых шага:

1. Сохранение промпта на контент-сервер

Мы не храним большие тексты в базе, так как это неэффективно и тяжело для аудита. Вместо этого:

lv_prompt = mo_ai_client->get_xprompt( ).lv_pretty_prompt = zclmm_ai_api_tools=>format_simple( lv_prompt ).lv_docid = mo_ai_client->upload_prompt_to_cs( iv_prompt = lv_pretty_prompt iv_crep_id = 'Z019' ).

Промпт преобразуется в XSTRING и загружается на контент-сервер. Возвращается DOCID — уникальный идентификатор, который потом связывается с логом.

2. Запись метаданных в таблицу ZMM_T_RFC_AI_LOG

В логе хранятся:

•TASK_ID (GUID из ответа ИИ)

•Отдел, пользователь, дата, время

•Статус (P — в процессе)

•Количество обработанных строк

Парсим TASK_ID через регулярное выражение:

FIND REGEX ‘»task_id»:\s*»([^»]*)»‘ IN iv_api_response SUBMATCHES ls_ai_log-task_id.

3. Создание фонового задания для мониторинга

ИИ может обрабатывать запрос несколько минут, и чтобы пользователь не ждал у экрана, мы создаём фоновое задание через класс ZCLMM_AI_STATUS_CHECK. Оно:

  • Периодически проверяет статус задачи.

  • При завершении обновляет лог.

  • При необходимости отправляет уведомление.

CREATE OBJECT lo_status.lo_status->submit_batch_job(EXPORTINGiv_department = ls_ai_log-depiv_rfc_name = ls_ai_log-rfc_nameiv_call_date = ls_ai_log-call_dateiv_call_lines = ls_ai_log-call_lines ).

Автоматизация обработки новых логистических кодов (ЛК) в пакетном режиме.

Особый вызов — масса новых товаров, которые приходят каждый день. Мы создали класс LCL_LK_BATCH_PROCESSOR, который работает как в интерактивном, так и в фоновом режиме.

Что он делает? Собирает все материалы, у которых ещё нет группы пересорта, и отправляет их ИИ единым пакетом.

Как это работает? Метод PREPARE_REQUEST_PARAMS формирует два массива JSON:

•products — список новых материалов (номер + описание).

•groups — существующие группы из справочника (чтобы ИИ не дублировал).

Обработка ошибок и уведомления.

Если при отправке происходит ошибка (например, недоступен внешний API), мы отправляем письмо всем ответственным пользователям:

  • Получаем список адресатов из настройки ZMM_AI_SEND через zcl_ifrs_custom_setting=>get_range.

  • Формируем письмо с текстом ошибки и номером отдела.

  • Отправляем через zcl_reestr=>send_mail_60.

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

lt_mail_recipients = get_receivers( ).lt_mail_message = get_mail_message( iv_error ).lv_mail_subject = 'Ошибка отправки запроса для Групп Пересорта'.zcl_reestr=>send_mail_60( ... ).

Что дальше?

В наших ближайших планах:

Модернизация архитектуры — вынести основную логику в глобальный класс ZCL_AI_PROMPT_EDITOR и интегрировать его с BADI, что позволит другим модулям (закупки, продажи) использовать инструмент без дополнительной настройки.

Расширяемость системы — добавление поддержки новых LLM-провайдеров станет возможным за счёт простой замены одного метода благодаря четкому разделению ответственности между компонентами системы.

Заключение.

Спасибо, что дочитали до конца! Надеюсь, наш опыт вдохновит вас на более смелые шаги по интеграции ИИ в SAP — системы. 

Помните: прототип — это начало пути. Главное не бояться переписывать, улучшать и масштабировать. 

Если у вас есть вопросы, идеи или просто хотите обсудить — пишите в комментариях. Всегда рада диалогу!

Удачи в цифровизации! 

P.S. А если вы уже делали что-то подобное — расскажите, как вы решали проблему с потерей данных при работе с ИИ? Я всегда рада новым кейсам! 😊

ссылка на оригинал статьи https://habr.com/ru/articles/1062716/