Accueil / Articles / Notes pratiques : Créez votre propre Claude Code à l’aide de Langchin : Une analyse approfondie

Notes pratiques : Créez votre propre Claude Code à l’aide de Langchin : Une analyse approfondie

Guide pratique pas à pas : Créez votre propre Claude Code avec Langchin – Une analyse approfondie des contrats, des vérifications et des emplacements de code intégrables pour les équipes utilisant ce modèle.

3402 mots

Ce guide reconstitue le parcours allant des matières premières à un système fonctionnel pour : Construisez votre propre Claude Code en utilisant Langchin : Une analyse approfondie des Deep Agents de LangChain. L’accent est mis sur des étapes opérationnelles, des vérifications explicites, ainsi que du code que vous pouvez intégrer directement dans un dépôt sans devoir deviner l’intention derrière lui. Pour l’étape d’aperçu, 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 avoir à deviner l’état caché. Gardez 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.

L’architecture d’un agent de codage

Lorsque vous travaillez sur « The Architecture of a stage », 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’une mise en forme ultérieure. Créez un point de contrôle après chaque étape coûteuse. 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.

Partie 0 : La boucle à partir de zéro — pas de framework, pas de magie

Lorsque vous travaillez sur l’étape de boucle de la Partie 0, notez d’abord les exigences : entrées requises, 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’erreur 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 du LLM lorsque l’opérateur réessaie un nœud ultérieur.

def run_agent_loop(client, user_message, tools, tool_functions, max_turns=20):
    messages = [{"role": "user", "content": user_message}]
    for _ in range(max_turns):
        # 1. Ask the model what to do next.
        response = client.messages.create(
            model="claude-sonnet-4-6", max_tokens=1024, tools=tools, messages=messages
        )
        messages = [*messages, {"role": "assistant", "content": response.content}]

        # 2. Plain text and no tool request? The job is done.
        tool_uses = [b for b in response.content if b.type == "tool_use"]
        if not tool_uses:
            return "".join(b.text for b in response.content if b.type == "text")
        # 3. Run each requested tool and hand the results back. 4. Repeat.
        results = [
            {"type": "tool_result", "tool_use_id": call.id,
             "content": tool_functions[call.name](**call.input)}
            for call in tool_uses
        ]
        messages = [*messages, {"role": "user", "content": results}]
    raise RuntimeError(f"agent loop did not finish within {max_turns} turns")

Partie 1 : La boucle — le moteur qui fait fonctionner tout le système

Lorsque vous travaillez sur l’étape « La boucle » de la Partie 1, 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. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définez des vérifications de succès et refusez toute exécution partielle silencieuse. 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 du LLM lorsque l’opérateur réessaie un nœud ultérieur. Lorsque vous travaillez sur l’étape « La boucle » de la Partie 1, 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. Gardez 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.

pip install deepagents langchain-anthropic
from deepagents import create_deep_agent

def get_weather(city: str) -> str:
    """Get the weather for a given city."""
    return f"It's always sunny in {city}!"
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[get_weather],
    system_prompt="You are a helpful assistant.",
)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)

Partie 2 : Les outils — donner des moyens à l’agent

La phase des outils de la Partie 2 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. Documentez ensemble le parcours réussi 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’une mise en forme ultérieure. Exposez les outils avec des schémas restreints et des étiquettes explicites indiquant leurs effets secondaires. Les hôtes doivent savoir quels appels modifient l’état avant d’approuver automatiquement.

Pourquoi ne pas simplement laisser le modèle exécuter n’importe quelle commande ?

Le principe fonctionne le mieux lorsque l’ensemble du processus est considéré comme une surface mesurable. Capturez un exemple réussi, un cas d’échec et la note de réversion avant d’élargir le périmètre du projet. 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é. Fixez des limites de tokens par tour et par session. Les outils agents élargissent rapidement le contexte ; des plafonds stricts empêchent que les démonstrations ne se transforment en factures inattendues.

Le développement avec des Deep Agents

