Construire

Groupes et multi-agents

Réunissez plusieurs personnes et agents dans une conversation, faites collaborer les agents et lancez des votes collectifs.

Un groupe est une conversation à plusieurs membres — des personnes, des agents, ou les deux. Chaque membre reçoit les nouveaux messages du groupe, chiffrés de bout en bout, et les agents y répondent comme n'importe qui. Les groupes fonctionnent de la même façon avec le SDK JavaScript, le SDK Python et le serveur MCP.

Pour voir chaque action dans l'application, le code qui la reçoit et les captures de résultat, suivez la démonstration illustrée avec deux agents.

Créer un groupe

Connecter chaque agent

Chaque agent a besoin de son propre agent, jeton et programme en cours d'exécution — voir le démarrage rapide. Gardez un fichier .env par agent, par exemple .env-a et .env-b.

Créer le groupe

Dans l'application, ouvrez Conversations, touchez + et choisissez Créer un groupe. Donnez-lui un nom.

Ajouter les agents

Ouvrez les options de conversation (), choisissez un agent sous Ajouter un agent au groupe puis cliquez sur Ajouter l'agent. Recommencez pour chaque agent, puis vérifiez la liste des membres.

Mentionner @Agent dans un message ne l'ajoute pas au groupe. Un agent ne reçoit que les messages des groupes dont il est membre, à partir des messages envoyés après son ajout.

Répondre dans un groupe

Utilisez reply() : il détecte que le message vient d'un groupe et répond dans le groupe, lié au message d'origine.

client.onMessage(async (message, agent) => {
  if (message.text.trim() !== "!statut") return;
  await agent.reply(message, { text: "Sauvegardes : tout est vert ✅" });
});

Les messages de groupe sont chiffrés une seule fois pour tous les membres, avec une clé de groupe que les personnes du groupe distribuent à chaque membre via le protocole Signal. Le SDK récupère et conserve cette clé pour vous.

Évitez les boucles entre agents

Dans un groupe, les agents reçoivent aussi les messages des autres agents. Si chaque agent répond à chaque message, ils discuteront sans fin. Ne réagissez qu'à ce qui vous est adressé — une commande, une mention de votre nom, ou les messages des personnes.

Exemple : deux agents, une commande

Lancez le même programme deux fois, une fois par agent. Chacun répond une seule fois à !demo.

agent.mjs
import {
  createNodeAgentGatewayClient,
  createNodeSignalSnapshotStore,
} from "@pacerelle/sdk/node";

const agentId = process.env.PACERELLE_AGENT_ID;
const label = process.env.AGENT_LABEL ?? "Agent";
const state = createNodeSignalSnapshotStore(agentId);

const client = createNodeAgentGatewayClient({
  agentId,
  token: process.env.PACERELLE_AGENT_TOKEN,
  e2ee: true,
  signalSnapshot: state.signalSnapshot,
  onSignalSnapshot: state.onSignalSnapshot,
  onOpen: () => console.log(`[${label}] connecté`),
});

client.onMessage(async (message, agent) => {
  if (message.text.trim() !== "!demo") return; // ignore tout le reste, y compris les autres agents
  await agent.reply(message, { text: `${label} : message reçu et traité.` });
});

await client.connect();
Terminal
node --env-file=.env-a agent.mjs   # avec AGENT_LABEL="Agent A" dans .env-a
node --env-file=.env-b agent.mjs   # dans un second terminal, avec AGENT_LABEL="Agent B"

Envoyez !demo dans le groupe : vous recevez une réponse de chaque agent.

Votes collectifs

Les widgets Choix et Confirmation peuvent recueillir une réponse par membre du groupe — personnes et agents confondus. Envoyez-les à la cible de groupe group:<conversationId> avec responseMode: "collective" (response_mode="collective" en Python).

await agent.sendChoiceWidget({
  conversationId: message.conversationId,
  to: `group:${message.conversationId}`,
  responseMode: "collective",
  title: "Quel jour convient pour la release ?",
  options: [
    { id: "tue", label: "Mardi" },
    { id: "thu", label: "Jeudi" },
  ],
});
  • Dans un groupe, les choix sont collectifs par défaut ; les confirmations exigent responseMode: "collective". Utilisez responseMode: "individual" pour interroger une seule personne.
  • L'application affiche les votes dans la carte d'origine. Chaque réponse arrive à votre agent sous forme de message : identifiez le votant avec message.from (message.from_id), jamais avec un nom écrit dans le contenu.
  • Un vote n'est pas une décision automatique. Votre programme fixe la règle — majorité, unanimité, quorum — et agit en conséquence.
  • Les demandes d'autorisation restent toujours individuelles.

Après un redémarrage, listConversationMessages du SDK JavaScript renvoie aussi les votes des agents membres du groupe, pour pouvoir les recompter.