LangChain LCEL vs. LangGraph
LangChain LCEL
LanngChain에서 제공하는 LangChain Expression Language(LCEL)은 기본적으로 복잡한 Chain을 쉽게 구성하고 관리하기 위한 도구입니다. 즉, LangChain 구성 요소의 체인을 구축할 수 있도록 하는 형식입니다.
LangChain의 주기능인 Expression Chain을 개발하기 위한 목적
Streaming(스트리밍), Async(비동기), Parallel execution(병렬 실행) 등과 같은 고급 기능을 제공
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 비교
LangChain LCEL
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
생성 응답을 보면 LangGraph가 더 정확합니다. 이는 Nodes, Edges, States에 의한 유연성으로 더 많은 출력으로 State에서 연결해주면 됩니다.
LCEL은 응답의 정확도를 위하여 몇 차례의 디버깅이 요구됩니다.
결론적으로 모듈화된 LangGraph의 Nodes 자체가 Agent나 함수로 사용 가능합니다.
Chain을 구성하고자 하면 LCEL을 Agent를 함수로 사용하여 연결하고 하면 LangGraph가 유용합니다.
단, LCEL의 Chain이 속도가 더 빠르며, LangGraph의 Agent는 상대적으로 속도가 느립니다.
Last updated