Home / LangGraph / ๐ŸŽฏ LangGraph
Module

๐ŸŽฏ LangGraph

StateGraph ยท Self-RAG ยท ReAct ยท Supervisor ยท HITL ยท Deep Agents

โฑ 60๋ถ„ 47 / 189

LangGraph

StateGraph ยท Self-RAG ยท ReAct ยท Supervisor ยท HITL

๊ทธ๋ž˜ํ”„๋กœ ์—์ด์ „ํŠธ์™€ RAG๋ฅผ ์ œ์–ดํ•œ๋‹ค

LCEL์˜ ์ง์„  ํ•œ๊ณ„๋ฅผ ๋„˜์–ด โ€” ์กฐ๊ฑด ๋ถ„๊ธฐยท๋ฃจํ”„ยท์ƒํƒœ ๊ด€๋ฆฌยท๋ฉ€ํ‹ฐ์—์ด์ „ํŠธ

LangGraph ํ•ต์‹ฌ ๊ตฌ์กฐ

LCEL ํ•œ๊ณ„ ยท StateGraph ยท 3์š”์†Œ

PART 1 ยท ํ•ต์‹ฌ ๊ตฌ์กฐ

ํ•ต์‹ฌ ๊ตฌ์กฐ

์ง์„ ์„ ๋„˜๋Š” 3์š”์†Œ

3์š”์†Œ๋กœ ๋ชจ๋“  ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ

LCEL์˜ ์ง์„  ํ•œ๊ณ„๋ฅผ ์ˆœํ™˜ ๊ทธ๋ž˜ํ”„๋กœ ๋„˜์–ด์„ญ๋‹ˆ๋‹ค โ€” StateยทNodeยทEdge ์„ธ ๊ฐ€์ง€๋กœ ๋ถ„๊ธฐ์™€ ๋ฃจํ”„๊นŒ์ง€ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

  • State โ€” TypedDict ๊ณต์œ  ๋ฐ์ดํ„ฐ
  • Node โ€” State๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” Python ํ•จ์ˆ˜
  • Edge โ€” add_edge ยท add_conditional_edges
  • compile() โ€” invoke/stream ๊ฐ€๋Šฅํ•œ Runnable
takeaway

์กฐ๊ฑด ๋ถ„๊ธฐยท๋ฃจํ”„ยท์ƒํƒœ ๊ด€๋ฆฌ โ€” LCEL์ด ๋ชป ํ•˜๋Š” ์„ธ ๊ฐ€์ง€๊ฐ€ StateGraph์˜ ์กด์žฌ ์ด์œ ์ž…๋‹ˆ๋‹ค.

PART 1 ยท ํ•ต์‹ฌ ๊ตฌ์กฐ

LCEL vs LangGraph

์ง์„  ํŒŒ์ดํ”„๋ผ์ธ์˜ ํ•œ๊ณ„๋ฅผ ์ˆœํ™˜ ๊ทธ๋ž˜ํ”„๋กœ ํ•ด๊ฒฐ

LCEL

์ง์„  ํŒŒ์ดํ”„๋ผ์ธ

  • A | B | C โ€” ํ•ญ์ƒ ๊ฐ™์€ ์ˆœ์„œ
  • ์กฐ๊ฑด ๋ถ„๊ธฐยท๋ฃจํ”„ ๋ถˆ๊ฐ€
  • ์ƒํƒœ ๊ด€๋ฆฌ ์—†์Œ
  • ๋น ๋ฅธ ํ”„๋กœํ† ํƒ€์ž…์— ์ ํ•ฉ

LangGraph

์ˆœํ™˜ ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„

  • ์กฐ๊ฑด ์—ฃ์ง€๋กœ ๋ถ„๊ธฐ
  • ์ˆœํ™˜ ์—ฃ์ง€๋กœ ๋ฃจํ”„ (์žฌ์‹œ๋„)
  • TypedDict State + Checkpointer
  • ํ”„๋กœ๋•์…˜ ์—์ด์ „ํŠธ์— ์ ํ•ฉ
takeaway

๋น ๋ฅธ ํ”„๋กœํ† ํƒ€์ž…์€ LCEL๋กœ, ๋ถ„๊ธฐยท๋ฃจํ”„ยท์ƒํƒœ๊ฐ€ ํ•„์š”ํ•œ ํ”„๋กœ๋•์…˜ ์—์ด์ „ํŠธ๋Š” LangGraph๋กœ ๊ฐ‘๋‹ˆ๋‹ค.

PART 1 ยท ํ•ต์‹ฌ ๊ตฌ์กฐ

StateGraph 3์š”์†Œ

State + Node + Edge โ€” ์ด 3๊ฐœ๋กœ ๋ชจ๋“  ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ํ‘œํ˜„

State

TypedDict โ€” ๊ทธ๋ž˜ํ”„ ์ „์ฒด ๊ณต์œ  ๋ฐ์ดํ„ฐ. Annotated[list, add]๋กœ ์ž๋™ ๋ˆ„์ 

Node

Python ํ•จ์ˆ˜ โ€” State๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์—…๋ฐ์ดํŠธ ๋ฐ˜ํ™˜

Edge

๋…ธ๋“œ ๊ฐ„ ์—ฐ๊ฒฐ โ€” ์ง์ ‘(add_edge) ๋˜๋Š” ์กฐ๊ฑด๋ถ€(conditional)

takeaway

State๋ฅผ Node๊ฐ€ ๊ฐฑ์‹ ํ•˜๊ณ  Edge๊ฐ€ ๋‹ค์Œ ๊ฒฝ๋กœ๋ฅผ ๊ณ ๋ฆ…๋‹ˆ๋‹ค โ€” ์…‹์˜ ์กฐํ•ฉ๋งŒ์œผ๋กœ ๋ถ„๊ธฐยท๋ฃจํ”„ยท๋ณ‘๋ ฌ์„ ๋ชจ๋‘ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

PART 1 ยท ํ•ต์‹ฌ ๊ตฌ์กฐ

๋ฌธ์˜ ํ•˜๋‚˜์˜ ๊ทธ๋ž˜ํ”„ ์—ฌ์ •

"๋ฐฐ์†ก์ด 3์ผ์งธ ์•ˆ ์™€์š”" โ€” ๋ถ„๋ฅ˜ ๋…ธ๋“œ์˜ ์œ ํ˜• ํŒ์ •๊ณผ ์กฐ๊ฑด ์—ฃ์ง€๊ฐ€ ๊ณ ๋ฅด๋Š” ๊ฐˆ๋ฆผ๊ธธ





"๋ฐฐ์†ก์ด 3์ผ์งธ ์•ˆ ์™€์š”"
๊ณ ๊ฐ ๋ฌธ์˜ โ€” State.question

โ†’

STATEGRAPH โ€” ๋ฌธ์˜๊ฐ€ ์ง€๋‚˜๋Š” ๊ธธ

classify ๋…ธ๋“œ
โ†’
์กฐ๊ฑด ์—ฃ์ง€ โ€” category?
โ†’
"๋ฐฐ์†ก" โ†’ check_delivery ๋…ธ๋“œ
โ†’
respond ๋…ธ๋“œ


โ†ณ ํ™˜๋ถˆ ๋ฌธ์˜์˜€๋‹ค๋ฉด
"ํ™˜๋ถˆ" โ†’ process_refund ๋…ธ๋“œ
โ†’ ๊ฐ™์€ respond๋กœ ํ•ฉ๋ฅ˜


โ†’

"๋‚ด์ผ ๋„์ฐฉ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค"
์‘๋‹ต โ€” State.answer



์กฐ๊ฑด ์—ฃ์ง€๊ฐ€ State์˜ category ๊ฐ’์„ ๋ณด๊ณ  ๋‹ค์Œ ๋…ธ๋“œ๋ฅผ ๊ณ ๋ฆ…๋‹ˆ๋‹ค โ€” A | B | C ์ง์„ (LCEL)์œผ๋กœ๋Š” ๊ทธ๋ฆด ์ˆ˜ ์—†๋Š” ๊ฐˆ๋ฆผ๊ธธ


takeaway

์ด ๊ทธ๋ฆผ์˜ ๋ถ€ํ’ˆ์ด ๊ณง 3์š”์†Œ์ž…๋‹ˆ๋‹ค โ€” ์ƒ์ž๋Š” Node, ํ™”์‚ดํ‘œ๋Š” Edge, ๊ทธ ์‚ฌ์ด๋ฅผ ํ๋ฅด๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ State์ž…๋‹ˆ๋‹ค.

PART 1 ยท ํ•ต์‹ฌ ๊ตฌ์กฐ

State ์Šค๋ƒ…์ƒท โ€” ๋…ธ๋“œ๋ฅผ ์ง€๋‚  ๋•Œ๋งˆ๋‹ค

"๋ฐฐ์†ก์ด 3์ผ์งธ ์•ˆ ์™€์š”" ๋ฌธ์˜์˜ ์—ฌ์ •์„ ๋ฐ์ดํ„ฐ๋กœ โ€” ๋…ธ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐฑ์‹ ๋ถ„์ด State์— ๋ณ‘ํ•ฉ๋˜๋Š” ๊ณผ์ •




์ด์–ด์ง€๋Š” ์˜ˆ์‹œ
"๋ฐฐ์†ก์ด 3์ผ์งธ ์•ˆ ์™€์š”" โ€” ์•ž ์žฅ์˜ ์—ฌ์ •์„ State๋กœ ๋‹ค์‹œ ๋ด…๋‹ˆ๋‹ค
(์˜ˆ์‹œ ์ˆ˜์น˜)



START โ€” ์ž…๋ ฅ ์งํ›„
{
  question:
    "๋ฐฐ์†ก์ด 3์ผ์งธ ์•ˆ ์™€์š”"
}



classify ํ†ต๊ณผ
{
  question: "๋ฐฐ์†ก์ดโ€ฆ",
  category: "๋ฐฐ์†ก"
}

๋ฐ˜ํ™˜๊ฐ’ {"category": "๋ฐฐ์†ก"}๋งŒ ๋ณ‘ํ•ฉ


check_delivery ํ†ต๊ณผ
{
  question: "๋ฐฐ์†ก์ดโ€ฆ",
  category: "๋ฐฐ์†ก",
  tracking_info:
    "๊ฐ„์„  ์ƒ์ฐจ ยท D-1"

}



respond ํ†ต๊ณผ โ†’ END
{
  question: "๋ฐฐ์†ก์ดโ€ฆ",
  category: "๋ฐฐ์†ก",
  tracking_info: "โ€ฆD-1",
  answer:
    "๋‚ด์ผ ๋„์ฐฉ ์˜ˆ์ •โ€ฆ"

}




๋…ธ๋“œ๋Š” State ์ „์ฒด๋ฅผ ๊ณ ์ณ ์“ฐ์ง€ ์•Š๊ณ  ๊ฐฑ์‹ ๋ถ„ dict๋งŒ ๋ฐ˜ํ™˜ โ€” ๋ณ‘ํ•ฉ์€ ๊ทธ๋ž˜ํ”„๊ฐ€ ๋งก์Šต๋‹ˆ๋‹ค (๋‹ค์Œ ์žฅ์˜ ๋ถˆ๋ณ€ ๊ฐฑ์‹  ์›์น™)


takeaway

์กฐ๊ฑด ์—ฃ์ง€๊ฐ€ ๋ณธ ๊ฒƒ๋„, ๋‹ต๋ณ€ ๋…ธ๋“œ๊ฐ€ ์“ด ๊ฒƒ๋„ ์ „๋ถ€ ์ด State ์•ˆ์˜ ๊ฐ’์ž…๋‹ˆ๋‹ค โ€” State ์„ค๊ณ„๊ฐ€ ๊ณง ๊ทธ๋ž˜ํ”„ ์„ค๊ณ„์ธ ์ด์œ ์ž…๋‹ˆ๋‹ค.

PART 1 ยท ํ•ต์‹ฌ ๊ตฌ์กฐ

State ์„ค๊ณ„ ์›์น™

๊ทธ๋ž˜ํ”„์˜ ๋ฐ์ดํ„ฐ ๊ณ„์•ฝ โ€” ํ•„๋“œ ์ตœ์†Œ ยท ๋ถˆ๋ณ€ ๊ฐฑ์‹  ยท ์ž๋™ ๋ˆ„์ 

ํ•ต์‹ฌ ํฌ์ธํŠธ

TypedDict
์ƒํƒœ ์Šคํ‚ค๋งˆ๋ฅผ ํƒ€์ž…์œผ๋กœ ์„ ์–ธ โ€” ํ•„๋“œ ๊ตฌ์กฐ๊ฐ€ ๊ณง ๊ทธ๋ž˜ํ”„์˜ ๊ณ„์•ฝ
์ตœ์†Œ ํ•„๋“œ
ํ•„์š”ํ•œ ๊ฐ’๋งŒ State์— โ€” ํ•„๋“œ๊ฐ€ ๋Š˜์ˆ˜๋ก ๋ฉ”๋ชจ๋ฆฌ์™€ ๋””๋ฒ„๊น… ๋ถ€๋‹ด ์ฆ๊ฐ€
๋ถˆ๋ณ€ ๊ฐฑ์‹ 
๋…ธ๋“œ๋Š” State๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ๊ฐฑ์‹ ๋ถ„์„ ๋ฐ˜ํ™˜ โ€” ํ๋ฆ„ ์ถ”์  ์šฉ์ด
Annotated[list, add]
๋ฆฌ์ŠคํŠธ ํ•„๋“œ ์ž๋™ ๋ˆ„์  โ€” messages์ฒ˜๋Ÿผ ์Œ“์ด๋Š” ๊ฐ’์— ์‚ฌ์šฉ

์ฝ”๋“œ

python
from typing import TypedDict

# ๊ทธ๋ž˜ํ”„ ์ „์ฒด๊ฐ€ ๊ณต์œ ํ•˜๋Š” ์ƒํƒœ ์Šคํ‚ค๋งˆ
class RAGState(TypedDict):
    question: str
    documents: list
    relevance_score: float
    answer: str
    retry_count: int

# ๋…ธ๋“œ๋Š” State๋ฅผ ๋ฐ›์•„ ๊ฐฑ์‹ ๋ถ„๋งŒ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜
def retrieve(state: RAGState):
    docs = retriever.invoke(state["question"])
    return {"documents": docs}
PART 1 ยท ํ•ต์‹ฌ ๊ตฌ์กฐ

StateGraph ์ฝ”๋“œ ํŒจํ„ด

add_node โ†’ add_edge โ†’ compile() โ€” 3๋‹จ๊ณ„๋กœ ๊ทธ๋ž˜ํ”„ ์กฐ๋ฆฝ

python
from langgraph.graph import StateGraph, MessagesState, START, END

# ๋…ธ๋“œ = State๋ฅผ ๋ฐ›์•„ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜
def retrieve(state): ...
def generate(state): ...

# State ์Šคํ‚ค๋งˆ๋กœ ๊ทธ๋ž˜ํ”„ ์„ ์–ธ โ€” MessagesState๋Š” messages๋ฅผ ์ž๋™ ๋ˆ„์ 
graph = StateGraph(MessagesState)
graph.add_node("retrieve", retrieve)
graph.add_node("generate", generate)
graph.add_edge(START, "retrieve")  # START/END ํŠน์ˆ˜ ๋…ธ๋“œ๋กœ ์ง„์ž…ยท์ข…๋ฃŒ ์ง€์ •
graph.add_edge("retrieve", "generate")
graph.add_edge("generate", END)
app = graph.compile()  # ์ปดํŒŒ์ผํ•˜๋ฉด invoke/stream ๊ฐ€๋Šฅํ•œ Runnable์ด ๋จ

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 ํŒจํ„ด ๊ตฌํ˜„