LangGraph: Revolutionizing Multi-Agent AI Debate
Le brief IA que les pros lisent chaque soir
Les 7 actus IA du jour, décryptées en 5 min. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
LangGraph: A New Era for AI Debate Systems
Why LangGraph? Stateful Graphs vs. Naive Loops
When building complex agent workflows, the biggest engineering challenge is not the LLM call itself, but the logic between the calls.
We needed a system capable of:
- Maintaining stateful context across dozens of debate turns
- Implementing conditional loops that reintegrate specific nodes in case of rejection
- Supporting attempts at the node level without restarting the entire workflow
Classic Python loops or simple LangChain chains do not handle this elegantly. A for loop over LLM calls does not allow for selectively relaunching a single node, inspecting intermediate state, or branching on structured output without building your own routing infrastructure from scratch.
LangGraph's directed graph model natively solves these three problems. It allows you to define an explicit typed state object, create conditional edges that read this state, and implement attempts at the node level with full visibility into what happened at each step. For a system where agents must iterate until satisfying a hostile internal critic, this is not just practical — it is architecturally necessary.
The Complete Debate Graph: How Each Turn is Orchestrated
At the heart of the project is the orchestration graph. Each turn of the debate follows a rigorous and deterministic path:
- The Pros agent generates an argument
- The argument goes through the internal refinement loop
- Only after approval is it recorded in shared memory
- The Cons agent reads the shared memory and generates a counter-argument
- The same internal loop applies before the Cons argument is published
- The cycle repeats for N configured turns
We rely on the graph visualization automatically generated by LangGraph to monitor this flow in real-time. Two conditional edges act as gatekeepers, reading the is_approved boolean from the structured output of the agent and deciding whether to move on to the next team or return for refinement.
The Refinement Loop: An Agent Designed to Reject Its Own Team
The most innovative component of this system is the internal loop Persona → Thinking → Critique. In most agent systems, critical agents are designed to be helpful — steering outputs toward better quality. In our experience, the critical agent is deliberately hostile.
Every argument generated by the Pros or Cons team must pass through three internal stages before reaching shared memory:
-
Persona Agent: Actively reshapes the adversarial identity of the team at each turn. It reads persona.json to assess the current persona, then decides whether to reuse the existing identity or design a new strategic persona based on the opponent's latest moves. This dynamic decision — to maintain or evolve — is precisely what makes the Persona agent the most sensitive node for drift detection. The persona it settles on becomes the identity anchor against which we measure all subsequent outputs.
-
Thinking Agent: Submits the argument to an internal stress test. It identifies logical gaps, weak chains of evidence, and rhetorical inconsistencies before the critical agent ever sees the output.
-
Critique Agent: Acts as a hostile internal auditor. Its sole function is to find grounds for rejection. If the argument is logically circular, emotionally inconsistent with the persona, or reasons from the same evidence as the previous turn, it issues a rejection with structured feedback — and the loop restarts at the Persona agent.
Arguments only go to shared_memory.json after surviving this audit. This imposes a high level of argument quality — but it also creates a fascinating failure mode that we actively monitor: the loop-lock, where the critical agent becomes so strict that no agent can produce an argument that passes. The loop-lock is, in itself, a measurable form of cognitive drift.
Memory Architecture: Isolation by Design
Memory management is considered a top architectural concern, not an afterthought. We have implemented a two-tier isolation system to preserve experimental integrity.
-
Shared Memory (shared_memory.json): The public transcript of the debate. Both teams can read this file — it contains only finalized and approved arguments. This represents the "official record" of what each agent has argued.
-
Team Private Memory: Each team maintains three private files invisible to the opposing agent:
- persona.json — the identity anchor and behavioral constraints for that team
- thinking.json — internal reasoning notebook (not included in the public argument)
- critique.json — rejection logs and feedback history from the critique agent
This isolation is architecturally critical. If the Cons team could read the Pros team's thinking.json, they would have access to reasoning that has not been explicitly published — which would constitute cheating. More importantly for measuring drift, cross-contamination of memory between teams would corrupt the persona coherence scores by introducing an external framework before the argument is finalized.
Structured Outputs: Making LLM Responses Graphically Routable
For LangGraph's conditional edges to function deterministically, the outputs from agents must be machine-readable — and not in free text requiring parsing. We enforce this by using Pydantic schemas on each node.
An agent does not simply return a string. It returns a typed object containing:
class CritiqueOutput(BaseModel):
is_approved: bool
critique_feedback: str
revised_argument: Optional[str] = None
The conditional edges in LangGraph read is_approved directly. If the LLM does not adhere to the schema — due to a malformed response, an unexpected rejection, or a truncated output — the graph cannot route the state, and a ValidationError is raised before erroneous data propagates downstream.
This unique design decision bridges the gap between the fuzzy and probabilistic nature of LLM outputs and the rigid routing requirements of production-quality agent software. Without this, a single malformed response in turn 30 of a 50-turn debate could corrupt the state of the entire experiment.
Retry Logic and Model-Independent Design
In a 50-turn debate, a single API delay in turn 45 could invalidate hours of accumulated simulation state. We have wrapped each LLM node with a Tenacity retry decorator implementing exponential backoff:
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(10), wait=wait_exponential(multiplier=2, min=4, max=60))
def node_retry(state: DebateState) -> DebateState:
...
This means that a google.genai.errors.ServerError triggers automatic retries at intervals of 4s, 8s, 16s, 32s, and 60s before the experiment raises a critical failure. In practice, this has allowed simulations to continue despite provider rate limits and intermittent delays that would otherwise require manual restarts.
The second resilience decision is a model-independent architecture. Since all LLM calls pass through LangChain's init_chat_model abstraction layer, changing providers requires modifying a single value in config.py. The complete configuration object looks like this:
# debate_agents/config/config.py — single source of truth
CONFIG = {
"version": "v6",
"model_name": "google_genai:[gemini](/dossier/google-ia)-3.1-flash-lite-preview",
"temperature": 1,
"max_tokens": 4096,
"max_retries": 10,
"thinking_budget": 2048
}
To perform a comparison with Claude or GPT-4o, you change model_name to "anthropic:claude-3-5-sonnet-20241022" or "openai:gpt-4o" — nothing else in the pipeline changes. This makes benchmarking between models operationally feasible without maintaining parallel codebases.
What We Would Do Differently: Honest Reflections
Building a system as complex as LangGraph has been a rewarding experience, but not without challenges. We have identified several areas where improvements could be made. For example, optimizing the refinement loop to avoid the loop-lock could be a priority. Additionally, enhancing the user interface for graph visualization could make the system more accessible to non-technical users. Finally, integrating new metrics to evaluate the performance of critical agents could provide interesting insights for further refining the system.
Brief IA — L'actualité IA en français
L'essentiel de l'actualité de l'intelligence artificielle, décrypté et expliqué chaque jour.