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.
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