Cette page s'applique à Apigee et à Apigee hybrid.
Consultez la documentation d'
Apigee Edge.
Apigee est compatible avec le streaming de réponses en continu à partir de points de terminaison d'événements envoyés par le serveur (SSE) vers les clients en temps réel. La fonctionnalité SSE d'Apigee est utile pour gérer les API de grands modèles de langage (LLM) qui fonctionnent le plus efficacement en renvoyant leurs réponses au client en streaming. Le streaming SSE réduit la latence, et les clients peuvent recevoir les données de réponse dès qu'elles sont générées par un LLM. Cette fonctionnalité prend en charge l'utilisation d'agents d'IA qui fonctionnent dans des environnements en temps réel, tels que des bots du service client ou des orchestrateurs de workflow.
Pour utiliser SSE avec Apigee, il vous suffit de diriger un proxy d'API vers un point de terminaison cible compatible avec SSE. Pour obtenir un contrôle plus précis sur la réponse SSE, Apigee fournit un flux de point de terminaison cible spécial appelé EventFlow
. Dans le contexte d'un EventFlow
, vous pouvez ajouter un ensemble limité de règles pour effectuer des opérations sur la réponse SSE, telles que le filtrage, la modification ou la gestion des erreurs. Pour en savoir plus sur les flux de proxy, consultez la section Contrôler des proxys d'API avec des flux.
Créer un proxy d'API pour SSE
L'interface utilisateur d'Apigee fournit un modèle permettant de créer un proxy qui inclut un EventFlow
.
Pour créer un proxy d'API avec le modèle EventFlow
à l'aide de l'interface utilisateur d'Apigee, procédez comme suit:
- Ouvrez l'interface utilisateur d'Apigee dans la console Cloud dans un navigateur.
- Dans le volet de navigation de gauche, cliquez sur Développement du proxy > Proxys d'API.
- Dans le volet Proxys d'API, cliquez sur + Créer.
- Dans le volet Créer un proxy, sous Modèle de proxy, sélectionnez Proxy avec événements envoyés par le serveur (SSE).
- Sous Détails du proxy, saisissez les informations suivantes :
- Nom du proxy : saisissez un nom pour le proxy, tel que
myproxy
. - Chemin de base : défini automatiquement sur la valeur que vous saisissez pour
Proxy name
. Le chemin de base fait partie de l'URL utilisée pour envoyer des requêtes à votre API. Apigee utilise l'URL pour mettre en correspondance et acheminer les requêtes entrantes vers le proxy d'API approprié. - Description (facultatif) : saisissez une description de votre nouveau proxy d'API, par exemple "Test Apigee avec un proxy simple".
- Target (Existing API) (Cible (API existante)):saisissez l'URL cible du SSE pour le proxy d'API. Par exemple :
https://mocktarget.apigee.net/sse-events/5
- Cliquez sur Suivant.
- Nom du proxy : saisissez un nom pour le proxy, tel que
- Déployer (facultatif) :
- Environnements de déploiement : facultatif. Cochez les cases pour sélectionner un ou plusieurs environnements dans lesquels déployer votre proxy. Si vous préférez ne pas déployer le proxy à ce stade, laissez le champ Environnements de déploiement vide. Vous pourrez toujours déployer le proxy ultérieurement.
Les proxys d'API déployés avec une configuration EventFlow
seront facturés en tant qu'Extensible.
Configurer un EventFlow
Pour obtenir un contrôle plus précis sur la réponse SSE, Apigee fournit un flux de point de terminaison cible spécial appelé EventFlow
. Dans le contexte d'un EventFlow
, vous pouvez ajouter un ensemble limité de règles, listées ci-dessous, pour modifier la réponse SSE avant qu'elle ne soit transmise en streaming au client. Pour en savoir plus sur les flux de proxy, consultez la section Contrôler des proxys d'API avec des flux.
Un EventFlow
doit être placé dans la définition TargetEndpoint
, comme indiqué dans l'exemple de code suivant:
<TargetEndpoint name="default"> <Description/> <FaultRules/> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <Flows/> <EventFlow name="EventFlow" content-type="text/event-stream"> <Response/> </EventFlow> <HTTPTargetConnection> <Properties/> <URL>https://httpbun.org/sse</URL> </HTTPTargetConnection> </TargetEndpoint>
EventFlow
comporte deux attributs:
name
: nom permettant d'identifier le flux.content-type
: la valeur de cet attribut doit êtretext/event-stream
.
Consultez également la documentation de référence sur la configuration des flux.
Vous pouvez ajouter jusqu'à quatre règles à l'élément Response
de EventFlow
. Comme pour tous les flux, les règles sont exécutées dans l'ordre dans lequel elles sont ajoutées. Vous pouvez ajouter des étapes conditionnelles pour contrôler leur exécution.
Notez que les types de stratégies que vous pouvez ajouter à un EventFlow
sont limités aux suivants.
Aucun autre type de stratégie n'est autorisé dans un EventFlow
:
Consultez également Associer et configurer des règles dans l'UI et Associer et configurer des règles dans des fichiers XML.
L'exemple suivant montre un EventFlow
avec une étape de stratégie RaiseFault conditionnelle ajoutée:
<TargetEndpoint name="default"> <EventFlow content-type="text/event-stream"> <Response> <Step> <Name>Raise-Fault-Cred-Invalid</Name> <Condition>fault.name equals "invalid_access_token"</Condition> </Step> </Response> </EventFlow> <HTTPTargetConnection> </TargetEndpoint></pre>
Pour obtenir d'autres exemples de code EventFlow
, consultez la section Cas d'utilisation et exemples d'EventFlow.
Variables de flux
Un EventFlow
renseigne deux variables de flux de réponse. Notez que ces variables ne sont utilisables que dans le champ d'application de l'événement en cours de traitement dans EventFlow
.
L'accès ou la définition de ces variables en dehors du champ d'application de EventFlow
n'a aucun effet. Elles n'ont de sens que dans le contexte de EventFlow
.
response.event.current.content
: chaîne contenant la réponse complète de l'événement actuel. Apigee n'analyse en aucun cas la chaîne. Il contient l'intégralité de la réponse, y compris tous les champs de données, sans modification.response.event.current.count
: compte de manière incrémentielle le nombre d'événements de réponse envoyés. Cette valeur est mise à jour pour chaque événement reçu. Le nombre sera de 1 pour le premier événement, puis il augmentera pour les événements suivants.
Consultez également la documentation de référence sur les variables de flux.
Cas d'utilisation et exemples d'EventFlow
Les exemples suivants montrent comment implémenter des cas d'utilisation courants pour les proxy SSE:
- Modifier une réponse SSE
- Filtrer une réponse SSE
- Envoyer un événement SSE à un système externe
- Utiliser une règle Apigee Model Armor dans un EventFlows
- Traitement des erreurs dans EventFlow
Modifier une réponse SSE
Cet exemple montre comment supprimer des données d'une réponse EventFlow
SSE avant de la renvoyer au client.
Le contenu de la réponse SSE est stocké dans une variable de flux appelée response.event.current.content
.
Dans ce cas, nous utilisons une règle JavaScript pour récupérer la valeur de la variable de flux, l'analyser et la modifier. Consultez également la section Variables de flux.
- Créez un proxy avec le modèle de proxy SSE. Consultez Créer un proxy d'API avec des événements envoyés par le serveur (SSE).
- Ouvrez le proxy dans l'éditeur de proxy Apigee, puis cliquez sur l'onglet Développer.
- Créez une règle JavaScript avec la définition suivante. Dans cet exemple, le code JavaScript est inclus directement dans la règle.
Vous pouvez également placer le code JavaScript dans un fichier de ressources pour configurer la règle.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Javascript continueOnError="false" enabled="true" timeLimit="200" name="js-update-resp"> <DisplayName>js-update-resp</DisplayName> <Properties/> <Source> var event = JSON.parse(context.getVariable("response.event.current.content")); event.modelVersion = null; context.setVariable("response.event.current.content",JSON.stringify(event)); </Source> </Javascript>
- Ajoutez la règle JavaScript à l'
EventFlow
du proxy.EventFlow
est associé àTargetEndpoint
par défaut. Cet exemple utilise l'API Gemini dans Vertex AI pour générer du contenu.<TargetEndpoint name="default"> <EventFlow content-type="text/event-stream"> <Response> <Step> <Name>js-update-resp</Name> </Step> </Response> </EventFlow> <HTTPTargetConnection> <URL>https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?key=GEMINI_API_KEY&alt=sse</URL> </HTTPTargetConnection> </TargetEndpoint>
- Enregistrez le proxy et déployez-le.
- Appelez le proxy déployé:
curl -X POST -H 'Content-Type: application/json' \ "https://YOUR_APIGEE_ENVIRONMENT_GROUP_HOSTNAME/YOUR_API_PATH" \ -d '{ "contents":[{"parts":[{"text": "Write a story about a magic pen."}]}]}'
Afficher un exemple de réponse
Il s'agit d'un exemple de réponse sans filtrage appliqué. Notez que la réponse inclut un attribut
modelVersion": "gemini-1.5-flash"
.data: { "candidates": [ { "content": { "parts": [ { "text": "ara found the pen tucked away in a dusty antique shop, nestled amongst chipped tea" } ], "role": "model" } } ], "usageMetadata": { "promptTokenCount": 8, "totalTokenCount": 8 }, "modelVersion": "gemini-1.5-flash" }
Voici un autre exemple de réponse avec la règle JavaScript appliquée. L'attribut
modelVersion
est supprimé.data: { "candidates": [ { "content": { "parts": [ { "text": " the fantastical creatures of her imagination. The quiet beauty of a simple life was a magic all its own.\n" } ], "role": "model" }, "finishReason": "STOP" } ], "usageMetadata": { "promptTokenCount": 8, "candidatesTokenCount": 601, "totalTokenCount": 609, "promptTokensDetails": [ { "modality": "TEXT", "tokenCount": 8 } ], "candidatesTokensDetails": [ { "modality": "TEXT", "tokenCount": 601 } ] } }
Filtrer une réponse SSE
Cet exemple montre comment filtrer les données d'une réponse SSE avant de les renvoyer au client. Dans ce cas, nous filtrons les données d'événement de la réponse à l'aide d'une règle JavaScript. La règle analyse la réponse d'événement au format JSON, modifie le fichier JSON pour supprimer les données d'événement, puis renvoie les données de réponse modifiées au client.
Comme dans l'exemple précédent, cet exemple récupère la valeur de la variable de flux response.event.current.content
et l'analyse en JSON, puis applique une logique pour implémenter le filtrage prévu.
- Créez un proxy avec le modèle de proxy SSE. Consultez Créer un proxy d'API avec des événements envoyés par le serveur (SSE).
- Ouvrez le proxy dans l'éditeur de proxy Apigee, puis cliquez sur l'onglet Développer.
- Créez une règle JavaScript avec la définition suivante. Dans cet exemple, le code JavaScript est inclus directement dans la règle.
Vous pouvez également placer le code JavaScript dans un fichier de ressources pour configurer la règle.
<Javascript continueOnError="false" enabled="true" timeLimit="200" name="js-filter-resp"> <DisplayName>js-filter-resp</DisplayName> <Properties/> <Source> var event = JSON.parse(context.getVariable("response.event.current.content")); if("error" in event){ // Do not send event to customer context.setVariable("response.event.current.content", ""); } </Source> </Javascript>
- Ajoutez la règle JavaScript à l'
EventFlow
du proxy.EventFlow
est associé àTargetEndpoint
par défaut. Cet exemple utilise l'API Gemini dans Vertex AI pour générer du contenu.<TargetEndpoint name="default"> <EventFlow content-type="text/event-stream"> <Response> <Step> <Name>js-filter-resp</Name> </Step> </Response> </EventFlow> <HTTPTargetConnection> <URL>https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?key=GEMINI_API_KEY&alt=sse </URL> </HTTPTargetConnection> </TargetEndpoint>
- Enregistrez le proxy et déployez-le.
- Appelez le proxy déployé:
curl -X POST -H 'Content-Type: application/json' \ "https://YOUR_APIGEE_ENVIRONMENT_GROUP_HOSTNAME/YOUR_API_PATH" \ -d '{ "contents":[{"parts":[{"text": "Write a story about a magic pen."}]}]}'
Afficher un exemple de réponse
Voici un exemple de réponse sans filtrage. Notez qu'il inclut des données d'erreur:
data: { "candidates": [ { "content": { "parts": [ { "text": "El" } ], "role": "model" } } ], "usageMetadata": { "promptTokenCount": 8, "totalTokenCount": 8 }, "modelVersion": "gemini-1.5-flash" } data: { "error": "Service temporarily unavailable. We are experiencing high traffic.", "modelVersion": "gemini-1.5-flash" }
Voici un autre exemple de réponse après le filtrage, avec le message d'erreur supprimé.
data: { "candidates": [ { "content": { "parts": [ { "text": "El" } ], "role": "model" } } ], "usageMetadata": { "promptTokenCount": 8, "totalTokenCount": 8 }, "modelVersion": "gemini-1.5-flash" } data: { "candidates": [ { "content": { "parts": [ { "text": "ara found the pen tucked away in a dusty antique shop, nestled amongst chipped tea" } ], "role": "model" } } ], "usageMetadata": { "promptTokenCount": 8, "totalTokenCount": 8 }, "modelVersion": "gemini-1.5-flash" }
Envoyer un événement SSE à un système externe
Dans cet exemple, nous associons la règle PublishMessage d'Apigee à EventFlow
pour envoyer un événement SSE à un sujet Pub/Sub.
- Créez un proxy avec le modèle de proxy SSE. Consultez Créer un proxy d'API avec des événements envoyés par le serveur (SSE).
- Ouvrez le proxy dans l'éditeur de proxy Apigee, puis cliquez sur l'onglet Développer.
- Créez une règle PublishMessage avec la définition suivante:
<PublishMessage continueOnError="false" enabled="true" name="PM-record-event"> <DisplayName>PM-record-event</DisplayName> <Source>{response.event.current.content}</Source> <CloudPubSub> <Topic>projects/<customer_project>/topics/<topic_name></Topic> </CloudPubSub> </PublishMessage>
- Ajoutez la règle PublishMessage en tant qu'étape dans le
EventFlow
du proxy d'API.<TargetEndpoint name="default"> <EventFlow content-type="text/event-stream"> <Response> <Step> <Name>PM-record-event</Name> </Step> </Response> </EventFlow> <HTTPTargetConnection> </TargetEndpoint>
- Déployez et testez le proxy d'API.
- Une fois votre contenu généré ajouté au sujet Pub/Sub, vous pouvez, par exemple, créer une fonction Cloud Run pour traiter les messages du sujet.
Utiliser une règle Apigee Model Armor dans un EventFlow
Vous pouvez utiliser la règle SanitizeModelResponse pour nettoyer les événements entrants envoyés par le serveur dans un EventFlow
.
Cette règle protège vos applications d'IA en nettoyant les réponses des grands modèles de langage (LLM). Pour en savoir plus sur Model Armor, consultez la section Présentation de Model Armor. Pour en savoir plus sur les règles Apigee Model Armor, consultez la section Premiers pas avec les règles Apigee Model Armor.
- Créez un proxy avec le modèle de proxy SSE. Consultez Créer un proxy d'API avec des événements envoyés par le serveur (SSE).
- Ouvrez le proxy dans l'éditeur de proxy Apigee, puis cliquez sur l'onglet Développer.
- Créez une stratégie SanitizeModelResponse avec la définition suivante:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <SanitizeModelResponse async="false" continueOnError="false" enabled="true" name="SMR-modelresponse"> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <DisplayName>SMR-modelresponse</DisplayName> <ModelArmor> <TemplateName>projects/{project}/locations/{location}/templates/{template-name}</TemplateName> </ModelArmor> <LLMResponseSource>{response_partial}</LLMResponseSource> <!-- Use the below settings if you want to call a Model Armor policy on every event --> <LLMResponseSource>{response.event.current.content}</LLMResponseSource> </SanitizeModelResponse>
- (Facultatif) Ajoutez une règle JavaScript pour regrouper les événements avant de les envoyer à la stratégie Apigee Model Armor.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Javascript continueOnError="false" enabled="true" timeLimit="200" name="JS-combine-resp"> <DisplayName>JS-combine-events</DisplayName> <Properties/> <Source> var eventText = JSON.parse(context.getVariable("response.event.current.content").substring(5)).candidates[0].content.parts[0].text; var finishReason = JSON.parse(context.getVariable("response.event.current.content").substring(5)).candidates[0].finishReason; var idx = context.getVariable("response.event.current.count"); if(idx%5==0 || finishReason=="STOP") { context.setVariable("response_partial", context.getVariable("tmp_buffer_pre")); context.setVariable("buff_ready", true); context.setVariable("tmp_buffer_pre", ""); } else { context.setVariable("buff_ready", false); context.setVariable("response_partial", ""); var previousBufferVal = context.getVariable("tmp_buffer_pre"); if(previousBufferVal) { context.setVariable("tmp_buffer_pre", previousBufferVal+eventText); } else { context.setVariable("tmp_buffer_pre", eventText); } } </Source> </Javascript>
- Ajoutez les règles JavaScript et ModelArmor à une étape de l'
EventFlow
du proxy:<EventFlow name="EventFlow" content-type="text/event-stream"> <Request/> <Response> <Step> <Name>JS-combine-resp</Name> </Step> <Step> <!-- Remove below Condition if you want to call model armor policy on every event --> <Condition> buff_ready = true </Condition> <Name>SMR-modelresponse</Name> </Step> </Response> </EventFlow>
- Déployez et testez le proxy d'API.
Gestion des erreurs dans EventFlow
Par défaut, le flux d'événements se termine lorsqu'une erreur se produit. Toutefois, si vous souhaitez effectuer un débogage supplémentaire, vous pouvez envoyer des informations sur les erreurs à Cloud Logging, comme indiqué dans cet exemple.
- Créez un proxy avec le modèle de proxy SSE. Consultez Créer un proxy d'API avec des événements envoyés par le serveur (SSE).
- Ouvrez le proxy dans l'éditeur de proxy Apigee, puis cliquez sur l'onglet Développer.
- Créez une règle RaiseFault avec la définition suivante:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <RaiseFault continueOnError="false" enabled="true" name="RF-Empty-Event"> <DisplayName>RF-Empty-Event</DisplayName> <Properties/> <FaultResponse> <AssignVariable> <Name>faultReason</Name> <Value>empty-event</Value> </AssignVariable> </FaultResponse> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </RaiseFault>
- Associez la règle RaiseFault à l'
EventFlow
du proxy SSE:<EventFlow content-type="text/event-stream"> <Response> <Step> <Name>RF-Empty-Event</Name> <Condition>response.event.current.content ~ "data: "</Condition> </Step> </Response> </EventFlow>
- Créez une règle MessageLogging pour consigner les erreurs. Exemple :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <MessageLogging continueOnError="false" enabled="true" name="ML-log-error"> <DisplayName>ML-log-error</DisplayName> <CloudLogging> <LogName>projects/{organization.name}/logs/apigee_errors</LogName> <Message contentType="text/plain">Request failed due to {faultReason}.</Message> <ResourceType>api</ResourceType> </CloudLogging> <logLevel>ALERT</logLevel> </MessageLogging>
- Ajoutez la règle MessageLogging aux règles d'erreur du point de terminaison cible:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <TargetEndpoint name="TargetEndpoint-1"> <Description/> <FaultRules> <FaultRule name="default-fault"> <Step> <Name>ML-log-error</Name> </Step> </FaultRule> </FaultRules> ... </TargetEndpoint>
- Déployez et testez le proxy d'API.
- Étant donné que les données analytiques sont enregistrées après la fermeture de la session SSE, vous remarquerez peut-être un certain retard dans la création des rapports sur les données analytiques.
- Les erreurs dans un EventFlow entraînent la fermeture immédiate du flux, et aucun événement d'erreur particulier n'est généré pour le client final. Pour savoir comment consigner manuellement ces types d'erreurs, consultez la section Cas d'utilisation et exemples d'EventFlow.
- Un client qui reçoit des réponses SSE en streaming reçoit les en-têtes
HTTP
, y compris les codes d'état, au début du flux d'événements. Par conséquent, si le flux d'événements passe dans un état d'erreur, le code d'état reçu initialement ne reflète pas l'état d'erreur.Cette limitation est visible lorsque vous consultez une session de débogage. Au cours de la session, vous remarquerez peut-être que le code d'état
HTTP
des flux qui passent à l'état d'erreur diffère des codes d'état envoyés au client. Cela peut se produire, car l'entrée de la session de débogage est générée après le traitement de l'ensemble de la requête, et non au début du flux d'événements. La session de débogage peut refléter le code d'erreur généré par l'erreur, tandis que le client ne voit que l'état 2xx initialement reçu dans les en-têtes.
Afficher les données SSE dans Apigee Analytics
Les données des proxys SSE s'affichent dans Apigee Analytics, comme pour tout proxy d'API. Dans Cloud Console, accédez à Analyse > Métriques de l'API.
Déboguer les proxys SSE
Utilisez l'outil de débogage Apigee pour déboguer les proxys SSE.
Les données de débogage sont collectées pour EventFlow
comme pour les autres types de flux.
Dépannage
Pour les problèmes de trafic en temps réel, consultez les journaux d'accès Apigee afin d'en déterminer la cause.
Limites
Les limites suivantes s'appliquent aux proxy SSE: