Écrire des scénarios de simulation
Un scénario est composé des instructions d'un utilisateur simulé (qui il est, ce qu'il veut) plus des agent_expectations (ce qui compte comme un succès). Une simulation joue le scénario contre l'agent réel, et un juge LLM évalue la transcription.
Les exécutions sont jetables. Le fichier de scénario est ce qui dure : il est revu en diffs, ré-exécuté pendant des années, et c'est ce qui capture une modification de prompt qui casse quelque chose sans que personne ne s'en aperçoive.
Avant d'écrire un fichier, consultez le schéma exact et les flags CLI avec reading-livekit-docs. Les noms de champs et les commandes changent, donc cette compétence ne les réénonce pas. Conceptuellement, un fichier est un groupe nommé de scénarios. Chaque scénario contient les instructions de l'utilisateur simulé, les critères de réussite, et optionnellement des tags pour le groupage et des données par scénario que l'agent peut lire à l'exécution. Si le CLI propose d'ajouter des ids stables par scénario à un fichier, acceptez et committez-les.
Partir d'une baseline générée
Ne partez pas d'un fichier vide. Le générateur de LiveKit lit le code source de l'agent et produit une première approche décente beaucoup plus vite que vous ne l'écririez dix scénarios à la main :
lk agent simulate text -n 10 # confirmez les flags exacts avec --help
Générer à partir du code source charge le code vers LiveKit Cloud afin que le générateur puisse le lire, c'est pourquoi le CLI demande d'abord une confirmation. Dites-le à l'utilisateur avant de l'exécuter et laissez-le décliner. Certains codes ne peuvent pas quitter la machine, et dans ce cas vous écrivez les scénarios à la main. Un flag ignore l'invite pour les exécutions non interactives.
Quand l'exécution se termine, le CLI vous dit soit où il a sauvegardé les scénarios générés, soit vous propose de les sauvegarder dans le projet. De toute façon, mettez ce fichier dans le repo comme point de départ.
Vous ne pouvez pas diriger le générateur. Il déduit l'intention du code, donc il écrit des conversations plausibles au lieu de celles que les utilisateurs de cet agent ont, et il ne sait pas de quoi l'utilisateur s'inquiète. Traitez sa sortie comme un brouillon :
- Lisez chaque scénario et supprimez ceux qui n'importent pas. Un fichier que vous n'avez pas lu n'est pas une suite de tests.
- Précisez les attentes vagues. Si le juge ne peut pas décider d'une
agent_expectations, son verdict change entre les exécutions. C'est la cause la plus fréquente de scénarios instables. - Ajoutez ce que la génération omet. Elle dérive vers des chemins heureux.
references/risk-coverage.mdexplique comment transformer les contraintes de l'agent en checklist et donner à chaque item un scénario. - Ajoutez ce dont l'utilisateur s'inquiète. S'il ne l'a pas dit, demandez ce qu'il veut tester en stress. Cette entrée est pourquoi une suite qu'une personne oriente est meilleure qu'une générée.
Demander quoi tester
L'utilisateur sait quel flux n'arrête pas de casser, quel client s'est plaint, et quel changement les rend nerveux. Demandez, et pondérez la suite vers ce domaine avec plus et de scénarios plus profonds.
La concentration ajoute de la couverture. Elle ne supprime jamais la couverture des limites dures de l'agent. Si l'utilisateur n'a pas de préférence, générez largement et dites-lui ce que vous avez fait.
Ancrer les scénarios dans ce que l'agent peut faire
Lisez le code de l'agent localement avec vos outils habituels avant d'écrire quoi que ce soit. Cherchez ce qu'un utilisateur peut demander (capabilities), où les requêtes sont bloquées (constraints : étapes requises, items indisponibles par nom, plafonds, admissibilité), et ce que l'agent doit refuser.
Les contraintes importent le plus. Un scénario qui demande quelque chose que l'agent ne peut pas faire n'est valide que si l'attente est que l'agent le dise. Écrit autrement, le test échoue quand l'agent se comporte correctement.
L'étendue est l'agent accessible depuis le point d'entrée de session, plus les agents auxquels il délègue et les tâches qu'il attend. Ignorez les autres classes du répertoire, les imports inutilisés, et les fichiers d'exemple.
Écrivez des instructions que l'utilisateur simulé peut suivre
Il y a deux formes, et celle que vous utilisez dépend de ce qu'est le scénario. Les détails et exemples sont dans references/scenario-craft.md.
- Direction sous forme de points pour les flux déterministes que vous noterez sur l'état final. Un template structuré (persona, ouverture, faits révélés seulement si demandé, étapes dans l'ordre, réactions conditionnelles) garde le modèle de persona sur la bonne voie et rend l'exécution reproductible.
- Un paragraphe de persona plus des objectifs pour les scénarios ouverts et adversariaux notés seulement sur la conversation, où vous voulez que l'utilisateur simulé improvise.
Dans les deux formes, les objectifs sont des requêtes à l'agent, jamais les actions propres de l'agent. Utilisez des valeurs réelles du domaine de l'agent et supposez aucun état préalable. Variez la persona, l'humeur et la difficulté dans la suite pour que ce ne soit pas dix copies du même appelant coopératif.
Diviser les scénarios en ensembles, un fichier par ensemble
La commande run prend un fichier de scénario, donc un fichier est une exécution. Divisez selon les lignes où vous voulez exécuter séparément, ce qui généralement n'est pas par sujet.
L'axe le plus important est comment l'ensemble est noté :
- Scénarios qui conduisent les flux d'outils concrets à un état final déterministe, notés sur l'état final et la conversation (voir « Make the agent consume the scenario » ci-dessous).
- Scénarios ouverts et adversariaux notés sur
agent_expectationsuniquement.
Ceux-ci ont besoin de formes d'instructions différentes, de câblage d'agent différent, et souvent d'une cadence de run différente, donc ils vont dans des fichiers différents. Le deuxième axe est cadence : un petit ensemble à exécuter avant une fusion, et l'ensemble complet avant une sortie.
Donnez à chaque fichier un name qui décrit l'ensemble, puisqu'il étiquette l'exécution. À l'intérieur d'un fichier, utilisez tags pour découper. Taggez feature afin qu'une défaillance pointe vers la partie de l'agent qui en est responsable, et ajoutez tout ce par quoi vous filtrez (canal, difficulté). Mettez un commentaire d'en-tête sur le fichier enregistrant les hypothèses de l'ensemble : dates épinglées, variables d'environnement requises, et ce sur quoi ses attentes dépendent.
Garder les scénarios reproductibles
Un scénario devrait donner le même résultat des mois à partir de maintenant qu'aujourd'hui.
- Écrivez des dates absolues et épinglez l'horloge de l'agent (généralement avec une variable d'environnement) afin que la disponibilité et les attentes s'alignent toujours. Les dates relatives se dégradent.
- Ne laissez pas les scénarios atteindre des backends réels. Alimentez plutôt l'état déterministe à partir du scénario (voir « Make the agent consume the scenario » ci-dessous).
- Gardez les ids stables où le CLI le supporte. Les labels et instructions changent, et l'id est ce qui lie les exécutions d'un scénario ensemble au fil du temps. Un scénario réécrit de zéro est un nouveau scénario et obtient un nouvel id.
Make the agent consume the scenario
Un fichier de scénario ne peut pas corriger deux problèmes par lui-même. Un scénario qui atteint un backend réel se note différemment à chaque exécution, et un juge qui lit seulement la transcription passera une exécution qui a réservé la mauvaise salle. Les deux sont corrigés dans le code de l'agent, dans une branche au sommet du point d'entrée :
- Détectez une simulation à partir du contexte job. En production, la vérification revient vide et rien d'autre ne change.
- Alimentez l'état à partir des données par scénario du scénario (un faux calendrier, une base de données en mémoire) que les vrais outils de l'agent lisent sans changement.
- Mockez les outils pour la durée de vie de la session, afin que la sélection d'outils soit encore testée mais l'exécution soit déterministe.
- Notez l'état final dans le callback de fin de simulation. Comparez avec quoi l'agent a terminé contre ce que le scénario attendait, et échouez l'exécution s'ils diffèrent. Votre vérification peut échouer une exécution que le juge a passée. Elle ne peut pas sauver une que le juge a échouée.
Seuls les scénarios de flux d'outils ont besoin de cela. Les scénarios ouverts et adversariaux sont notés sur la conversation seule. references/connecting-the-agent.md le couvre en intégralité, y compris comment confirmer que le câblage a pris effet. Consultez les noms d'API actuels avec reading-livekit-docs.
Développer la suite à partir des défaillances réelles
Les scénarios les plus précieux décrivent quelque chose qui a mal tourné. Une fois que l'agent est en direct, dérivez-les des sessions enregistrées au lieu d'en inventer davantage. Où le CLI le supporte, une sous-commande dérive un scénario à partir d'une session enregistrée (consultez lk agent simulate --help). Un scénario dérivé décrit un appel, donc élargissez-le à la classe d'appels qu'il représente et affinez son attente dans la règle que vous voulez faire respecter.
Chaque bug de production que vous corrigez devrait obtenir un scénario permanent dans le fichier.
N'écrivez pas de mauvais tests
Le juge évalue l'agent contre agent_expectations, donc une attente négligente punit le comportement correct :
- Pour les garde-fous et les cas négatifs, le passage est que l'agent refuse, escalade, ou décline d'inventer des données. Écrivez l'attente de cette façon.
- N'écrivez jamais une attente que l'agent ne peut respecter qu'en se conduisant mal, comme énoncer des données qu'il ne peut pas connaître ou donner des directives médicales, juridiques ou financières spécifiques. Si passer nécessite un mauvais comportement, le scénario est mauvais.
- Jugez par résultat, du point de vue de l'utilisateur. Ne prescrivez pas la formulation.
Références
references/risk-coverage.md— transformer les contraintes en checklist et garantir la couverturereferences/scenario-craft.md— formes d'instructions, variété de personas, scénarios audio-spécifiquesreferences/connecting-the-agent.md— le code côté agent : détecter, alimenter, mocker, noter l'état final
Compétences connexes
- Les exécuter :
running-livekit-simulations - Faits sur le schéma et CLI :
reading-livekit-docs