SAP AI Core est l’infrastructure IA centrale de la SAP Business Technology Platform (BTP). Avec ABAP Cloud, vous pouvez intégrer directement des services IA tels que la classification de texte, la reconnaissance d’entités nommées, la génération d’embeddings ou les modèles d’IA générative dans vos applications métier.
Qu’est-ce que SAP AI Core ?
SAP AI Core est un service pour l’exécution et la gestion de modèles de Machine Learning sur BTP. Il offre :
| Fonctionnalité | Description |
|---|---|
| Model Serving | Hébergement et mise à l’échelle de modèles ML |
| SAP AI Services | Services IA préfabriqués (Document Extraction, etc.) |
| Generative AI Hub | Accès aux LLMs (GPT, Claude, etc.) |
| Custom Models | Entraîner et déployer vos propres modèles |
| MLOps | Versioning, monitoring, gestion du cycle de vie |
Aperçu de l’architecture
┌─────────────────────────────────────────────────────────────────────┐│ SAP BTP ││ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ││ │ ABAP Cloud │ │ Destination │ │ SAP AI Core │ ││ │ │──>│ Service │──>│ │ ││ │ ┌───────────┐ │ │ │ │ ┌───────────┐ │ ││ │ │ RAP App │ │ │ ┌───────────┐ │ │ │ Gen AI Hub│ │ ││ │ │ │ │ │ │ AI Core │ │ │ │ (LLMs) │ │ ││ │ │ AI Client │──────│ │ Destination│──────│ ├───────────┤ │ ││ │ │ │ │ │ └───────────┘ │ │ │ ML Models │ │ ││ │ └───────────┘ │ │ │ │ │ (Custom) │ │ ││ │ │ │ │ │ └───────────┘ │ ││ └─────────────────┘ └─────────────────┘ └─────────────────┘ │└─────────────────────────────────────────────────────────────────────┘Services IA disponibles
SAP AI Business Services
| Service | Description | Cas d’utilisation |
|---|---|---|
| Document Information Extraction | Analyser des documents et extraire des données | Traitement de factures |
| Business Entity Recognition | Reconnaître des entités dans les textes | Classifier les demandes clients |
| Service Ticket Intelligence | Catégoriser et router les tickets | Automatisation du helpdesk |
| Data Attribute Recommendation | Suggérer des attributs | Maintenance des données de base |
Generative AI Hub
Le Generative AI Hub offre l’accès aux Large Language Models (LLMs) :
| Famille de modèles | Exemples | Utilisation |
|---|---|---|
| OpenAI GPT | GPT-4, GPT-3.5-turbo | Génération de texte, analyse |
| Anthropic Claude | Claude 3 Opus/Sonnet | Analyse de documents, codage |
| Gemini Pro | Applications multimodales | |
| Embeddings | text-embedding-ada-002 | Recherche sémantique, RAG |
Configuration et paramétrage
1. Créer une instance de service AI Core
Dans le BTP Cockpit sous Service Marketplace :
┌──────────────────────────────────────────────────────────────┐│ Service Instance Configuration │├──────────────────────────────────────────────────────────────┤│ Service: SAP AI Core ││ Plan: standard (ou extended) ││ Instance Name: ai-core-instance ││ ││ Parameters (JSON): ││ { ││ "servicePlanName": "standard" ││ } │└──────────────────────────────────────────────────────────────┘2. Générer une clé de service
Créez une clé de service pour l’authentification :
{ "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. Configurer la destination
Créez une destination dans le BTP Cockpit :
┌──────────────────────────────────────────────────────────────┐│ Destination: SAP_AI_CORE │├──────────────────────────────────────────────────────────────┤│ Name: SAP_AI_CORE ││ Type: HTTP ││ URL: <AI_API_URL de la clé de service> ││ Proxy Type: Internet ││ Authentication: OAuth2ClientCredentials ││ ││ Token Service URL: <url de la clé de service>/oauth/token ││ Client ID: <clientid de la clé de service> ││ Client Secret: <clientsecret de la clé de service> ││ ││ Additional Properties: ││ ├── AI-Resource-Group: default ││ └── URL.headers.AI-Resource-Group: default │└──────────────────────────────────────────────────────────────┘4. Communication Arrangement
Créez un Communication Arrangement dans le système ABAP :
Communication Scenario: SAP_COM_0276 (Destination Service Integration)Communication System: BTP_DESTINATION_SERVICEOutbound Services: Destination Service API → ActiveAppeler le service SAP AI Core
Classe client de base
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. " Créer le JSON de la requête DATA(lv_json) = /ui2/cl_json=>serialize( data = is_request compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
" Appeler l'API (Endpoint Gen AI Hub) 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 ).
" Parser la réponse /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 ).
" Définir l'en-tête AI-Resource-Group 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( ). " Logger l'erreur et lever une exception RAISE EXCEPTION TYPE cx_web_http_client_error. ENDIF.
lo_client->close( ). ENDMETHOD.ENDCLASS.Exemples pratiques
Exemple 1 : Classification de texte
Classifiez automatiquement les demandes clients entrantes :
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( ).
" Prompt système pour la classification DATA(lv_system_prompt) = |Tu es un système de classification de tickets. | && |Analyse la demande client et retourne la classification en JSON.\n| && |Catégories: BILLING, TECHNICAL, SALES, GENERAL\n| && |Priorités: HIGH, MEDIUM, LOW\n| && |Format de réponse: \{"category": "...", "priority": "...", "confidence": 0.0-1.0\}|.
" Construire la requête 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 ) ) ).
" Appeler l'IA DATA(ls_response) = lo_client->chat_completion( ls_request ).
" Parser la réponse IF lines( ls_response-choices ) > 0. DATA(lv_content) = ls_response-choices[ 1 ]-message-content.
" Extraire et parser le JSON de la réponse /ui2/cl_json=>deserialize( EXPORTING json = lv_content CHANGING data = rs_result ). ENDIF. ENDMETHOD.ENDCLASS.Utilisation dans une détermination RAP :
METHOD classify_on_create. " Lire les nouveaux tickets 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. " Classifier le ticket 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. " Gérer l'erreur - définir des valeurs par défaut APPEND VALUE #( %tky = ls_ticket-%tky category = 'GENERAL" priority = 'MEDIUM" ) TO lt_update. ENDTRY. ENDLOOP.
" Mettre à jour les tickets MODIFY ENTITIES OF zi_ticket IN LOCAL MODE ENTITY Ticket UPDATE FIELDS ( category priority ) WITH lt_update.ENDMETHOD.Exemple 2 : Extraction de texte à partir de documents
Extrayez des données structurées à partir de texte libre :
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) = |Tu es un système d'analyse de documents. Extrais les données de facture | && |du texte suivant et retourne-les en JSON.\n| && |Schéma: \{\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": ["Description Quantité Prix", ...]\n| && |\}\n| && |Retourne uniquement le JSON, pas d'explications.|.
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.
" Nettoyer le JSON (supprimer les blocs de code Markdown si présents) 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.Exemple 3 : Génération d’embeddings pour la recherche sémantique
Créez des embeddings pour une recherche vectorielle :
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 ).
" Corps de la requête 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( ).
" Parser la réponse 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. " Traitement par lots pour plusieurs textes 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. " Calculer la similarité cosinus 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.Application : Recherche sémantique de produits
METHOD search_similar_products. DATA(lo_embedding_svc) = NEW zcl_embedding_service( ).
" Générer l'embedding pour la requête de recherche DATA(lt_query_embedding) = lo_embedding_svc->generate_embedding( iv_search_query ).
" Charger les produits avec leurs embeddings stockés SELECT product_id, name, embedding_json FROM zproduct_embeddings INTO TABLE @DATA(lt_products).
" Calculer les similarités 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.
" Trier par similarité SORT lt_results BY similarity DESCENDING.
" Retourner le top 10 rt_result = VALUE #( FOR i = 1 WHILE i <= 10 ( lt_results[ i ] ) ).ENDMETHOD.Exemple 4 : Assistant intelligent dans RAP
Intégrez un assistant IA comme action RAP :
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{ // ... opérations standard ...
// Action Assistant IA static action askAssistant parameter ZA_AssistantQuery result [1] ZA_AssistantResponse;}Behavior Implementation :
METHOD askAssistant. DATA(lo_client) = NEW zcl_ai_core_client( ).
" Construire le contexte à partir des données système DATA(lv_system_context) = |Tu es un assistant commercial pour un système SAP. | && |Réponds aux questions sur les commandes clients, les produits et les prix. | && |Réponds de manière précise et professionnelle. Si tu n'es pas sûr, dis-le.|.
" Requête utilisateur avec contexte DATA(lv_user_query) = keys[ 1 ]-%param-question. DATA(lv_context) = keys[ 1 ]-%param-context.
IF lv_context IS NOT INITIAL. lv_user_query = |Contexte: { lv_context }\n\nQuestion: { 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 = |Erreur: { lx_error->get_text( ) }| confidence = '0.00" sources = '" ) ) ). ENDTRY.ENDMETHOD.Traitement des réponses
Forcer des réponses structurées
Pour obtenir des données structurées de manière fiable, utilisez le mode JSON ou des instructions claires :
METHOD get_structured_response. DATA(lv_system_prompt) = |Tu es un système d'extraction de données. | && |Réponds TOUJOURS avec un JSON valide dans le format suivant:\n| && |\{"field1": "value1", "field2": "value2"\}\n| && |Pas d'explications, uniquement du JSON.|.
DATA(ls_request) = VALUE zcl_ai_core_client=>ty_chat_request( model = 'gpt-4" max_tokens = 500 temperature = '0.0' " Température basse pour une sortie cohérente 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.
" Nettoyage JSON 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.
" Désérialiser /ui2/cl_json=>deserialize( EXPORTING json = lv_content CHANGING data = rs_result ). ENDIF.ENDMETHOD.Surveiller la consommation de tokens
METHOD log_token_usage. DATA(ls_response) = mo_client->chat_completion( is_request ).
" Logger la consommation de tokens 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 }|.
" Écrire dans le log applicatif 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.Gestion des erreurs
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.Appels API robustes :
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. " Succès
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.
" Backoff exponentiel DATA(lv_wait) = 1000 * lv_retries * lv_retries. cl_abap_session=>sleep( lv_wait ). ENDTRY. ENDWHILE.ENDMETHOD.Bonnes pratiques
| Thème | Recommandation |
|---|---|
| Prompts | Prompts clairs et structurés avec des exemples pour des résultats cohérents |
| Température | Basse (0.0-0.3) pour les tâches déterministes, plus haute pour les tâches créatives |
| Limites de tokens | Limiter max_tokens pour contrôler les coûts |
| Gestion des erreurs | Implémenter une logique de retry avec backoff exponentiel |
| Mise en cache | Mettre en cache les requêtes répétées (ex. embeddings) |
| Logging | Logger la consommation de tokens et la latence pour le monitoring |
| Fallbacks | Toujours prévoir une logique de secours pour les pannes IA |
| Protection des données | Ne pas envoyer de données sensibles aux LLMs externes |
| Coûts | Utiliser des modèles moins chers (GPT-3.5) pour les tâches simples |
| Tests | Tester les composants IA avec des réponses mock |
Sujets connexes
- SAP Destination Service - Fondamentaux de l’intégration BTP
- RAP avec Custom Entities - Intégrer des données externes dans RAP
- SAP Event Mesh avec ABAP Cloud - Architecture événementielle