AI Sparkup

복잡한 AI 세상을 읽는 힘 ⚡

LangChain 1.0: Middleware로 에이전트 제어권을 되찾다

월간 9천만 다운로드를 기록하는 LangChain이 정식 1.0을 출시했습니다. 핵심은 Middleware 시스템입니다. 에이전트 루프의 모든 단계를 제어할 수 있는 훅(hook)을 제공해서, 프로덕션 환경에서 겪었던 커스터마이징 한계를 해결합니다. LangGraph 1.0도 함께 출시되어 견고한 상태 관리와 Human-in-the-loop을 일급 기능으로 지원합니다.

핵심 포인트:

  • 세 가지 Middleware 훅으로 전체 제어: before_model은 모델 호출 전 상태 업데이트와 라우팅, modify_model_request는 특정 요청의 도구/프롬프트/모델 변경, after_model은 응답 검증과 후처리를 담당. 여러 Middleware를 조합해 웹 서버처럼 순차 실행
  • 프로덕션 필수 기능이 내장 Middleware로: Human-in-the-loop는 도구 실행 전 승인 요청, Summarization은 4천 토큰 도달 시 자동 요약, Anthropic Prompt Caching은 캐시 태그 자동 추가. 직접 구현하지 않아도 즉시 사용 가능
  • LangGraph 1.0의 실전 검증: Uber는 대규모 코드 마이그레이션, LinkedIn은 AI 채용 자동화, Replit은 소프트웨어 빌드 코파일럿에 활용. 서버 재시작 시에도 워크플로우 중단 없이 재개되는 퍼시스턴스가 핵심

3년간 쌓인 불만의 해결

“추상화가 너무 무겁다”, “커스터마이징이 어렵다”. LangChain 팀이 가장 많이 들었던 피드백입니다.

에이전트 프레임워크의 딜레마는 명확합니다. 기본 루프(모델 → 도구 → 응답)는 시작하기 쉽지만, 복잡도가 올라가면 컨텍스트 엔지니어링을 위한 세밀한 제어가 필요합니다. 하지만 대부분의 프레임워크는 이를 허용하지 않습니다. 결국 개발자들은 프레임워크를 벗어나 처음부터 직접 구현하게 됩니다.

LangChain은 지난 2년간 이 문제를 해결하려 했습니다. 런타임 설정 지정, 커스텀 상태 스키마, 동적 프롬프트 함수, 메시지 리스트 제어 함수, pre/post 모델 훅, 동적 모델 전환 등을 순차적으로 추가했습니다. 하지만 파라미터가 너무 많아지고 의존성이 복잡해졌습니다. 여러 커스터마이징을 조합하기도 어려웠습니다.

Middleware는 이 모든 것을 통합합니다.

Middleware 아키텍처

Middleware 훅 포인트
에이전트 루프의 세 가지 Middleware 훅 (출처: LangChain)

Middleware는 웹 서버 미들웨어와 유사하게 작동합니다. 여러 Middleware를 제공하면 모델 호출로 가는 인바운드 여정에서 순차적으로 실행되고, 리턴 여정에서는 역순으로 실행됩니다.

세 가지 핵심 훅이 있습니다.

before_model: 라우팅과 전처리

모델 호출 전에 실행됩니다. 상태를 업데이트하거나 다른 노드로 점프할 수 있습니다. 가장 강력한 훅입니다.

from langchain.agents.middleware import AgentState, AgentMiddleware

class CustomRoutingMiddleware(AgentMiddleware):
    def before_model(self, state: AgentState) -> dict[str, Any] | None:
        # 메시지가 50개를 넘으면 요약
        if len(state["messages"]) > 50:
            return {"messages": self.summarize_messages(state["messages"])}

        # 종료 조건 체크
        if self.should_terminate(state):
            return {"jump_to": "__end__"}

        return None  # 정상 흐름 계속

jump_to"tools", "__end__"로 이동할 수 있습니다. 단, "model"로는 점프할 수 없습니다(실행 순서 보장을 위해).

modify_model_request: 요청별 파라미터 조정

모델 호출 직전에 실행되지만, 특정 요청에 대해서만 파라미터를 수정합니다. 영구 상태를 변경하거나 점프할 수 없습니다.

중요한 점: request.model은 문자열이 아닌 BaseChatModel 인스턴스여야 합니다.

from langchain.agents.middleware import ModelRequest, AgentMiddleware
from langchain_openai import ChatOpenAI
from pydantic import BaseModel

class Answer(BaseModel):
    answer: str
    confidence: float

class DynamicModelMiddleware(AgentMiddleware):
    def modify_model_request(self, request: ModelRequest, state: AgentState) -> ModelRequest:
        # 쿼리 복잡도에 따라 모델 동적 선택
        if self.is_complex_query(state):
            request.model = ChatOpenAI(model="gpt-4o")
        else:
            request.model = ChatOpenAI(model="gpt-4o-mini")

        # 컨텍스트에 맞는 프롬프트 생성
        request.system_prompt = self.generate_contextual_prompt(state)

        # 도구 접근 제한
        if self.should_restrict_tools(state):
            request.tools = [t for t in request.tools if self.is_tool_allowed(t, state)]

        # 구조화된 출력 (Pydantic 모델 사용)
        if self.needs_structured_output(state):
            request.response_format = Answer

        return request

after_model: 검증과 후처리

모델 호출 후 실행됩니다. 결과 검증, 상태 수정이 가능하고 jump_to도 사용할 수 있습니다.

class ValidationMiddleware(AgentMiddleware):
    def after_model(self, state: AgentState) -> dict[str, Any] | None:
        last_message = state["messages"][-1]

        # 민감 정보 검증 및 제거
        if self.contains_sensitive_info(last_message):
            cleaned = self.redact_sensitive(last_message)
            return {"messages": state["messages"][:-1] + [cleaned]}

        # 즉시 도구 실행이 필요하면 점프
        if self.requires_immediate_tools(last_message):
            return {"jump_to": "tools"}

        return None

내장 Middleware 3종

바로 사용할 수 있는 프로덕션급 Middleware가 포함되어 있습니다.

Human-in-the-Loop

도구 실행 전 사용자 승인을 요구합니다. 체크포인터(InMemorySaver 등)가 필수입니다.

from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.memory import InMemorySaver

hitl = HumanInTheLoopMiddleware(
    tool_configs={
        "delete_database": {"require_approval": True},
        "send_email": {"require_approval": True}
    }
)

agent = create_agent(
    model="openai:gpt-4o",
    tools=[...],
    middleware=[hitl],
    checkpointer=InMemorySaver()  # 필수
)

Summarization

메시지가 지정된 토큰 수를 넘으면 자동으로 요약합니다. 최근 메시지는 유지하면서 오래된 컨텍스트를 압축합니다.

from langchain.agents.middleware import SummarizationMiddleware

summarization = SummarizationMiddleware(
    model="openai:gpt-4o-mini",
    max_tokens_before_summary=4000,
    messages_to_keep=20
)

Anthropic Prompt Caching

프롬프트 캐싱 태그를 자동으로 추가해서 비용을 절감합니다.

from langchain_anthropic import ChatAnthropic
from langchain.agents.middleware.prompt_caching import AnthropicPromptCachingMiddleware

caching = AnthropicPromptCachingMiddleware(ttl="5m")

agent = create_agent(
    model=ChatAnthropic(model="claude-sonnet-4-latest"),
    middleware=[caching],
    checkpointer=InMemorySaver()
)

Middleware 조합하기

여러 Middleware를 조합하면 강력합니다. 레고 블록처럼 쌓으면 됩니다.

from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model=ChatOpenAI(model="gpt-4o"),
    tools=[...],
    middleware=[
        routing_middleware,      # 인바운드 1번째
        model_middleware,        # 인바운드 2번째
        validation_middleware,   # 인바운드 3번째
        SummarizationMiddleware(...),
        HumanInTheLoopMiddleware(...)
    ],
    checkpointer=InMemorySaver()
)

인바운드는 순서대로 실행되고, 아웃바운드는 역순으로 실행됩니다.

LangGraph 1.0: 프로덕션 에이전트의 토대

에이전트 실행 루프
LangChain의 create_agent는 LangGraph 런타임 위에서 작동 (출처: LangChain)

LangGraph는 LangChain보다 저수준입니다. 복잡한 워크플로우와 장기 실행 프로세스를 위한 프레임워크입니다.

핵심 기능은 세 가지입니다.

견고한 상태 관리: 에이전트 실행 상태를 자동으로 유지합니다. 서버가 재시작되어도 컨텍스트를 잃지 않고 정확히 중단된 지점에서 재개합니다.

내장 퍼시스턴스: 커스텀 데이터베이스 로직 없이 워크플로우를 저장하고 재개할 수 있습니다. 며칠에 걸친 승인 프로세스나 백그라운드 작업에 활용됩니다.

Human-in-the-loop 패턴: 일급 API 지원으로 에이전트를 일시 중지하고 사람의 검토, 수정, 승인을 받을 수 있습니다.

실제 사례가 있습니다. LinkedIn은 계층적 에이전트 시스템으로 AI 채용 자동화를 구현했습니다. 후보자 소싱, 매칭, 메시징을 자동화해서 채용 담당자가 고수준 전략에 집중할 수 있게 했습니다.

Uber는 LangGraph로 대규모 코드 마이그레이션을 간소화했습니다. 특화된 에이전트 네트워크를 구조화해서 단위 테스트 생성의 각 단계를 정밀하게 처리했습니다.

Replit의 AI 에이전트는 소프트웨어를 처음부터 빌드하는 코파일럿입니다. LangGraph 기반 멀티 에이전트 시스템으로 패키지 설치부터 파일 생성까지 모든 에이전트 액션을 사용자가 볼 수 있게 만들었습니다.

Elastic은 실시간 위협 탐지를 위한 AI 에이전트 네트워크를 LangGraph로 조율합니다. 보안 위험에 훨씬 빠르고 효과적으로 대응할 수 있게 되었습니다.

언제 무엇을 선택할까

LangChain과 LangGraph는 다른 목적을 가집니다. 좋은 소식은 LangChain 에이전트가 LangGraph 위에 구축된다는 점입니다. 락인되지 않습니다.

LangChain의 고수준 API로 시작해서 더 많은 제어가 필요할 때 LangGraph로 내려갈 수 있습니다. 그래프는 조합 가능하므로 create_agent로 만든 에이전트를 커스텀 LangGraph 워크플로우 안에서 사용할 수 있습니다.

LangChain 1.0 선택 기준

  • 표준 에이전트 패턴으로 빠르게 출시하고 싶을 때
  • 기본 루프(모델 → 도구 → 응답)에 맞는 에이전트
  • Middleware 기반 커스터마이징으로 충분할 때
  • 저수준 제어보다 고수준 추상화를 선호할 때

LangGraph 1.0 선택 기준

  • 결정론적 컴포넌트와 에이전틱 컴포넌트가 혼합된 워크플로우
  • 장기 실행 비즈니스 프로세스 자동화
  • 더 많은 감독과 Human-in-the-loop가 필요한 민감한 워크플로우
  • 고도로 커스텀하거나 복잡한 워크플로우
  • 레이턴시나 비용을 신중하게 제어해야 하는 애플리케이션

개발자를 위한 실용 팁

1. Middleware 설계 원칙

각 Middleware는 하나의 책임만 가져야 합니다. modify_model_request에서는 가능하면 상태 없는 작업을 수행하세요. 에러 핸들링을 견고하게 구현해서 연쇄 실패를 방지하세요.

2. 성능 최적화

비싼 작업은 미리 계산하고 캐싱하세요.

class OptimizedMiddleware(AgentMiddleware):
    def __init__(self):
        self.compiled_patterns = self.compile_patterns()
        self.cached_prompts = {}

    def modify_model_request(self, request: ModelRequest, state: AgentState) -> ModelRequest:
        cache_key = self.generate_cache_key(state)
        if cache_key in self.cached_prompts:
            request.system_prompt = self.cached_prompts[cache_key]
        else:
            prompt = self.generate_prompt(state)
            self.cached_prompts[cache_key] = prompt
            request.system_prompt = prompt
        return request

3. 마이그레이션 주의사항

  • pre_model_hook, post_model_hook 파라미터는 Middleware 메서드로 대체됩니다
  • Middleware 사용 시 model 파라미터는 문자열 또는 BaseChatModel이어야 합니다 (함수 불가)
  • 프롬프트는 문자열 또는 None이어야 합니다
  • v1에서는 prompted JSON이 response_format으로 지원되지 않습니다. Pydantic, TypedDict, JSON Schema를 사용하세요
  • Python 3.10 이상 필요 (3.9 지원 종료)

4. 설치 방법

# Python (알파 버전)
pip install --pre -U langchain

# Provider 패키지
pip install -U langchain-openai langchain-anthropic

# JavaScript
npm install langchain@next

안정성 약속

LangChain과 LangGraph 1.0은 2.0 전까지 breaking change가 없습니다.

월간 다운로드 9천만 건을 기록하고 Uber, JP Morgan, Blackrock, Cisco의 프로덕션 애플리케이션을 구동하는 프레임워크로서, 혁신을 지속하면서도 가장 신뢰할 수 있는 에이전트 프레임워크로 남을 의무가 있습니다.

새로운 문서 사이트에는 Python과 JavaScript의 모든 문서가 통합되어 있습니다. 병렬 예제, 공유 개념 가이드, 통합 API 레퍼런스가 제공됩니다.


참고자료:

Fediverse reactions

AI Sparkup 구독하기

최신 게시물 요약과 더 심층적인 정보를 이메일로 받아 보세요! (무료)

Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다