Gestionnaires de transformation LLM

Chaque fournisseur a son propre format pour les données utiles de demande, de réponse et d'erreur. Pour cette raison, le fournisseur LLM et Oracle Digital Assistant ne peuvent pas communiquer directement. Pour faciliter l'échange entre la compétence et ses fournisseurs LLM, vous devez transformer ces données utiles en interface LLM commune d'Oracle Digital Assistant et inversement.

Vous activez cette transformation en créant un programme de traitement de transformation LLM, un script dont les méthodes transformRequestPayload, transformResponsePayload et transformErrorResponsePayload exécutent les transformations de données utiles. Ces méthodes de transformation comportent deux signatures :
  • event : Les propriétés utilisées pour cet objet dépendent du type d'événement (transformRequestPayload, transformResponsePayload, transformErrorResponsePayload).
  • context : Référence la classe LlmTransformationContext, qui fournit l'accès aux méthodes pratiques que vous pouvez utiliser pour créer votre logique de programme de traitement d'événements.

Créer un programme de traitement de transformation LLM

Pour créer un programme de traitement d'événements de transformation LLM :
  1. Cliquez sur Components (Composants) dans la barre de navigation gauche.
  2. Cliquez sur +New Service.
  3. Remplissez la boîte de dialogue Create Service :
    • Nom : Entrez le nom du service.
    • Type de service : Conteneur intégré
    • Type d'ensemble de services de composant : Nouveau composant
    • Type de composant : Transformation LLLM
    • Nom du composant : Entrez un nom facilement identifiable pour le programme de traitement d'événements d'entité. Vous référencerez ce nom lorsque vous créerez le service LLM pour la compétence.
    • Modèle : Nous fournissons des modèles pour les compétences qui appellent Cohere directement ou au moyen du service d'intelligence artificielle générative d'Oracle. Vous n'avez pas besoin de modifier ces modèles. Si votre compétence appelle un modèle d'IA générative non Cohere/Oracle, tel qu'Azure Open AI, vous devez ajouter le code approprié.

      Les modèles pour Oracle Generative AI Cohere (génération de texte et récapitulation) et Llama (synthèse de texte) sont triés sous Generative AI dans le menu de liste Template (Modèle). Le modèle permettant d'accéder directement à Cohere se trouve sous Other (Autre). Pour accéder au modèle qui contient le code de démarrage d'autres modèles, sélectionnez Personnalisé (également situé sous Autre).

  4. Cliquez sur Créer pour générer le code du programme de traitement d'événements.
  5. Une fois le déploiement terminé, développez le service, puis sélectionnez le programme de traitement de transformation pour ouvrir sa page de propriétés, qui répertorie les trois méthodes de transformation LLM fournisseur-CLMI (transformRequestPayload, transformResponsePayload et transformErrorResponsePayload).

    Si vous créez un service Cohere ou un service d'intelligence artificielle générative Oracle hébergé sur la même location que votre instance Digital Assistant, le code du programme de traitement est complet.

  6. Si vous créez un service d'IA générative Oracle hébergé dans une location OCI différente, cliquez sur Modifier pour ouvrir la boîte de dialogue Modifier le composant et remplacer la variable event.compartmentId par l'ID compartiment de la location OCI à laquelle le service d'IA générative est abonné.
  7. Si vous utilisez le modèle personnalisé, cliquez sur Modifier pour ouvrir la boîte de dialogue Modifier le composant, puis mettez à jour le code de paramètre fictif suivant avec le code propre au fournisseur :
    Méthode Emplacement dans l'éditeur (modèle personnalisé) Code de paramètre fictif (modèle personnalisé)
    transformRequestPayload Courbes 23-25
    transformRequestPayload: async (event, context) => {
          return event.payload;
        },
    transformResponsePayload Courbes 33-35
        transformResponsePayload: async (event, context) => {
          return event.payload;
        },
    transformErrorResponsePayload Courbes 44-46
        transformErrorResponsePayload: async (event, context) => {
          return event.payload;
        }
  8. Vérifiez le numéro de système de vos mises à jour en cliquant sur Valider. Corrigez les erreurs de validation (le cas échéant), puis cliquez sur Enregistrer. Cliquez ensuite sur Fermer.

Exemples de code de transformation de fournisseur LLM

Azure OpenAI

Méthode Code de transformation du programme de traitement d'événements
Demande
transformRequestPayload: async (event, context) => {
  let payload = { "model": "gpt-4-0314",
                    "messages": event.payload.messages.map(m => { return {"role": m.role, "content": m.content}; }),                     "max_tokens": event.payload.maxTokens,
                    "temperature": event.payload.temperature,
                    "stream": event.payload.streamResponse
                  };
  return payload;
},
Réponse (non-streaming)
transformResponsePayload: async (event, context) => {
     let llmPayload = {};      
     if (event.payload.responseItems) {
       // streaming case
       llmPayload.responseItems = [];
       event.payload.responseItems
           .filter(item => item.choices.length > 0)
           .forEach(item => {
         llmPayload.responseItems.push({"candidates": item.choices.map( c => {return {"content": c.delta.content || "" };})});
       });
     } else {
        // non-streaming case
        llmPayload.candidates = event.payload.choices.map( c => {return {"content": c.message.content || "" };});
     } 
     return llmPayload;
   }
Lorsque la diffusion en continu est activée, le programme de traitement d'événements de transformation de réponse est appelé par lots de 20 messages transmis en continu. Ce tableau par lots de réponses en continu est stocké sous la clé responseItems.
Erreur
transformErrorResponsePayload: async (event, context) => {
  let errorCode = 'unknown';
  if (event.payload.error) {
    if ( 'context_length_exceeded' === event.payload.error.code) {
      errorCode = 'modelLengthExceeded';
    }  else if ('content_filter' === event.payload.error.code) {
      errorCode = 'flagged'; 
    } 
    return {"errorCode" : errorCode, "errorMessage": event.payload.error.message};
  } else {
    return {"errorCode" : errorCode, "errorMessage": JSON.stringify(event.payload)};
  }   
}

Service d'IA générative d'Oracle - Cohère

Note

Les modèles de commande ont été abandonnés. Nous vous recommandons de migrer vers le point d'extrémité /chat, ce qui implique la déclaration d'un modèle de clavardage plus récent et le remplacement des paramètres propres à la commande par des paramètres propres au clavardage.
Méthode Code de programme de traitement d'événement
Demande
transformRequestPayload: async (event, context) => {
      // Cohere doesn't support chat completions, so we first print the system prompt, and if there
      // are additional chat entries, we add these to the system prompt under the heading CONVERSATION HISTORY
      let prompt = event.payload.messages[0].content;
      if (event.payload.messages.length > 1) {
         let history = event.payload.messages.slice(1).reduce((acc, cur) => `${acc}\n${cur.role}: ${cur.content}` , '');
         prompt += `\n\nCONVERSATION HISTORY:${history}\nassistant:`
      }
      // using Cohere
      let modelId = "cohere.command"
      let runtimeType = "COHERE";
       return {
        "compartmentId": event.compartmentId,
        "servingMode": {
          "servingType": "ON_DEMAND",
            "modelId": modelId
        },
        "inferenceRequest": {
          "runtimeType": runtimeType,
          "prompt": prompt,
          "isStream": event.payload.streamResponse,
          "maxTokens": event.payload.maxTokens,
          "temperature": event.payload.temperature,
          // parameters set to default values
          "frequencyPenalty": 0,
          "isEcho": false,
          "numGenerations": 1,
          "presencePenalty": 0,
          "returnLikelihoods": "NONE",
          "topK": 0,
          "topP": 0.75,
          "truncate": "NONE"
        }
      };
}
Réponse
transformResponsePayload: async (event, context) => {      
    let llmPayload = {};
    if (event.payload.responseItems) {
        // streaming case
        llmPayload.responseItems = [];
        event.payload.responseItems.forEach(item => {
          llmPayload.responseItems.push({"candidates": [{"content": item.text || "" }]});
        });
      } else {
        // non-streaming
        llmPayload.candidates = event.payload.inferenceResponse.generatedTexts.map( item => {return {"content": item.text || "" };});
      }
      return llmPayload;
 }
Erreur
transformErrorResponsePayload: async (event, context) => {      
      const error = event.payload.message || 'unknown error';
      if (error.startsWith('invalid request: total number of tokens')) {
        // returning modelLengthExceeded error code will cause a retry with reduced chat history
        return {"errorCode" : "modelLengthExceeded", "errorMessage": error};
      } else {
        return {"errorCode" : "unknown", "errorMessage": error};
      }
}

Oracle Generative AI - Lama

Note

Les modèles de commande ont été retraités. Nous vous recommandons de migrer vers le point d'extrémité /chat, ce qui implique de déclarer le modèle de clavardage et de remplacer les paramètres propres à la commande par des paramètres propres au clavardage.
Méthode Code de programme de traitement d'événement
Demande
transformRequestPayload: async (event, context) => {
      // Cohere doesn't support chat completions, so we first print the system prompt, and if there
      // are additional chat entries, we add these to the system prompt under the heading CONVERSATION HISTORY
      let prompt = event.payload.messages[0].content;
      if (event.payload.messages.length > 1) {
         let history = event.payload.messages.slice(1).reduce((acc, cur) => `${acc}\n${cur.role}: ${cur.content}` , '');
         prompt += `\n\nCONVERSATION HISTORY:${history}\nassistant:`
      }
      // using Llama
      let modelId = "meta.llama-2-70b-chat"
      let runtimeType = "LLAMA";
       return {
        "compartmentId": event.compartmentId,
        "servingMode": {
          "servingType": "ON_DEMAND",
            "modelId": modelId
        },
        "inferenceRequest": {
          "runtimeType": runtimeType,
          "prompt": prompt,
          "isStream": event.payload.streamResponse,
          "maxTokens": event.payload.maxTokens,
          "temperature": event.payload.temperature,
          // parameters set to default values
          "frequencyPenalty": 0,
          "isEcho": false,
          "numGenerations": 1,
          "presencePenalty": 0,
          "returnLikelihoods": "NONE",
          "topK": 0,
          "topP": 0.75,
          "truncate": "NONE"
        }
      };
}
Réponse
transformResponsePayload: async (event, context) => {      
    let llmPayload = {};
    if (event.payload.responseItems) {
        // streaming case
        llmPayload.responseItems = [];
        event.payload.responseItems.forEach(item => {
          llmPayload.responseItems.push({"candidates": [{"content": item.text || "" }]});
        });
      } else {
        // non-streaming
        llmPayload.candidates = event.payload.inferenceResponse.choices.map( item => {return {"content": item.text || "" };});
      }
      return llmPayload;
 }
Erreur
transformErrorResponsePayload: async (event, context) => {      
      const error = event.payload.message || 'unknown error';
      if (error.startsWith('invalid request: total number of tokens')) {
        // returning modelLengthExceeded error code will cause a retry with reduced chat history
        return {"errorCode" : "modelLengthExceeded", "errorMessage": error};
      } else {
        return {"errorCode" : "unknown", "errorMessage": error};
      }
}

Oracle Generative AI - Résumer

Note

