Esta página se aplica a Apigee y Apigee Hybrid.
Consulta la documentación de
Apigee Edge.
Apigee admite la transmisión continua de respuestas desde los extremos de eventos enviados por el servidor (SSE) a los clientes en tiempo real. La función SSE de Apigee es útil para controlar las APIs de modelos de lenguaje grandes (LLM) que funcionan de manera más eficaz transmitiendo sus respuestas al cliente. La transmisión de SSE reduce la latencia, y los clientes pueden recibir datos de respuesta en cuanto los genera un LLM. Esta función admite el uso de agentes de IA que operan en entornos en tiempo real, como bots de atención al cliente o orquestadores de flujos de trabajo.
Para usar SSE con Apigee, simplemente dirige un proxy de API a un extremo de destino habilitado para SSE. Para lograr un control más detallado sobre la respuesta de SSE, Apigee proporciona un flujo de extremo de destino especial llamado EventFlow
. En el contexto de un EventFlow
, puedes agregar un conjunto limitado de políticas para realizar operaciones en la respuesta de SSE, como filtrar, modificar o controlar errores. Para obtener más información sobre los flujos de proxy, consulta Controla proxies de API con flujos.
Crea un proxy de API para SSE
La IU de Apigee proporciona una plantilla para crear un proxy nuevo que incluye un EventFlow
.
Sigue estos pasos para crear un proxy de API con la plantilla EventFlow
mediante la IU de Apigee:
- Abre la IU de Apigee en la consola de Cloud en un navegador.
- En el panel de navegación izquierdo, haz clic en Desarrollo de proxy > Proxies de API.
- En el panel Proxies de API, haz clic en + Crear.
- En el panel Crear un proxy, en Plantilla de proxy, selecciona Proxy con eventos enviados por el servidor (SSE).
- En Detalles del proxy, ingresa lo siguiente:
- Nombre del proxy: Ingresa un nombre para el proxy, como
myproxy
. - Ruta base: Se establece de forma automática en el valor que ingresas para
Proxy name
. La ruta base es parte de la URL que se usa para realizar solicitudes a la API. Edge usa la URL para hacer coincidir solicitudes entrantes y enrutarlas al proxy de API adecuado. - Descripción (Opcional): Ingresa una descripción para tu nuevo proxy de API, como "Prueba de Apigee con un proxy simple".
- Destino (API existente): Ingresa la URL de destino de SSE para el proxy de API. Por ejemplo:
https://mocktarget.apigee.net/sse-events/5
. - Haz clic en Siguiente.
- Nombre del proxy: Ingresa un nombre para el proxy, como
- Implementa (opcional):
- Entornos de implementación: Opcional. Usa las casillas de verificación para seleccionar uno o más entornos en los que implementar tu proxy. Si prefieres no implementar el proxy en este punto, deja vacío el campo Entornos de implementación. Siempre puedes implementar el proxy más adelante.
Los proxies de API implementados con una configuración EventFlow
se facturarán como extensibles.
Configura un flujo de eventos
Para lograr un control más detallado sobre la respuesta de SSE, Apigee proporciona un flujo de extremo de destino especial llamado EventFlow
. En el contexto de un EventFlow
, puedes agregar un conjunto limitado de políticas, que se indican a continuación, para modificar la respuesta de SSE antes de que se vuelva a transmitir al cliente. Para obtener más información sobre los flujos de proxy, consulta Controla proxies de API con flujos.
Se debe colocar un EventFlow
dentro de la definición de TargetEndpoint
, como se muestra en la siguiente muestra de código:
<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
tiene dos atributos:
name
: Es un nombre para identificar el flujo.content-type
: El valor de este atributo debe sertext/event-stream
.
Consulta también la Referencia de configuración de flujo.
Puedes agregar hasta un total de cuatro políticas al elemento Response
de EventFlow
. Al igual que con todos los flujos, las políticas se ejecutan en el orden en que se agregan, y puedes agregar pasos condicionales para controlar su ejecución.
Es importante tener en cuenta que los tipos de políticas que puedes agregar a un EventFlow
se limitan a los siguientes.
No se permiten otros tipos de políticas en un EventFlow
:
Consulta también Adjunta y configura políticas en la IU y Adjunta y configura políticas en archivos en formato XML.
En el siguiente ejemplo, se muestra un EventFlow
con un paso de política RaiseFault condicional agregado:
<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>
Para ver más ejemplos de código EventFlow
, consulta la sección Casos de uso y ejemplos de EventFlow.
Variables de flujo
Un EventFlow
propaga dos variables de flujo de respuesta. Ten en cuenta que estas variables solo se pueden usar dentro del alcance del evento actual que se procesa en EventFlow
.
Acceder a estas variables o establecerlas fuera del alcance de EventFlow
no tiene ningún efecto. Solo tienen sentido en el contexto de EventFlow
.
response.event.current.content
: Es una cadena que contiene toda la respuesta del evento actual. Apigee no analiza la cadena de ninguna manera. Contiene toda la respuesta sin cambios, incluidos todos los campos de datos.response.event.current.count
: Cuenta de forma incremental la cantidad de eventos de respuesta enviados. Este valor se actualiza para cada evento recibido. El recuento será 1 para el primer evento y aumentará para los eventos posteriores.
Consulta también la Referencia de variables de flujo.
Casos de uso y ejemplos de EventFlow
En los siguientes ejemplos, se muestra cómo implementar casos de uso comunes para los proxies de SSE:
- Cómo modificar una respuesta de SSE
- Cómo filtrar una respuesta de SSE
- Cómo enviar un evento SSE a un sistema externo
- Cómo usar una política de Apigee Model Armor en un flujo de eventos
- Manejo de errores en EventFlow
Cómo modificar una respuesta de SSE
En este ejemplo, se muestra cómo quitar datos de una respuesta EventFlow
de SSE antes de devolverla al cliente.
El contenido de la respuesta de SSE se almacena en una variable de flujo llamada response.event.current.content
.
En este caso, usamos una política de JavaScript para recuperar el valor de la variable de flujo, analizarla y modificarla. Consulta también Variables de flujo.
- Crea un proxy nuevo con la plantilla de proxy de SSE. Consulta Crea un proxy de API con eventos enviados por el servidor (SSE).
- Abre el proxy en el editor de proxy de Apigee y haz clic en la pestaña Desarrollar.
- Crea una nueva política de JavaScript
con la siguiente definición. En este ejemplo, el código JavaScript se incluye directamente en la política.
Colocar el código de JavaScript en un archivo de recursos es otra opción para configurar la política.
<?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>
- Agrega la política de JavaScript al
EventFlow
del proxy. ElEventFlow
está conectado alTargetEndpoint
predeterminado. En este ejemplo, se usa la API de Gemini en Vertex AI para generar contenido.<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>
- Guarda el proxy y, luego, impleméntalo.
- Llama al proxy implementado:
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."}]}]}'
Muestra una respuesta de ejemplo
Esta es una respuesta de ejemplo sin ningún filtro aplicado. Ten en cuenta que la respuesta incluye un atributo
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" }
Esta es otra respuesta de muestra con la política de JavaScript aplicada. Se quitó el atributo
modelVersion
.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 } ] } }
Cómo filtrar una respuesta de SSE
En este ejemplo, se muestra cómo filtrar datos de una respuesta de SSE antes de devolverlos al cliente. En este caso, filtramos los datos de eventos de la respuesta con una política de JavaScript. La política analiza la respuesta del evento en JSON, lo modifica para quitar los datos del evento y, luego, le envía los datos de respuesta modificados al cliente.
Al igual que en el ejemplo anterior, este ejemplo recupera el valor de la variable de flujo response.event.current.content
y lo analiza en JSON. Luego, aplica lógica para implementar el filtrado deseado.
- Crea un proxy nuevo con la plantilla de proxy de SSE. Consulta Crea un proxy de API con eventos enviados por el servidor (SSE).
- Abre el proxy en el editor de proxy de Apigee y haz clic en la pestaña Desarrollar.
- Crea una nueva política de JavaScript
con la siguiente definición. En este ejemplo, el código JavaScript se incluye directamente en la política.
Colocar el código de JavaScript en un archivo de recursos es otra opción para configurar la política.
<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>
- Agrega la política de JavaScript al
EventFlow
del proxy. ElEventFlow
está conectado alTargetEndpoint
predeterminado. En este ejemplo, se usa la API de Gemini en Vertex AI para generar contenido.<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>
- Guarda el proxy y, luego, impleméntalo.
- Llama al proxy implementado:
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."}]}]}'
Muestra una respuesta de ejemplo
Este es un ejemplo de cómo se vería la respuesta sin aplicar ningún filtro. Observa que incluye datos de error:
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" }
Esta es otra respuesta de muestra después de aplicar el filtrado con el mensaje de error borrado.
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" }
Cómo enviar un evento SSE a un sistema externo
En este ejemplo, adjuntamos la política PublishMessage de Apigee a EventFlow
para enviar un evento SSE a un tema de Pub/Sub.
- Crea un proxy nuevo con la plantilla de proxy de SSE. Consulta Crea un proxy de API con eventos enviados por el servidor (SSE).
- Abre el proxy en el editor de proxy de Apigee y haz clic en la pestaña Desarrollar.
- Crea una nueva política PublishMessage con la siguiente definición:
<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>
- Agrega la política PublishMessage como un paso en el
EventFlow
del proxy de API.<TargetEndpoint name="default"> <EventFlow content-type="text/event-stream"> <Response> <Step> <Name>PM-record-event</Name> </Step> </Response> </EventFlow> <HTTPTargetConnection> </TargetEndpoint>
- Implementa y prueba el proxy de API.
- Con el contenido generado agregado al tema de Pub/Sub, puedes, por ejemplo, crear una función de Cloud Run para procesar los mensajes del tema.
Usa una política de Model Armor de Apigee en un flujo de eventos
Puedes usar la política SanitizeModelResponse para limpiar los eventos entrantes enviados por el servidor en un EventFlow
.
Esta política protege tus aplicaciones de IA, ya que limpia las respuestas de los modelos de lenguaje grandes (LLM). Para obtener información sobre Model Armor, consulta la descripción general de Model Armor. Para obtener información sobre las políticas de Apigee Model Armor, consulta Comienza a usar las políticas de Apigee Model Armor.
- Crea un proxy nuevo con la plantilla de proxy de SSE. Consulta Crea un proxy de API con eventos enviados por el servidor (SSE).
- Abre el proxy en el editor de proxy de Apigee y haz clic en la pestaña Desarrollar.
- Crea una nueva política SanitizeModelResponse con la siguiente definición:
<?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>
- (Opcional) Agrega una política de JavaScript para agrupar eventos antes de enviarlos a la política de Model Armor de Apigee.
<?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>
- Agrega las políticas de JavaScript y ModelArmor a un paso en el
EventFlow
del 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>
- Implementa y prueba el proxy de API.
Manejo de errores en EventFlow
De forma predeterminada, el flujo de eventos finaliza cuando se produce una falla. Sin embargo, si quieres realizar una depuración adicional, puedes enviar información de fallas a Cloud Logging, como se muestra en este ejemplo.
- Crea un proxy nuevo con la plantilla de proxy de SSE. Consulta Crea un proxy de API con eventos enviados por el servidor (SSE).
- Abre el proxy en el editor de proxy de Apigee y haz clic en la pestaña Desarrollar.
- Crea una nueva política de RaiseFault con la siguiente definición:
<?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>
- Adjunta la política de RaiseFault al
EventFlow
del proxy de SSE:<EventFlow content-type="text/event-stream"> <Response> <Step> <Name>RF-Empty-Event</Name> <Condition>response.event.current.content ~ "data: "</Condition> </Step> </Response> </EventFlow>
- Crea una política de MessageLogging para registrar errores. Por ejemplo:
<?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>
- Agrega la política de MessageLogging a las FaultRules del extremo de destino:
<?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>
- Implementa y prueba el proxy de API.
- Debido a que los datos de estadísticas se registran después de que se cierra la sesión de SSE, es posible que notes cierta demora en los informes de datos de estadísticas.
- Las fallas dentro de un EventFlow hacen que la transmisión se cierre de inmediato y no se genere ningún evento de error en particular para el cliente final. Si deseas obtener información para registrar manualmente este tipo de errores, consulta los casos de uso y ejemplos de EventFlow.
- Un cliente que recibe respuestas SSE transmitidas recibirá los encabezados
HTTP
, incluidos los códigos de estado, al comienzo de la transmisión de eventos. Como resultado, si el flujo de eventos entra en un estado de error, el código de estado que se recibió inicialmente no reflejará el estado de error.Esta limitación se puede ver cuando se visualiza una sesión de depuración. En la sesión, es posible que notes que el código de estado
HTTP
de las transmisiones que ingresan al estado de error difiere de los códigos de estado que se envían al cliente. Esto puede ocurrir porque la entrada de la sesión de depuración se genera después de que se procesa toda la solicitud, en lugar de al comienzo del flujo de eventos. La sesión de depuración puede reflejar el código de falla que genera el error, mientras que el cliente solo ve el estado 2xx que se recibió inicialmente en los encabezados.
Cómo ver datos de SSE en Apigee Analytics
Los datos de los proxies de SSE aparecen en las estadísticas de Apigee, como se espera para cualquier proxy de API. En la consola de Cloud, ve a Analytics > Métricas de API.
Depuración de proxies de SSE
Usa la herramienta de depuración de Apigee para depurar los proxies de SSE.
Los datos de depuración se capturan para EventFlow
de la misma manera que para los otros tipos de flujo.
Soluciona problemas
Si tienes problemas de tráfico en tiempo real, consulta los registros de acceso de Apigee para determinar la causa.
Limitaciones
Se aplican las siguientes limitaciones a los proxies de SSE: