Accueil / Articles

De l’ingénierie de boucles à l’ingénierie de graphes : Créer des systèmes fiables

De l’ingénierie des boucles à l’ingénierie des graphes : la boucle d’agent en tant qu’unité d’ingénierie, où une seule boucle échoue en raison de problèmes de liens d’état, et pourquoi les graphes aident.

Éditeur : REACTAPP.TOP22 min de lecture4967 mots

Sources: From Loop Engineering to Graph Engineering: Building Reliable Agentic Systems in Tech Startups

Ce guide reconstitue le parcours allant des matières premières à un système fonctionnel pour : De l’ingénierie en boucle à l’ingénierie graphique : construction de systèmes agents fiables dans les startups technologiques. L’accent est mis sur des étapes opérationnelles, des vérifications explicites et du code que vous pouvez intégrer directement dans un dépôt sans devoir deviner son intention. Pour l’étape d’aperçu, définissez les entrées, le responsable de l’étape et les critères d’achèvement avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans avoir à deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le parcours passe de la démonstration aux environnements partagés.

while not finished:
    context = build_context(state)
    action = model.decide(context)
    observation = tools.execute(action)
    state = update(state, action, observation)

1. La boucle de l’agent en tant qu’objet d’ingénierie

Lors de la phase 1 « The Agent Loop », notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les flags fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Créez des points de contrôle après les étapes coûteuses. Le mécanisme de reprise ne doit pas facturer à nouveau la même appel au LLM lorsque l’opérateur réessaie un nœud ultérieur.

action = model(current_state)
observation = execute(action)
next_state = transition(current_state, action, observation)

continue_execution =
    task_is_not_complete
    and execution_budget_is_available
MAX_ITERATIONS = 12
MAX_TOOL_CALLS = 30
MAX_RUNTIME_SECONDS = 600
MAX_TOKEN_COST = 250_000

while budgets_available(state):
    action = agent.next_action(state)

    if not policy.allows(action):
        return TerminalFailure("policy_violation")

    result = execute_idempotently(action)
    state = persist_transition(state, action, result)

    verification = verifier.evaluate(state)

    if verification.passed:
        return VerifiedSuccess(
            state=state,
            evidence=verification.evidence
        )

return TerminalFailure("budget_exhausted")

2. Où un seul cycle commence à défaillir

Lorsque vous travaillez sur les étapes où il n’y a qu’un seul niveau, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Créez un point de contrôle après les étapes coûteuses. Le mécanisme de reprise ne doit pas facturer à nouveau la même appel au LLM lorsque l’opérateur tente à nouveau un nœud ultérieur.

Entrelacement d’états

Lors du traitement de l’étape d’entrelacement des états, notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Préférez des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité et non un processus embrouillé. Créez des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel du LLM lorsque l’opérateur réessaie un nœud ultérieur. Lors du traitement de l’étape d’entrelacement des états, notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.

Achevement ambigu

La phase de complétion ambiguë fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript parfait, un cas d’échec et la note de réversion avant d’élargir le périmètre. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du graphe. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption.

Réessais globaux

La phase de tentatives globales fonctionne le mieux lorsqu’elle est considérée comme une entité mesurable. Capturez un exemple idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Documentez en même temps le parcours normal et le parcours de récupération. Les tentatives, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Gardez l’état des graphes simple et typé : les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption.

Isolement faible des pannes

La phase d’isolation des pannes Weak fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas de panne et la note de réversion avant d’élargir le périmètre. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, la panne doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption. La phase d’isolation des pannes Weak fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas de panne et la note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le parcours passe de la démonstration aux environnements partagés.

Aggregation des privilèges

Pendant l’étape d’agrégation des privilèges, définissez les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système. Imposez une approbation humaine pour les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas la complétude du processus métier.

Concurrence limitée

Pour la phase de concurrence limitée, définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez conjointement le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations ultérieures. Imposez une approbation humaine pour les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas la complétude du processus métier.

Pauvre reproductibilité

Pour la phase de reproductibilité limitée, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Faites approuver par un humain les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas la complétude du processus métier. Pour la phase de reproductibilité limitée, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.

3. Quelles modifications pour l’ingénierie des graphes

Lors de la phase « 3 Quelles modifications pour l’ingénierie des graphes », notez d’abord les exigences : entrées requises, signal de succès et conséquences en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du graphe. Créez des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel d’LLM lorsque l’opérateur réessaie un nœud ultérieur.

Graph:
    nodes
    edges
    shared state
    terminal states
interface Node<Input, Output> {
  id: string;

  inputSchema: Schema<Input>;
  outputSchema: Schema<Output>;

  timeoutMs: number;
  retryPolicy: RetryPolicy;
  requiredCapabilities: Capability[];

  execute(
    input: Input,
    context: RunContext
  ): Promise<Output>;

  verify(
    output: Output,
    context: RunContext
  ): Promise<Evidence>;
}
interface Edge {
  from: NodeId;
  to: NodeId;
  condition: (
    state: WorkflowState
  ) => boolean;
}
const edges = [
  edge(
    "build",
    "tests",
    state => state.build.exitCode === 0
  ),

  edge(
    "build",
    "repair",
    state =>
      state.build.exitCode !== 0 &&
      state.repairAttempts < 3
  ),

  edge(
    "build",
    "failed",
    state =>
      state.build.exitCode !== 0 &&
      state.repairAttempts >= 3
  )
];

4. Un graphe pour un pipeline de livraison assisté par l’IA

Lors de l’élaboration du graphique 4A pour une étape donnée, notez d’abord les éléments essentiels : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Documentez en même temps le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Créez des points de contrôle après les étapes coûteuses. Le mécanisme de reprise ne doit pas facturer à nouveau la même appel au LLM lorsque l’opérateur tente une nouvelle fois un nœud ultérieur.

                         +----------------+
                         | Threat Model   |
                         +--------+-------+
                                  |
Intake -> Normalize -> Plan ------+-----> Implementation
                     |            |              |
                     |    +-------v--------+     |
                     +--->| Test Planning  |-----+
                          +----------------+     |
                                                 v
                                               Build
                                                 |
                          +----------------------+------------------+
                          | pass                                    | fail
                          v                                         v
                  Integration Tests                         Diagnose -> Repair
                          |                                         |
                     +----+----+                                    +-> Build
                     |         |
                   pass       fail
                     |         |
                     v         +-> Diagnose
                Security Check
                     |
                +----+----+
                |         |
              pass     high risk
                |         |
                v         v
            PR Creation  Human Approval
                |         |
                +----+----+
                     |
                     v
                Canary Deploy
                     |
                Runtime Verify
                  |       |
                pass     fail
                  |       |
                  v       v
                Done   Rollback -> Failed

5. L’état doit être de type défini, durable et partitionné

Lors de la phase des 5 États requis, notez d’abord le contrat : les entrées nécessaires, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Faites un point après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel d’LLM lorsque l’opérateur réessaie un nœud ultérieur. Lors de la phase des 5 États requis, notez d’abord le contrat : les entrées nécessaires, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le processus passe de l’environnement de démonstration à des environnements partagés.

{
  "runId": "run_93af",
  "goal": {
    "ticketId": "ENG-482",
    "repository": "payments-api",
    "baseRevision": "5df87a1"
  },
  "plan": {
    "artifactId": "sha256:71d...",
    "version": 2
  },
  "implementation": {
    "commit": "81f3ce2",
    "changedFiles": [
      "src/refunds/service.ts",
      "tests/refunds/service.test.ts"
    ]
  },
  "build": {
    "exitCode": 0,
    "artifactId": "sha256:932..."
  },
  "verification": {
    "unitTests": "passed",
    "integrationTests": "passed",
    "security": "pending"
  },
  "budgets": {
    "repairAttempts": 1,
    "toolCalls": 18,
    "tokens": 84320
  }
}
{
  "eventId": "evt_1092",
  "runId": "run_93af",
  "nodeId": "integration-tests",
  "attempt": 2,
  "inputHash": "sha256:8a2...",
  "outputHash": "sha256:19c...",
  "status": "succeeded",
  "startedAt": "2026-09-14T08:41:02Z",
  "completedAt": "2026-09-14T08:43:18Z"
}

6. Transitions conditionnées par des preuves

La phase des 6 transitions conditionnées par des preuves fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du graphe. Garantissez que l’état du graphe soit plat et typé. Les blocs imbriqués masquent l’identité du nœud qui a écrit tel champ, ce qui perturbe la reprise après interruption.

type TestEvidence = {
  command: string;
  revision: string;
  exitCode: number;
  totalTests: number;
  failedTests: number;
  reportArtifact: ArtifactRef;
};
function testsPassed(
  evidence: TestEvidence,
  workflow: WorkflowState
): boolean {
  return (
    evidence.exitCode === 0 &&
    evidence.totalTests > 0 &&
    evidence.failedTests === 0 &&
    evidence.revision === workflow.currentRevision
  );
}
repository_valid
and build_passed
and tests_passed
and security_accepted
and deployment_verified

7. Généalogie des artefacts et lecture sélective

La lignée des 7 artefacts et les étapes associées fonctionnent le mieux lorsqu’elles sont considérées comme une surface mesurable. Capturez un enregistrement réussi, un cas d’échec ainsi que la note de réversion avant d’élargir le périmètre. Documentez en même temps le parcours optimal et celui de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Gardez l’état des graphes simple et typé ; les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption.

{
  "artifactId": "sha256:f39...",
  "type": "test_report",
  "producedBy": "integration-tests",
  "graphVersion": "delivery-v4",
  "inputs": [
    "sha256:source-revision-81f3ce2",
    "sha256:test-config-a17"
  ]
}
Source code changed:
    invalidate build artifact
    invalidate unit-test report
    invalidate integration-test report
    invalidate deployment artifact

Threat model unchanged:
    preserve existing threat-model artifact

Requirements unchanged:
    preserve normalized requirements
    preserve approved implementation plan

8. Idempotence et contrôle des effets secondaires

La phase des 8 principes d’idempotence et d’effets secondaires fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement exemplaire, un cas d’échec et une note de réversion avant d’élargir le périmètre. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’erreur doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a modifié tel champ, ce qui perturbe la reprise après interruption. La phase des 8 principes d’idempotence et d’effets secondaires fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement exemplaire, un cas d’échec et une note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.

const idempotencyKey = [
  runId,
  nodeId,
  inputArtifactHash
].join(":");

await deploymentApi.deploy({
  idempotencyKey,
  revision,
  environment
});
deploy_canary -> verify_runtime
                       |
                       +-> failure -> rollback_canary

9. Routage déterministe et basé sur un modèle

Pour l’étape 9 déterministe et basée sur un modèle, définissez les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du système. Préférez des sorties structurées avec validation de schéma plutôt que du texte libre lorsque l’étape suivante consiste en du code ou une appel à outil.

if (testReport.failedTests > 0) {
  return "repair";
}

if (securityReport.criticalFindings > 0) {
  return "human-review";
}

return "deploy";
const decision = await riskClassifier.run({
  changeSummary,
  affectedServices,
  dataClassification,
  migrationPlan
});
type RiskDecision = {
  level: "low" | "medium" | "high";
  reasons: string[];
  requiredChecks: CheckId[];
};

10. Planification, parallélisme et jonctions

Pour les 10 cas de parallélisme et d’étapes de planification, définissez les entrées, le responsable de l’étape ainsi que les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez conjointement le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Imposez une approbation humaine pour les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas la complétude du processus métier.

all required predecessor nodes are complete
and the incoming transition conditions are satisfied
                 +-> Generate Tests --+
Plan Complete ---+-> Threat Model ----+-> Join -> Implementation Review
                 +-> API Analysis ----+

Tout

Pour l’étape « All », définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Faites approuver par un humain les actions qui entraînent des dépenses ou modifient des données de production. Une connexion en temps de compilation ne garantit pas la complétude du processus métier. Pour l’étape « All », définissez les entrées, le responsable de l’étape et les critères de sortie avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.

N’importe lequel

Lorsque vous travaillez sur n’importe quelle étape, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système. Créez un point de contrôle après les étapes coûteuses. Le mécanisme de reprise ne doit pas facturer à nouveau la même appel au LLM lorsque l’opérateur réessaie un nœud ultérieur.

Quorum

Lors du travail sur l’étape Quorum, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie du produit, et non d’améliorations ultérieures. Faites un point après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel d’LLM lorsque l’opérateur tente à nouveau un nœud ultérieur.

Moyens optimisés

Lors de la phase d’effort optimal, notez d’abord les conditions du contrat : entrées requises, signal de succès et conséquences en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Préférez des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité et non un processus embrouillé. Faites des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel d’LLM lorsque l’opérateur réessaie un nœud ultérieur. Lors de la phase d’effort optimal, notez d’abord les conditions du contrat : entrées requises, signal de succès et conséquences en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.

Échouer rapidement

La phase « Échouer rapidement » fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du graphe. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption.

11. Sémantique des échecs

La phase 11 des sémantiques d’échec fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et le traitement des messages non livrés font partie du produit, et non d’une mise en forme ultérieure. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a écrit tel champ et perturbent la reprise après interruption.

type FailureClass =
  | "transient_dependency"
  | "invalid_input"
  | "verification_failed"
  | "policy_denied"
  | "budget_exhausted"
  | "human_rejected"
  | "unknown";
transient_dependency -> retry with backoff

invalid_input -> return to the upstream producer

verification_failed -> diagnose and repair

policy_denied -> terminal failure

budget_exhausted -> human escalation

human_rejected -> terminal cancellation

unknown -> quarantine and inspect
repair_attempts_remaining
and runtime_budget_available
and token_budget_available
and permitted_blast_radius_not_exceeded

12. Les limites de sécurité appartiennent aux nœuds

La phase des 12 frontières de sécurité fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et une note de réversion avant d’élargir le périmètre. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit pointer vers une seule responsabilité plutôt que vers un processus embrouillé. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a écrit tel champ et perturbent la reprise après interruption. La phase des 12 frontières de sécurité fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et une note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le processus passe de la démonstration aux environnements partagés.

nodes:
  repository_analysis:
    capabilities:
      - repository:read

  implementation:
    capabilities:
      - repository:read
      - workspace:write

  create_pull_request:
    capabilities:
      - repository:pull_request:create

  deploy_canary:
    capabilities:
      - deployment:preview:create

  production_release:
    capabilities:
      - deployment:production:create
    approval:
      required: true

13. Versionning et reproductibilité

Pour l’étape 13 relative à la versionning et à la reproductibilité, définissez les entrées, le responsable de l’étape ainsi que les critères d’achèvement avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système. Imposez une approbation humaine pour les actions qui entraînent des dépenses ou modifient des données de production. Une connexion effectuée en temps de compilation ne garantit pas la complétude des processus métier.

{
  "runId": "run_93af",
  "graph": {
    "name": "software-delivery",
    "version": "4.2.1"
  },
  "nodes": {
    "planner": "planner@2.3.0",
    "implementation": "coding-agent@5.1.2",
    "security-review": "security-review@1.8.0"
  },
  "models": {
    "planner": "model-a-2026-08",
    "implementation": "model-b-2026-09"
  },
  "policyVersion": "delivery-policy@3.4.0",
  "baseRevision": "5df87a1"
}

14. Observabilité au niveau du graphe

Pour la phase 14 « Observabilité au niveau du graphe », définissez les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez conjointement le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’une amélioration ultérieure. Imposez une approbation humaine pour les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas la complétude du fonctionnement métier.

workflow_run_id
graph_version
node_id
node_attempt
parent_node_id
artifact_ids
model_version
prompt_version

15. Une implémentation minimale pour les startups

Pour la phase 15 A Minimal Startup, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Faites approuver par un humain les actions qui entraînent des dépenses ou modifient des données de production. Une connexion en temps de compilation ne garantit pas la complétude du processus métier. Pour la phase 15 A Minimal Startup, définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier du code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe de la démo aux environnements partagés.

>
workflow_definitions
workflow_versions
workflow_runs
node_definitions
node_attempts
transition_events
artifacts
approvals
capability_grants
def schedule(run):
    state = load_state(run.id)
    candidates = find_pending_nodes(run.graph_version)

    for node in candidates:
        if dependencies_satisfied(node, state):
            if incoming_guards_allow(node, state):
                enqueue(
                    run_id=run.id,
                    node_id=node.id,
                    graph_version=run.graph_version
                )
def execute_node(job):
    attempt = create_attempt(job)

    try:
        inputs = resolve_inputs(job)
        validate(inputs, job.node.input_schema)

        capabilities = issue_capabilities(job.node)
        output = job.node.execute(inputs, capabilities)

        validate(output, job.node.output_schema)
        evidence = job.node.verify(output)

        persist_success(attempt, output, evidence)
        evaluate_outgoing_edges(job.run_id, job.node.id)

    except Exception as error:
        failure = classify_failure(error)
        persist_failure(attempt, failure)
        apply_failure_transition(job, failure)

    finally:
        revoke_capabilities(job.node)

16. Migration d’un cycle vers un graphe

Lorsque vous travaillez sur la phase de migration, notez d’abord les exigences : entrées requises, signal de succès et conséquences en cas d’échec partiel. Cette liste de contrôle permet de maintenir l’honnêteté des modifications ultérieures du code. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du graphe. Créez des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel au LLM lorsque un opérateur réessaie un nœud ultérieur.

Étape 1 : Instrumenter le cycle existant

Lorsque vous travaillez sur l’étape 1 concernant l’instrumentation de la phase, notez d’abord le contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Documentez ensemble le parcours normal et le parcours de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Créez des points de contrôle après les étapes coûteuses. Le mécanisme de reprise ne doit pas facturer à nouveau la même appel du LLM lorsque l’opérateur tente à nouveau un nœud ultérieur.

Étape 2 : Identifier les phases stables

Lors de l’exécution de l’Étape 2 « Identifier la phase stable », notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Préférez des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité et non un processus embrouillé. Faites des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel d’LLM lorsque l’opérateur réessaie un nœud ultérieur. Lors de l’exécution de l’Étape 2 « Identifier la phase stable », notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’honnêteté des modifications ultérieures du code. Enregistrez les temps d’exécution ainsi que le coût en tokens ou en requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le processus passe de l’environnement de démonstration à des environnements partagés.

Étape 3 : Définir des artefacts typés

La phase 3, « Définir les types », fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript exemplaire, un cas d’échec et la note de réversion avant d’élargir le périmètre. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans devoir lire l’ensemble du graphe. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption.

Étape 4 : Externaliser les transitions

La phase 4, « Externaliser les transitions », fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un transcript idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Documentez ensemble le parcours réussi et le parcours de récupération. Les tentatives répétées, les contrôles humains et le traitement des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Gardez l’état du graphe plat et typé : les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption.

Étape 5 : Ajouter une vérification indépendante

