LangChain is an open-source Python framework for composing applications powered by large language models. Rather than wrapping a single model call, it provides modular building blocks — prompts, models, output parsers, retrievers, tools, and memory — that you stitch together into chains or agents. The modern package layout splits responsibilities across langchain-core (the base abstractions such as Runnable, BaseMessage, BaseChatModel, BaseRetriever, and Document, with no third-party LLM dependencies), langchain as the orchestration layer, langchain-community for hundreds of community-maintained integrations, and dedicated partner packages such as langchain-openai, langchain-anthropic, langchain-chroma, and langchain-pinecone that host the stable, actively-maintained integrations. Installation follows the pattern of installing langchain, langchain-core, the relevant partner package, and optionally langchain-community, with API keys read automatically from environment variables via python-dotenv.
At the heart of the framework is the Runnable interface, the common contract that every component implements. A Runnable supports invoke for a single input returning a single output, an invoke for async execution, stream for an iterator of output chunks, astream, batch for processing a list of inputs, abatch, astream_log, and transform. This uniformity is what makes the LangChain Expression Language work: any two runnables can be joined with the pipe operator to form a RunnableSequence, where the output of one stage becomes the input of the next. A chain written as prompt piped to llm piped to parser is functionally identical to explicitly constructing a RunnableSequence with first, middle, and last runnables. Because LCEL chains are themselves runnables, they automatically inherit streaming, batching, and async execution without extra glue code, and tokens flow through the chain as the model produces them rather than only after the entire response has completed.
The base abstractions include BaseChatModel for chat-style models such as GPT-4o, Claude, and Gemini, and the legacy LLM class, which is now largely deprecated. Chat models accept a list of BaseMessage subclasses — SystemMessage, HumanMessage, AIMessage, ToolMessage, and FunctionMessage — and return an AIMessage. AIMessage carries a tool_calls attribute describing any tools the model wants to invoke, where each entry has an id, a name, parsed args, a type, and an optional artifact. The matching ToolMessage is what you append to the conversation to return tool results, identified by the tool_call_id from the originating AIMessage entry. Together, these abstractions form a uniform message protocol that any provider can implement, letting you swap models without rewriting application code.
Configuration flows through a chain via RunnableConfig, a TypedDict carrying callbacks, tags, metadata, run_name, configurable, and recursion_limit that propagates automatically to every nested step. For introspection, runnables expose methods such as get_input_schema, get_output_schema, get_graph (a drawable graph of the chain), and get_prompts (the list of prompt templates nested in the chain), all of which surface to debugging tools like LangSmith. The lc_namespace class attribute and a Pydantic model_config flag control how custom subclasses serialize and integrate with the rest of the framework.