Skip to main content
이 가이드는 LangChain v1과 이전 버전 간의 주요 변경 사항을 설명합니다.

간소화된 패키지

langchain 패키지의 네임스페이스는 v1에서 에이전트를 위한 필수 빌딩 블록에 집중하도록 대폭 축소되었습니다. 간소화된 패키지를 통해 핵심 기능을 더욱 쉽게 발견하고 사용할 수 있습니다.

네임스페이스

모듈사용 가능한 항목설명
langchain.agentscreate_agent, AgentState핵심 에이전트 생성 기능
langchain.messagesMessage 타입, content blocks, trim_messageslangchain-core에서 재내보내기
langchain.tools@tool, BaseTool, injection 헬퍼langchain-core에서 재내보내기
langchain.chat_modelsinit_chat_model, BaseChatModel통합된 모델 초기화
langchain.embeddingsinit_embeddings, Embeddings임베딩 모델

langchain-classic

langchain 패키지에서 다음 항목 중 하나라도 사용하고 있었다면, langchain-classic을 설치하고 import를 업데이트해야 합니다:
  • 레거시 체인(LLMChain, ConversationChain 등)
  • Retriever(예: MultiQueryRetriever 또는 이전 langchain.retrievers 모듈의 모든 항목)
  • Indexing API
  • Hub 모듈(프롬프트를 프로그래밍 방식으로 관리)
  • Embeddings 모듈(예: CacheBackedEmbeddings 및 커뮤니티 임베딩)
  • langchain-community 재내보내기
  • 기타 더 이상 사용되지 않는 기능
# Chains
from langchain_classic.chains import LLMChain

# Retrievers
from langchain_classic.retrievers import ...

# Indexing
from langchain_classic.indexes import ...

# Hub
from langchain_classic import hub
설치 방법:
pip install langchain-classic

create_agent로 마이그레이션

v1.0 이전에는 에이전트를 구축할 때 langgraph.prebuilt.create_react_agent를 사용하도록 권장했습니다. 이제는 에이전트를 구축할 때 langchain.agents.create_agent를 사용하도록 권장합니다. 아래 표는 create_react_agent에서 create_agent로 변경된 기능을 요약합니다:
섹션요약 - 변경 사항
Import 경로패키지가 langgraph.prebuilt에서 langchain.agents로 이동
프롬프트파라미터가 system_prompt로 변경, 동적 프롬프트는 미들웨어 사용
Pre-model hookbefore_model 메서드를 가진 미들웨어로 대체
Post-model hookafter_model 메서드를 가진 미들웨어로 대체
커스텀 stateTypedDict만 가능, state_schema 또는 미들웨어를 통해 정의
모델미들웨어를 통한 동적 선택, 사전 바인딩된 모델은 지원되지 않음
도구도구 에러 처리가 wrap_tool_call이 있는 미들웨어로 이동
구조화된 출력프롬프트 출력 제거, ToolStrategy/ProviderStrategy 사용
스트리밍 노드 이름노드 이름이 "agent"에서 "model"로 변경
런타임 컨텍스트config["configurable"] 대신 context 인자를 통한 의존성 주입
네임스페이스에이전트 빌딩 블록에 집중하도록 간소화, 레거시 코드는 langchain-classic으로 이동

Import 경로

에이전트 사전 빌드의 import 경로가 langgraph.prebuilt에서 langchain.agents로 변경되었습니다. 함수 이름은 create_react_agent에서 create_agent로 변경되었습니다:
from langgraph.prebuilt import create_react_agent 
from langchain.agents import create_agent 
자세한 내용은 Agents를 참조하세요.

프롬프트

정적 프롬프트 이름 변경

prompt 파라미터가 system_prompt로 이름이 변경되었습니다:
from langchain.agents import create_agent


agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[check_weather],
    system_prompt="You are a helpful assistant"
)

SystemMessage를 문자열로

시스템 프롬프트에서 SystemMessage 객체를 사용하는 경우, 문자열 내용을 추출하세요:
from langchain.agents import create_agent


agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[check_weather],
    system_prompt="You are a helpful assistant"
)

동적 프롬프트

동적 프롬프트는 핵심 컨텍스트 엔지니어링 패턴입니다. 현재 대화 상태에 따라 모델에게 전달하는 내용을 조정합니다. 이를 위해 @dynamic_prompt 데코레이터를 사용하세요:
from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from langgraph.runtime import Runtime


@dataclass
class Context:  
    user_role: str = "user"

@dynamic_prompt
def dynamic_prompt(request: ModelRequest) -> str:  
    user_role = request.runtime.context.user_role
    base_prompt = "You are a helpful assistant."

    if user_role == "expert":
        prompt = (
            f"{base_prompt} Provide detailed technical responses."
        )
    elif user_role == "beginner":
        prompt = (
            f"{base_prompt} Explain concepts simply and avoid jargon."
        )
    else:
        prompt = base_prompt

    return prompt  

agent = create_agent(
    model="openai:gpt-4o",
    tools=tools,
    middleware=[dynamic_prompt],  
    context_schema=Context
)

# Use with context
agent.invoke(
    {"messages": [{"role": "user", "content": "Explain async programming"}]},
    context=Context(user_role="expert")
)

Pre-model hook

Pre-model hook은 이제 before_model 메서드를 가진 미들웨어로 구현됩니다. 이 새로운 패턴은 더욱 확장 가능합니다. 모델이 호출되기 전에 실행될 여러 미들웨어를 정의하고, 서로 다른 에이전트 간에 공통 패턴을 재사용할 수 있습니다. 일반적인 사용 사례는 다음과 같습니다:
  • 대화 기록 요약
  • 메시지 정리
  • PII 제거와 같은 입력 가드레일
v1에는 이제 요약 미들웨어가 내장 옵션으로 제공됩니다:
from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware


agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=tools,
    middleware=[
        SummarizationMiddleware(  
            model="anthropic:claude-sonnet-4-5",  
            max_tokens_before_summary=1000
        )  
    ]  
)

Post-model hook

Post-model hook은 이제 after_model 메서드를 가진 미들웨어로 구현됩니다. 이 새로운 패턴은 더욱 확장 가능합니다. 모델이 호출된 후 실행될 여러 미들웨어를 정의하고, 서로 다른 에이전트 간에 공통 패턴을 재사용할 수 있습니다. 일반적인 사용 사례는 다음과 같습니다: v1에는 도구 호출에 대한 human in the loop 승인을 위한 내장 미들웨어가 있습니다:
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware


agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[read_email, send_email],
    middleware=[HumanInTheLoopMiddleware(
        interrupt_on={
            "send_email": True,
            "description": "Please review this email before sending"
        },
    )]
)

커스텀 state

커스텀 state는 기본 에이전트 state를 추가 필드로 확장합니다. 커스텀 state는 두 가지 방법으로 정의할 수 있습니다:
  1. create_agentstate_schema를 통해 - 도구에서 사용되는 state에 가장 적합
  2. 미들웨어를 통해 - 특정 미들웨어 hook과 해당 미들웨어에 연결된 도구에서 관리되는 state에 가장 적합
미들웨어를 통한 커스텀 state 정의는 create_agentstate_schema를 통한 정의보다 선호됩니다. 관련 미들웨어와 도구에 개념적으로 범위를 지정하여 state 확장을 유지할 수 있기 때문입니다.state_schemacreate_agent에서 하위 호환성을 위해 여전히 지원됩니다.

state_schema를 통한 state 정의

커스텀 state가 도구에서 액세스되어야 하는 경우 state_schema 파라미터를 사용하세요:
from langchain.tools import tool, ToolRuntime
from langchain.agents import create_agent, AgentState  


# Define custom state extending AgentState
class CustomState(AgentState):
    user_name: str

@tool
def greet(
    runtime: ToolRuntime[CustomState]
) -> str:
    """Use this to greet the user by name."""
    user_name = runtime.state.get("user_name", "Unknown")  
    return f"Hello {user_name}!"

agent = create_agent(  
    model="anthropic:claude-sonnet-4-5",
    tools=[greet],
    state_schema=CustomState  
)

미들웨어를 통한 state 정의

미들웨어는 state_schema 속성을 설정하여 커스텀 state를 정의할 수도 있습니다. 이를 통해 관련 미들웨어와 도구에 개념적으로 범위가 지정된 state 확장을 유지할 수 있습니다.
from langchain.agents.middleware import AgentState, AgentMiddleware
from typing_extensions import NotRequired
from typing import Any

class CustomState(AgentState):
    model_call_count: NotRequired[int]

class CallCounterMiddleware(AgentMiddleware[CustomState]):
    state_schema = CustomState  

    def before_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
        count = state.get("model_call_count", 0)
        if count > 10:
            return {"jump_to": "end"}
        return None

    def after_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
        return {"model_call_count": state.get("model_call_count", 0) + 1}

agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[...],
    middleware=[CallCounterMiddleware()]  
)
미들웨어를 통한 커스텀 state 정의에 대한 자세한 내용은 middleware documentation을 참조하세요.

State 타입 제한

create_agent는 state 스키마에 대해 TypedDict만 지원합니다. Pydantic 모델과 dataclass는 더 이상 지원되지 않습니다.
from langchain.agents import AgentState, create_agent

# AgentState is a TypedDict
class CustomAgentState(AgentState):  
    user_id: str

agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=tools,
    state_schema=CustomAgentState  
)
BaseModel을 상속하거나 dataclass로 데코레이팅하는 대신 langchain.agents.AgentState를 상속하세요. 검증이 필요한 경우, 미들웨어 hook에서 처리하세요.

모델

동적 모델 선택을 통해 런타임 컨텍스트(예: 작업 복잡도, 비용 제약 또는 사용자 선호도)에 따라 서로 다른 모델을 선택할 수 있습니다. langgraph-prebuilt의 v0.6에서 출시된 create_react_agentmodel 파라미터에 전달되는 callable을 통해 동적 모델 및 도구 선택을 지원했습니다. 이 기능은 v1에서 미들웨어 인터페이스로 포팅되었습니다.

동적 모델 선택

from langchain.agents import create_agent
from langchain.agents.middleware import (
    AgentMiddleware, ModelRequest, ModelRequestHandler
)
from langchain.messages import AIMessage
from langchain_openai import ChatOpenAI


basic_model = ChatOpenAI(model="gpt-5-nano")
advanced_model = ChatOpenAI(model="gpt-5")

class DynamicModelMiddleware(AgentMiddleware):

    def wrap_model_call(self, request: ModelRequest, handler: ModelRequestHandler) -> AIMessage:
        if len(request.state.messages) > self.messages_threshold:
            model = advanced_model
        else:
            model = basic_model

        return handler(request.replace(model=model))

    def __init__(self, messages_threshold: int) -> None:
        self.messages_threshold = messages_threshold

agent = create_agent(
    model=basic_model,
    tools=tools,
    middleware=[DynamicModelMiddleware(messages_threshold=10)]
)

사전 바인딩된 모델

구조화된 출력을 더욱 잘 지원하기 위해 create_agent는 더 이상 도구나 구성이 사전 바인딩된 모델을 허용하지 않습니다:
# 더 이상 지원되지 않음
model_with_tools = ChatOpenAI().bind_tools([some_tool])
agent = create_agent(model_with_tools, tools=[])

# 대신 사용
agent = create_agent("openai:gpt-4o-mini", tools=[some_tool])
구조화된 출력이 사용되지 않는 경우, 동적 모델 함수는 사전 바인딩된 모델을 반환할 수 있습니다.

도구

create_agenttools 인자는 다음 목록을 허용합니다:
  • LangChain BaseTool 인스턴스(@tool로 데코레이팅된 함수)
  • 적절한 타입 힌트와 docstring이 있는 Callable 객체(함수)
  • 내장 프로바이더 도구를 나타내는 dict
이 인자는 더 이상 ToolNode 인스턴스를 허용하지 않습니다.
from langchain.agents import create_agent


agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[check_weather, search_web]
)

도구 에러 처리

이제 wrap_tool_call 메서드를 구현하는 미들웨어를 사용하여 도구 에러 처리를 구성할 수 있습니다.
# 예제가 곧 제공됩니다

구조화된 출력

노드 변경

구조화된 출력은 이전에는 메인 에이전트와 별도의 노드에서 생성되었습니다. 이제는 더 이상 그렇지 않습니다. 메인 루프에서 구조화된 출력을 생성하여 비용과 지연 시간을 줄입니다.

