LangChain 1.0 — AI 애플리케이션 개발을 위한 거대한 도약
Source: Dev.to
소개
지난 1~2년 동안 LangChain을 접해보았다면, 약속과 불안이 뒤섞인 느낌을 받았을 것입니다. 같은 일을 수행할 수 있는 방법이 너무 많고, Azure AI나 다른 벤더 대신 프로덕션에 사용할지 고민하게 됩니다. LangChain은 프로토타이핑과 에이전트 학습에는 훌륭했지만, 프로덕션 급 도구로 신뢰하기는 어려웠습니다.
LangChain 1.0은 마침내 생태계가 필요로 했던 정리를 제공했습니다. 누군가가 발을 딛고 “이제 이걸 정상화하자”라고 선언한 느낌이죠. 아래는 AI 에이전트 프레임워크와 툴체인을 이해하려고 많은 시간을 보낸 사람의 관점에서 본 1.0의 핵심 내용입니다.
create_agent() — 에이전트를 만드는 합리적인 방법
from langchain.agents import create_agent
from langchain.models import OpenAI
def my_tool(text: str) -> str:
return text[::-1]
agent = create_agent(
model=OpenAI(model_name="gpt-4o-mini"),
tools=[my_tool],
system_prompt="You are a helpful assistant."
)
result = agent.invoke({"input": "Reverse hello world"})
이전 버전에서는 LLM 전후 로직을 해킹하거나, 특이한 Runnable 체인을 엮거나, “미니‑미들웨어”를 직접 작성해야 했습니다.
버전 1.0에서는 일급 훅을 도입했습니다:
before_modelafter_model- 동적 프롬프트 훅
- 검증
- 안전 필터
- 캐싱
- 예산 가드
- 컨텍스트 주입
예시: 채팅 히스토리 요약
from langchain.agents.middleware import AgentMiddleware
class SummarizeHistory(AgentMiddleware):
def before_model(self, req, state):
if len(state["messages"]) > 20:
state["messages"] = summarize_history(state["messages"])
return req, state
미들웨어 (정말 유용합니다!)
미들웨어가 이제 일급 시민이 되었습니다. 모델 실행 전후에 동작을 주입할 수 있으며, 임시 방편 해킹에 의존할 필요가 없습니다.
from langchain.agents.middleware import AgentMiddleware
class ValidateOutputs(AgentMiddleware):
def after_model(self, res, state):
if "delete" in res["text"].lower():
raise ValueError("Dangerous action detected")
return res, state
동적 프롬프트
from langchain.agents.middleware import dynamic_prompt
@dynamic_prompt
def choose_prompt(req, state):
if state.get("mode") == "analysis":
return "Analyze deeply: {text}"
return "Summarize: {text}"
수동 문자열 연결이 필요 없습니다. 상태에 따라 깔끔하게 프롬프트가 생성됩니다.
구조화된 공유 상태 (AgentState)
from langchain.agents import AgentState
state = AgentState()
state["messages"] = []
state["user_id"] = "u123"
도구, 미들웨어, 모델 등 모든 구성 요소가 이 메모리 표면을 공유하므로 “어떤 컴포넌트가 이 임의 키를 추가했지?” 하는 놀라움이 사라집니다.
도구: 더 엄격하고, 더 안전하며, 실수 위험 감소
- 엄격한 인자 스키마
- 통합된 tool‑call 포맷
- 예측 가능한 검증
- 내장 안전 레이어
이러한 개선으로 도구를 보안에 민감한 애플리케이션에서도 안심하고 사용할 수 있습니다.
invoke() + ContentBlocks
통합된 invoke API는 공급자에 관계없이 동작합니다:
model.invoke(...)
model.batch(...)
model.stream(...)
ContentBlocks는 이제 다음을 처리합니다:
- 텍스트
- 이미지
- 툴 호출
- 멀티모달 입력
- 구조화된 메시지
이 통합으로 다중 에이전트 워크플로우 구축이 간편해졌습니다.
LangGraph: 다중 에이전트 워크플로우를 위한 성숙한 선택
LangGraph는 다음을 추가합니다:
- 감독자/작업자 (전문가/비평가) 패턴
- 결정론적 전이
- 재시도 + 중단점
- 체크포인터
- 장기 실행 루프
- 올바른 async 동작
워크플로우 엔진이 필요하다면 LangGraph가 기본 시작점이 되어야 합니다.
디버깅 및 추적
버전 1.0에서 제공하는 기능:
- 더 깔끔한 트레이스백
- 안정된 스트리밍 순서
- 향상된 노트북 렌더링
- 개선된 LangSmith 추적
- 구조화되고 읽기 쉬운 로그
화려하지는 않지만 프로덕션에 필수적인 요소입니다.
Runnable API: 예측 가능한 동작
model.with_fallbacks([backup_model])
- 안정된 스트리밍 순서
- 일관된 폴백 처리
거친 부분들이 모두 매끄럽게 다듬어졌습니다.
전형적인 프로덕션 설정
class Retrieval(AgentMiddleware):
def before_model(self, req, state):
docs = vectorstore.similarity_search(req["input"], k=3)
req["retrievals"] = [d.page_content for d in docs]
return req, state
class Summarizer(AgentMiddleware):
def before_model(self, req, state):
if len(state["messages"]) > 25:
state["messages"] = summarize_messages(state["messages"])
return req, state
class Safety(AgentMiddleware):
def after_model(self, res, state):
if "delete database" in res["text"].lower():
raise ValueError("Blocked unsafe content")
return res, state
agent = create_agent(
model=OpenAI("gpt-4o-mini"),
system_prompt="You are an assistant.",
tools=[...]
)
agent.with_middleware([
Retrieval(),
Summarizer(),
Safety()
])
이와 같은 모듈식 구성이 오늘날 프로덕션 AI 에이전트가 가져야 할 모습과 일치합니다.
업그레이드 가이드
- 기존 에이전트 생성자를
create_agent()로 교체합니다. - 복잡한 프롬프트 로직을 미들웨어 또는 동적 프롬프트로 이동합니다.
- 딕셔너리 기반 상태를
AgentState로 변환합니다. - 도구를 새로운 스키마 검증에 맞게 업데이트합니다.
- LangSmith을 활용해 미세한 마이그레이션 이슈를 찾아냅니다.
결론
LangChain 1.0은 마침내 성숙함을 보여줍니다: 마법 같은 요소는 줄이고, 명시성을 높이며, 프로덕션 마인드셋으로 설계되었습니다. 주말에 0.x 버전을 가지고 놀며 예산과 가동 시간을 고민하던 시절이 지나고, 이제 1.0을 도입해 “실제 고객에게 배포할 수 있는 진짜 제품을 만들 수 있다”는 자신감을 가질 수 있게 되었습니다.