โํ ๋ฒ์ ๋ํ๊ฐ ์๋๋ผ, ์ง์์ ์ธ ๋งฅ๋ฝ์ ๊ฐ์ง ํ๋ฆ์ผ๋ก.โ
LangGraph๋ฅผ โ์ํ ๊ธฐ๋ฐ ์์ด์ ํธโ๋ก ๋ฐ์ ์ํค๋ ํต์ฌ ๋จ๊ณ.
LLM์ ๋จ์ ํธ์ถ๊ธฐ๋ก๋ง ์ฐ๋ฉด, โ์ง๋ฌธ โ ๋ต๋ณ โ ๋โ์์ ๋ฉ์ถฅ๋๋ค.
ํ์ง๋ง LangGraph๋ ์ํ๋ฅผ ์ ์ด์ํค๋ฉฐ LLM์ ๋ํ๋ฅผ ์ด์ด๊ฐ๊ฒ ๋ง๋ญ๋๋ค.
์๋ฅผ ๋ค์ด,
์ด ๋ชจ๋ ๊ฑธ ๊ด๋ฆฌํ๋ ๊ฒ์ด ๋ฐ๋ก Reducer์ MessageGraph์ ๋๋ค.
Reducer๋ โ์ํ๋ฅผ ๋์ ๊ด๋ฆฌํ๋ ํจ์โ์
๋๋ค.
์ฌ๋ฌ ๋
ธ๋์ ๊ฒฐ๊ณผ๋ฅผ ํ๋์ ์ํ๋ก ํฉ์น๊ฑฐ๋ ๊ฐฑ์ ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
๐ ์ฐธ๊ณ : ์ด๋ฆ์ React์
useReducerํจํด๊ณผ ์ ์ฌํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ํ ๊ธฐ๋ก์ ๋์ ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํฉ๋๋ค.
from langgraph.graph import StateGraph
class ChatState:
history: list[str]
user_input: str
bot_reply: str
def reducer(prev: ChatState, new: ChatState):
prev.history.append(f"User: {new.user_input}")
prev.history.append(f"Bot: {new.bot_reply}")
return prev
์ด Reducer๋ฅผ ๊ทธ๋ํ์ ๋ฑ๋กํ๋ฉด,
๊ฐ ๋
ธ๋ ์คํ ํ ์ํ๊ฐ ๋์ ์ ์ฅ๋ฉ๋๋ค.
LangGraph์ MessageGraph๋
LLM๊ณผ ์ฌ์ฉ์ ๋ฉ์์ง๋ฅผ โ์ํ ๊ฐ์ฒดโ๋ก ๊ด๋ฆฌํฉ๋๋ค.
๊ธฐ์กด LangChain์ ConversationBufferMemory์ ์ ์ฌํ์ง๋ง,
LangGraph์์๋ โ๊ทธ๋ํ ๋จ์โ๋ก ์ํ๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค.
from langgraph.graph import MessageGraph
from langchain_openai import ChatOpenAI
# ๋ฉ์์ง ๊ธฐ๋ฐ ๊ทธ๋ํ ์์ฑ
graph = MessageGraph()
llm = ChatOpenAI(model="gpt-4o-mini")
# ๋
ธ๋: ๋ํ ์ฒ๋ฆฌ
def chat_node(messages):
response = llm.invoke(messages)
messages.append({"role": "assistant", "content": response.content})
return messages
# ๊ทธ๋ํ ๊ตฌ์ฑ
graph.add_node("chat", chat_node)
graph.set_entry_point("chat")
# ์คํ (์ฌ๋ฌ ๋ฒ ๋ํ ์ ์ํ๊ฐ ๋์ ๋จ)
app = graph.compile()
state = []
state = app.invoke(state + [{"role": "user", "content": "LangGraph๋ ๋ญ์ผ?"}])
state = app.invoke(state + [{"role": "user", "content": "ReAct ํจํด์ด๋ ๋ฌ๋ผ?"}])
for msg in state:
print(f"{msg['role']}: {msg['content']}")
๐ค ์ถ๋ ฅ ์์:
user: LangGraph๋ ๋ญ์ผ?
assistant: LangGraph๋ LangChain ์์์ ์ํฌํ๋ก์ฐ๋ฅผ ๊ทธ๋ํ๋ก ํํํ๋ ํ๋ ์์ํฌ์
๋๋ค.
user: ReAct ํจํด์ด๋ ๋ฌ๋ผ?
assistant: ReAct๋ ์ฌ๊ณ -ํ๋-๊ด์ฐฐ ๋ฃจํ ํจํด์ด๊ณ , LangGraph๋ ์ด๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.
๐ง ์ด ์ํ(messages)๋ ๋ค์ LLM ํธ์ถ์์๋ ๊ทธ๋๋ก ์ด์ด์ง๋๋ค.
์ฆ, ๊ทธ๋ํ ์ฐจ์์ Memory๊ฐ ์๊ธด ๊ฒ์ด์์.
LangGraph์์๋ ๋
ธ๋ ๊ฐ ์ฃ์ง๋ฅผ ์ํ์์ผ
์์ฒด ํ๊ฐ(Self-Evaluation) ๋๋ ์๋ ์์ (Revision) ํ๋ฆ์ ๋ง๋ค ์ ์์ต๋๋ค.
from langgraph.graph import StateGraph
class EvalState:
question: str
answer: str
feedback: str
retry: int = 0
def generate(state: EvalState):
state.answer = f"{state.question}์ ๋ต๋ณ์
๋๋ค."
return state
def evaluate(state: EvalState):
if "๋ต๋ณ" not in state.answer:
state.feedback = "๋ถ์ถฉ๋ถํ ๋ต๋ณ"
state.retry += 1
return "retry"
return "finish"
graph = StateGraph(EvalState)
graph.add_node("generate", generate)
graph.add_node("evaluate", evaluate)
graph.add_edge("generate", "evaluate")
graph.add_conditional_edges("evaluate", lambda s: "generate" if s.retry < 2 else "finish")
graph.set_entry_point("generate")
graph.set_finish_point("evaluate")
app = graph.compile()
app.invoke({"question": "LangGraph๋?"})
์ด๋ ๊ฒ ํ๋ฉด LLM์ ๋ต๋ณ ํ์ง์ด ๋ถ์กฑํ๋ฉด ์๋์ผ๋ก ๋ค์ ์์ฑํฉ๋๋ค.
์ฆ, โ์๊ฐ ํ๊ฐ + ์์ ๋ฃจํโ๊ฐ ๋ง๋ค์ด์ง ๊ฑฐ์ฃ .
LangGraph์์ ์ํ ๊ด๋ฆฌ๋ ๋ค์ ์ธ ๊ฐ์ง ํจํด์ผ๋ก ๋ฐ์ ํฉ๋๋ค.
| ํจํด | ์ค๋ช | ์์ |
|---|---|---|
| ๋จ์ ์ํ(StateGraph) | ๊ฐ ๋ ธ๋ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ก ์ฐ๊ฒฐ | โ์ ๋ ฅ โ ๋ต๋ณ โ ์ข ๋ฃโ |
| Reducer ๋์ ํ | ์ํ๋ฅผ ๊ณ์ ๋ณํฉ | โ๋ํ ๊ธฐ๋ก ๋์ โ |
| Feedback ๋ฃจํํ | ํ๊ฐ โ ์ฌ์คํ ๊ตฌ์กฐ | โ์๊ฐ ์์ ์์ด์ ํธโ |
์ด ์ธ ๊ฐ์ง๋ฅผ ์กฐํฉํ๋ฉด โ๊ธฐ์ตํ๊ณ , ํ๋จํ๋ฉฐ, ์์ ํ๋โ LLM์ ๋ง๋ค ์ ์์ต๋๋ค.

