Streaming de eventos enviados pelo servidor

Esta página aplica-se ao Apigee e ao Apigee Hybrid.

Veja a documentação do Apigee Edge.

O Apigee suporta o streaming de respostas contínuo a partir de endpoints de eventos enviados pelo servidor (SSE) para clientes em tempo real. A funcionalidade SSE do Apigee é útil para processar APIs de modelos de linguagem (conteúdo extenso) (MDIs/CEs) que funcionam de forma mais eficaz ao transmitir as respetivas respostas de volta para o cliente. O streaming SSE reduz a latência e os clientes podem receber dados de resposta assim que são gerados por um MDG. Esta funcionalidade suporta a utilização de agentes de IA que operam em ambientes em tempo real, como bots de serviço ao cliente ou orquestradores de fluxo de trabalho.

Para usar SSE com o Apigee, basta direcionar um proxy de API para um destino ou um ponto final de proxy com SSE ativado. Para alcançar um controlo mais detalhado sobre a resposta SSE, o Apigee fornece um fluxo de endpoint especial denominado EventFlow. No contexto de um EventFlow, pode adicionar um conjunto limitado de políticas para realizar operações na resposta SSE, como filtrar, modificar ou processar erros. Para saber mais sobre os fluxos de proxy, consulte o artigo Controlar proxies de API com fluxos.

Crie um proxy de API para SSE

A IU do Apigee fornece um modelo para criar um novo proxy que inclui um EventFlow.

Siga estes passos para criar um proxy de API com o modelo EventFlow através da IU do Apigee:

  1. Na Google Cloud consola, aceda à página Proxy Development > API Proxies.

    Aceda a Proxies de API

  2. No painel Proxies de API, clique em + Criar.
  3. No painel Criar um proxy, em Modelo de proxy, selecione Proxy com eventos enviados pelo servidor (SSE).
  4. Em Detalhes do proxy, introduza o seguinte:
    • Nome do proxy: introduza um nome para o proxy, como myproxy.
    • Caminho base: definido automaticamente para o valor que introduz para o Nome do proxy. O caminho base faz parte do URL usado para fazer pedidos à sua API. O Apigee usa o URL para fazer corresponder e encaminhar os pedidos recebidos para o proxy de API adequado.
    • Descrição (opcional): introduza uma descrição para o novo proxy de API, como "Testar o Apigee com um proxy simples".
    • Destino (API existente): introduza o URL de destino da SSE para o proxy de API. Por exemplo: https://mocktarget.apigee.net/sse-events/5
    • Clicar em Seguinte.
  5. Implemente (opcional):
    • Ambientes de implementação: opcional. Use as caixas de verificação para selecionar um ou mais ambientes nos quais implementar o proxy. Se preferir não implementar o proxy neste ponto, deixe o campo Ambientes de implementação vazio. Pode sempre implementar o proxy mais tarde.
    • Conta de serviço: opcional. Uma conta de serviço para o proxy. A conta de serviço representa a identidade do proxy implementado e determina as autorizações que tem. Esta é uma funcionalidade avançada e, para efeitos deste tutorial, pode ignorá-la.

    Os proxies de API implementados com uma configuração EventFlow são faturados como extensíveis.

  6. Clique em Criar.

Consulte também o artigo Criar um proxy de API simples.

Configure um EventFlow

Para alcançar um controlo mais detalhado sobre a resposta SSE, o Apigee fornece um fluxo de endpoint especial denominado EventFlow. No contexto de um EventFlow, pode adicionar um conjunto limitado de políticas, indicadas abaixo, para modificar a resposta SSE antes de ser transmitida de volta ao cliente. Para saber mais sobre os fluxos de proxy, consulte o artigo Controlar proxies de API com fluxos.

Posicionamento de um EventFlow

Um elemento EventFlow tem dois atributos:

  • name: um nome para identificar o fluxo.
  • content-type: o valor deste atributo tem de ser text/event-stream.

Consulte também a referência de configuração do fluxo.

Um EventFlow pode ser colocado dentro de uma definição de TargetEndpoint ou ProxyEndpoint, conforme mostrado nos seguintes exemplos de código:

<ProxyEndpoint>

<ProxyEndpoint 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>
  <HTTPProxyConnection>
    <Properties/>
    <URL>https://httpbin.org/sse</URL>
  </HTTPProxyConnection>
</ProxyEndpoint>

<TargetEndpoint>

<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://httpbin.org/sse</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Também é importante ter em atenção que, embora possa adicionar um EventFlow a um TargetEndpoint, ProxyEndpoint ou ambos, apenas um EventFlow é executado.

A tabela seguinte mostra a execução de parágrafos EventFlow com base no posicionamento do ponto final:

ProxyEndpoint TargetEndpoint EventFlow usado
EventFlow em ProxyEndpoint EventFlow em TargetEndpoint EventFlow em TargetEndpoint
Sem EventFlow EventFlow em TargetEndpoint EventFlow em TargetEndpoint
EventFlow em ProxyEndpoint Sem EventFlow EventFlow em ProxyEndpoint

Adicione políticas a um EventFlow

Pode adicionar um total de quatro políticas ao elemento Response do elemento EventFlow. Tal como acontece com todos os fluxos, as políticas são executadas pela ordem em que são adicionadas, e pode adicionar passos condicionais para controlar a respetiva execução. É importante ter em atenção que os tipos de políticas que pode adicionar a um EventFlow estão restritos ao seguinte. Não são permitidos outros tipos de políticas num EventFlow:

Consulte também os artigos Anexar e configurar políticas na IU e Anexar e configurar políticas em ficheiros XML.

Os exemplos seguintes mostram um EventFlow com um passo de política RaiseFault condicional adicionado:

<ProxyEndpoint>

<ProxyEndpoint 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>
  <HTTPProxyConnection>
</ProxyEndpoint></pre>

<TargetEndpoint>

<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 mais EventFlowexemplos de código, consulte a secção Exemplos de utilização e exemplos do EventFlow.

Variáveis de fluxo

Um EventFlow preenche duas variáveis de fluxo de resposta. Tenha em atenção que estas variáveis só são utilizáveis no âmbito do evento atual que está a ser processado no EventFlow. Aceder ou definir estas variáveis fora do âmbito de EventFlow não tem efeito. Só são relevantes no contexto do EventFlow.

  • response.event.current.content: uma string que contém a resposta completa do evento atual. O Apigee não analisa a string de forma alguma. Contém a resposta completa inalterada, incluindo todos os campos de dados.
  • response.event.current.count: contabiliza incrementalmente o número de eventos de resposta enviados. Este valor é atualizado para cada evento recebido. A contagem é 1 para o primeiro evento e aumenta para os eventos subsequentes.

Consulte também a referência de variáveis de fluxo.

Exemplos de utilização e exemplos do EventFlow

Os exemplos seguintes mostram como implementar exemplos de utilização comuns para proxies SSE:

Modifique uma resposta SSE

Este exemplo mostra como remover dados de uma resposta SSE EventFlow antes de a devolver ao cliente. O conteúdo da resposta SSE é armazenado numa variável de fluxo denominada response.event.current.content. Neste caso, usamos uma política JavaScript para obter o valor da variável de fluxo, analisá-lo e modificá-lo. Consulte também as variáveis de fluxo.

  1. Crie um novo proxy com o modelo de proxy SSE. Consulte o artigo Crie um proxy de API com eventos enviados pelo servidor (SSE).
  2. Abra o proxy no editor de proxies do Apigee e clique no separador Desenvolver.
  3. Crie uma nova política de JavaScript com a seguinte definição. Neste exemplo, o código JavaScript está incluído diretamente na política. Colocar o código JavaScript num ficheiro de recursos é outra opção para configurar a 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>
  4. Adicione a política de JavaScript ao EventFlow do proxy. O EventFlow está associado ao TargetEndpoint ou ProxyEndpoint predefinido. Este exemplo usa a API Gemini no Vertex AI para gerar conteúdo.

    <ProxyEndpoint>

    <ProxyEndpoint name="default">
      <EventFlow content-type="text/event-stream">
        <Response>
          <Step>
            <Name>js-update-resp</Name>
          </Step>
        </Response>
      </EventFlow>
      <HTTPProxyConnection>
        <URL>https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?key=GEMINI_API_KEY&alt=sse</URL>
      </HTTPProxyConnection>
    </ProxyEndpoint>
    

    <TargetEndpoint>

    <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-2.5-flash:streamGenerateContent?key=GEMINI_API_KEY&alt=sse</URL>
      </HTTPTargetConnection>
    </TargetEndpoint>
    
  5. Guarde o proxy e implemente-o.
  6. Ligue para o 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."}]}]}'

    Mostrar uma resposta de exemplo

    Esta é uma resposta de exemplo sem filtros aplicados. Tenha em atenção que a resposta inclui um atributo modelVersion": "gemini-2.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-2.5-flash"
      }

    Esta é outra resposta de exemplo com a política de JavaScript aplicada. O atributo modelVersion é removido.

    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
            }
          ]
        }
      }

Filtre uma resposta SSE

Este exemplo mostra como filtrar dados de uma resposta SSE antes de os devolver ao cliente. Neste caso, filtramos os dados de eventos da resposta através de uma política de JavaScript. A política analisa a resposta do evento em JSON, modifica o JSON para remover os dados do evento e, em seguida, envia os dados de resposta modificados de volta para o cliente.

Tal como no exemplo anterior, este exemplo obtém o valor da variável de fluxo response.event.current.content e analisa-o em JSON, aplicando em seguida a lógica para implementar a filtragem pretendida.

  1. Crie um novo proxy com o modelo de proxy SSE. Consulte o artigo Crie um proxy de API com eventos enviados pelo servidor (SSE).
  2. Abra o proxy no editor de proxies do Apigee e clique no separador Desenvolver.
  3. Crie uma nova política de JavaScript com a seguinte definição. Neste exemplo, o código JavaScript está incluído diretamente na política. Colocar o código JavaScript num ficheiro de recursos é outra opção para configurar a 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>
  4. Adicione a política de JavaScript ao EventFlow do proxy. O EventFlow está anexado ao TargetEndpoint ou ProxyEndpoint predefinido. Este exemplo usa a API Gemini no Vertex AI para gerar conteúdo.

    <ProxyEndpoint>

    <ProxyEndpoint name="default">
      <EventFlow content-type="text/event-stream">
        <Response>
          <Step>
            <Name>js-filter-resp</Name>
          </Step>
        </Response>
      </EventFlow>
      <HTTPProxyConnection>
    	  <URL>https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?key=GEMINI_API_KEY&alt=sse	</URL>
      </HTTPProxyConnection>
    </ProxyEndpoint>
    

    <TargetEndpoint>

    <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-2.5-flash:streamGenerateContent?key=GEMINI_API_KEY&alt=sse	</URL>
      </HTTPTargetConnection>
    </TargetEndpoint>
    
  5. Guarde o proxy e implemente-o.
  6. Ligue para o 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."}]}]}'

    Mostrar uma resposta de exemplo

    Segue-se um exemplo do aspeto da resposta sem aplicar qualquer filtragem. Repare que inclui dados de erro:

    data: {
        "candidates": [
          {
            "content": {
              "parts": [
                {
                  "text": "El"
                }
              ],
              "role": "model"
            }
          }
        ],
        "usageMetadata": {
          "promptTokenCount": 8,
          "totalTokenCount": 8
        },
        "modelVersion": "gemini-2.5-flash"
      }
        data: {
        "error": "Service temporarily unavailable. We are experiencing high traffic.",
        "modelVersion": "gemini-2.5-flash"
        }

    Segue-se outra resposta de exemplo após a aplicação da filtragem com a mensagem de erro ocultada.

    data: {
      "candidates": [
        {
          "content": {
            "parts": [
              {
                "text": "El"
              }
            ],
            "role": "model"
          }
        }
      ],
      "usageMetadata": {
        "promptTokenCount": 8,
        "totalTokenCount": 8
      },
      "modelVersion": "gemini-2.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-2.5-flash"
    }

Envie um evento SSE para um sistema externo

Neste exemplo, anexamos a política PublishMessage do Apigee ao EventFlow para enviar um evento SSE para um tópico do Pub/Sub.

  1. Crie um novo proxy com o modelo de proxy SSE. Consulte o artigo Crie um proxy de API com eventos enviados pelo servidor (SSE).
  2. Abra o proxy no editor de proxies do Apigee e clique no separador Desenvolver.
  3. Crie uma nova política PublishMessage com a seguinte definição:
    <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>
  4. Adicione a política PublishMessage como um passo no EventFlow do proxy de API.

    <ProxyEndpoint>

    <ProxyEndpoint name="default">
      <EventFlow content-type="text/event-stream">
        <Response>
          <Step>
            <Name>PM-record-event</Name>
          </Step>
        </Response>
      </EventFlow>
      <HTTPProxyConnection>
    </ProxyEndpoint>

    <TargetEndpoint>

    <TargetEndpoint name="default">
      <EventFlow content-type="text/event-stream">
        <Response>
          <Step>
            <Name>PM-record-event</Name>
          </Step>
        </Response>
      </EventFlow>
      <HTTPTargetConnection>
    </TargetEndpoint>
  5. Implemente e teste o proxy de API.
  6. Com o conteúdo gerado adicionado ao tópico Pub/Sub, pode, por exemplo, criar uma função do Cloud Run para processar mensagens do tópico.

Use uma política Apigee Model Armor num EventFlow

Pode usar a política SanitizeModelResponse para limpar eventos enviados pelo servidor recebidos num EventFlow. Esta política protege as suas aplicações de IA ao higienizar as respostas de modelos de linguagem (conteúdo extenso) (MDIs/CEs). Para informações sobre o Model Armor, consulte o artigo Vista geral do Model Armor. Para informações sobre as políticas do Apigee Model Armor, consulte o artigo Comece a usar as políticas do Apigee Model Armor.

  1. Crie um novo proxy com o modelo de proxy SSE. Consulte o artigo Crie um proxy de API com eventos enviados pelo servidor (SSE).
  2. Abra o proxy no editor de proxies do Apigee e clique no separador Desenvolver.
  3. Crie uma nova política SanitizeModelResponse com a seguinte definição:
      <?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>
  4. (Opcional) Adicione uma política de JavaScript para agrupar eventos antes de os enviar para a política 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>
  5. Adicione as políticas de JavaScript e ModelArmor a um passo no EventFlow do 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>
  6. Implemente e teste o proxy de API.

Processamento de erros no EventFlow

Por predefinição, a stream de eventos termina quando ocorre uma falha. No entanto, se quiser fazer uma depuração adicional, pode enviar informações sobre falhas para o Cloud Logging conforme mostrado neste exemplo.

  1. Crie um novo proxy com o modelo de proxy SSE. Consulte o artigo Crie um proxy de API com eventos enviados pelo servidor (SSE).
  2. Abra o proxy no editor de proxies do Apigee e clique no separador Desenvolver.
  3. Crie uma nova política RaiseFault com a seguinte definição:
    <?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>
  4. Anexe a política RaiseFault ao EventFlow do 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>
  5. Crie uma política MessageLogging para registar erros. Por exemplo:
    <?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>
  6. Adicione a política MessageLogging às FaultRules do ponto final de destino ou do proxy:

    <TargetEndpoint>

    <?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>

    <ProxyEndpoint>

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ProxyEndpoint name="ProxyEndpoint-1">
      <Description/>
      <FaultRules>
        <FaultRule name="default-fault">
          <Step>
            <Name>ML-log-error</Name>
          </Step>
        </FaultRule>
      </FaultRules>
      ...
    </ProxyEndpoint>
  7. Implemente e teste o proxy de API.

Propague erros de falhas num EventFlow