La phase « The Building it with Deep » 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. Traitez cette phase comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définez des vérifications de succès et refusez toute mise en œuvre partielle silencieuse. Maintenez l’état du graphe plat et typé. Les blocs imbriqués cachent le fait que tel nœud a modifié tel champ et perturbent la reprise après interruption. La phase « The Building it with Deep » 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. Gardez 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.

import subprocess
from langchain_core.tools import tool

MAX_OUTPUT_CHARS = 20_000  # roughly 5k tokens
@tool
def run_tests(path: str = ".") -> str:
    """Run the project's pytest suite and return its output.
    Output is truncated to the last 20k characters (failures appear at the
    end). The run is killed after 5 minutes.
    """
    try:
        result = subprocess.run(["pytest", path], capture_output=True,
                                text=True, check=False, timeout=300)
    except subprocess.TimeoutExpired:
        return "pytest timed out after 300s"
    output = result.stdout + result.stderr
    if len(output) > MAX_OUTPUT_CHARS:
        return ("[... output truncated to the last 20,000 characters ...]\n"
                + output[-MAX_OUTPUT_CHARS:])
    return output
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[run_tests],            # merged in alongside the built-ins
    system_prompt="You are a coding assistant. Always run tests after editing.",
)

Partie 3 : Planification — réfléchir avant d’agir

Pour l’étape de réflexion de planification de la Partie 3, définissez les entrées, le responsable de l’étape et 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é. Documentez ensemble le parcours idéal 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. Faites approuver par un humain les cas où de l’argent est dépensé ou où des données de production sont modifiées. La configuration en temps de compilation ne garantit pas l’exhaustivité du fonctionnement commercial.

Partie 4 : Gestion du contexte — dépasser la limite de mémoire

Pour l’étape de gestion du contexte de la Partie 4, 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 à des 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.

Le développement avec des agents avancés

Pour l’étape « Building it with Deep », 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é. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Nommez les artefacts, définissez des vérifications de succès et refusez toute mise à jour partielle silencieuse. Faites approuver par des humains les actions qui entraînent des dépenses ou modifient des données de production. La connexion en temps de compilation ne garantit pas l’exhaustivité du processus métier. Pour l’étape « Building it with Deep », 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é. 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.

Partie 5 : Sous-agents – diviser pour conquérir

Lorsque vous travaillez sur l’étape de division en sous-agents de la Partie 5, 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 maintenir l’honnêteté 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. 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.

code_searcher = {
    "name": "code-searcher",
    "description": "Searches the codebase to find where specific logic lives. "
                   "Use this for any open-ended 'where is X?' question.",
    # ⚠️ NOTE: the key is `system_prompt`, NOT `prompt` (see correction below).
    "system_prompt": "You are an expert at navigating codebases. Use the grep "
                     "and glob tools to locate relevant files, then report a "
                     "concise summary of what you found and where. Do not make "
                     "any edits.",
}

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[run_tests],
    system_prompt="You are a coding assistant.",
    subagents=[code_searcher],
)

Partie 6 : Sécurité et intervention humaine – les freins

Lorsque vous travaillez sur l’étape de sécurité de la Partie 6, 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 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’erreur 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.

Le développement avec Deep Agents

Lors du travail dans l’étape « Construire avec Deep », 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. Considérez cette étape comme un contrat entre les entrées et les sorties validées. Donnez des noms aux artefacts, définez des vérifications de succès et refusez les terminations partielles silencieuses. 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 du LLM lorsque l’opérateur réessaie un nœud ultérieur. Lors du travail dans l’étape « Construire avec Deep », 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. Gardez la configuration en dehors du code de l’application. Les fichiers d’environnement, les stocks de secrets et les flags fonctionnels doivent être regroupés en un seul endroit que les opérateurs peuvent auditer sans avoir à lire l’ensemble du graphe.

from deepagents import create_deep_agent
# Import path for backends can vary by version - check the current
# "Backends" page in the Deep Agents docs.
from deepagents.backends import LocalShellBackend

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    system_prompt="You are a coding assistant working inside this project.",
    backend=LocalShellBackend(),   # enables the `execute` shell tool
)
from langgraph.types import Command

