Skip to main content
This guide outlines the major changes between LangChain v1 and previous versions.

Simplified package

The langchain package namespace has been significantly reduced in v1 to focus on essential building blocks for agents. The streamlined package makes it easier to discover and use the core functionality.

Namespace

langchain-classic

If you were using any of the following from the langchain package, you’ll need to install langchain-classic and update your imports:
  • Legacy chains (LLMChain, ConversationChain, etc.)
  • Retrievers (e.g. MultiQueryRetriever or anything from the previous langchain.retrievers module)
  • The indexing API
  • The hub module (for managing prompts programmatically)
  • Embeddings modules (e.g. CacheBackedEmbeddings and community embeddings)
  • langchain-community re-exports
  • Other deprecated functionality
Install with:

Migrate to create_agent

Prior to v1.0, we recommended using langgraph.prebuilt.create_react_agent to build agents. Now, we recommend you use langchain.agents.create_agent to build agents. The table below outlines what functionality has changed from create_react_agent to create_agent:

Import path

The import path for the agent prebuilt has changed from langgraph.prebuilt to langchain.agents. The name of the function has changed from create_react_agent to create_agent:
For more information, see Agents.

Prompts

Static prompt rename

The prompt parameter has been renamed to system_prompt:

SystemMessage to string

If using SystemMessage objects in the system prompt, extract the string content:

Dynamic prompts

Dynamic prompts are a core context engineering pattern—they adapt what you tell the model based on the current conversation state. To do this, use the @dynamic_prompt decorator:

Pre-model hook

Pre-model hooks are now implemented as middleware with the before_model method. This new pattern is more extensible—you can define multiple middlewares to run before the model is called, reusing common patterns across different agents. Common use cases include:
  • Summarizing conversation history
  • Trimming messages
  • Input guardrails, like PII redaction
v1 now has summarization middleware as a built in option:

Post-model hook

Post-model hooks are now implemented as middleware with the after_model method. This new pattern is more extensible—you can define multiple middlewares to run after the model is called, reusing common patterns across different agents. Common use cases include: v1 has a built in middleware for human in the loop approval for tool calls:

Custom state

Custom state extends the default agent state with additional fields. You can define custom state in two ways:
  1. Via state_schema on create_agent - Best for state used in tools
  2. Via middleware - Best for state managed by specific middleware hooks and tools attached to said middleware
Defining custom state via middleware is preferred over defining it via state_schema on create_agent because it allows you to keep state extensions conceptually scoped to the relevant middleware and tools.state_schema is still supported for backwards compatibility on create_agent.

Defining state via state_schema

Use the state_schema parameter when your custom state needs to be accessed by tools:

Defining state via middleware

Middleware can also define custom state by setting the state_schema attribute. This helps to keep state extensions conceptually scoped to the relevant middleware and tools.
See the middleware documentation for more details on defining custom state via middleware.

State type restrictions

create_agent only supports TypedDict for state schemas. Pydantic models and dataclasses are no longer supported.
Simply inherit from langchain.agents.AgentState instead of BaseModel or decorating with dataclass. If you need to perform validation, handle it in middleware hooks instead.

Model

Dynamic model selection allows you to choose different models based on runtime context (e.g., task complexity, cost constraints, or user preferences). create_react_agent released in v0.6 of langgraph-prebuilt supported dynamic model and tool selection via a callable passed to the model parameter. This functionality has been ported to the middleware interface in v1.

Dynamic model selection

Pre-bound models

To better support structured output, create_agent no longer accepts pre-bound models with tools or configuration:
Dynamic model functions can return pre-bound models if structured output is not used.

Tools

The tools argument to create_agent accepts a list of:
  • LangChain BaseTool instances (functions decorated with @tool)
  • Callable objects (functions) with proper type hints and a docstring
  • dict that represents a built-in provider tools
The argument will no longer accept ToolNode instances.

Handling tool errors

You can now configure the handling of tool errors with middleware implementing the wrap_tool_call method.

Structured output

Node changes

Structured output used to be generated in a separate node from the main agent. This is no longer the case. We generate structured output in the main loop, reducing cost and latency.

Tool and provider strategies

In v1, there are two new structured output strategies:
  • ToolStrategy uses artificial tool calling to generate structured output
  • ProviderStrategy uses provider-native structured output generation