Neste exemplo, mostramos como usar um EventFlow para propagar erros de falhas ao cliente. O processo funciona para notificar o cliente de erros imediatamente durante a execução da política.

  1. Crie um novo proxy com o modelo de proxy SSE. Consulte o artigo Crie um proxy de API com eventos enviados pelo servidor (SSE).
  2. Abra o proxy no editor de proxies do Apigee e clique no separador Desenvolver.
  3. Crie uma nova política de JavaScript com a seguinte definição:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <Javascript continueOnError="false" enabled="true" timeLimit="200" name="js-error">
        <DisplayName>js-error</DisplayName>
        <Properties/>
        <Source>
          if(context.getVariable("response.event.current.count")=="2") {
            throw new Error("Internal Error");
          }
          context.setVariable("response.event.current.content", context.getVariable("response.event.current.content"));
        </Source>
      </Javascript>

    Esta política foi concebida para gerar um erro quando uma condição específica é cumprida.

  4. Anexe a política de JavaScript ao EventFlow do proxy de SSE na configuração TargetEndpoint ou ProxyEndpoint. Este passo garante que o EventFlow processa a política durante o processamento de respostas:

    <TargetEndpoint>

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <TargetEndpoint name="default">
      <EventFlow content-type="text/event-stream">
        <Response>
          <Step>
            <Name>js-error</Name>
          </Step>
        </Response>
      </EventFlow>
      <HTTPTargetConnection>
        <URL>https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent</URL>
      </HTTPTargetConnection>
    </TargetEndpoint>

    <ProxyEndpoint>

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ProxyEndpoint name="default">
      <EventFlow content-type="text/event-stream">
        <Response>
          <Step>
            <Name>js-error</Name>
          </Step>
        </Response>
      </EventFlow>
      <HTTPProxyConnection>
        <URL>https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent</URL>
      </HTTPProxyConnection>
    </ProxyEndpoint>
  5. Implemente o proxy de API.
  6. Teste com o comportamento do proxy através do seguinte comando curl:
    curl -X POST -H 'Content-Type: application/json'  "https://ENVIRONMENT_GROUP_NAME/llm-api" -d '{ "contents":[{"parts":[{"text": "Write a story about a magic pen."}]}]}'

    Substitua ENVIRONMENT_GROUP_NAME pelo nome do grupo de ambientes.

    O resultado deve ser semelhante ao seguinte exemplo:

    data: {"candidates": [{"content": {"parts": [{"text": "El"}],"role": "model"}}],"usageMetadata": {"promptTokenCount": 8,"totalTokenCount": 8},"modelVersion": "gemini-2.5-flash"}
    data: {"fault":{"faultstring":"Execution of JS-error failed with error: Exception thrown from JavaScript : Error: Internal Error (Resource_1_js#2)","detail":{"errorcode":"steps.javascript.ScriptExecutionFailed"}}}

    O resultado mostra o fluxo de dados inicial seguido de uma mensagem fault. Em caso de erro, o Apigee captura as informações de falha e envia-as ao cliente como um evento.

Para mais informações sobre o processamento de falhas no Apigee, consulte o artigo Processamento de falhas.

Visualizar dados de SSE nas estatísticas do Apigee

Os dados dos proxies SSE são apresentados nas estatísticas do Apigee conforme esperado para qualquer proxy de API. Na Cloud Console, aceda a Analytics > Métricas de API.

Depuração de proxies SSE

Use a ferramenta de depuração do Apigee para depurar proxies SSE. Os dados de depuração são capturados para EventFlow tal como para os outros tipos de fluxo.

Resolução de problemas

Para problemas de trânsito em tempo real, verifique os registos de acesso do Apigee para determinar a causa.

Limitações

As seguintes limitações aplicam-se aos proxies SSE:

  • Uma vez que os dados de estatísticas são registados após o fecho da sessão de SSE, pode notar algum atraso na criação de relatórios de dados de estatísticas.
  • As falhas num EventFlow fazem com que o stream termine imediatamente e apresente um erro. Para obter informações sobre o registo manual destes tipos de erros ou o envio dos mesmos para o cliente, consulte os exemplos e as utilizações do EventFlow.
  • Um cliente que receba respostas SSE transmitidas recebe os cabeçalhos HTTP, incluindo quaisquer códigos de estado, no início da stream de eventos. Como resultado, se a stream de eventos entrar num estado de erro, o código de estado recebido inicialmente não reflete o estado de erro.

    Esta limitação pode ser vista quando visualiza uma sessão de depuração. Na sessão, pode reparar que o código de estado HTTP para streams que entram no estado de erro difere dos códigos de estado enviados para o cliente. Isto pode ocorrer porque a entrada da sessão de depuração é gerada depois de todo o pedido ter sido processado e não no início do fluxo de eventos. A sessão de depuração pode refletir o código de falha gerado pelo erro, enquanto o cliente só vê o estado 2xx inicialmente recebido nos cabeçalhos.