result = agent.invoke({"messages": [...]}, config)
result["__interrupt__"]   # the pending action + allowed decisions — show your user

# You decide; the loop picks up exactly where it paused:
agent.invoke(Command(resume={"decisions": [{"type": "approve"}]}), config)
# ... or {"type": "reject"} — the tool is never run, and the model is told so.

Partie 7 : Mémoire et persistance — mémoriser entre sessions

La partie 7 consacrée à la mémoire 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 rollback 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 la gestion des messages non livrés font partie intégrante du produit, et non d’une mise en forme ultérieure. Maintenez l’état des graphes 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.

Le construire avec des Deep Agents

Le modèle Deep stage fonctionne le mieux lorsqu’il est considéré comme une surface mesurable. Capturez un exemple réussi, un cas d’échec 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, l’erreur doit indiquer une seule responsabilité plutôt qu’un processus embrouillé. Maintenez 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.

from deepagents import create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[run_tests],
    system_prompt="You are a coding assistant.",
    checkpointer=InMemorySaver(),   # remembers state within a session
)
# A "thread_id" ties messages together into one ongoing conversation.
config = {"configurable": {"thread_id": "project-alpha"}}
agent.invoke(
    {"messages": [{"role": "user", "content": "Start refactoring the auth module."}]},
    config=config,
)
# Later, same thread_id - the agent remembers the earlier turn:
agent.invoke(
    {"messages": [{"role": "user", "content": "Now update the tests too."}]},
    config=config,
)

Assemblage final

La phase de mise en œuvre globale fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemplaire idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Considérez cette phase comme un contrat entre les entrées et les sorties validées. Nommez les artefacts, définites des vérifications de succès et refusez toute mise en œuvre partielle silencieuse. Maintenez l’état du graphe plat et typé. Les blocs imbriqués masquent le fait que tel nœud a modifié tel champ et perturbent la reprise après interruption. La phase de mise en œuvre globale fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemplaire idéal, un cas d’échec et la note de réversion avant d’élargir le périmètre. Gardez 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.

from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
from langchain_core.tools import tool
from langgraph.checkpoint.memory import InMemorySaver

# --- A custom tool (Part 2) — token-budgeted, see Part 2 for the full body ---
@tool
def run_tests(path: str = ".") -> str:
    """Run the project's pytest suite and return its (truncated) output."""
    import subprocess
    try:
        result = subprocess.run(["pytest", path], capture_output=True,
                                text=True, check=False, timeout=300)
    except subprocess.TimeoutExpired:
        return "pytest timed out after 300s"
    output = result.stdout + result.stderr
    return output if len(output) <= 20_000 else "[... truncated ...]\n" + output[-20_000:]

# --- A specialized subagent (Part 5) — note the `system_prompt` key ---
code_searcher = {
    "name": "code-searcher",
    "description": "Finds where specific logic lives in the codebase. "
                   "Use for open-ended 'where is X?' questions.",
    "system_prompt": "You navigate codebases using grep and glob, then report a "
                     "concise summary of what you found. You never make edits.",
}

# --- A system prompt that teaches good behavior (Parts 2 & 3) ---
SYSTEM_PROMPT = """You are a careful coding assistant.
Workflow:
1. Plan the task as a to-do list before doing anything.
2. Use your built-in read, grep, and glob tools to explore - never the raw shell
   equivalents like cat or grep.
3. Make focused edits.
4. ALWAYS run the tests after editing, and fix anything that breaks.
5. Delegate broad codebase searches to the code-searcher subagent.
"""

# --- Assemble the agent (Parts 1, 4, 6, 7 handled by the harness) ---
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",                  # Part 1: the loop, model-agnostic
    tools=[run_tests],                                     # Part 2: custom hands
    system_prompt=SYSTEM_PROMPT,                           # Parts 2 & 3: behavior + planning
    subagents=[code_searcher],                             # Part 5: delegation
    backend=LocalShellBackend(root_dir=".", virtual_mode=False),  # Part 6: shell access
    interrupt_on={"execute": True,                         # Part 6: the brakes —
                  "write_file": True, "edit_file": True},  #   approval before anything destructive
    checkpointer=InMemorySaver(),                          # Part 7: memory across turns
)
# Part 4 (context management) and built-in planning come on automatically.

config = {"configurable": {"thread_id": "my-project"}}
result = agent.invoke(
    {"messages": [{"role": "user", "content": "The login tests are failing. Fix them."}]},
    config=config,
)
print(result["messages"][-1].content)

La partie honnête : ce qui est facile et ce qui est difficile

Pour être honnête, il faut définir les entrées, le responsable de chaque é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 avoir à 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 actions qui entraînent des dépenses ou modifient des données de production. Une configuration en temps de compilation ne garantit pas la complétude du fonctionnement commercial.

Conclusion

Pour l’étape de clôture, 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.

Liste de contrôle opérationnelle

L’étape de la liste de contrôle opérationnelle fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un enregistrement type 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 les factures inattendues lorsque le processus passe de l’environnement de démonstration à des environnements partagés.

Gardez l’état du graphe plat et typé. Les blocs imbriqués cachent le fait que tel nœud a écrit telle champ et empêchent la reprise après interruption.

Ajoutez un test de base qui met à l’épreuve le chemin critique dans les processus d’intégration continue en utilisant des fixtures, et non des API payantes en temps réel, chaque fois que le budget le permet.

Gardez la configuration en dehors du code de l’application. Les fichiers d’environnement, les stockages de secrets et les indicateurs fonctionnels doivent être regroupés en un seul endroit que les administrateurs peuvent auditer sans devoir lire l’ensemble du graphe.

Gardez l’état du graphe plat et typé. Les blocs imbriqués cachent le fait que tel nœud a écrit telle champ et empêchent la reprise après interruption.

Au préalable de promouvoir la pile technique, figez les versions, conservez une transcription exemplaire du chemin critique et vérifiez les étapes de rollback. Les environnements partagés nécessitent des limites de débit, des contrôles d’attribution et un responsable clair pour la rotation des secrets. Préférez une fiabilité solide à de brillantes démonstrations ponctuelles.

Note de lot pour 9ef98d98a69a : ne pas inclure les clés du fournisseur dans le répertoire, fixer une limite pour les tokens par session, et stocker les transcriptions à côté des fichiers de test afin que les remplacements ultérieurs de modèles restent comparables.

Pour la note de renforcement au stade 0, définir 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érer des unités petites et testables plutôt que des scripts complexes. Lorsqu’une étape échoue, l’échec doit indiquer une seule responsabilité plutôt qu’un processus embrouillé.

Détail de renforcement 0/891 : mesurer le temps d’exécution, la catégorie de l’erreur et la consommation de tokens pour cette note, puis décider de conserver ou non le changement en se basant sur un ensemble de questions prédéfini plutôt que sur des observations subjectives.

Lors de la première étape des notes de renforcement, notez d’abord les éléments essentiels : 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. Enregistrez les temps d’exécution ainsi que le coût des jetons 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 l’environnement de démonstration à des environnements partagés.

Détail de renforcement 1/891 : mesurez le temps d’exécution, la catégorie de l’erreur et la consommation de jetons pour cette note, puis décidez si vous souhaitez conserver la modification en vous basant sur un ensemble de questions prédéfinies plutôt que sur des observations subjectives.

La deuxième étape des notes de renforcement fonctionne le mieux lorsqu’elle est considérée comme une surface mesurable. Capturez un exemple idéal de fonctionnement, 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 de répétition, 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.

Détail de renforcement 2/891 : mesurer le temps d’exécution du mur, la classe d’erreur et l’utilisation des tokens pour cette note, puis décider de conserver ou non le changement en se basant sur un ensemble fixe de questions plutôt que sur des anecdotes.