Prompted output removed

Prompted output is no longer supported via the response_format argument. Compared to strategies like artificial tool calling and provider native structured output, prompted output has not proven to be particularly reliable.

Streaming node name rename

When streaming events from agents, the node name has changed from "agent" to "model" to better reflect the node’s purpose.

Runtime context

When you invoke an agent, it’s often the case that you want to pass two types of data:
  • Dynamic state that changes throughout the conversation (e.g., message history)
  • Static context that doesn’t change during the conversation (e.g., user metadata)
In v1, static context is supported by setting the context parameter to invoke and stream.
The old config["configurable"] pattern still works for backward compatibility, but using the new context parameter is recommended for new applications or applications migrating to v1.

Standard content

In v1, messages gain provider-agnostic standard content blocks. Access them via message.content_blocks for a consistent, typed view across providers. The existing message.content field remains unchanged for strings or provider-native structures.

What changed

  • New content_blocks property on messages for normalized content
  • Standardized block shapes, documented in Messages
  • Optional serialization of standard blocks into content via LC_OUTPUT_VERSION=v1 or output_version="v1"

Read standardized content

Create multimodal messages

Example block shapes

See the content blocks reference for more details.

Serialize standard content

Standard content blocks are not serialized into the content attribute by default. If you need to access standard content blocks in the content attribute (e.g., when sending messages to a client), you can opt-in to serializing them into content.

Simplified package

The langchain package namespace has been significantly reduced in v1 to focus on essential building blocks for agents. The streamlined package makes it easier to discover and use the core functionality.

Namespace

langchain-classic

If you were using any of the following from the langchain package, you’ll need to install langchain-classic and update your imports:
  • Legacy chains (LLMChain, ConversationChain, etc.)
  • Retrievers (e.g. MultiQueryRetriever or anything from the previous langchain.retrievers module)
  • The indexing API
  • The hub module (for managing prompts programmatically)
  • Embeddings modules (e.g. CacheBackedEmbeddings and community embeddings)
  • langchain-community re-exports
  • Other deprecated functionality
Installation:

Breaking changes

Dropped Python 3.9 support

All LangChain packages now require Python 3.10 or higher. Python 3.9 reaches end of life in October 2025.

Updated return type for chat models

The return type signature for chat model invocation has been fixed from BaseMessage to AIMessage. Custom chat models implementing bind_tools should update their return signature:

Default message format for OpenAI responses API

When interacting with the Responses API, langchain-openai now defaults to storing response items in message content. To restore previous behavior, set the LC_OUTPUT_VERSION environment variable to v0, or specify output_version="v0" when instantiating ChatOpenAI.

Default max_tokens in langchain-anthropic

The max_tokens parameter in langchain-anthropic now defaults to higher values based on the model chosen, rather than the previous default of 1024. If you relied on the old default, explicitly set max_tokens=1024.

Legacy code moved to langchain-classic

Existing functionality outside the focus of standard interfaces and agents has been moved to the langchain-classic package. See the Simplified namespace section for details on what’s available in the core langchain package and what moved to langchain-classic.

Removal of deprecated APIs

Methods, functions, and other objects that were already deprecated and slated for removal in 1.0 have been deleted. Check the deprecation notices from previous versions for replacement APIs.

Text property

Use of the .text() method on message objects should drop the parentheses, as it is now a property:
Existing usage patterns (i.e., .text()) will continue to function but now emit a warning. The method form will be removed in v2.

example parameter removed from AIMessage

The example parameter has been removed from AIMessage objects. We recommend migrating to use additional_kwargs for passing extra metadata as needed.

Minor changes

  • AIMessageChunk objects now include a chunk_position attribute with position 'last' to indicate the final chunk in a stream. This allows for clearer handling of streamed messages. If the chunk is not the final one, chunk_position will be None.
  • LanguageModelOutputVar is now typed to AIMessage instead of BaseMessage.
  • The logic for merging message chunks (AIMessageChunk.add) has been updated with more sophisticated selection handling for the final id for the merged chunk. It prioritizes provider-assigned IDs over LangChain-generated IDs.
  • We now open files with utf-8 encoding by default.
  • Standard tests now use multimodal content blocks.

Archived docs

Old docs are archived for reference: