8️⃣LangChain LCEL vs. LangGraph

LangChain LCEL

LanngChain에서 제공하는 LangChain Expression Language(LCEL)은 기본적으로 복잡한 Chain을 쉽게 구성하고 관리하기 위한 도구입니다. 즉, LangChain 구성 요소의 체인을 구축할 수 있도록 하는 형식입니다.

  1. LangChain의 주기능인 Expression Chain을 개발하기 위한 목적

  2. Streaming(스트리밍), Async(비동기), Parallel execution(병렬 실행) 등과 같은 고급 기능을 제공

  3. LangSmith 및 LangServe와의 손쉬운 통합 활용

LangGraph

LangGraph는 LangChain을 사용하여 사용자 정의 Agents를 쉽게 구축하고 단순한 체인 이상의 것을 구축하기 위한 라이브러리 입니다. LangGraph는 제품에서 다이어그램 화할 수 있다면 엔지니어링에서도 정확하게 만들 수 있다는 아이디어를 기반으로 간단한 Graph로의 접근 방식을 사용합니다.

에이전트 워크플로를 순환 그래프 구조로 취급하며, 각 노드는 함수 또는 Langchain 실행 가능한 객체를 나타내고 에지는 노드 간의 연결입니다.

LangGraph의 주요 기능은 다음과 같습니다.

  • Nodes: 도구와 같은 모든 함수 또는 Langchain 실행 가능한 객체(Runnable Object).

  • Edge: 노드 사이의 방향을 정의합니다.

  • Stateful Graph: 그래프의 기본 유형입니다. 노드를 통해 데이터를 처리할 때 상태 객체를 관리하고 업데이트하도록 설계되었습니다.

LCEL과 LangGraph 차이점

여러 에이전트 간의 조정을 통해 Multi-agent 시스템을 만드는 것이 목표라면 LangGraph를 사용하는 것이 좋습니다. 그러나 작업을 완료하기 위해 DAGs 또는 Chain을 생성하려는 경우에는 LangChain LCEL 사용이 가장 적합합니다.

LCEL vs LangGraph: PDF 문서 RAG 비교

  1. LangChain LCEL

  2. LangGraph

Setup Environments

from langchain.schema import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import PyPDFLoader

from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma

from langchain_core.runnables import RunnablePassthrough 
from langchain_core.output_parsers import StrOutputParser 
from langchain_core.prompts import ChatPromptTemplate
import os
from dotenv import load_dotenv  

!echo "<OPENAI_API_KEY=<Your OpenAPI Key>" >> .env # OpenAPI Key 기재
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")

Dataset

!mkdir dataset
!wget https://www.dasomks.org/jml/attachments/article/1230/20_Jung_Keup_Listening_Script.pdf -O dataset/koreanchat.pdf
mkdir: cannot create directory ‘dataset’: File exists
--2024-06-07 13:46:40--  https://www.dasomks.org/jml/attachments/article/1230/20_Jung_Keup_Listening_Script.pdf
Resolving www.dasomks.org (www.dasomks.org)... 50.87.235.106
Connecting to www.dasomks.org (www.dasomks.org)|50.87.235.106|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 221677 (216K) [application/pdf]
Saving to: ‘dataset/koreanchat.pdf’

dataset/koreanchat. 100%[===================>] 216.48K   452KB/s    in 0.5s    

2024-06-07 13:46:41 (452 KB/s) - ‘dataset/koreanchat.pdf’ saved [221677/221677]

Loader, Embedding, Retrieval

# pdf document 불러오기
document = PyPDFLoader('dataset/koreanchat.pdf')
document = loader.load()
#document[0].page_content[:100]

# Text spliter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
docs = text_splitter.split_documents(document)

# embedding
embeddings = OpenAIEmbeddings()

# ChromaDB Reriever
vectors = Chroma.from_documents(docs, embeddings)
retriever = vectors.as_retriever()

1. LangChain LCEL

template ="""Answer the question in korean based only on the following context:{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()
retrieval_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    |prompt 
    |model 
    |StrOutputParser()
)
retrieval_chain.invoke(input="시험 문제는 몇 문제가 있어?")
'context에 따라 시험 문제의 수는 다를 수 있습니다.'

2. LangGraph

from typing import TypedDict 
from langchain_core.messages import BaseMessage 

chain_with_prompt = prompt | model | StrOutputParser()
class AgentState(TypedDict):
    question: str
    raw_docs: list[BaseMessage]
    formatted_docs: list[str]
    generation: str
def get_docs(state: AgentState):
    print ("get_docs:", state)
    question = state[ "question"]
    docs = retriever.invoke(question)
    state["raw_docs"] = docs
    return state

def format_docs(state: AgentState):
    print ("format_docs:", state)
    documents = state["raw_docs"]
    state["'formatted _docs"] = "In\n".join(doc.page_content for doc in documents)
    return state

def generate (state:AgentState):
    print("generate:", state)
    question = state["question"]
    formatted_docs = state["formatted_docs"]
    result = chain_with_prompt.invoke({"question": question, "context": formatted_docs})
    state["generation"] =result
    return state
from langgraph.graph import StateGraph, END

workflow = StateGraph(AgentState)
workflow.add_node("get_docs", get_docs) 
workflow.add_node("format_docs", format_docs) 
workflow.add_node("generate", generate)

workflow.add_edge("get_docs", "format_docs")
workflow.add_edge("format_docs", "generate")
workflow.add_edge("generate", END)
workflow.set_entry_point("get_docs")

app = workflow.compile()
from IPython.display import Image, display
try:
    display(Image(app.get_graph(xray=True).draw_mermaid_png()))
except:
    pass

result = app.invoke({"question": "시험 문제는 몇 문제가 있어?"})
get_docs: {'question': '시험 문제는 몇 문제가 있어?', 'raw_docs': None, 'formatted_docs': None, 'generation': None}
format_docs: {'question': '시험 문제는 몇 문제가 있어?', 'raw_docs': [Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'}), Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'}), Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'}), Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'})], 'formatted_docs': None, 'generation': None}
generate: {'question': '시험 문제는 몇 문제가 있어?', 'raw_docs': [Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'}), Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'}), Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'}), Document(page_content='제 20 회 한국어능력시험\n 6 17. (4 점 )\n남자 : 신문을  보니까 명절이  다 가오 는데도 시 장에 손님이  별로 없대 요. \n경제가 어렵다 고  하니까 다 들 돈을  아끼나 봐요.\n여 자 : 당연하죠. 워낙 어렵다 고 들 하니까요. 저도 장을  보러 가면 살까 말 까  \n몇  번 을  망설이 게 되더라고 요. \n남자 : 과 소비도 문제지만 무 조건 절약하는 것도 좋은  것만은  아니에요. \n적당한  소비가 이 루어져야 생산이  늘 것이 고  그 래야 경제도 좋아\n지지 않겠어요?\n※ [ 1 8 ~ 2 0 ] 다 음  대 화 를  듣 고  여 자 가  할  행 동 으 로  알 맞 은  것 을  고 르 십 시 오 .\n( 각  3 점 )\n18 . 남자 : 수 미야,  학교 홍보 모델 뽑는다 는 공고  봤어?  조건을  보니까 딱 네가  \n하면 좋을  것 같더라. \n여자 : 홍보 모델 ? 해 보고  싶기는 한 데 내 가 할 수  있 을 까?\n남 자 : 학 과 사무 실 앞에 공고 가 붙어 있 으니까 가서 한 번 확인 해 봐. 지원서를  \n작성해서 내 면 되는 것 같던데…….\n여자 : 알 았어. 그 렇게 할게.\n1 9 . 남 자 :  어 서  오십시오.  무엇을 도 와  드 릴 까 요 ?\n여자 : 회원 카드를 하나 만들고  싶은 데 여기서 신청해야 된다 고  해서요.\n남자 :  아,  회원 카드요? 우선 번호표를 뽑으시 고 ,  앉아서 기다 리세요. 여자 :  신청서 같은  건 안 써도 돼요?\n남자 :  그 건 이 따가 상담 창구에 가셔서 쓰시 면 돼요.', metadata={'page': 5, 'source': 'dataset/koreanchat.pdf'})], 'formatted_docs': None, 'generation': None}
result["generation"]
'Context: 시험 문제는 총 30문제가 있습니다.\n\nAnswer: 시험 문제는 30문제가 있어요.'

Conclusion

  1. 생성 응답을 보면 LangGraph가 더 정확합니다. 이는 Nodes, Edges, States에 의한 유연성으로 더 많은 출력으로 State에서 연결해주면 됩니다.

  2. LCEL은 응답의 정확도를 위하여 몇 차례의 디버깅이 요구됩니다.

  3. 결론적으로 모듈화된 LangGraph의 Nodes 자체가 Agent나 함수로 사용 가능합니다.

  4. Chain을 구성하고자 하면 LCEL을 Agent를 함수로 사용하여 연결하고 하면 LangGraph가 유용합니다.

  5. 단, LCEL의 Chain이 속도가 더 빠르며, LangGraph의 Agent는 상대적으로 속도가 느립니다.

Last updated