Accueil / Articles / Streaming de modèles LLM résumables grâce à Redis Streams comme point de rencontre par tour

Streaming de modèles LLM résumables grâce à Redis Streams comme point de rencontre par tour

Survivez aux interruptions de connexion et aux pauses prolongées des outils en publiant des événements d’agent dans un flux Redis ciblé par tour, permettant aux clients de reprendre leur travail.

2049 mots

Ce que nous voulions

Les réponses des agents peuvent prendre des dizaines de secondes : réflexion, chargement d’une compétence, appel à des outils, attente, transmission de tokens. Les démos maintiennent une connexion ouverte. En environnement de production, la transmission s’interrompt au milieu d’une réponse, les passerelles doivent être redéployées, et il faut attendre que les outils répondent après plusieurs minutes. L’objectif est un streaming en temps réel reprendable permettant à un client de se reconnecter et de poursuivre la même interaction.

Le parcours

Itération 1 : le client communique directement avec l’agent

Méthode simple mais fragile. Tout problème réseau met fin au streaming. L’échelle horizontale entraîne soit des sessions persistantes, soit la perte d’événements.

Itération 2 : streaming gRPC entre services

Contrats internes améliorés, mais la méthode reste peu adaptée aux clients navigateur et fragile face à des pauses de plusieurs minutes lors du redémarrage des pods.

Pourquoi pas Kafka ?

Idéal pour les journaux durables ; trop lourd pour une rencontre par tour avec un stockage limité et des groupes de consommateurs qui ne correspondent pas bien à « une seule fenêtre du navigateur ».

Itération 3 (ce qui a fonctionné) : une rencontre nommée par tour

// Agent output
{
  "type": "tool_result",
  "tool": "product_search",
  "data": {
    "items": [...]
  }
}

// Gateway -> TV
{
  "type": "product_carousel",
  "items": [...]
}

// Gateway -> Mobile
{
  "type": "product_list",
  "items": [...]
}
cursor = last_event_id or "0-0"

while True:
    entries = xread({key: cursor}, block=30_000)

    if not entries:          # the only timeout check point
        check_timeouts()
        continue

    for entry_id, event in entries:
        # writes to the socket; not an ack that the client received it
        sse.send(id=entry_id, data=event.payload)
        cursor = entry_id
        if event.type in TERMINAL:
            return
id: 1755600000123-0
data: {"type":"tool_selected","tool":"search"}

id: 1755600000871-0
data: {"type":"response_block","block":{...}}
GET /sessions/{sid}/turns/{tid}/stream
Last-Event-ID: 1755600000871-0
# turn starts: one atomic step (MULTI/EXEC, or a Lua script)
xadd(key, first_event)
expire(key, GENEROUS_TTL)

# producer finishes: bring it in
expire(key, RECONNECT_TTL)

Chaque tour de l’utilisateur dispose d’un Redis Stream (ou du schéma stream+groupe de consommateurs) identifié par turn_id. L’agent publie des événements de jeton/outil ; le gateway reprend la lecture à partir du dernier id du client. La réconnexion reprend à ce curseur. Les pods peuvent tomber en panne ; le stream conserve suffisamment d’historique pour ce tour.

Détails importants

  • Discipline du curseur — les clients confirment l’ID du stream vu pour la dernière fois ; ils ne reprennent jamais à partir de 0 après la première connexion.
  • Événements de battement cardiaque — empêcher les intermédiaires de fermer les connexions inactives pendant l’attente du outil.
  • Cycle de vie — indicateurs explicites turn_started / turn_paused / turn_completed / turn_failed.
  • TTL — expiration des flux une fois le cycle terminé afin que Redis ne devienne pas un archive infinie.
  • Authentification — turn_id ne constitue pas une autorisation ; les cycles doivent être liés à la session authentifiée.
  • Le cas qui a résolu le problème : une pause de plusieurs minutes

    Ce que nous envoyons au client

    Événements saisis : tokens, résumés de tool_start et tool_result (jamais de secrets), erreurs et fin de traitement. Gardez les en-têtes de données petits ; stockez les éléments volumineux dans un système de stockage d’objets et envoyez des références.

    Costs, limites, points d’attention

    Faites attention à la mémoire de Redis, à la longueur maximale du flux et au nombre d’extensions si de nombreux gateways suivent une même étape. Limitez le nombre d’étapes simultanées par utilisateur. Effectuez des tests de charge pour gérer les pics de reconnectations après le déploiement d’un gateway.

    L’état final

    Le gateway est un lecteur conscient des points de reprise ; l’agent est un écrivain ; Redis Streams sert de point de rencontre. Une expérience utilisateur en temps réel survit aux échecs banals qui détruisent les architectures de démonstration.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.

    Conseil opérationnel : stockez l’ID de la dernière diffusion dans le cookie de session ou en mémoire du client, ainsi que du côté serveur afin de permettre la réécoute. Lorsqu’un utilisateur indique que « tout est bloqué », le service client doit pouvoir reconstituer l’échange à partir de la diffusion sans lui demander de reproduire une attente de dix minutes. Ajoutez des tableaux de bord indiquant le taux de reprise, le nombre d’échanges abandonnés et la durée moyenne des pauses, afin que l’équipe de développement puisse déterminer si c’est la lenteur des agents ou les problèmes de réseau qui en sont la cause.