Open-Source Wikis

/

LangChain

/

LangChain

/

Architecture

langchain-ai/langchain

Architecture

LangChain is organized as four layers stacked on top of each other. Every layer has a strict dependency direction: lower layers do not import from higher ones.

graph TD
    subgraph User["User code"]
        APP["Application / agent"]
    end
    subgraph V1["langchain (libs/langchain_v1/)"]
        AGENT["create_agent"]
        ICM["init_chat_model"]
        MW["Middleware"]
    end
    subgraph CORE["langchain-core (libs/core/)"]
        RUN["Runnable / LCEL"]
        MSG["Messages + ContentBlocks"]
        LM["BaseChatModel / BaseLLM"]
        TOOL["BaseTool"]
        OUT["OutputParsers"]
        CB["Callbacks / Tracers"]
    end
    subgraph PARTNERS["Partners (libs/partners/*)"]
        OAI["langchain-openai"]
        ANT["langchain-anthropic"]
        OLLAMA["langchain-ollama"]
        OTHER["..."]
    end
    subgraph EXT["External"]
        LG["langgraph"]
        LS["langsmith"]
    end

    APP --> AGENT
    APP --> ICM
    AGENT --> MW
    AGENT --> LG
    AGENT --> LM
    ICM --> PARTNERS
    PARTNERS --> LM
    LM --> RUN
    TOOL --> RUN
    OUT --> RUN
    MSG --> RUN
    CB --> LS

The four layers

1. Core (langchain-core)

langchain-core defines the protocols and base classes everything else implements. It is intentionally thin — its only runtime dependencies are langsmith, tenacity, jsonpatch, PyYAML, typing-extensions, packaging, pydantic, uuid-utils, and langchain-protocol (see libs/core/pyproject.toml).

Key subsystems live in libs/core/langchain_core/:

  • runnables/ — the Runnable interface and LCEL composition operators (|, RunnableParallel, RunnableBranch, …). The base class is in libs/core/langchain_core/runnables/base.py.
  • language_models/BaseLanguageModel, BaseChatModel, BaseLLM, plus BaseChatModelV1 (the streaming-first protocol used by modern partners). See libs/core/langchain_core/language_models/chat_models.py and chat_model_stream.py.
  • messages/HumanMessage, AIMessage, ToolMessage, SystemMessage, plus the v1 ContentBlock taxonomy (TextContentBlock, ImageContentBlock, ReasoningContentBlock, …). See libs/core/langchain_core/messages/content.py.
  • tools/BaseTool, StructuredTool, the @tool decorator, JSON-Schema conversion. See libs/core/langchain_core/tools/base.py.
  • prompts/PromptTemplate, ChatPromptTemplate, few-shot variants. See libs/core/langchain_core/prompts/.
  • output_parsers/ — string, JSON, Pydantic, OpenAI-tools, XML parsers.
  • callbacks/, tracers/ — the observability backbone that emits LangSmith run trees.
  • vectorstores/, retrievers.py, documents/, indexing/ — RAG primitives.
  • _security/ — sandboxed transports and policy hooks.

2. langchain (libs/langchain_v1/)

The actively maintained langchain package (version 1.x, source root libs/langchain_v1/langchain/) is intentionally small. It holds:

  • agents/factory.pycreate_agent, the high-level entry point. It compiles a langgraph.StateGraph from a model, a tool list, and an ordered set of middleware.
  • agents/middleware/ — built-in middleware: human-in-the-loop, summarization, PII redaction, tool-call limits, model fallbacks, todo tracking, shell tool, and more.
  • agents/structured_output.pyToolStrategy, ProviderStrategy, AutoStrategy for shaping a model's response into a typed schema.
  • chat_models/base.pyinit_chat_model, the provider-agnostic factory.
  • Thin re-exports for messages/, tools/, embeddings/, rate_limiters/.

This package depends on langchain-core and langgraph. It does not import any partner package directly; partner imports happen lazily inside init_chat_model.