์ด ๊ตฌ์กฐ๊ฐ ReAct ์์ด์ ํธ ์ค๊ณ์ ์ ์ด ๋จ๊ณ๊ฐ ๋ฉ๋๋ค.
๋ค์ ํ์ฐจ์์ ์ค์ โThink โ Act โ Observeโ ๊ตฌ์กฐ๋ก ๋ฐ์ ์ํต๋๋ค.
๐ 4ํธ: LangGraph์ Tool์ ์ฐ๊ฒฐ โ LLM์ด ๋๊ตฌ๋ฅผ ์ง์ ํธ์ถํ๋ ๊ทธ๋ํ
๋ค์ ํธ์์๋ LLM์ด ์ธ๋ถ API(์: ๋ ์จ, ๋ด์ค, DB ์ฟผ๋ฆฌ ๋ฑ)๋ฅผ ์ง์ ํธ์ถํ ์ ์๊ฒ ๋ง๋๋ ToolNode + Runnable ๊ตฌ์กฐ๋ฅผ ๋ค๋ฃน๋๋ค.
| ์ฃผ์ | ํ์ต ์ด์ | ์ถ์ฒ ํ์ต ๋ฐฉํฅ |
|---|---|---|
| Functional Programming | Reducer์ ์ํ ๋์ ์๋ฆฌ ์ดํด | reduce, map, lambda ํจํด ์ฐ์ต |
| Event-Driven Architecture | Feedback ๋ฃจํ๋ฅผ ์์คํ ์ ์ผ๋ก ํ์ฅ | ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ ๋ชจ๋ธ |
| LangGraph Memory Internals | LangGraph์ ๋ฉ์์ง/๋ฉ๋ชจ๋ฆฌ ๋ด๋ถ ๊ตฌ์กฐ ์ดํด | MessageGraph ๋ด๋ถ ์ํ ์ถ์ ์ฝ๋ ๋ถ์ |
| LLM ํ๊ฐ ๋ฃจํ ์ค๊ณ(Self-RAG) | LLM์ด ์ค์ค๋ก ๋ต๋ณ ํ๊ฐ ๋ฐ ์์ | ํ๊ฐ-์ฌ์์ฑ-๊ฒ์ฆ ํจํด ๊ตฌํ |
| LangGraph Callback & Logging | ์ํ ๋ณํ ์ถ์ ๋ฐ ๋ก๊น | graph.callbacks, state diff ๋ก๊น
|
| Reinforcement-style Feedback | ์ ์ ๊ธฐ๋ฐ ํ์ตํ ๋ฃจํ ์ค๊ณ | ๋ณด์ ์ค์ฝ์ด, ๋ฃจํ ์ ์ด ํจ์ ์์ฑ |
- LangGraph๋ ์ํ ์ค์ฌ ์ค๊ณ๋ฅผ ํตํด ๋ํ๋ฅผ ์ง์์ํจ๋ค.
- Reducer๋ ์ํ๋ฅผ ๋ณํฉํ๊ณ , MessageGraph๋ ๋ํ ๋งฅ๋ฝ์ ๋ณด์กดํ๋ค.
- Feedback ๋ฃจํ๋ฅผ ํตํด ์๊ฐ ํ๊ฐํ ๊ทธ๋ํ๊ฐ ๋๋ค.
๐ฌ ์ฆ, โ์ง๋ฌธ-์๋ต ๊ทธ๋ํโ์์ โํ์ตํ ์์ด์ ํธ ๊ทธ๋ํโ๋ก ์งํํ ๊ฒ์ด๋ค.