La phase « Add independent » de l’Étape 5 fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et une note de réversion avant d’élargir le périmètre. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit pointer vers une seule responsabilité plutôt que vers un processus embrouillé. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a écrit telle champ et perturbent la reprise après interruption. La phase « Add independent » de l’Étape 5 fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement idéal, un cas d’échec et une note de réversion avant d’élargir le périmètre. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite des factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.

Étape 6 : Introduire des points de contrôle

Pour l’étape 6 « Introduction des points de contrôle », définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du système. Imposez une approbation humaine pour les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas la complétude du processus métier.

Étape 7 : Isoler les fonctionnalités

Pour l’étape 7 « Isoler les capacités », définissez les entrées, le responsable de l’étape et les critères d’arrêt avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Documentez conjointement le parcours normal et les scénarios de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non traités font partie intégrante du produit, et non d’améliorations ultérieures. Imposez une approbation humaine pour les cas où de l’argent est dépensé ou des données de production sont modifiées. La configuration en temps de compilation ne garantit pas la complétude du fonctionnement métier.

Étape 8 : Ajouter des chemins de récupération limités

Pour l’étape 8 « Ajouter une étape délimitée », définitz les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Préférez des unités petites et testables aux scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Faites approuver par un humain les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas la complétude du processus métier. Pour l’étape 8 « Ajouter une étape délimitée », définitz les entrées, le responsable de l’étape et les critères de fin avant de modifier le code. Les opérateurs doivent pouvoir relancer l’étape à partir d’un point de contrôle connu sans deviner l’état caché. Enregistrez les temps d’exécution ainsi que le coût des tokens ou des requêtes à côté des résultats fonctionnels. Une visibilité précoce des coûts évite les factures inattendues lorsque le processus passe d’un environnement de démonstration à des environnements partagés.

Étape 9 : Paralléliser les tâches indépendantes éprouvées

Lors de l’exécution de l’étape 9 visant à paralléliser les tâches indépendantes éprouvées, notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de garantir l’intégrité des modifications ultérieures du code. Conservez la configuration en dehors du code de l’application. Les fichiers d’environnement, les bases de données secrètes et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du graphe. Créez des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel d’LLM lorsque un opérateur réessaie un nœud ultérieur.

Étape 10 : Versionner le graphe

Lorsque vous travaillez sur l’étape 10, notez d’abord les éléments du contrat : les entrées requises, le signal de succès, ainsi que ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Documentez ensemble le parcours normal et les scénarios de récupération. Les tentatives répétées, les contrôles humains et la gestion des messages non livrés font partie intégrante du produit, et non d’améliorations apportées ultérieurement. Créez des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel du LLM lorsque l’opérateur tente à nouveau un nœud ultérieur.

17. Schémas anti-pattern courants en ingénierie de graphes

Lorsque vous travaillez sur les 17 étapes de l’ingénierie graphique courante, notez d’abord le contrat : les entrées requises, le signal de succès et ce qui se passe en cas d’échec partiel. Cette liste de contrôle permet de rester honnête lors des modifications ultérieures du code. Préférez des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’échec doit pointer vers une seule responsabilité et non vers un processus embrouillé. Faites des points de contrôle après les étapes coûteuses. Le système de reprise ne doit pas facturer à nouveau la même appel d’LLM lorsque l’opérateur réessaie un nœud ultérieur.

Un agent par nœud

Décisions déterministes contrôlées par le modèle

État mutable partagé

Cycles illimités

Vérification rapportée par l’agent

Credenciaux globaux

Voies de compensation manquantes

Graphes sans historique

Acheminement dynamique prématuré

18. Lorsqu’un graphique est inutile

Conclusion

Implicit control flow
becomes
explicit workflow topology

Conversation state
becomes
typed durable state

Agent-declared success
becomes
evidence-gated completion

Global retries
become
bounded local recovery

Shared privileges
become
node-scoped capabilities

Complete reruns
become
dependency-aware replay

Sequential execution
becomes
controlled concurrency

Opaque behavior
becomes
graph-level observability

Liste de contrôle opérationnelle