Multi-Agent Systems and Subagents

Purpose and Scope

This page explains the multi-agent patterns LangChain documentation calls out for building agent systems with a central coordinating agent and specialized worker agents. A multi-agent system is an application architecture in which more than one agent participates in a task. A subagent is a specialized agent invoked by another agent, usually through a tool interface, so the main agent can keep user-facing control while delegating domain-specific work. The central coordinator is often called a supervisor because it decides when to invoke workers, what input to pass, and how to combine their results.

The official subagents pattern is useful when one conversation must span distinct domains such as calendar, email, CRM, research, or database work. Instead of giving a single agent every tool and every instruction, the application gives each subagent a narrower tool set and prompt. The supervisor keeps the overall conversation state and routes work to the right specialist. This separation helps reduce prompt and tool confusion, makes debugging easier, and gives teams a cleaner place to iterate on one domain without destabilizing the entire assistant.

A key design point is context isolation. In the synchronous subagent pattern, subagents are stateless from call to call: they receive the task input chosen by the supervisor, run in a clean context window, and return a result to the supervisor rather than directly carrying on the user conversation. The supervisor remains responsible for memory, user interaction, and final synthesis. This is different from simply adding more tools to one agent because each specialist can have its own instructions and domain assumptions while still being controlled by a single user-facing loop.

Core Primitives

The central primitive is the supervisor agent. It is a full agent, not just a classifier. It maintains the conversation context across turns, decides whether to answer directly or delegate, and can call one or more subagents in a turn. A router is narrower: it is typically a single routing or classification step that dispatches work without maintaining an ongoing conversation state. Use a router when the application mostly needs one-time dispatch; use a supervisor when the system must coordinate several decisions, preserve context, and combine partial outputs over multiple turns.

Subagents are exposed to the supervisor as callable capabilities. The official docs describe them as being invoked via tools, which means the supervisor can reason about the name, description, and input schema of each specialist much like it reasons about any other tool. The difference is that the tool body can run another agent with its own prompt and tools. This keeps the public contract simple for the supervisor while allowing implementation details inside the specialist to remain independently testable and adjustable.

Human-in-the-loop review can still fit inside this architecture. Although subagents normally return results to the supervisor rather than conversing directly with users, the official docs describe using interrupts when a subagent needs clarification or approval. The important constraint is that the main agent remains the orchestrator. For example, a personal assistant can delegate drafting to an email subagent, pause for approval before sending, and then return control to the supervisor so it can continue the broader workflow.

Relevant Source Files

  • libs/langchain/langchain_classic/document_loaders/parsers/language/javascript.py — preserves the classic import name JavaScriptSegmenter and dynamically redirects it to the maintained langchain_community.document_loaders.parsers.language.javascript implementation.
  • libs/langchain/langchain_classic/document_loaders/parsers/language/code_segmenter.py — preserves the classic import name CodeSegmenter and dynamically redirects it to the maintained langchain_community.document_loaders.parsers.language.code_segmenter implementation.

Sources: libs/langchain/langchain_classic/document_loaders/parsers/language/javascript.py, libs/langchain/langchain_classic/document_loaders/parsers/language/code_segmenter.py

The repository files provided for this page are not the supervisor runtime itself; they are compatibility modules in langchain_classic. They are still relevant to multi-agent applications because practical agents often need prepared context before delegation. A supervisor that coordinates coding, documentation, or repository-analysis subagents may depend on language-aware document loading and segmentation. These modules show the public names available through the classic package boundary and the packaging pattern used to keep older imports working while implementation lives in community integration modules.

System-to-Code Mapping

Both requested files follow the same source-level pattern. They import create_importer from langchain_classic._api, define a DEPRECATED_LOOKUP dictionary, build _import_attribute, and expose a module-level __getattr__. When user code imports a deprecated symbol such as JavaScriptSegmenter or CodeSegmenter from the classic namespace, __getattr__ delegates lookup to the importer. The __all__ list declares the public symbol that this shim supports. This is a compact but important compatibility contract because agent applications may combine newer agent orchestration with older loader imports.

Public nameClassic moduleRedirect targetRole in agent systems
JavaScriptSegmenterlibs/langchain/langchain_classic/document_loaders/parsers/language/javascript.pylangchain_community.document_loaders.parsers.language.javascriptJavaScript-aware code segmentation for context preparation
CodeSegmenterlibs/langchain/langchain_classic/document_loaders/parsers/language/code_segmenter.pylangchain_community.document_loaders.parsers.language.code_segmenterBase code segmentation abstraction for loader/parser workflows

Sources: libs/langchain/langchain_classic/document_loaders/parsers/language/javascript.py, libs/langchain/langchain_classic/document_loaders/parsers/language/code_segmenter.py

In a multi-agent implementation, this mapping matters at the boundary between orchestration and knowledge preparation. The supervisor pattern answers the question “which specialist should act next?” while document loaders and segmenters help answer “what context should that specialist receive?” A code-review subagent, for example, should not receive an unbounded repository dump. It should receive focused segments selected by retrieval or preprocessing. The provided modules identify two classic import points that can participate in that preprocessing layer while preserving compatibility for applications that have not moved imports directly to langchain_community.

Execution Flow

A typical synchronous subagent flow begins with the user sending a request to the supervisor. The supervisor evaluates the request against its instructions and the available specialist tools. If the request is simple, it can answer directly. If the request crosses a specialized domain, it invokes the appropriate subagent tool with a focused instruction. The subagent runs with its own prompt and tool set, returns a result, and the supervisor decides whether to call another specialist, ask the user a follow-up question, or produce the final answer.

For a personal assistant, the supervisor might receive “Schedule lunch with Maya and send her a confirmation.” It can first call a calendar subagent to check availability and create the event. It can then call an email subagent to draft the confirmation. If outbound email requires review, the email subagent or supervisor can interrupt for approval before sending. This illustrates why supervisors are valuable: the calendar and email workers stay focused, while the supervisor manages ordering, dependencies, user approval, and final communication.

Async subagents extend the same mental model for long-running or parallelizable work. The official JavaScript deep agents docs describe async subagents as background tasks controlled through an Agent Protocol-compatible server. Instead of blocking until a specialist finishes, the supervisor receives a job identifier and can continue interacting with the user, check progress, send updates, or cancel. This model is better for research, coding, or analysis tasks where the user may want mid-flight steering rather than waiting for a single synchronous response.

Implementation Details and Constraints

When designing subagents, define each specialist around a domain boundary, not around an implementation preference. A calendar subagent should own scheduling concepts and calendar tools; an email subagent should own message drafting and delivery rules. The supervisor prompt should describe when to delegate and how to combine results, but it should not duplicate every specialist instruction. This keeps the supervisor’s context smaller and makes it easier to improve one worker’s behavior without retuning the whole system.

Prefer a single agent when the task has only a few tools or when tool choice is not causing ambiguity. Multi-agent systems introduce coordination overhead: the supervisor must choose specialists, serialize task input, interpret returned results, and handle errors. They are most justified when tools naturally form separate domains, when prompts need substantially different instructions, or when clean context windows improve model performance. If the supervisor is only dispatching once and never maintaining state, a router may be the simpler and more transparent design.

For code-heavy or retrieval-heavy subagents, treat context preparation as part of the architecture. The compatibility files on this page expose CodeSegmenter and JavaScriptSegmenter through dynamic deprecated-import lookups, indicating that classic applications can still refer to these symbols while implementations are resolved elsewhere. That pattern supports gradual migration: teams can modernize orchestration and specialist design without immediately rewriting every loader import. It also reinforces a broader LangChain convention: public interfaces should remain stable even as integrations move to maintained provider or community packages.

Testing Signals and Next Steps

Test a subagent system at three levels. First, test each specialist in isolation with representative inputs and edge cases. Second, test supervisor routing so the correct specialist is selected, the input is scoped, and unnecessary delegation is avoided. Third, test end-to-end conversations that require multiple specialists, approval interruptions, and error recovery. For async subagents, also test progress checks, cancellation, and follow-up updates because those behaviors shape the user experience as much as the final answer.

Next, read the pages on agent configuration, middleware, human-in-the-loop approvals, event streaming, and tools. Those topics complete the operational picture: instructions determine when delegation happens, middleware can enforce policies around model or tool calls, approvals make risky actions reviewable, streaming exposes progress to users, and tools are the mechanism through which synchronous subagents are commonly presented to the supervisor.