Home / LangGraph / LangGraph Self-RAG
Note

LangGraph Self-RAG

검색 품질 판단과 재검색/재작성 분기

⏱ 20분 49 / 189

LangGraph Self-RAG

검색 품질 판단과 재검색/재작성 분기

그래프로 에이전트와 RAG를 제어한다

LCEL의 직선 한계를 넘어 — 조건 분기·루프·상태 관리·멀티에이전트

RAG 그래프 패턴

Self-RAG · CRAG · Query Router

PART 2 · RAG 패턴

RAG 그래프 패턴

검증과 재시도를 노드로 만드는 세 패턴

검증을 노드로 만든다

검색 전에는 라우팅, 검색 후에는 관련성 검증, 생성 후에는 근거 검증 — 순환 엣지가 재시도를 만듭니다.

  • Self-RAG — 생성 후 근거 검증 → 불합격 시 재생성
  • CRAG — 검색 후 관련성 검증 → 웹 검색 폴백
  • Query Router — 질문 유형 분류 → 벡터/키워드/웹 분기
takeaway

세 패턴의 공통분모는 "검증 → 불합격 시 다른 경로" — 직선 LCEL로는 만들 수 없는 구조입니다.

PART 2 · RAG 패턴

Self-RAG

생성 후 "답변이 문서에 근거하는가" 검증 → 불합격 시 재생성

takeaway

합격이면 END로, 불합격이면 프롬프트를 수정해 재생성합니다 — 이 재시도 루프가 순환 엣지의 대표 사례입니다.

PART 2 · RAG 패턴

재시도 루프 안전장치

retry_count와 best effort — 무한 루프 없는 자기 교정

핵심 포인트

relevance_score >= 0.7
합격선 — LLM이 매긴 관련성 점수로 생성 진행 여부 판정
retry_count
재작성 횟수를 State에 기록 — 최대 2회로 제한해 무한 루프 차단
best effort
한계 도달 시 현재 문서로 답변 생성 — 멈추지 않고 마무리
판단용 경량 모델
관련성 판정은 Haiku급 경량 모델로 — 추가 호출 비용 최소화

코드

python
# 조건 분기 함수 — 다음 노드 이름을 문자열로 반환
def decide_next(state: RAGState) -> str:
    if state["relevance_score"] >= 0.7:
        return "generate"   # 충분 → 답변 생성
    if state["retry_count"] >= 2:
        return "generate"   # 재시도 한계 → best effort
    return "rewrite"        # 부족 → 쿼리 재작성

# 재작성 노드가 카운터를 올린다 — 안전장치의 실체
def rewrite_query(state: RAGState):
    new_query = rewrite_chain.invoke({"question": state["question"]})
    return {"rewritten_query": new_query,
            "retry_count": state["retry_count"] + 1}
PART 2 · RAG 패턴

CRAG + Query Router

검색 전 라우팅 + 검색 후 관련성 검증

  1. 1
    Query Router

    질문 분류 → 벡터/키워드/웹 검색 분기

  2. 2
    Retrieve

    선택된 경로로 문서 검색

  3. 3
    Grade Docs

    관련성 LLM 판정 — relevant / not relevant

  4. 4
    분기

    관련 문서 있음 → Generate, 없음 → Web Search 폴백

  5. 5
    Generate

    검증된 문서 기반 최종 답변 생성

takeaway

검색 전에는 라우터가 경로를 고르고, 검색 후에는 LLM이 관련성을 판정합니다 — 관련 문서가 없으면 웹 검색으로 폴백합니다.

ReAct 에이전트

ToolNode · 순환 루프 · should_continue

PART 3 · ReAct

ReAct 에이전트

추론→도구→관찰 순환의 구현

순환 루프가 에이전트

추론→도구→관찰 순환을 StateGraph로 직접 구현합니다 — create_react_agent는 deprecated, 공식 대체는 langchain.agents의 create_agent입니다.

  • LLM Node — tool_calls 또는 최종 답변 생성
  • ToolNode — tool_calls 실행 빌트인 노드
  • should_continue — 도구 루프 종료 조건 함수
takeaway

도구 호출이 남아 있으면 ToolNode로, 없으면 END로 — should_continue 한 함수가 루프를 제어합니다.

PART 3 · ReAct

ReAct = StateGraph + ToolNode

추론→도구→관찰을 그래프 순환으로 구현

PART 3 · ReAct

ReAct 에이전트 코드

StateGraph로 도구 순환 루프 직접 구현

python
from langgraph.prebuilt import ToolNode

# tool_calls를 실행하고 결과를 messages에 추가하는 빌트인 노드
tool_node = ToolNode([get_weather, search])

def should_continue(state):
    last = state["messages"][-1]
    return "tools" if last.tool_calls else "end"  # 도구 호출이 없으면 루프 종료

graph = StateGraph(MessagesState)
graph.add_node("agent", call_model)
graph.add_node("tools", tool_node)
graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", should_continue,
    {"tools": "tools", "end": END})
graph.add_edge("tools", "agent")  # 순환!
PART 3 · ReAct

create_agent vs 직접 구성

표준 루프는 한 줄로, 루프 안을 바꿔야 하면 StateGraph로

create_agent

langchain.agents — 공식 프리빌트

  • 표준 ReAct 루프를 함수 호출 하나로
  • LangGraph 위에서 동작 — 그래프 직접 작성 불필요
  • middleware 시스템으로 실행 훅 확장
  • deprecated된 create_react_agent의 공식 대체

StateGraph 직접 구성

세밀 제어

  • should_continue 등 루프 조건 직접 정의
  • 검증 · 요약 같은 커스텀 노드 자유 삽입
  • Self-RAG처럼 표준을 벗어난 순환 구현
  • 앞 슬라이드의 코드 패턴이 그 골격
takeaway

표준 도구 루프면 create_agent 한 줄, 루프 구조 자체를 바꿔야 하면 StateGraph 직접 구성으로 내려갑니다.

멀티에이전트

Supervisor · Swarm · HITL · Checkpoint

PART 4 · 멀티에이전트

멀티에이전트

협업 패턴과 사람의 개입 지점

협업 방식도 그래프로

여러 에이전트의 협업 방식을 그래프로 설계합니다 — 위험한 단계에는 사람의 승인 게이트를 끼워 넣습니다.

  • Supervisor — 중앙 위임 · langgraph-supervisor
  • Swarm — 자율 핸드오프 · 분산 의사결정
  • HITL — interrupt() + Command(resume)
takeaway

명확한 작업 분해가 있으면 Supervisor, 동적 워크플로우면 Swarm — 고위험 노드에는 HITL을 겁니다.

PART 4 · 멀티에이전트

Supervisor vs Swarm

작업 분해 방식에 따라 패턴을 선택

Supervisor

중앙 위임

  • 상위 LLM이 하위 에이전트에 태스크 배정
  • 전체 상태를 Supervisor가 관리
  • langgraph-supervisor로 빠르게 구축
  • 명확한 작업 분해가 있을 때

Swarm

자율 핸드오프

  • 에이전트가 스스로 다음에 전달
  • 분산 의사결정 — 중앙 없음
  • 핸드오프 함수로 전환 조건 정의
  • 동적 워크플로우에 적합
takeaway

작업 분해가 명확하면 Supervisor로 중앙에서 배정하고, 흐름이 동적이면 Swarm의 자율 핸드오프에 맡깁니다.

PART 4 · 멀티에이전트

langgraph-supervisor로 구축

중앙 위임 패턴을 패키지 하나로 — 직접 구현 전에 먼저 검토

pip install langgraph-supervisor
별도 패키지(0.0.31) — LangGraph 1.x 호환 공식 확인
create_supervisor()
하위 에이전트 목록으로 Supervisor 그래프를 바로 생성
중앙 상태 관리
전체 상태는 Supervisor가 보유 — 하위 에이전트는 배정받은 태스크만
직접 구현 전환점
배정 로직이 특수해지면 StateGraph + 조건 엣지로 커스텀
takeaway

표준 중앙 위임이면 패키지로 충분합니다 — 배정 로직이 특수해지는 순간이 직접 구현으로 내려가는 시점입니다.

PART 4 · 멀티에이전트

HITL 승인 게이트

interrupt()로 그래프 일시 중지 → 사용자 확인 → Command(resume)로 재개

  1. 1
    invoke()

    사용자 요청으로 그래프 실행 시작

  2. 2
    interrupt_before

    위험 노드 진입 전 자동 중지 — Checkpointer에 저장

  3. 3
    사용자 확인

    "결제를 승인하시겠습니까?" 표시

  4. 4
    Command(resume)

    승인 → True로 그래프 재개, 거부 → 다른 경로

takeaway

중단 시점의 상태는 Checkpointer에 저장됩니다 — 사용자가 승인하면 Command(resume)로 그 지점부터 재개합니다.

PART 4 · 멀티에이전트

HITL 메시지 왕복

중단 · 저장 · 재개가 오가는 실제 순서 — 클라이언트 · 그래프 · Checkpointer · 승인자

takeaway

재개가 가능한 이유는 중단 시점 상태가 Checkpointer에 남아 있기 때문입니다 — 프로세스가 기다리는 것이 아니라 상태가 기다립니다.

Deep Agents와 프로덕션

create_deep_agent · Checkpoint · LangSmith · 배포

PART 5 · 프로덕션

Deep Agents와 프로덕션

추상화 선택과 배포 전 점검

빠르게 시작, 단단하게 배포

시작은 Deep Agents의 고수준 추상화로 빠르게, 세밀한 제어가 필요하면 StateGraph 직접 구성으로 — 배포 전 체크리스트까지 짚습니다.

  • Deep Agents — create_deep_agent() 한 줄
  • Checkpointer — MemorySaver → PostgresSaver
  • LangSmith — 노드별 Trace 디버깅
  • 배포 — AgentCore Runtime 또는 ECS/Lambda
takeaway

개발용 MemorySaver를 프로덕션 PostgresSaver로 바꾸는 것이 배포 전 첫 번째 점검 항목입니다.

PART 5 · 프로덕션

LangGraph vs Deep Agents

직접 구현 vs 고수준 추상화 — 시작은 Deep Agents, 제어는 LangGraph

항목LangGraph (직접)Deep Agents (추상화)
시작StateGraph 직접 구성create_deep_agent() 한 줄
유연성✓ 모든 패턴 구현 가능프리셋 패턴 내에서
빌트인없음 — 직접 구현execute·eval(코드 실행), Harness Profiles
배포AgentCore Runtime / 자체Managed Deep Agents (LangSmith)
버전LangGraph 1.x (안정)v0.6 (빠른 진화 중)
takeaway

시작은 create_deep_agent() 한 줄로 빠르게, 프리셋을 벗어나는 패턴이 필요하면 StateGraph 직접 구성으로 내려갑니다.

PART 5 · 프로덕션

Checkpointer — 상태 영속화

스냅샷이 만드는 세 가지 능력 — HITL 재개 · 장애 복구 · 시간여행

MemorySaver

개발용 인메모리

  • 설정 없이 바로 사용 — 빠른 실험
  • 프로세스 종료 시 상태 소실
  • 로컬 개발 · 단위 테스트에 적합
  • 프로덕션 사용 금지

PostgresSaver

프로덕션 영속화

  • DB에 상태 스냅샷 저장 — 재시작에도 유지
  • HITL 재개와 장애 복구의 전제 조건
  • 과거 체크포인트로 되돌리는 시간여행 디버깅
  • DynamoDB 등은 커뮤니티 구현
takeaway

Checkpointer는 편의 기능이 아니라 HITL과 장애 복구의 전제 조건입니다 — 배포 전 교체가 체크리스트 1번인 이유입니다.

PART 5 · 프로덕션

AgentCore Runtime으로 배포

컴파일된 그래프를 관리형 런타임에 올리는 4단계

  1. 1
    스캐폴드 생성

    agentcore create --framework LangChain_LangGraph — 프레임워크 옵션으로 LangGraph 프로젝트 골격을 만듭니다.

  2. 2
    그래프 컴파일

    app = graph.compile(checkpointer=...) — 이때 Checkpointer는 프로덕션 백엔드로 교체합니다.

  3. 3
    진입점 래핑

    BedrockAgentCoreApp의 @app.entrypoint로 호출 진입점을 선언합니다. bedrock-agentcore 패키지는 langgraph extras를 제공합니다.

  4. 4
    배포

    agentcore deploy 한 번으로 패키징과 배포가 끝납니다. 오토스케일 · 내장 관측성 · 버전 관리는 Runtime이 제공합니다.

takeaway

ECS/Lambda 자체 운영과 달리 스케일 · 관측성 · 버전 관리가 런타임에 내장됩니다 — LangGraph 코드는 그대로, 진입점만 래핑합니다.

PART 5 · 프로덕션

프로덕션 체크리스트

LangGraph 에이전트를 프로덕션에 배포하기 전 확인

  1. 1
    Checkpointer 교체

    MemorySaver(개발) → PostgresSaver(프로덕션, DynamoDB는 커뮤니티 구현) — 상태 영속화 필수

  2. 2
    LangSmith 연동

    노드별 실행 시간·토큰·에러 시각화 — 병목 발견

  3. 3
    interrupt 설계

    고위험 노드에 interrupt_before 설정 — HITL 경로 확보

  4. 4
    배포 선택

    AgentCore Runtime(관리형) 또는 ECS/Lambda(자체 운영)

takeaway

Checkpointer 교체·LangSmith 연동·interrupt 설계·배포 선택 — 네 가지를 확인한 뒤 프로덕션으로 내보냅니다.

PART 5 · 프로덕션

에이전트의 두뇌 회로

State·Node·Edge 3요소 위의 Self-RAG·ReAct·Supervisor·HITL — 그래프가 곧 에이전트 설계

그래프로 에이전트와 RAG를 제어한다

State·Node·Edge 3요소 위에 Self-RAG·ReAct·Supervisor·HITL — LangGraph는 에이전트의 두뇌 회로를 설계하는 도구입니다.

그래프로 에이전트의 두뇌 회로를 설계합니다.

StateGraph 위에 RAG 루프 · ReAct · Supervisor · HITL 패턴 구현