3. Partners (libs/partners/*)

Each partner package implements BaseChatModel/BaseLLM/Embeddings for a specific provider. The mono-repo currently hosts openai, anthropic, chroma, deepseek, exa, fireworks, groq, huggingface, mistralai, nomic, ollama, openrouter, perplexity, qdrant, and xai. Other providers (Google, AWS, Cohere, NVIDIA, IBM, …) are maintained in sibling repositories and discovered at runtime via init_chat_model's _BUILTIN_PROVIDERS registry in libs/langchain_v1/langchain/chat_models/base.py.

Partner packages share a common shape: a chat_models.py, optional llms.py and embeddings.py, a data/ directory of model profiles, and standardized tests that subclass langchain_tests from libs/standard-tests/.

4. langchain-classic (libs/langchain/)

langchain-classic is the legacy implementation layer. It still ships under the package name langchain-classic and contains chains (chains/), the older agent framework (agents/), retrievers (retrievers/), evaluation harnesses (evaluation/), graph-QA tooling (graphs/), Memory classes, and re-exports from langchain-community. It is in maintenance only — no new features are added — but its surface area is large (~1,300 source files) because many production deployments still rely on it.

Cross-cutting components

Text splitters (libs/text-splitters/)

langchain-text-splitters is a small standalone package (~14 modules) that handles document chunking. It is split out so RAG users can install it without pulling in the full langchain dependency chain. See libs/text-splitters/langchain_text_splitters/__init__.py for the exported splitters (CharacterTextSplitter, RecursiveCharacterTextSplitter, MarkdownHeaderTextSplitter, HTMLHeaderTextSplitter, RecursiveJsonSplitter, …).

Standard tests (libs/standard-tests/)

langchain-tests exposes reusable test base classes (ChatModelUnitTests, ChatModelIntegrationTests, ToolsUnitTests, …) that every partner package inherits. This is how the project enforces behavioral consistency across 15+ providers.

Model profiles (libs/model-profiles/)

langchain-model-profiles is a tiny package that ships the langchain-profiles CLI in libs/model-profiles/langchain_model_profiles/cli.py. The CLI pulls capability data (context window, multimodal support, tool-calling support, pricing) from models.dev and writes it into each partner's data/ directory. Partner runtime code reads this data through BaseChatModel.profile.

Request flow inside an agent

sequenceDiagram
    participant User
    participant Agent as create_agent (StateGraph)
    participant MW as Middleware chain
    participant Model as BaseChatModel
    participant Tools as ToolNode

    User->>Agent: invoke({messages: [...]})
    Agent->>MW: before_model
    MW->>Model: ainvoke(messages, tools)
    Model-->>MW: AIMessage (maybe tool_calls)
    MW-->>Agent: after_model
    alt tool_calls present
        Agent->>Tools: execute calls
        Tools-->>Agent: ToolMessage(s)
        Agent->>MW: before_model (next iteration)
    else no tool_calls
        Agent-->>User: final state
    end

The middleware layer can intercept anywhere along this loop using before_agent, before_model, wrap_model_call, wrap_tool_call, after_model, and after_agent. Built-in middleware in libs/langchain_v1/langchain/agents/middleware/ use these hooks to implement summarization, retries, fallbacks, PII redaction, and human approval.

CI/CD topology

The monorepo uses reusable GitHub Actions workflows defined in .github/workflows/:

  • _test.yml, _lint.yml, _compile_integration_test.yml, _test_pydantic.yml, _test_vcr.yml — composable per-package jobs
  • check_diffs.yml — picks which packages to run based on changed paths
  • _release.yml — manual release with working-directory and release-version inputs
  • _refresh_model_profiles.yml, refresh_model_profiles.yml — scheduled refreshes via the langchain-profiles CLI
  • pr_labeler.yml, pr_lint.yml, auto-label-by-package.yml — PR housekeeping

Each package can be released independently; _release.yml builds and publishes whichever package is selected.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – LangChain wiki | Factory