1. LangGraph๋?
: LangCahain ์ํ๊ณ์์ ๋ง๋ ๊ทธ๋ํ ๊ตฌ์กฐ ๊ธฐ๋ฐ ์ํฌํ๋ก์ฐ/์์ด์ ํธ ๊ฐ๋ฐ์ฉ ๋ฐํ์ ํ๋ ์์ํฌ
• ํน์ง : ์ฌ์ดํด(์ํ) ์ง์ → LCEL๋ก ๊ตฌํ ๋ถ๊ฐ๋ฅํ '๋ง์กฑ์ค๋ฝ์ง ์์ผ๋ฉด ๋๋์๊ฐ๊ธฐ' ๋ก์ง ๊ตฌํ ๊ฐ๋ฅ
• ๊ทธ๋ํ ๊ตฌ์กฐ : ๋ฐ์ดํฐ ๊ฐ ๊ด๊ณ ํํํ๋ ์๋ฃ ๊ตฌ์กฐ - Node(์์ ์ํ) + Edge(์์ ํ๋ฆ ์ ์)
• ๋ฐํ์ ํ๋ ์์ํฌ : ๋ง๋ ์ํฌํ๋ก์ฐ๋ฅผ ์คํ ์์ ๊น์ง ๊ด๋ฆฌ
• LangChain vs LangGraph
| ํญ๋ชฉ | LangChain | LangGraph |
| ์คํ ํ๋ฆ | ์ ํ/์์ฐจ ์ค์ฌ | ๊ทธ๋ํ ๊ธฐ๋ฐ(๋ถ๊ธฐ/๋ฃจํ) |
| ์ํ ๊ด๋ฆฌ | ๊ธฐ๋ณธ ๋ฉ๋ชจ๋ฆฌ/์ธ์ ์ค์ฌ | ์ง์ ์ํ(durable) |
| ์ถ์ํ ์์ค | LCEL ๊ณ ์์ค API | ์ ์์ค ์ ์ด |
| ์ ํฉ ์ฉ๋ | ๊ฐ๋จํ ์์ด์ ํธ/์ํฌํ๋ก์ฐ | ๋ณต์กํ ๋ฉํฐ์์ด์ ํธ, ์ํ ๊ธฐ๋ฐ ์์คํ |
2. ํต์ฌ ๊ฐ๋ (Node, Edge, State)
1) Node(๋ ธ๋)
: ์ค์ ์์ ์ํํ๋ Python ํจ์. ํ์ฌ ์ํ ์ ๋ ฅ๋ฐ์ ์ ๋ฐ์ดํธ๋ ์ํ ๋ฐํ
- ํน์ ๋ ธ๋ START, END : ์คํ ํจ์ ์์. add_node()๋ก ๋ฑ๋กํ์ง ์๋ ์์ฝ๋ ์์
2) State(์ํ)
: ๊ทธ๋ํ ์คํ ์ค ์ ์ง๋๋ key-value ํํ์ ์ ์ฅ์(dict)
- State Schema(TypedDict or pydantic.BaseModel)๋ก ๋จผ์ ์ค๊ณ → Graph ์์ฑ ์ ์ ๋ฌ
- Schema์ ์ ์๋ Field๋ง ์ ์ฅ ๊ฐ๋ฅ
• ์ํ ์ ๋ฐ์ดํธ ๋ฐฉ์ 2๊ฐ์ง
โ ์์ ์ฌ์ ์ : ๊ฐ์ key๋ก ๋ฐํ๋๋ฉด ๊ธฐ์กด ๊ฐ ๋ฎ์ด์
โก Reducer ์ฌ์ฉ : Annotated[ํ์ , reducerํจ์] ํํ๋ก ์ง์ , ๋ฆฌ์คํธ ๋์ ๋ฑ์ ์ฌ์ฉ(ex. add_messages)
3. StateGraph ๊ตฌํ ํ๋ฆ
from langgraph.graph import StateGraph, START, END
graph = StateGraph(MyState) # 1. State Schema๋ก ๊ทธ๋ํ ์์ฑ
graph.add_node("increment", increment_counter) # 2. ๋
ธ๋ ๋ฑ๋ก
graph.add_edge(START, "increment") # 3. ์ฃ์ง ์ฐ๊ฒฐ
graph.add_edge("increment", END)
app = graph.compile() # 4. ์ปดํ์ผ
• ํธ์ถ ๋ฐฉ๋ฒ
- invoke(input, config) : ๊ทธ๋ํ ํ ๋ฒ์ ์คํ, ์ต์ข State๋ง ๋ฐํ
- stream(input, config) : ์คํ ์ค ์ด๋ฒคํธ ์ค์๊ฐ yield
4. ๋ค์ํ ์ฃ์ง ์ ํ
• ๊ธฐ๋ณธ ์ฃ์ง(Normal Edge)
: ๊ณ ์ ๋ ํ๋ฆ์ผ๋ก ์์ฐจ ์คํ - add_edge(A, B)
• ์กฐ๊ฑด๋ถ ์ฃ์ง(Conditional Edge)
: add_conditional_edges(์์ค๋ ธ๋, ๋ผ์ฐํ ํจ์, path_map)์ผ๋ก ์ ์
- 3์์
โ ์์ค ๋ ธ๋ : ์กฐ๊ฑด ํ๊ฐ๊ฐ ์์๋๋ ๋ ธ๋
โ ๋ผ์ฐํ ํจ์ : ์ํ๊ฐ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ ๋ ธ๋ ์ด๋ฆ ๋ฐํ
โ path_map : ๋ฐํ๊ฐ → ์ด๋ํ ๋ ธ๋ ๋งคํ(dict or list)
graph.add_conditional_edges(
"llm_answer", relevance_check,
{"grounded": END, "not_grounded": "retrieve"}
)
• ๋ฐ๋ณต ๊ตฌ์กฐ(์ํ)
: ๊ฒ์ ์ฌ์๋, ๋ต๋ณ ์ฌ์์ฑ, ํ ๋ฃจ์๋ค์ด์ ๋ฐฉ์ง, HITL(Human-In-The-Loop) ๋ฑ์ ํ์ฉ
• Command
: ๋ ธ๋๊ฐ '์ํ ์ ๋ฐ์ดํธ + ๋ค์ ๋ ธ๋ ์ง์ ' ๋์์ ๋ฐํ
- ํ๋ผ๋ฏธํฐ : updata(์ํ ๊ฐฑ์ ), goto(์ด๋ํ ๋ ธ๋), graph(subgraph → parent ์ด๋ ์ Command.PARENT ์ง์ ), resume(interrupt ์ฌ๊ฐ์ฉ)
| ๊ตฌ๋ถ | Conditional Edge | Command |
| ํ๋ฆ ์ ์ด ์์น | ๊ทธ๋ํ ์ ์๋ถ | ๋ ธ๋ ๋ด๋ถ |
| ์ฌ์ฉ ์ | ๋ถ๋ฅ๊ธฐ, ๋ผ์ฐํฐ | ์์ด์ ํธ ํธ๋์คํ, ๋์ ๋ผ์ฐํ |
• Send
: ํ๋์ ๋ ธ๋์์ ์ฌ๋ฌ ์์ ์ ๋์ ์์ฑํด ๋ค๋ฅธ ๋ ธ๋๋ก ๋ณ๋ ฌ ์ ๋ฌ(Fan-out, map-reduce ํจํด)
- ํ๋ผ๋ฏธํฐ : node(๋์ ๋ ธ๋), arg(์ ๋ฌํ state - ์ ์ฒด Schema์ ์๋ ํ๋๋ ๊ฐ๋ฅ)
| ๊ตฌ๋ถ | ๋ฐ๋ณต ๊ตฌ์กฐ | Send |
| ๋ชฉ์ | ์กฐ๊ฑด ๋ง์กฑ๊น์ง ๊ฐ์ ํ๋ฆ ๋ฐ๋ณต | ์ฌ๋ฌ ์์ ๋๋ ์คํ |
| ํต์ฌ ๊ฐ๋ | Loop | Fan-out |
'STUDY > AI Agent' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [AI Agent] AI Agent์ ToolCalling2 (0) | 2026.07.14 |
|---|---|
| [AI Agent] AI Agent์ ToolCalling1 (0) | 2026.07.13 |