Les modèles de commande ont été abandonnés. Nous vous recommandons de migrer vers le point d'extrémité /chat, ce qui implique la déclaration d'un modèle de clavardage plus récent et le remplacement des paramètres propres à la commande par des paramètres propres au clavardage.
Méthode Code de programme de traitement d'événement
Demande
transformRequestPayload: async (event, context) => {
      // Cohere doesn't support chat completions, so we first print the system prompt, and if there
      // are additional chat entries, we add these to the system prompt under the heading CONVERSATION HISTORY
      let prompt = event.payload.messages[0].content;
      if (event.payload.messages.length > 1) {
         let history = event.payload.messages.slice(1).reduce((acc, cur) => `${acc}\n${cur.role}: ${cur.content}` , '');
         prompt += `\n\nCONVERSATION HISTORY:${history}\nassistant:`
      }
      let modelId = "cohere.command"
      return {
        "compartmentId": event.compartmentId,
        "servingMode": {
          "servingType": "ON_DEMAND",
          "modelId": modelId
        },
        "input" : prompt,
        "temperature": event.payload.temperature,
        // parameters set to default values
        "length": "AUTO",
        "extractiveness": "AUTO",
        "format": "PARAGRAPH",
        // natural language instructions
        "additionalCommand": "write in a conversational style"
      };
}
Réponse
transformResponsePayload: async (event, context) => {
      let llmPayload = {};
      // non-streaming only: streaming is not supported
      llmPayload.candidates = [{"content": event.payload.summary}];
      return llmPayload;
}
Erreur
transformErrorResponsePayload: async (event, context) => {             const error = event.payload.message ||
          'unknown error';      if(error.startsWith('invalid request:
          total number of tokens')) {        // returning modelLengthExceeded error
          code will cause a retry with reduced chat history        return{"errorCode": "modelLengthExceeded", "errorMessage": error};      }
          else{        return{"errorCode": "unknown", "errorMessage": error};      }}

Cohere (Modèle de commande) - Accès direct à la cohésion

Les programmes de traitement de ce code de transformation prennent en charge l'API /generate et le modèle Cohere.command associé, et non l'API /chat utilisée pour le modèle cohere.command.R. Si vous effectuez la migration vers le point d'extrémité /chat, vous devez mettre à jour manuellement les données utiles de demande et de réponse et le modèle de code généré.
Méthode Code de programme de traitement d'événement
Demande
transformRequestPayload: async (event, context) => {            
      // Cohere doesn't support chat completions, so we first print the system prompt, and if there
      // are additional chat entries, we add these to the system prompt under the heading CONVERSATION HISTORY
      let prompt = event.payload.messages[0].content;
      if (event.payload.messages.length > 1) {
         let history = event.payload.messages.slice(1).reduce((acc, cur) => `${acc}\n${cur.role}: ${cur.content}` , '');
         prompt += `\n\nCONVERSATION HISTORY:${history}\nassistant:`
      }
      return {
        "max_tokens": event.payload.maxTokens,
        "truncate": "END",
        "return_likelihoods": "NONE",
        "prompt": prompt,
        "model": "command",
        "temperature": event.payload.temperature,
        "stream": event.payload.streamResponse
      };
 }
Ce programme de traitement gère l'historique de conversation pour tenir à jour le contexte de conversation.
Réponse
transformResponsePayload: async (event, context) => {
  let llmPayload = {};      
  if (event.payload.responseItems) {
        // streaming case
        llmPayload.responseItems = [];
        event.payload.responseItems.forEach(item => {
          llmPayload.responseItems.push({"candidates": [{"content": item.text || "" }]});
        });
      } else {
        // non-streaming
        llmPayload.candidates = event.payload.generations.map( item => {return {"content": item.text || "" };});
      }
   return llmPayload;
}
Erreur
transformErrorResponsePayload: async (event, context) => {      
    // NOTE: Depending on the Cohere version, this code might need to be updated
      const error = event.payload.message || 'unknown error';
      if (error.startsWith('invalid request: total number of tokens')) {
        // returning modelLengthExceeded error code will cause a retry with reduced chat history
        return {"errorCode" : "modelLengthExceeded", "errorMessage": error};
      } else {
        return {"errorCode" : "unknown", "errorMessage": error};
      }
 
}

Interface LLM commune

Chaque fournisseur LLM a son propre format pour ses données utiles de demande et de réponse. L'interface LLM commune, ou CLMI, permet au composant invokeLLM de gérer ces données utiles de demande et de réponse propriétaires.

L'interface CMLI comprend les éléments suivants :
  • Spécification du corps de la demande.
  • Spécification de corps de réponse de réussite, applicable lorsque l'appel REST LLM retourne un statut HTTP 200.
  • Spécification du corps de la réponse d'erreur, applicable lorsque l'appel REST LLM retourne un statut HTTP autre que 200 mais que l'appel du service LLM a toujours réussi.
    Note

    Pour les appels ayant échoué, le composant invokeLLM traite les erreurs 401 (non autorisées) ou 500 (erreur du serveur interne).

Spécification du corps de la demande CLMI

Le corps de la demande CLMI JSON contient les propriétés suivantes :
Propriété Type Valeur par défaut Description Obligatoire?
messages Tableau d'objets de message S.O. Une liste de messages. Le premier message est l'invite avec la propriété role réglée à system. Si le LLM prend en charge une conversation à plusieurs tours afin que la réponse LLM puisse être affinée ou améliorée, les messages suivants seront des paires de messages provenant des rôles user et assistant. Le message de l'utilisateur contient les instructions ou la question de suivi pour le LLM. Le message de l'assistant contient la réponse LLM au message de l'utilisateur (achèvement). Si le LLM ne prend pas en charge les conversations à plusieurs tours, le tableau messages ne contient qu'un seul message système contenant l'invite. Oui
streamResponse booléen false Détermine si la réponse du LLM sera retransmise au composant LLM. Le réglage de cette propriété à true améliore l'expérience utilisateur, car la diffusion en continu permet au composant LLM d'envoyer des messages de réponse partielle aux utilisateurs afin qu'ils n'aient pas à attendre que le LLM termine la réponse.

Réglez streamResponse à false lorsque la validation de la réponse est utilisée. Etant donné que l'ensemble du message est requis avant que la validation puisse avoir lieu, le message peut être affiché plusieurs fois pour les utilisateurs : d'abord diffusé en continu, puis validé, puis retransmis en continu.

Non
maxTokens entier 1024 Le modèle génère des jetons pour les mots dans ses résultats. Les jetons peuvent être considérés comme des morceaux de mots. 100 jetons équivaut à environ 75 mots en anglais, par exemple. Cette propriété limite la taille du contenu généré par le modèle en définissant le nombre maximal de jetons qu'il génère pour la réponse. Non
temperature nombre 0 Le modèle utilise la température pour évaluer le caractère aléatoire - et donc la créativité - de ses réponses. Vous définissez cette valeur comme allant de 0 (résultats prévisibles) à 1 (résultats plus aléatoires). 0 signifie que le modèle enverra les mêmes résultats à une invite donnée. 1 signifie que les résultats du modèle à une réponse donnée peuvent varier considérablement. Utilisez un gestionnaire d'événements pour appliquer un multiplicateur si le fournisseur LLM prend en charge une plage autre que 0-1. Non
user chaîne S.O. Un identifiant unique représentant votre utilisateur final, qui peut être utilisé pour surveiller et détecter le langage abusif. Non
providerExtension objet S.O. Active les options de configuration propres au fournisseur LLM qui ne sont pas définies dans le cadre de CLMI. Non

Structure d'objet de message

Propriété Type Description Obligatoire?
role chaîne Créateur du message. Les valeurs sont system, user et assistant. Oui
content chaîne Contenu du message Oui
turn entier Nombre qui indique le tour de précision courant de l'échange de messages de clavardage. Lorsque la première invite est envoyée au LLM, le tour est 1. Oui
retry booléen Indicateur qui indique si le message est envoyé au LLM pour corriger une erreur dans la réponse Non (par défaut, false)
tag chaîne Balise personnalisée qui marque une invite spécifique. Si vous améliorez la réponse LLM à l'aide de l'option Critique et amélioration récursives (RCI), vous pouvez activer la logique personnalisée dans le programme de traitement validateResponsePayload pour détecter l'étape courante du processus RCI en réglant le marqueur à "criticize" ou "improve". Non

Spécification du corps de la réponse de réussite

Propriété Type Description Obligatoire?
candidates Tableau d'objets candidate Liste des messages de candidat retournés par le LLM Oui

Objets de candidat

Le corps de la demande CLMI JSON contient les propriétés suivantes :
Propriété Type Description Obligatoire?
content chaîne Contenu du message Oui

Spécification de corps de réponse d'erreur

Le corps de la réponse d'erreur CLMI JSON contient les propriétés suivantes :
Propriété Type Description Obligatoire?
errorCode Chaîne
  • notAuthorized : Indique que la demande LLM n'a pas la clé d'autorisation appropriée.
  • modelLengthExceeded : Indique que la combinaison de messages de demande (invite du système avec les messages de raffinement de l'utilisateur et de l'assistant) et le nombre maximal de jetons dépasse la limite de jetons du modèle.
  • requestFlagged : Indique que le LLM ne peut pas exécuter la demande, car il viole les politiques de modération du fournisseur LLM. Par exemple, les demandes qui contiennent du contenu raciste ou sexuellement abusif seraient signalées.
  • responseFlagged : Indique que la réponse LLM viole les politiques de modération du fournisseur LLM. Par exemple, les réponses qui contiennent du contenu toxique, comme un langage raciste ou sexuellement abusif, seraient signalées.
  • requestInvalid : Indique que la demande au LLM n'est pas valide. Par exemple, la demande n'est pas valide, car elle a échoué à certaines des règles de validation définies dans un programme de traitement d'événements, ou elle est dans un format qui n'est pas reconnu par le LLM.
  • responseInvalid : Indique que la réponse générée par LLM n'est pas valide. Par exemple, la réponse n'est pas valide car elle a échoué à certaines des règles de validation définies dans un programme de traitement d'événements de validation.
  • unknown : Lorsque d'autres erreurs se produisent.
Oui
errorMessage Chaîne Message d'erreur propre au fournisseur LLM. Il peut s'agir d'un objet JSON chaîne. Oui