SAP AI Core ist die zentrale KI-Infrastruktur in der SAP Business Technology Platform (BTP). Mit ABAP Cloud kannst du KI-Services wie Textklassifizierung, Named Entity Recognition, Embedding-Generierung oder generative AI-Modelle direkt in deine Geschäftsanwendungen integrieren.
Was ist SAP AI Core?
SAP AI Core ist ein Service zur Ausführung und Verwaltung von Machine-Learning-Modellen auf der BTP. Er bietet:
| Feature | Beschreibung |
|---|---|
| Model Serving | Hosting und Skalierung von ML-Modellen |
| SAP AI Services | Vorgefertigte KI-Services (Document Extraction, etc.) |
| Generative AI Hub | Zugang zu LLMs (GPT, Claude, etc.) |
| Custom Models | Eigene Modelle trainieren und deployen |
| MLOps | Versionierung, Monitoring, Lifecycle Management |
Architektur-Übersicht
┌─────────────────────────────────────────────────────────────────────┐│ SAP BTP ││ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ││ │ ABAP Cloud │ │ Destination │ │ SAP AI Core │ ││ │ │──>│ Service │──>│ │ ││ │ ┌───────────┐ │ │ │ │ ┌───────────┐ │ ││ │ │ RAP App │ │ │ ┌───────────┐ │ │ │ Gen AI Hub│ │ ││ │ │ │ │ │ │ AI Core │ │ │ │ (LLMs) │ │ ││ │ │ AI Client │──────│ │ Destination│──────│ ├───────────┤ │ ││ │ │ │ │ │ └───────────┘ │ │ │ ML Models │ │ ││ │ └───────────┘ │ │ │ │ │ (Custom) │ │ ││ │ │ │ │ │ └───────────┘ │ ││ └─────────────────┘ └─────────────────┘ └─────────────────┘ │└─────────────────────────────────────────────────────────────────────┘Verfügbare KI-Services
SAP AI Business Services
| Service | Beschreibung | Use Case |
|---|---|---|
| Document Information Extraction | Dokumente analysieren und Daten extrahieren | Rechnungsverarbeitung |
| Business Entity Recognition | Entitäten in Texten erkennen | Kundenanfragen klassifizieren |
| Service Ticket Intelligence | Tickets kategorisieren und routen | Helpdesk-Automatisierung |
| Data Attribute Recommendation | Attribute vorschlagen | Stammdatenpflege |
Generative AI Hub
Der Generative AI Hub bietet Zugang zu Large Language Models (LLMs):
| Modell-Familie | Beispiele | Einsatz |
|---|---|---|
| OpenAI GPT | GPT-4, GPT-3.5-turbo | Textgenerierung, Analyse |
| Anthropic Claude | Claude 3 Opus/Sonnet | Dokumentenanalyse, Coding |
| Gemini Pro | Multimodale Anwendungen | |
| Embeddings | text-embedding-ada-002 | Semantische Suche, RAG |
Setup und Konfiguration
1. AI Core Service Instance erstellen
Im BTP Cockpit unter Service Marketplace:
┌──────────────────────────────────────────────────────────────┐│ Service Instance Configuration │├──────────────────────────────────────────────────────────────┤│ Service: SAP AI Core ││ Plan: standard (oder extended) ││ Instance Name: ai-core-instance ││ ││ Parameters (JSON): ││ { ││ "servicePlanName": "standard" ││ } │└──────────────────────────────────────────────────────────────┘2. Service Key generieren
Erstelle einen Service Key für die Authentifizierung:
{ "clientid": "sb-ai-core-xxx", "clientsecret": "***", "url": "https://ai-core.cfapps.eu10.hana.ondemand.com", "serviceurls": { "AI_API_URL": "https://api.ai.prod.eu-central-1.aws.ml.hana.ondemand.com" }, "appname": "ai-core-xxx", "identityzone": "my-subaccount"}3. Destination konfigurieren
Erstelle eine Destination im BTP Cockpit:
┌──────────────────────────────────────────────────────────────┐│ Destination: SAP_AI_CORE │├──────────────────────────────────────────────────────────────┤│ Name: SAP_AI_CORE ││ Type: HTTP ││ URL: <AI_API_URL aus Service Key> ││ Proxy Type: Internet ││ Authentication: OAuth2ClientCredentials ││ ││ Token Service URL: <url aus Service Key>/oauth/token ││ Client ID: <clientid aus Service Key> ││ Client Secret: <clientsecret aus Service Key> ││ ││ Additional Properties: ││ ├── AI-Resource-Group: default ││ └── URL.headers.AI-Resource-Group: default │└──────────────────────────────────────────────────────────────┘4. Communication Arrangement
Im ABAP-System ein Communication Arrangement anlegen:
Communication Scenario: SAP_COM_0276 (Destination Service Integration)Communication System: BTP_DESTINATION_SERVICEOutbound Services: Destination Service API → ActiveSAP AI Core Service aufrufen
Basis-Client-Klasse
CLASS zcl_ai_core_client DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_message, role TYPE string, content TYPE string, END OF ty_message, tt_messages TYPE STANDARD TABLE OF ty_message WITH EMPTY KEY,
BEGIN OF ty_chat_request, model TYPE string, messages TYPE tt_messages, max_tokens TYPE i, temperature TYPE decfloat16, END OF ty_chat_request,
BEGIN OF ty_choice, index TYPE i, message TYPE ty_message, END OF ty_choice, tt_choices TYPE STANDARD TABLE OF ty_choice WITH EMPTY KEY,
BEGIN OF ty_usage, prompt_tokens TYPE i, completion_tokens TYPE i, total_tokens TYPE i, END OF ty_usage,
BEGIN OF ty_chat_response, id TYPE string, object TYPE string, created TYPE i, model TYPE string, choices TYPE tt_choices, usage TYPE ty_usage, END OF ty_chat_response.
METHODS constructor RAISING cx_http_dest_provider_error.
METHODS chat_completion IMPORTING is_request TYPE ty_chat_request RETURNING VALUE(rs_result) TYPE ty_chat_response RAISING cx_web_http_client_error.
PRIVATE SECTION. DATA mo_destination TYPE REF TO if_http_destination. DATA mv_resource_group TYPE string VALUE 'default'.
METHODS execute_request IMPORTING iv_path TYPE string iv_method TYPE i iv_body TYPE string RETURNING VALUE(rv_result) TYPE string RAISING cx_web_http_client_error.ENDCLASS.
CLASS zcl_ai_core_client IMPLEMENTATION. METHOD constructor. mo_destination = cl_http_destination_provider=>create_by_cloud_destination( i_name = 'SAP_AI_CORE' i_authn_mode = if_a4c_cp_service=>service_specific ). ENDMETHOD.
METHOD chat_completion. " Request JSON erstellen DATA(lv_json) = /ui2/cl_json=>serialize( data = is_request compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
" API aufrufen (Gen AI Hub Endpoint) DATA(lv_response) = execute_request( iv_path = '/v2/inference/deployments/<deployment-id>/chat/completions' iv_method = if_web_http_client=>post iv_body = lv_json ).
" Response parsen /ui2/cl_json=>deserialize( EXPORTING json = lv_response CHANGING data = rs_result ). ENDMETHOD.
METHOD execute_request. DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( i_destination = mo_destination ).
DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_uri_path( iv_path ).
" AI-Resource-Group Header setzen lo_request->set_header_field( i_name = 'AI-Resource-Group' i_value = mv_resource_group ).
IF iv_body IS NOT INITIAL. lo_request->set_text( iv_body ). lo_request->set_header_field( i_name = 'Content-Type' i_value = 'application/json' ). ENDIF.
DATA(lo_response) = lo_client->execute( iv_method ). DATA(lv_status) = lo_response->get_status( )-code.
IF lv_status >= 200 AND lv_status < 300. rv_result = lo_response->get_text( ). ELSE. DATA(lv_error) = lo_response->get_text( ). lo_client->close( ). " Fehler loggen und Exception werfen RAISE EXCEPTION TYPE cx_web_http_client_error. ENDIF.
lo_client->close( ). ENDMETHOD.ENDCLASS.Praktische Beispiele
Beispiel 1: Textklassifizierung
Klassifiziere eingehende Kundenanfragen automatisch:
CLASS zcl_ticket_classifier DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_classification, category TYPE string, priority TYPE string, confidence TYPE decfloat16, END OF ty_classification.
METHODS classify_ticket IMPORTING iv_ticket_text TYPE string RETURNING VALUE(rs_result) TYPE ty_classification RAISING cx_http_dest_provider_error cx_web_http_client_error.ENDCLASS.
CLASS zcl_ticket_classifier IMPLEMENTATION. METHOD classify_ticket. DATA(lo_client) = NEW zcl_ai_core_client( ).
" System-Prompt für Klassifizierung DATA(lv_system_prompt) = |Du bist ein Ticket-Klassifizierungssystem. | && |Analysiere die Kundenanfrage und gib die Klassifizierung als JSON zurück.\n| && |Kategorien: BILLING, TECHNICAL, SALES, GENERAL\n| && |Prioritäten: HIGH, MEDIUM, LOW\n| && |Antwortformat: \{"category": "...", "priority": "...", "confidence": 0.0-1.0\}|.
" Request aufbauen DATA(ls_request) = VALUE zcl_ai_core_client=>ty_chat_request( model = 'gpt-4' max_tokens = 100 temperature = '0.1' messages = VALUE #( ( role = 'system' content = lv_system_prompt ) ( role = 'user' content = iv_ticket_text ) ) ).
" AI aufrufen DATA(ls_response) = lo_client->chat_completion( ls_request ).
" Antwort parsen IF lines( ls_response-choices ) > 0. DATA(lv_content) = ls_response-choices[ 1 ]-message-content.
" JSON aus Antwort extrahieren und parsen /ui2/cl_json=>deserialize( EXPORTING json = lv_content CHANGING data = rs_result ). ENDIF. ENDMETHOD.ENDCLASS.Nutzung in einer RAP-Determination:
METHOD classify_on_create. " Neue Tickets lesen READ ENTITIES OF zi_ticket IN LOCAL MODE ENTITY Ticket FIELDS ( description ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_tickets).
DATA lt_update TYPE TABLE FOR UPDATE zi_ticket\\Ticket.
LOOP AT lt_tickets INTO DATA(ls_ticket). TRY. " Ticket klassifizieren DATA(lo_classifier) = NEW zcl_ticket_classifier( ). DATA(ls_class) = lo_classifier->classify_ticket( ls_ticket-description ).
APPEND VALUE #( %tky = ls_ticket-%tky category = ls_class-category priority = ls_class-priority ) TO lt_update.
CATCH cx_root. " Fehler behandeln - Standardwerte setzen APPEND VALUE #( %tky = ls_ticket-%tky category = 'GENERAL' priority = 'MEDIUM' ) TO lt_update. ENDTRY. ENDLOOP.
" Tickets aktualisieren MODIFY ENTITIES OF zi_ticket IN LOCAL MODE ENTITY Ticket UPDATE FIELDS ( category priority ) WITH lt_update.ENDMETHOD.Beispiel 2: Text-Extraktion aus Dokumenten
Extrahiere strukturierte Daten aus Freitext:
CLASS zcl_document_extractor DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_address, street TYPE string, city TYPE string, zip TYPE string, country TYPE string, END OF ty_address,
BEGIN OF ty_invoice_data, invoice_number TYPE string, invoice_date TYPE string, vendor_name TYPE string, vendor_address TYPE ty_address, total_amount TYPE decfloat16, currency TYPE string, line_items TYPE STANDARD TABLE OF string WITH EMPTY KEY, END OF ty_invoice_data.
METHODS extract_invoice_data IMPORTING iv_document_text TYPE string RETURNING VALUE(rs_result) TYPE ty_invoice_data RAISING cx_http_dest_provider_error cx_web_http_client_error.ENDCLASS.
CLASS zcl_document_extractor IMPLEMENTATION. METHOD extract_invoice_data. DATA(lo_client) = NEW zcl_ai_core_client( ).
DATA(lv_system_prompt) = |Du bist ein Dokumentenanalyse-System. Extrahiere die Rechnungsdaten | && |aus dem folgenden Text und gib sie als JSON zurück.\n| && |Schema: \{\n| && | "invoice_number": "string",\n| && | "invoice_date": "YYYY-MM-DD",\n| && | "vendor_name": "string",\n| && | "vendor_address": \{"street": "", "city": "", "zip": "", "country": ""\},\n| && | "total_amount": number,\n| && | "currency": "EUR/USD/etc",\n| && | "line_items": ["Beschreibung Menge Preis", ...]\n| && |\}\n| && |Gib nur das JSON zurück, keine Erklärungen.|.
DATA(ls_request) = VALUE zcl_ai_core_client=>ty_chat_request( model = 'gpt-4' max_tokens = 1000 temperature = '0.0' messages = VALUE #( ( role = 'system' content = lv_system_prompt ) ( role = 'user' content = iv_document_text ) ) ).
DATA(ls_response) = lo_client->chat_completion( ls_request ).
IF lines( ls_response-choices ) > 0. DATA(lv_json) = ls_response-choices[ 1 ]-message-content.
" JSON bereinigen (Markdown Code-Blöcke entfernen falls vorhanden) REPLACE ALL OCCURRENCES OF '```json' IN lv_json WITH ``. REPLACE ALL OCCURRENCES OF '```' IN lv_json WITH ``.
/ui2/cl_json=>deserialize( EXPORTING json = lv_json CHANGING data = rs_result ). ENDIF. ENDMETHOD.ENDCLASS.Beispiel 3: Embedding-Generierung für Semantische Suche
Erstelle Embeddings für eine Vektor-Suche:
CLASS zcl_embedding_service DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: tt_embedding TYPE STANDARD TABLE OF decfloat16 WITH EMPTY KEY,
BEGIN OF ty_embedding_result, text TYPE string, embedding TYPE tt_embedding, END OF ty_embedding_result, tt_embedding_results TYPE STANDARD TABLE OF ty_embedding_result WITH EMPTY KEY.
METHODS generate_embedding IMPORTING iv_text TYPE string RETURNING VALUE(rt_result) TYPE tt_embedding RAISING cx_http_dest_provider_error cx_web_http_client_error.
METHODS generate_embeddings IMPORTING it_texts TYPE string_table RETURNING VALUE(rt_result) TYPE tt_embedding_results RAISING cx_http_dest_provider_error cx_web_http_client_error.
METHODS calculate_similarity IMPORTING it_embedding1 TYPE tt_embedding it_embedding2 TYPE tt_embedding RETURNING VALUE(rv_result) TYPE decfloat16.
ENDCLASS.
CLASS zcl_embedding_service IMPLEMENTATION. METHOD generate_embedding. DATA(lo_destination) = cl_http_destination_provider=>create_by_cloud_destination( i_name = 'SAP_AI_CORE' i_authn_mode = if_a4c_cp_service=>service_specific ).
DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( i_destination = lo_destination ).
" Request Body DATA: BEGIN OF ls_request, model TYPE string VALUE 'text-embedding-ada-002', input TYPE string, END OF ls_request. ls_request-input = iv_text.
DATA(lv_json) = /ui2/cl_json=>serialize( data = ls_request compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_uri_path( '/v2/inference/deployments/<deployment-id>/embeddings' ). lo_request->set_header_field( i_name = 'AI-Resource-Group' i_value = 'default' ). lo_request->set_header_field( i_name = 'Content-Type' i_value = 'application/json' ). lo_request->set_text( lv_json ).
DATA(lo_response) = lo_client->execute( if_web_http_client=>post ).
IF lo_response->get_status( )-code = 200. DATA(lv_response) = lo_response->get_text( ).
" Response parsen DATA: BEGIN OF ls_response, data TYPE STANDARD TABLE OF BEGIN OF ls_data, embedding TYPE tt_embedding, END OF ls_data WITH EMPTY KEY, END OF ls_response.
/ui2/cl_json=>deserialize( EXPORTING json = lv_response CHANGING data = ls_response ).
IF lines( ls_response-data ) > 0. rt_result = ls_response-data[ 1 ]-embedding. ENDIF. ENDIF.
lo_client->close( ). ENDMETHOD.
METHOD generate_embeddings. " Batch-Verarbeitung für mehrere Texte LOOP AT it_texts INTO DATA(lv_text). DATA(lt_embedding) = generate_embedding( lv_text ). APPEND VALUE #( text = lv_text embedding = lt_embedding ) TO rt_result. ENDLOOP. ENDMETHOD.
METHOD calculate_similarity. " Kosinus-Ähnlichkeit berechnen DATA: lv_dot_product TYPE decfloat16 VALUE 0, lv_norm1 TYPE decfloat16 VALUE 0, lv_norm2 TYPE decfloat16 VALUE 0.
DATA(lv_length) = lines( it_embedding1 ).
DO lv_length TIMES. DATA(lv_idx) = sy-index. DATA(lv_val1) = it_embedding1[ lv_idx ]. DATA(lv_val2) = it_embedding2[ lv_idx ].
lv_dot_product = lv_dot_product + ( lv_val1 * lv_val2 ). lv_norm1 = lv_norm1 + ( lv_val1 * lv_val1 ). lv_norm2 = lv_norm2 + ( lv_val2 * lv_val2 ). ENDDO.
IF lv_norm1 > 0 AND lv_norm2 > 0. rv_result = lv_dot_product / ( sqrt( lv_norm1 ) * sqrt( lv_norm2 ) ). ENDIF. ENDMETHOD.ENDCLASS.Anwendung: Semantische Produktsuche
METHOD search_similar_products. DATA(lo_embedding_svc) = NEW zcl_embedding_service( ).
" Embedding für Suchanfrage generieren DATA(lt_query_embedding) = lo_embedding_svc->generate_embedding( iv_search_query ).
" Produkte mit gespeicherten Embeddings laden SELECT product_id, name, embedding_json FROM zproduct_embeddings INTO TABLE @DATA(lt_products).
" Ähnlichkeiten berechnen DATA: BEGIN OF ls_result, product_id TYPE string, name TYPE string, similarity TYPE decfloat16, END OF ls_result, lt_results LIKE STANDARD TABLE OF ls_result.
LOOP AT lt_products INTO DATA(ls_product). DATA lt_product_embedding TYPE zcl_embedding_service=>tt_embedding.
/ui2/cl_json=>deserialize( EXPORTING json = ls_product-embedding_json CHANGING data = lt_product_embedding ).
DATA(lv_similarity) = lo_embedding_svc->calculate_similarity( it_embedding1 = lt_query_embedding it_embedding2 = lt_product_embedding ).
APPEND VALUE #( product_id = ls_product-product_id name = ls_product-name similarity = lv_similarity ) TO lt_results. ENDLOOP.
" Nach Ähnlichkeit sortieren SORT lt_results BY similarity DESCENDING.
" Top 10 zurückgeben rt_result = VALUE #( FOR i = 1 WHILE i <= 10 ( lt_results[ i ] ) ).ENDMETHOD.Beispiel 4: Intelligenter Assistent in RAP
Integriere einen KI-Assistenten als RAP Action:
define abstract entity ZA_AssistantQuery{ question : abap.string(1000); context : abap.string(5000);}
define abstract entity ZA_AssistantResponse{ answer : abap.string(5000); confidence : abap.dec(5,2); sources : abap.string(1000);}Behavior Definition:
managed implementation in class zbp_i_salesorder unique;strict ( 2 );
define behavior for ZI_SalesOrder alias SalesOrder{ // ... standard operations ...
// AI Assistant Action static action askAssistant parameter ZA_AssistantQuery result [1] ZA_AssistantResponse;}Behavior Implementation:
METHOD askAssistant. DATA(lo_client) = NEW zcl_ai_core_client( ).
" Kontext aus System-Daten aufbauen DATA(lv_system_context) = |Du bist ein Vertriebsassistent für ein SAP-System. | && |Beantworte Fragen zu Kundenaufträgen, Produkten und Preisen. | && |Antworte präzise und geschäftlich. Wenn du unsicher bist, sage es.|.
" User-Query mit Kontext DATA(lv_user_query) = keys[ 1 ]-%param-question. DATA(lv_context) = keys[ 1 ]-%param-context.
IF lv_context IS NOT INITIAL. lv_user_query = |Kontext: { lv_context }\n\nFrage: { lv_user_query }|. ENDIF.
TRY. DATA(ls_request) = VALUE zcl_ai_core_client=>ty_chat_request( model = 'gpt-4' max_tokens = 500 temperature = '0.3' messages = VALUE #( ( role = 'system' content = lv_system_context ) ( role = 'user' content = lv_user_query ) ) ).
DATA(ls_response) = lo_client->chat_completion( ls_request ).
IF lines( ls_response-choices ) > 0. result = VALUE #( ( %cid = keys[ 1 ]-%cid %param = VALUE #( answer = ls_response-choices[ 1 ]-message-content confidence = '0.85' sources = 'SAP AI Core - GPT-4' ) ) ). ENDIF.
CATCH cx_root INTO DATA(lx_error). result = VALUE #( ( %cid = keys[ 1 ]-%cid %param = VALUE #( answer = |Fehler: { lx_error->get_text( ) }| confidence = '0.00' sources = '' ) ) ). ENDTRY.ENDMETHOD.Response verarbeiten
Strukturierte Antworten erzwingen
Um zuverlässig strukturierte Daten zu erhalten, nutze JSON-Mode oder klare Anweisungen:
METHOD get_structured_response. DATA(lv_system_prompt) = |Du bist ein Datenextraktionssystem. | && |Antworte IMMER mit gültigem JSON im folgenden Format:\n| && |\{"field1": "value1", "field2": "value2"\}\n| && |Keine Erklärungen, nur JSON.|.
DATA(ls_request) = VALUE zcl_ai_core_client=>ty_chat_request( model = 'gpt-4' max_tokens = 500 temperature = '0.0' " Niedrige Temperatur für konsistente Ausgabe messages = VALUE #( ( role = 'system' content = lv_system_prompt ) ( role = 'user' content = iv_input ) ) ).
DATA(ls_response) = mo_client->chat_completion( ls_request ).
IF lines( ls_response-choices ) > 0. DATA(lv_content) = ls_response-choices[ 1 ]-message-content.
" JSON-Bereinigung FIND REGEX '\{.*\}' IN lv_content MATCH OFFSET DATA(lv_offset) MATCH LENGTH DATA(lv_length). IF sy-subrc = 0. lv_content = substring( val = lv_content off = lv_offset len = lv_length ). ENDIF.
" Deserialisieren /ui2/cl_json=>deserialize( EXPORTING json = lv_content CHANGING data = rs_result ). ENDIF.ENDMETHOD.Token-Verbrauch überwachen
METHOD log_token_usage. DATA(ls_response) = mo_client->chat_completion( is_request ).
" Token-Verbrauch loggen DATA(lv_log_message) = |AI Call: { ls_response-model } | && |Prompt: { ls_response-usage-prompt_tokens } | && |Completion: { ls_response-usage-completion_tokens } | && |Total: { ls_response-usage-total_tokens }|.
" In Application Log schreiben cl_bali_log=>create_with_header( EXPORTING header = cl_bali_header_setter=>create( object = 'ZAI_CORE' subobject = 'USAGE' ) )->add_item( item = cl_bali_message_setter=>create( severity = if_bali_constants=>c_severity_information text = lv_log_message ) )->save( ).
rs_result = ls_response.ENDMETHOD.Error Handling
CLASS zcx_ai_core_error DEFINITION PUBLIC INHERITING FROM cx_static_check CREATE PUBLIC.
PUBLIC SECTION. INTERFACES if_t100_message.
CONSTANTS: BEGIN OF connection_failed, msgid TYPE symsgid VALUE 'ZAI', msgno TYPE symsgno VALUE '001', attr1 TYPE scx_attrname VALUE 'MV_DESTINATION', attr2 TYPE scx_attrname VALUE '', attr3 TYPE scx_attrname VALUE '', attr4 TYPE scx_attrname VALUE '', END OF connection_failed,
BEGIN OF rate_limit_exceeded, msgid TYPE symsgid VALUE 'ZAI', msgno TYPE symsgno VALUE '002', attr1 TYPE scx_attrname VALUE '', attr2 TYPE scx_attrname VALUE '', attr3 TYPE scx_attrname VALUE '', attr4 TYPE scx_attrname VALUE '', END OF rate_limit_exceeded,
BEGIN OF invalid_response, msgid TYPE symsgid VALUE 'ZAI', msgno TYPE symsgno VALUE '003', attr1 TYPE scx_attrname VALUE 'MV_STATUS_CODE', attr2 TYPE scx_attrname VALUE '', attr3 TYPE scx_attrname VALUE '', attr4 TYPE scx_attrname VALUE '', END OF invalid_response.
DATA mv_destination TYPE string. DATA mv_status_code TYPE i.
METHODS constructor IMPORTING textid LIKE if_t100_message=>t100key OPTIONAL previous LIKE previous OPTIONAL destination TYPE string OPTIONAL status_code TYPE i OPTIONAL.ENDCLASS.Robuste API-Aufrufe:
METHOD call_ai_with_retry. CONSTANTS: lc_max_retries TYPE i VALUE 3. DATA: lv_retries TYPE i VALUE 0.
WHILE lv_retries < lc_max_retries. TRY. rs_result = mo_client->chat_completion( is_request ). RETURN. " Erfolg
CATCH cx_web_http_client_error INTO DATA(lx_http). lv_retries = lv_retries + 1.
IF lv_retries >= lc_max_retries. RAISE EXCEPTION TYPE zcx_ai_core_error EXPORTING textid = zcx_ai_core_error=>connection_failed previous = lx_http. ENDIF.
" Exponentielles Backoff DATA(lv_wait) = 1000 * lv_retries * lv_retries. cl_abap_session=>sleep( lv_wait ). ENDTRY. ENDWHILE.ENDMETHOD.Best Practices
| Thema | Empfehlung |
|---|---|
| Prompts | Klare, strukturierte Prompts mit Beispielen für konsistente Ergebnisse |
| Temperatur | Niedrig (0.0-0.3) für deterministische Aufgaben, höher für kreative |
| Token-Limits | Max_tokens begrenzen, um Kosten zu kontrollieren |
| Fehlerbehandlung | Retry-Logik mit exponentiellem Backoff implementieren |
| Caching | Wiederholte Anfragen cachen (z.B. Embeddings) |
| Logging | Token-Verbrauch und Latenz für Monitoring loggen |
| Fallbacks | Immer Fallback-Logik für AI-Ausfälle vorsehen |
| Datenschutz | Keine sensiblen Daten an externe LLMs senden |
| Kosten | Günstigere Modelle (GPT-3.5) für einfache Aufgaben nutzen |
| Testing | AI-Komponenten mit Mock-Responses testen |
Weiterführende Themen
- SAP Destination Service - Grundlagen der BTP-Integration
- RAP mit Custom Entities - Externe Daten in RAP einbinden
- SAP Event Mesh mit ABAP Cloud - Event-driven Architecture