How LangGraph Integration Orchestrates Multi-Agent Classroom Interactions in OpenMAIC

OpenMAIC uses LangGraph's Director Graph to coordinate AI agents through a stateless, single-round StateGraph topology that streams real-time classroom dialogue via Server-Sent Events.

The THU-MAIC/OpenMAIC repository implements a sophisticated multi-agent classroom simulation using LangGraph (@langchain/langgraph) to manage conversational flow between AI participants. The system centers on a fixed-topology StateGraph called the Director Graph, which processes one turn per HTTP request to maintain stateless scalability while enabling complex multi-turn discussions through client-side orchestration.

The Director Graph Architecture

At the core of OpenMAIC's orchestration lies a deliberately constrained graph topology designed for reliability and horizontal scaling.

Fixed Graph Topology

The Director Graph follows a strict linear path: START → director → (agent_generate) → END. This single-round design ensures deterministic termination while supporting dynamic speaker selection. In lib/orchestration/director-graph.ts (lines 4-9), the graph is constructed using LangGraph's StateGraph API with a custom OrchestratorState annotation that tracks messages, turn counts, available agents, and the whiteboard ledger.

The director node evaluates the current context to determine which agent speaks next, while the agent-generate node executes the selected agent's LLM call. This separation of concerns allows the system to inject decision logic between conversation turns without persisting server-side state.

Stateless Design Philosophy

Unlike persistent multi-turn graphs, OpenMAIC's implementation in lib/orchestration/stateless-generate.ts (lines 406-413) treats each HTTP request as an independent graph invocation. The client serializes the entire conversation history—messages, agent configurations, and metadata—into the StatelessChatRequest payload. The server processes one director → agent cycle, returns the updated state and generated events, and immediately terminates the graph execution.

This architectural choice eliminates server-side session management, allowing requests to be handled by any available instance. The buildInitialState function (lines 31-48 in director-graph.ts) reconstructs the LangGraph state object from the incoming request payload, enabling seamless horizontal scaling.

The Director Node: Orchestrating Speaker Selection

The director node serves as the classroom moderator, implementing distinct logic paths for single-agent and multi-agent scenarios.

Single-Agent vs Multi-Agent Modes

In single-agent mode, the director operates as a pure code path without LLM calls. During turn 0, it automatically dispatches the sole configured agent; subsequent turns cue the user for input. This optimization avoids unnecessary latency when only one AI participant is present, as implemented in director-graph.ts (lines 15-34).

In multi-agent mode, the director employs more complex logic. On the first turn, it can dispatch a predefined trigger agent immediately. For subsequent turns, the director invokes an LLM to analyze the conversation context and select the next speaker, determine if the user should respond, or terminate the discussion. This decision flow appears in lines 59-78 of director-graph.ts, where the director constructs a specialized prompt describing available agents, their personas, and the conversation history.

LLM-Based Decision Flow

When multiple agents are available, the director calls the underlying language model through the AISdkLangGraphAdapter. The LLM returns a structured decision indicating which agentId should speak next or whether to yield to the user. This implementation leverages LangGraph's conditional edge support, where the director node's return value determines whether the flow proceeds to agent_generate or exits to END.

Agent Generation and Streaming

Once the director selects a speaker, the system transitions to the agent-generate node, which handles LLM interaction and real-time event streaming.

Event-Driven Streaming Architecture

The runAgentGeneration function (lines 31-68 in director-graph.ts) streams agent responses using LangGraph's custom stream mode via config.writer(). As the LLM generates content, the system emits a sequence of SSE-compatible events:

  • agent_start: Signals that an agent has begun generating
  • text_delta: Contains incremental text chunks as they are produced
  • action: Transmits structured tool calls or classroom actions
  • agent_end: Marks completion of the generation cycle

The streaming loop (lines 114-176 in director-graph.ts) parses the LLM's structured output while simultaneously yielding delta chunks, enabling the frontend to display real-time typing animations and immediate feedback.

AI-SDK Adapter Bridge

OpenMAIC bridges LangGraph's BaseChatModel interface with the Vercel AI SDK through the AISdkLangGraphAdapter class in lib/orchestration/ai-sdk-adapter.ts. This adapter (lines 43-52) unifies access to multiple providers including OpenAI, Anthropic, and Google.

The _generate method (lines 80-110) implements synchronous LLM calls via callLLM, while streamGenerate yields incremental chunks from streamLLM. This abstraction allows the Director Graph to remain provider-agnostic, switching between models by changing configuration rather than implementation code.

Implementation Workflow

Integrating LangGraph into the classroom simulation requires three coordinated steps: state preparation, graph compilation, and execution.

Building Initial State

Before invoking the graph, the system constructs the initial state using the buildInitialState utility:

import { buildInitialState } from '@/lib/orchestration/director-graph';
import { getModel } from '@/lib/ai/llm';

async function prepareState(request: StatelessChatRequest) {
  const lm = await getModel(request.config.provider);
  return buildInitialState(request, lm, request.config.thinking);
}

This function (lines 31-48 in director-graph.ts) assembles the OrchestratorState object, including message history, available agents from the configuration, user profile data, and whiteboard ledger entries.

Graph Compilation and Execution

The orchestration entry point compiles and invokes the graph for each request:

import { createOrchestrationGraph } from '@/lib/orchestration/director-graph';

export async function runOrchestration(request: StatelessChatRequest) {
  const state = await prepareState(request);
  const graph = createOrchestrationGraph();
  const result = await graph.invoke(state);
  return result;
}

The createOrchestrationGraph function (lines 84-96 in director-graph.ts) constructs the StateGraph with its fixed topology and returns a compiled graph instance. The invoke call executes one complete director → agent cycle, returning the updated state containing new messages and generated events (as shown in stateless-generate.ts lines 406-413).

Summary

  • LangGraph Director Graph: OpenMAIC uses a single-round StateGraph with fixed topology (START → director → agent_generate → END) to orchestrate classroom interactions.
  • Stateless Architecture: Each HTTP request carries the complete conversation context, enabling horizontal scaling and eliminating server-side session management.
  • Dual Operating Modes: The director node implements optimized pure-code paths for single-agent scenarios and LLM-driven decision-making for multi-agent discussions.
  • Real-Time Streaming: The system leverages LangGraph's config.writer() to emit SSE-compatible events including text_delta, action, and thinking updates.
  • Provider Abstraction: The AISdkLangGraphAdapter bridges LangGraph with the Vercel AI SDK, supporting unified access to OpenAI, Anthropic, and other providers.

Frequently Asked Questions

What is the Director Graph in OpenMAIC?

The Director Graph is a LangGraph StateGraph defined in lib/orchestration/director-graph.ts that coordinates multi-agent classroom simulations. It features a fixed linear topology with two primary nodes: the director, which selects the next speaker based on conversation context, and agent_generate, which executes the selected agent's LLM call and streams the response.

How does OpenMAIC handle multi-turn conversations with a single-round graph?

OpenMAIC maintains statelessness by having the client serialize the entire conversation history—including messages, turn counts, and agent configurations—into each HTTP request. The server processes exactly one graph cycle (director decision + agent generation) per request, returning the updated state to the client. The client then issues subsequent requests to continue the dialogue, effectively externalizing the turn management while keeping the server horizontally scalable.

What role does the AI-SDK Adapter play in the LangGraph integration?

The AISdkLangGraphAdapter (located in lib/orchestration/ai-sdk-adapter.ts) implements LangGraph's BaseChatModel interface using the Vercel AI SDK as the backend. It provides _generate for synchronous LLM calls and streamGenerate for incremental streaming, allowing the Director Graph to switch between AI providers (OpenAI, Anthropic, Google) without modifying the orchestration logic.

How are real-time classroom updates streamed to the client?

The system uses LangGraph's custom stream mode through config.writer() callbacks. During agent generation, the runAgentGeneration function emits structured events such as agent_start, text_delta, and agent_end via the writer. These events are captured in the graph invocation result and forwarded to the client as Server-Sent Events, enabling the frontend to display real-time typing indicators, agent actions, and whiteboard updates.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →