MCP Fusion/Core concepts/Gating d’état FSM

Gating d’état FSM

Demandez à l’IA à propos de Vinkius

Anti-hallucination temporelle : liez les tools aux états du workflow afin qu’une action prématurée disparaisse physiquement de la liste au lieu d’être rejetée après la tentative de l’agent.

L’hallucination la plus coûteuse dans un workflow d’agent n’est pas une valeur erronée : c’est appeler l’étape quatre avant l’étape trois. L’agent voit un tool, l’appelle, le serveur le rejette et le tour est perdu. MCP Fusion retire l’étape du menu.

Lier un tool à un état

typescript
export default f.action('invoice.discharge')
  .describe('Discharge an approved invoice')
  .bindState('approved', 'DISCHARGE')
  .handle(async (input, ctx) => discharge(input.id));

bindState(states, transition) signifie que ce tool apparaît dans tools/list uniquement lorsque le workflow se trouve dans l’un des états indiqués et qu’un appel réussi déclenche transition. Les états viennent d’une machine que vous configurez une fois :

typescript
const fsm = f.fsm({
  id: 'invoice',
  initial: 'draft',
  states: {
    draft: { on: { SUBMIT: 'review' } },
    review: { on: { APPROVE: 'approved', REJECT: 'draft' } },
    approved: { on: { DISCHARGE: 'discharged' } },
    discharged: { type: 'final' },
  },
});

La forme est compatible avec XState v5. XState est un peer facultatif : lorsqu’il est installé, le gate exécute un actor réel ; sinon, il pilote une table de transitions manuelle intégrée. La fonctionnalité se dégrade donc gracieusement au lieu d’empêcher le démarrage.

Ce que l’agent voit

  • Dans draft, invoice.discharge n’est pas dans la liste. L’agent ne peut pas appeler ce qu’il ne voit pas.
  • Pour le tool qui mène à approved, l’appel réussi fait avancer la machine et le serveur envoie notifications/tools/list_changed.
  • Le client actualise la liste, et invoice.discharge apparaît alors avec sa propre description.

C’est plus fort qu’une garde : une garde rejette après la tentative, tandis que le gating retire la tentation. Les erreurs de validation liées à l’ordre disparaissent des logs, car le conflit d’ordre ne peut pas être exprimé.

Le gating est aussi appliqué sur le chemin d’appel, pas seulement dans la liste. Un client qui devine un nom de tool reçoit toujours FORBIDDEN avec les actions autorisées, la sécurité ne dépend donc jamais de l’actualisation du menu par le client.

Divulgation progressive dans le schéma

Un connecteur lié à une FSM peut aussi réduire son propre contexte. compactDescription() donne au tool une description courte lorsque la machine est dans l’état initial, puis le .describe() complet arrive dans les états suivants. Le menu de l’agent dans draft est plus petit et plus précis que celui du même tool dans approved, sans second déploiement.

État serverless et stateless

Une machine à états est un état durable, tandis que les transports stateless de MCP 2.0 n’ont pas de session où l’accrocher. Trois mécanismes couvrent ce cas :

  1. stateHandleKey : l’appel du tool peut porter un argument handle explicite que le modèle renvoie, le modèle recommandé par la spécification pour les flux stateless
  2. identifiant de session : lorsque le transport en possède un (Mcp-Session-Id), le gate conserve l’état par session
  3. repli par attachment : un serveur single-tenant sans aucune de ces clés utilise une identité en mémoire du processus

La persistance est une interface FsmStateStore que vous implémentez :

typescript
interface FsmStateStore {
  load(handle: string): Promise<{ state: string; updatedAt: string } | undefined>;
  save(handle: string, snapshot: { state: string; updatedAt: string }): Promise<void>;
}

Utilisez le store en mémoire pour un processus unique, ou adossez-le à Redis, DynamoDB, un KV edge ou une ligne de base de données. Le framework clone et restaure le gate par requête, les requêtes concurrentes ne partagent donc jamais une machine par accident.

Quand l’utiliser

  • Workflows d’approbation et de revue, rien ne peut être libéré avant l’approbation
  • Paiement et fulfillment, capturez après l’autorisation, jamais avant
  • Migrations en plusieurs étapes et fenêtres de maintenance destructive
  • Toute situation où un ordre incorrect coûte de l’argent ou des données, et où un appel rejeté coûte tout de même un tour

Le gating FSM se compose avec l’Exposition des tools, puisque la surface visible change avec l’état, et avec le Routage, puisque les tools liés à un état vivent dans leurs propres fichiers. Les handlers ne changent pas : ils ont toujours été écrits pour un état donné du monde.

Étapes suivantes