도구 및 프로바이더 전략

v1에는 두 가지 새로운 구조화된 출력 전략이 있습니다:
  • ToolStrategy는 인공 도구 호출을 사용하여 구조화된 출력을 생성합니다
  • ProviderStrategy는 프로바이더 네이티브 구조화된 출력 생성을 사용합니다
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy, ProviderStrategy
from pydantic import BaseModel


class OutputSchema(BaseModel):
    summary: str
    sentiment: str

# Using ToolStrategy
agent = create_agent(
    model="openai:gpt-4o-mini",
    tools=tools,
    # explicitly using tool strategy
    response_format=ToolStrategy(OutputSchema)  
)

프롬프트 출력 제거

프롬프트 출력은 더 이상 response_format 인자를 통해 지원되지 않습니다. 인공 도구 호출 및 프로바이더 네이티브 구조화된 출력과 같은 전략과 비교했을 때, 프롬프트 출력은 특별히 신뢰할 만한 것으로 입증되지 않았습니다.

스트리밍 노드 이름 변경

에이전트에서 이벤트를 스트리밍할 때, 노드 이름이 노드의 목적을 더 잘 반영하도록 "agent"에서 "model"로 변경되었습니다.

런타임 컨텍스트

에이전트를 호출할 때, 두 가지 유형의 데이터를 전달하고자 하는 경우가 많습니다:
  • 대화 전반에 걸쳐 변경되는 동적 state(예: 메시지 기록)
  • 대화 중에 변경되지 않는 정적 컨텍스트(예: 사용자 메타데이터)
v1에서는 invokestreamcontext 파라미터를 설정하여 정적 컨텍스트를 지원합니다.
from dataclasses import dataclass

from langchain.agents import create_agent


@dataclass
class Context:
    user_id: str
    session_id: str

agent = create_agent(
    model=model,
    tools=tools,
    context_schema=ContextSchema  
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "Hello"}]},
    context=Context(user_id="123", session_id="abc")  
)
이전의 config["configurable"] 패턴은 하위 호환성을 위해 여전히 작동하지만, 새 애플리케이션이나 v1으로 마이그레이션하는 애플리케이션에서는 새로운 context 파라미터를 사용하는 것이 권장됩니다.

표준 콘텐츠

v1에서는 메시지가 프로바이더에 구애받지 않는 표준 콘텐츠 블록을 얻습니다. @[message.content_blocks][content_blocks]를 통해 프로바이더 간에 일관되고 타입이 지정된 뷰로 액세스하세요. 기존의 message.content 필드는 문자열이나 프로바이더 네이티브 구조에 대해 변경되지 않습니다.

변경된 사항

  • 정규화된 콘텐츠를 위한 메시지의 새로운 content_blocks 속성
  • Messages에 문서화된 표준화된 블록 형태
  • LC_OUTPUT_VERSION=v1 또는 output_version="v1"을 통한 표준 블록의 content로의 선택적 직렬화

표준화된 콘텐츠 읽기

from langchain.chat_models import init_chat_model

model = init_chat_model("openai:gpt-5-nano")
response = model.invoke("Explain AI")

for block in response.content_blocks:
    if block["type"] == "reasoning":
        print(block.get("reasoning"))
    elif block["type"] == "text":
        print(block.get("text"))

멀티모달 메시지 생성

from langchain.messages import HumanMessage

message = HumanMessage(content_blocks=[
    {"type": "text", "text": "Describe this image."},
    {"type": "image", "url": "https://example.com/image.jpg"},
])
res = model.invoke([message])

예제 블록 형태

# 텍스트 블록
text_block = {
    "type": "text",
    "text": "Hello world",
}

# 이미지 블록
image_block = {
    "type": "image",
    "url": "https://example.com/image.png",
    "mime_type": "image/png",
}
자세한 내용은 content blocks reference를 참조하세요.

표준 콘텐츠 직렬화

표준 콘텐츠 블록은 기본적으로 content 속성으로 직렬화되지 않습니다. content 속성에서 표준 콘텐츠 블록에 액세스해야 하는 경우(예: 클라이언트에 메시지를 보낼 때), content로 직렬화하는 것을 선택할 수 있습니다.
export LC_OUTPUT_VERSION=v1
자세히 알아보기: Messages, Standard content blocks, Multimodal.

간소화된 패키지

langchain 패키지의 네임스페이스는 v1에서 에이전트를 위한 필수 빌딩 블록에 집중하도록 대폭 축소되었습니다. 간소화된 패키지를 통해 핵심 기능을 더욱 쉽게 발견하고 사용할 수 있습니다.

네임스페이스

모듈사용 가능한 항목설명
langchain.agentscreate_agent, AgentState핵심 에이전트 생성 기능
langchain.messagesMessage 타입, content blocks, trim_messageslangchain-core에서 재내보내기
langchain.tools@tool, BaseTool, injection 헬퍼langchain-core에서 재내보내기
langchain.chat_modelsinit_chat_model, BaseChatModel통합된 모델 초기화
langchain.embeddingsinit_embeddings, Embeddings임베딩 모델

langchain-classic

langchain 패키지에서 다음 항목 중 하나라도 사용하고 있었다면, langchain-classic을 설치하고 import를 업데이트해야 합니다:
  • 레거시 체인(LLMChain, ConversationChain 등)
  • Retriever(예: MultiQueryRetriever 또는 이전 langchain.retrievers 모듈의 모든 항목)
  • Indexing API
  • Hub 모듈(프롬프트를 프로그래밍 방식으로 관리)
  • Embeddings 모듈(예: CacheBackedEmbeddings 및 커뮤니티 임베딩)
  • langchain-community 재내보내기
  • 기타 더 이상 사용되지 않는 기능
# Chains
from langchain_classic.chains import LLMChain

# Retrievers
from langchain_classic.retrievers import ...

# Indexing
from langchain_classic.indexes import ...

# Hub
from langchain_classic import hub
설치:
uv pip install langchain-classic

중단(Breaking) 변경 사항

Python 3.9 지원 중단

모든 LangChain 패키지는 이제 Python 3.10 이상을 요구합니다. Python 3.9는 2025년 10월에 수명이 종료됩니다.

채팅 모델의 반환 타입 업데이트

채팅 모델 호출의 반환 타입 시그니처가 BaseMessage에서 AIMessage로 수정되었습니다. bind_tools를 구현하는 커스텀 채팅 모델은 반환 시그니처를 업데이트해야 합니다:
def bind_tools(
        ...
    ) -> Runnable[LanguageModelInput, AIMessage]:

OpenAI Responses API의 기본 메시지 형식

Responses API와 상호 작용할 때, langchain-openai는 이제 기본적으로 응답 항목을 메시지 content에 저장합니다. 이전 동작을 복원하려면 LC_OUTPUT_VERSION 환경 변수를 v0으로 설정하거나 ChatOpenAI를 인스턴스화할 때 output_version="v0"을 지정하세요.
# output_version 플래그로 이전 동작 강제
model = ChatOpenAI(model="gpt-4o-mini", output_version="v0")

langchain-anthropic의 기본 max_tokens

langchain-anthropicmax_tokens 파라미터는 이제 이전 기본값인 1024 대신 선택한 모델에 따라 더 높은 값으로 기본 설정됩니다. 이전 기본값을 사용하려면 명시적으로 max_tokens=1024를 설정하세요.

langchain-classic으로 이동된 레거시 코드

표준 인터페이스와 에이전트의 초점 범위를 벗어나는 기존 기능은 langchain-classic 패키지로 이동되었습니다. 핵심 langchain 패키지에서 사용 가능한 항목과 langchain-classic으로 이동된 항목에 대한 자세한 내용은 Simplified namespace 섹션을 참조하세요.

더 이상 사용되지 않는 API 제거

이미 더 이상 사용되지 않으며 1.0에서 제거될 예정이었던 메서드, 함수 및 기타 객체는 삭제되었습니다. 대체 API에 대해서는 이전 버전의 deprecation notices를 확인하세요.

.text()가 이제 속성임

메시지 객체의 .text() 메서드 사용 시 괄호를 제거해야 합니다:
# 속성 액세스
text = response.text

# 더 이상 사용되지 않는 메서드 호출
text = response.text()
기존 사용 패턴(즉, .text())은 계속 작동하지만 이제 경고를 출력합니다.
Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I