20240420

LangGraph 초기 도입 실험

LangChain의 자매 라이브러리 LangGraph가 올해 초 나왔다. 이름은 거창한데 결국 상태 머신 위에 LLM 노드를 배치하는 프레임워크.

기존 LangChain agent가 AgentExecutor로 루프 도는 방식이었는데 분기/조건/재시도 다루기가 지저분했다. LangGraph는 명시적 그래프라 디버깅이 훨씬 낫다.

기본 구조

from langgraph.graph import StateGraph, END

class State(TypedDict):
    question: str
    docs: list
    answer: str
    attempts: int

def retrieve(state): ...
def grade(state): ...   # retrieval 품질 판정
def generate(state): ...
def rewrite(state): ... # 질의 재작성

g = StateGraph(State)
g.add_node("retrieve", retrieve)
g.add_node("grade", grade)
g.add_node("generate", generate)
g.add_node("rewrite", rewrite)

g.set_entry_point("retrieve")
g.add_edge("retrieve", "grade")
g.add_conditional_edges("grade",
    lambda s: "generate" if s["docs"] else "rewrite",
    {"generate":"generate", "rewrite":"rewrite"})
g.add_edge("rewrite", "retrieve")
g.add_edge("generate", END)
app = g.compile()

써본 소감

좋은 점: 노드별 로그가 자연스럽게 쌓임. LangSmith에 꽂으면 각 노드 입출력이 전부 trace. 디버깅 훨씬 쉬움.

애매한 점: TypedDict로 state가 정의되는데 중첩 구조 관리가 살짝 피곤. Pydantic 쓰려다가 호환 이슈로 도로 Typeddict.

주의할 점: 조건부 엣지에서 무한 루프 쉽게 남. 우리 첫 버전은 rewrite → retrieve → grade → rewrite ... 이 순환에 20턴 돌다가 terminate됨. 그래서 state에 attempts를 두고 3회 초과 시 END로 강제.

CrewAI는?

같은 시기에 나온 CrewAI도 살짝 봤는데, "역할 기반 agent들의 협업"에 더 초점. 우리 케이스는 분기/상태가 명확한 파이프라인이라 LangGraph가 맞았다.

1년 뒤쯤엔 agent framework 시장이 또 갈릴 것 같다. 지금은 일단 LangGraph로 베팅.

댓글 없음: