โChain์ ํ๋ฆ์ ์ฐ๊ฒฐํ๋ค. ํ์ง๋ง ํ๋ฆ์ ์ ์ดํ๋ ค๋ฉด ๊ทธ๋ํ๊ฐ ํ์ํ๋ค.โ
์์ ๋ ํธ์์ ์ฐ๋ฆฌ๋ LangChain์ ํตํด LLM์ ์ค์ผ์คํธ๋ ์ด์ (Orchestration) ํ๊ณ , Chain โ Memory โ Agent ๊ตฌ์กฐ๋ก ๋ฐ์ ์์ผฐ์ต๋๋ค.
ํ์ง๋ง ์ค์ ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด ์ด๋ฐ ํ๊ณ๊ฐ ์๊น๋๋ค ๐
์ด์ LangChain์ ๋ด๋ถ ์์ง LCEL (LangChain Expression Language) ์ ํตํด ๊ตฌ์กฐ๋ฅผ ์ดํดํ๊ณ , LangGraph๊ฐ ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
LangChain์ ๋ด๋ถ์ ์ผ๋ก LCEL์ด๋ผ๋ ํํ ์ธ์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
LCEL์ Chain, Tool, Agent ๋ฑ ๋ชจ๋ ์คํ ๋จ์๋ฅผ ํ๋์ โRunnableโ๋ก ๋ค๋ฃน๋๋ค.
LCEL = LangChain Execution Language
์ฆ, LLM ์ํฌํ๋ก์ฐ์ โํํ์โ์ ์ฝ๋๋ก ์ ์ํ๋ ์ธ์ด์ ๋๋ค.
from langchain_openai import ChatOpenAI
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda, RunnableBranch
llm = ChatOpenAI(model="gpt-4o-mini")
def is_weather_query(x):
return "๋ ์จ" in x["query"]
# RunnableBranch = ์กฐ๊ฑด ๋ถ๊ธฐ
branch = RunnableBranch(
(is_weather_query, llm.bind()),
(lambda x: True, RunnablePassthrough())
)
result = branch.invoke({"query": "์ค๋ ๋ ์จ ์๋ ค์ค"})
print(result)
๐ ๋์ ์์ฝ

์ด๋ ๊ฒ LCEL์ ํตํด ์กฐ๊ฑด ๋ถ๊ธฐ ์ ๋๋ ํํํ ์ ์์ต๋๋ค.
ํ์ง๋งโฆ
LCEL์ ๋ฐ์ด๋ ์คํ ์์ง์ด์ง๋ง, โ๋ณต์กํ ์ํฌํ๋ก์ฐ ์ค๊ณโ์๋ ํ๊ณ๊ฐ ์์ต๋๋ค.
| ๋ฌธ์ | ์ค๋ช | ์ค์ ์์ |
|---|---|---|
| ๋ณต์กํ ๋ถ๊ธฐ ์ ์ด | ๋ถ๊ธฐ ์กฐ๊ฑด์ด ๋์ด๋ ์๋ก ์ฝ๋ ๊ฐ๋ ์ฑ ํ๋ฝ | if/else๊ฐ ์ค์ฒฉ๋จ |
| ์ํ ์ถ์ ์ ๋ชจํธ์ฑ | Memory ์ธ์ ๋ณ๋ ์ํ(State) ํํ ๋ถ๊ฐ | ๋ํ + ๊ฒ์ + ํ๊ฐ ๋ฑ ๋ณตํฉ ์ํ ๊ด๋ฆฌ ๋ถ๊ฐ |
| ๋ฃจํ/๋ฐ๋ณต ์ ์ฝ | ์ฌ๊ท์ ํธ์ถ ์ธ์ ๋ฃจํ ๊ตฌํ ์ด๋ ค์ | ํผ๋๋ฐฑ ๋ฃจํ๋ ์ฌ์๋ ๊ตฌ์กฐ ํ๊ณ |
| ์๊ฐํ ๋ถ์ฌ | ์คํ ๊ทธ๋ํ ๊ตฌ์กฐ๋ฅผ ๋์ผ๋ก ๋ณด๊ธฐ ์ด๋ ค์ | ๋๋ฒ๊น ์ ์ด๋ ค์ |
| ๋ํ ์์คํ ํ์ฅ์ฑ ๋ถ์กฑ | ์ฒด์ธ ๊ฐ ์ฐ๊ฒฐ์ด ํ๋์ฝ๋ฉ๋จ | ์ ์ง๋ณด์ ๋น์ฉ ๊ธ์ฆ |
LangChain์ผ๋ก RAG ์์คํ ์ ๊ตฌ์ฑํ๋ค๊ณ ํด๋ด ์๋ค.
Query โ Retriever โ LLM โ Evaluator โ (์ฌ๊ฒ์ or ์ข
๋ฃ)
์ด ๊ณผ์ ์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ฃจํ์ํค๋ ค๋ฉด RunnableBranch์ if ์กฐ๊ฑด์ ๋ฐ๋ณต ์ ์ํด์ผ ํฉ๋๋ค.
# ๊ฐ๋จํ ํํํ๋ฉด ์ด๋ฐ ๊ตฌ์กฐ
while True:
answer = llm.invoke(query)
score = evaluator.invoke(answer)
if score > 0.8:
break
else:
query = retriever.invoke(query)
์ด๊ฑด ๊ฒฐ๊ตญ ๋ช ๋ นํ ๋ฃจํ์ ๋ถ๊ณผํ๋ฉฐ, LangChain์ ์ด ๋ฃจํ๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ํํํ ์ ์์ต๋๋ค.
์ฆ, โ์คํ ํ๋ฆ(Flow)โ์ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ค๊ณํ๊ณ ์๊ฐํํ ๋ฐฉ๋ฒ์ด ์๋ค๋ ๊ฒ์ด์ฃ .
์ด ํ๊ณ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด LangGraph๊ฐ ํ์ํ์ต๋๋ค.
LangGraph๋ LangChain์ LCEL ์์ง ์์ ๊ตฌ์ถ๋ ๊ทธ๋ํ ๊ธฐ๋ฐ ์ํฌํ๋ก์ฐ ํ๋ ์์ํฌ์
๋๋ค.
| ํญ๋ชฉ | LangChain | LangGraph |
|---|---|---|
| ํต์ฌ ๋จ์ | Runnable, Chain | Node, Edge, StateGraph |
| ํ๋ฆ ๊ตฌ์กฐ | ์ ํ(Sequential) | ๊ทธ๋ํ(Graph) |
| ์ํ ๊ด๋ฆฌ | Memory ์ค์ฌ | Reducer ๊ธฐ๋ฐ ๋ช ์์ State |
| ๋ฃจํ/๋ถ๊ธฐ | ์ ํ์ | Edge ์กฐ๊ฑด์ผ๋ก ์์ฐ์ค๋ฌ์ด ํํ |
| ์๊ฐํ | ์ด๋ ค์ | Mermaid, Gradio ๋ฑ์ผ๋ก ๊ทธ๋ํ ์๊ฐํ ๊ฐ๋ฅ |


LangGraph๋ ๋ฐ๋ก ์ด โํ๋ฆ ์ ์ด์ ์ถ์ํโ๋ฅผ ๋ด๋นํฉ๋๋ค.
| ์ฌ๊ณ ๋ฐฉ์ | ์ค๋ช |
|---|---|
| Chain ์ค์ฌ ์ฌ๊ณ | โLLM์ ์์๋๋ก ์คํํ์.โ |
| Graph ์ค์ฌ ์ฌ๊ณ | โLLM์ด ์ด๋ ์ํ์์ ์ด๋ค ๋ ธ๋๋ฅผ ๊ฑฐ์ณ์ผ ํ ๊น?โ |
LangGraph์์๋ ๋ ์ด์ if/else, loop ๊ฐ์ ๋ช
๋ นํ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ์ง ์์ต๋๋ค.
๋์ Node(๋์) ์ Edge(์กฐ๊ฑด) ๋ก ํ๋ฆ์ ์ ์ธ์ ์ผ๋ก ์ ์ํฉ๋๋ค.
from langgraph.graph import StateGraph
from langchain_openai import ChatOpenAI
# ์ํ ์ ์
class GraphState:
question: str
answer: str
# ๋
ธ๋ ์ ์
def ask_llm(state: GraphState):
llm = ChatOpenAI(model="gpt-4o-mini")
response = llm.invoke(f"Q: {state.question}\nA:")
state.answer = response.content
return state
# ๊ทธ๋ํ ์์ฑ
graph = StateGraph(GraphState)
graph.add_node("ask_llm", ask_llm)
graph.set_entry_point("ask_llm")
graph.set_finish_point("ask_llm")
app = graph.compile()
result = app.invoke({"question": "LangGraph๋ ๋ฌด์์ธ๊ฐ?"})
print(result["answer"])
์ด์ ์คํ ํ๋ฆ์ โํจ์ ํธ์ถโ์ด ์๋๋ผ โ๊ทธ๋ํ ํ์โ์ผ๋ก ์ ์ด๋ฉ๋๋ค.
| ๋ฌธ์ ์ํฉ | LangChain ํ๊ณ | LangGraph์ ํด๊ฒฐ ๋ฐฉ์ |
|---|---|---|
| ๋ณต์กํ ์กฐ๊ฑด ๋ถ๊ธฐ | RunnableBranch ํ์ | Edge ์กฐ๊ฑด์ผ๋ก ์ ์ธ์ ํํ |
| ๋ฃจํ/์ฌ์๋ | ์ฌ๊ท ์ฝ๋ ํ์ | Edge ๋ฃจํ ๊ตฌ์กฐ๋ก ์์ฐ์ค๋ฌ์ด ๋ฐ๋ณต |
| ์ํ ๊ด๋ฆฌ | ๋จ์ผ Memory ๊ฐ์ฒด | Reducer ๊ธฐ๋ฐ State ํธ๋ํน |
| ๋ณ๋ ฌ ์คํ | RunnableParallel๋ก ์ ํ | ์ฌ๋ฌ Node ๋ณ๋ ฌ ์คํ ์ง์ |
| ๋๋ฒ๊น /์๊ฐํ | ์ด๋ ค์ | MermaidยทGradio ์๊ฐํ ๊ฐ๋ฅ |
LangChain์ด โ๊ธฐ๋ฅ ์ค์ฌโ์ด๋ผ๋ฉด, LangGraph๋ โํ๋ฆ ์ค์ฌโ์ ๋๋ค.
| ๊ตฌ๋ถ | LangChain | LangGraph |
|---|---|---|
| ์ฒ ํ | ๊ธฐ๋ฅ์ ์กฐํฉํ๋ค | ํ๋ฆ์ ์ค๊ณํ๋ค |
| ๋จ์ | Chain | Node + Edge |
| ์ฌ๊ณ ๋ฐฉ์ | ์ ์ฐจ์ | ์ ์ธ์ |
| ์ด์ | Prompt / Tool | ์ํ / ๊ฒฝ๋ก / ์กฐ๊ฑด |
| ๊ฒฐ๊ณผ๋ฌผ | LLM ์ฒด์ธ | LLM ์์คํ |
LangChain์ ์ฌ์ ํ LangGraph์ ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ฉ๋๋ฉฐ, LangGraph๋ ๊ทธ ์์์ LLM ์์คํ ์ค๊ณ์ ์ฐจ์์ ๋์ด์ฌ๋ฆฝ๋๋ค.
| ์ฃผ์ | ํ์ต ์ด์ | ์ถ์ฒ ๋ฐฉํฅ |
|---|---|---|
| LCEL ๊ตฌ์กฐ | LangGraph์ ๋ฐํ์ ๊ธฐ๋ฐ | Runnable, RunnableBranch ์ค์ต |
| Reducer ํจํด | ์ํ ๋์ ๋ฐฉ์ ์ดํด | Python ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๋ณต์ต |
| Async Flow ์ ์ด | ๋น๋๊ธฐ ๋ ธ๋ ์ฒ๋ฆฌ ํ์ต | asyncio, gather ํ์ฉ |
| Graph Visualization | ์๊ฐ์ ๋๋ฒ๊น ์ตํ๊ธฐ | Mermaid, Gradio ์ค์ต |
| LangServe / MCP | LangGraph ๋ฐฐํฌ์ ์๋น์คํ | LangServe ๋ฌธ์ ์ค์ต |
| ํญ๋ชฉ | ์์ฝ |
|---|---|
| ํต์ฌ ๊ฐ๋ | LCEL์ ์คํ ์์ง, LangGraph๋ ๊ตฌ์กฐ ์ค๊ณ ์์ง |
| ํต์ฌ ์ฝ๋ | RunnableBranch ์์, StateGraph ์์ |
| ํต์ฌ ์ธ์ฌ์ดํธ | โChain์ ํ๊ณ๋ฅผ ๋์ ๊ทธ๋ํ ๊ธฐ๋ฐ ์ ์ดโ |
| ๋ค์ ํธ ์๊ณ | ๐ LangGraph ์์ ์ ๋ณต โ โ LangGraph๋ ๋ฌด์์ธ๊ฐ |
LangChain์ โLLM์ ์คํํ๋ ๋ฒโ์ ์๋ ค์ค๋ค.
LangGraph๋ โLLM์ด ์ด๋ป๊ฒ ์ฌ๊ณ ํ๊ณ ํ๋ฆ์ ์ ์ดํ ์งโ๋ฅผ ์ค๊ณํ๊ฒ ํ๋ค.