목차
LLM LangChain 개발 가이드
서론
최근 대규모 언어 모델(LLM)의 발전은 인공지능 분야에 혁신을 가져왔습니다. 하지만 LLM을 실제 애플리케이션에 통합하고 복잡한 작업을 수행하도록 만드는 것은 여전히 도전적인 과제입니다. LangChain은 이러한 LLM 기반 애플리케이션 개발을 효율적이고 모듈화하여 수행할 수 있도록 돕는 강력한 프레임워크입니다. 이 가이드는 LangChain의 기본 개념부터 고급 활용법까지 다루며, LLM 개발자들이 더욱 쉽게 강력한 애플리케이션을 구축할 수 있도록 돕기 위해 작성되었습니다.
1. LangChain 개요
LangChain은 LLM을 기반으로 하는 애플리케이션을 개발하기 위한 프레임워크입니다. LLM의 추론 능력과 외부 데이터, 도구를 결합하여 복잡한 워크플로우를 구성할 수 있도록 지원합니다.
1) LangChain이란?
LangChain은 LLM을 활용한 애플리케이션 개발을 위한 도구 모음입니다. 다음은 LangChain의 주요 특징입니다.
- 모듈화된 구성 요소: LLM, 프롬프트, 체인, 에이전트, 도구, 메모리 등 다양한 구성 요소를 제공하여 개발자가 각 부분을 독립적으로 구축하고 조합할 수 있습니다.
- 쉬운 통합: 다양한 LLM 제공자(OpenAI, Anthropic 등), 벡터 데이터베이스, 외부 API 등과 쉽게 통합할 수 있습니다.
- 재사용성: 한 번 정의된 체인이나 도구는 다른 애플리케이션에서 쉽게 재사용할 수 있습니다.
- 유연성: 단순한 Q&A 봇부터 복잡한 에이전트 기반 시스템까지 다양한 애플리케이션을 구축할 수 있습니다.
2) LangChain의 필요성
LLM을 직접 사용하는 경우 다음과 같은 한계에 부딪힐 수 있습니다.
- 지식 부족: LLM은 학습 데이터 이후의 최신 정보나 특정 도메인 지식을 알지 못합니다.
- 외부 도구 사용 불가: LLM은 자체적으로 웹 검색, 계산, 데이터베이스 조회 등의 외부 작업을 수행할 수 없습니다.
- 대화 기록 관리의 어려움: 복잡한 대화에서 이전 대화 내용을 기억하고 활용하기 어렵습니다.
- 복잡한 워크플로우 구성: 여러 단계를 거쳐야 하는 복잡한 작업을 LLM만으로 처리하기 어렵습니다.
LangChain은 이러한 문제들을 해결하여 LLM의 잠재력을 최대한 활용할 수 있도록 돕습니다.
2. LangChain 설치 및 기본 설정
LangChain을 사용하기 위한 기본적인 설치 및 환경 설정 방법을 설명합니다.
1) 설치 방법
LangChain은 Python 패키지로 제공되므로 pip
를 사용하여 쉽게 설치할 수 있습니다.
pip install langchain langchain-openai
langchain
: LangChain의 핵심 프레임워크입니다.langchain-openai
: OpenAI 모델을 사용하기 위한 통합 패키지입니다. 다른 LLM 제공자를 사용하려면 해당 패키지를 추가로 설치해야 합니다 (예:langchain-anthropic
).
2) API 키 설정
LLM 제공자(예: OpenAI)의 API를 사용하려면 API 키를 설정해야 합니다. 보안을 위해 환경 변수로 설정하는 것을 권장합니다.
import os os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"
또는 python-dotenv
라이브러리를 사용하여
.env
파일에서 환경 변수를 로드할 수 있습니다.
- 프로젝트 루트에
.env
파일 생성:
<file> OPENAI_API_KEY="YOUR_OPENAI_API_KEY" </file>
- Python 코드에서 로드:
<file> from dotenv import load_dotenv load_dotenv() # .env 파일에서 환경 변수를 로드합니다.
import os api_key = os.getenv("OPENAI_API_KEY") print(f"API Key: {api_key}") </file>
3. LangChain 핵심 구성 요소
LangChain은 여러 핵심 구성 요소로 이루어져 있으며, 이들을 조합하여 다양한 LLM 애플리케이션을 구축할 수 있습니다.
1) LLM / Chat Models
LangChain의 가장 기본적인 구성 요소는 LLM 자체입니다.
- LLM: 텍스트를 입력받아 텍스트를 생성하는 모델 (예:
text-davinci-003
).
- Chat Models: 대화 형식의 입력을 받고 대화 형식의 출력을 생성하는 모델 (예:
gpt-3.5-turbo
,
gpt-4
).
이들의 주요 차이점은 입출력 형식입니다. Chat Models는 HumanMessage
,
AIMessage
,
SystemMessage
와 같은 메시지 객체 리스트를 사용합니다.
from langchain_openai import OpenAI, ChatOpenAI from langchain_core.messages import HumanMessage # LLM 사용 예시 llm = OpenAI(model="gpt-3.5-turbo-instruct", temperature=0.7) response_llm = llm.invoke("안녕, 나를 소개해줘.") print(f"LLM 응답: {response_llm}") # Chat Model 사용 예시 chat_model = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7) messages = [HumanMessage(content="안녕, 나를 소개해줘.")] response_chat = chat_model.invoke(messages) print(f"Chat Model 응답: {response_chat.content}")
2) Prompts
LLM에 전달되는 입력 텍스트(프롬프트)를 효과적으로 관리하고 생성하는 데 사용됩니다.
PromptTemplate
: 문자열 기반의 프롬프트 템플릿을 정의합니다. 변수를 사용하여 동적으로 프롬프트를 생성할 수 있습니다.ChatPromptTemplate
: Chat Model을 위한 메시지 기반 프롬프트 템플릿을 정의합니다. 시스템, 사용자, AI 메시지 등을 조합할 수 있습니다.
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate from langchain_core.messages import HumanMessage, SystemMessage # PromptTemplate 예시 prompt_template = PromptTemplate.from_template( "다음 질문에 대해 {topic} 관점에서 답변해줘: {question}" ) formatted_prompt = prompt_template.format(topic="과학", question="중력이란 무엇인가?") print(f"Formatted Prompt: {formatted_prompt}") # ChatPromptTemplate 예시 chat_template = ChatPromptTemplate.from_messages( [ ("system", "너는 친절하고 유용한 AI 비서야."), ("human", "안녕하세요, 저는 {name}입니다. {query}에 대해 알려주세요."), ] ) formatted_chat_prompt = chat_template.format_messages(name="김철수", query="LangChain") print(f"Formatted Chat Prompt: {formatted_chat_prompt}")
3) Chains
여러 LLM 호출과 다른 구성 요소(프롬프트, 파서 등)를 연결하여 복잡한 작업을 수행하는 워크플로우를 정의합니다.
LLMChain
: 가장 기본적인 체인으로, 프롬프트 템플릿과 LLM을 연결합니다.SequentialChain
: 여러 체인을 순차적으로 연결하여 각 단계의 출력이 다음 단계의 입력이 되도록 합니다.RouterChain
: 입력에 따라 다른 체인으로 라우팅합니다.- LCEL (LangChain Expression Language): 체인을 구성하는 가장 강력하고 유연한 방법입니다. 파이프 (
|
) 연산자를 사용하여 구성 요소를 연결합니다.
from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # LCEL을 사용한 간단한 체인 model = ChatOpenAI(model="gpt-3.5-turbo") prompt = ChatPromptTemplate.from_template("다음 주제에 대해 간략하게 설명해줘: {topic}") output_parser = StrOutputParser() chain = prompt | model | output_parser response = chain.invoke({"topic": "인공지능"}) print(f"Chain 응답: {response}")
4) Agents & Tools
에이전트는 LLM이 어떤 Tool
을 사용해야 할지 스스로 결정하고, 여러 번의 실행을 통해 목표를 달성하도록 하는 구성 요소입니다.
Tool
: LLM이 상호작용할 수 있는 특정 기능(예: 웹 검색, 계산기, 코드 실행 등)을 캡슐화한 것입니다.AgentExecutor
: 에이전트의 핵심 로직을 실행하며, LLM, 도구 목록, 그리고 에이전트 유형을 조합하여 작동합니다.
from langchain_openai import ChatOpenAI from langchain import hub from langchain.agents import AgentExecutor, create_react_agent, load_tools # 도구 로드 (예: SerpAPI를 사용한 웹 검색, 수학 계산) # 실제 사용 시 SerpAPI_API_KEY 환경 변수가 필요합니다. # pip install google-search-results tools = load_tools(["serpapi", "llm-math"], llm=ChatOpenAI(temperature=0)) # ReAct 에이전트 프롬프트 허브에서 가져오기 prompt = hub.pull("hwchase17/react") # 에이전트 생성 llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo") agent = create_react_agent(llm, tools, prompt) # AgentExecutor 생성 및 실행 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True) response = agent_executor.invoke({"input": "대한민국의 현재 대통령은 누구이며, 그 사람의 취미는 무엇인가?"}) print(f"Agent 응답: {response['output']}")
5) Memory
LangChain의 메모리 컴포넌트는 LLM이 이전 대화 내용을 기억하고 활용할 수 있도록 돕는 핵심 기능입니다. 이는 대화형 애플리케이션에서 연속성을 유지하는 데 필수적입니다.
- ConversationBufferMemory: 모든 대화 기록을 버퍼에 저장합니다. 간단한 대화에 적합합니다.
- ConversationSummaryBufferMemory: 대화가 길어질수록 요약본을 생성하여 메모리 사용량을 줄입니다. 긴 대화에 유용합니다.
from langchain.chains import LLMChain from langchain.memory import ConversationBufferMemory from langchain_openai import ChatOpenAI from langchain_core.prompts import PromptTemplate # LLM 모델 초기화 llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo") # 메모리 초기화 # 'memory_key'는 프롬프트 템플릿에서 대화 기록을 참조할 변수명입니다. memory = ConversationBufferMemory(memory_key="chat_history") # 프롬프트 템플릿 정의 # 대화 기록과 사용자 질문을 포함합니다. prompt = PromptTemplate.from_template(""" 다음 대화 기록을 바탕으로 사용자의 질문에 답변해줘. {chat_history} User: {question} AI: """) # LLMChain에 메모리 연결 # 'verbose=True'로 설정하면 체인 실행 과정을 더 자세히 볼 수 있습니다. conversation = LLMChain( llm=llm, prompt=prompt, verbose=True, memory=memory ) # 대화 시작 print(conversation.invoke({"question": "안녕, 나는 김철수야."})) print(conversation.invoke({"question": "내 이름이 뭐였지?"}))
6) Retrieval (Vector Stores & Embeddings)
LangChain의 검색(Retrieval) 컴포넌트는 LLM이 학습 데이터에 없는 외부 데이터를 활용할 수 있도록 돕는 핵심 기능입니다. 이는 RAG(Retrieval Augmented Generation) 패턴의 기반이 됩니다.
- Embeddings: 텍스트 데이터를 수치형 벡터(임베딩)로 변환하는 모델입니다. 유사한 의미의 텍스트는 유사한 벡터 공간에 위치하게 됩니다.
- Vector Stores: 임베딩된 벡터를 저장하고, 주어진 쿼리 벡터와 유사한 벡터를 효율적으로 검색할 수 있도록 하는 데이터베이스입니다 (예: FAISS, Chroma, Pinecone).
- Document Loaders: PDF, 웹 페이지, 텍스트 파일 등 다양한 형식의 문서를 로드하는 도구입니다.
- Text Splitters: 로드된 문서를 LLM이 처리하기 적합한 크기의 작은 청크(chunk)로 분할하는 도구입니다.
다음은 간단한 RAG 워크플로우 예시입니다.
from langchain_community.document_loaders import TextLoader from langchain.text_splitter import CharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import FAISS from langchain.chains import create_retrieval_chain from langchain.chains.combine_documents import create_stuff_documents_chain from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI import os # 필요한 라이브러리 설치 (예시) # pip install pypdf faiss-cpu # 1. 예시 문서 생성 (실제 애플리케이션에서는 파일에서 로드) doc_content = "LangChain은 LLM 애플리케이션 개발을 돕는 프레임워크입니다. LangChain은 모듈화된 구성 요소를 제공하며, 다양한 LLM 및 외부 도구와 쉽게 통합됩니다. 재사용성과 유연성이 뛰어나며, 복잡한 워크플로우를 구성할 수 있습니다." doc_content += "\nFAISS는 벡터 검색을 위한 효율적인 라이브러리입니다. 대규모 데이터셋에서 유사한 벡터를 빠르게 찾을 수 있도록 최적화되어 있습니다." with open("example_rag_doc.txt", "w", encoding="utf-8") as f: f.write(doc_content) # 2. 문서 로드 loader = TextLoader("example_rag_doc.txt", encoding="utf-8") documents = loader.load() # 3. 문서 분할 (LLM이 처리하기 쉽게) text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) docs = text_splitter.split_documents(documents) # 4. 임베딩 생성 및 벡터 스토어 저장 # OpenAI API 키가 환경 변수에 설정되어 있어야 합니다. embeddings = OpenAIEmbeddings() vectorstore = FAISS.from_documents(docs, embeddings) # 5. 검색기(Retriever) 생성 retriever = vectorstore.as_retriever() # 6. LLM 및 프롬프트 설정 llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) prompt = ChatPromptTemplate.from_template(""" 다음 문맥을 참고하여 질문에 답변해줘: {context} 질문: {input} """) # 7. 문서와 LLM을 결합하는 체인 생성 document_chain = create_stuff_documents_chain(llm, prompt) # 8. 검색기와 문서 체인을 결합하여 최종 RAG 체인 생성 retrieval_chain = create_retrieval_chain(retriever, document_chain) # 9. 질문 실행 response_langchain = retrieval_chain.invoke({"input": "LangChain은 무엇을 돕는 프레임워크인가요?"}) print(f"RAG 응답 (LangChain): {response_langchain['answer']}") response_faiss = retrieval_chain.invoke({"input": "FAISS는 어떤 용도로 사용되나요?"}) print(f"RAG 응답 (FAISS): {response_faiss['answer']}") # 임시 파일 삭제 os.remove("example_rag_doc.txt")
7) Callbacks
LangChain의 콜백(Callbacks) 시스템은 LLM 애플리케이션의 다양한 이벤트(LLM 호출, 체인 실행, 에이전트 단계 등)에 후크(hook)를 걸어 모니터링, 로깅, 디버깅, 스트리밍 등의 작업을 수행할 수 있도록 합니다.
- 사용 목적:
- 실행 과정 추적 및 디버깅
- 성능 측정 및 로깅
- 스트리밍 응답 처리
- 사용자 인터페이스 업데이트
from langchain.chains import LLMChain from langchain_openai import ChatOpenAI from langchain_core.prompts import PromptTemplate from langchain.callbacks import StdOutCallbackHandler # 표준 출력 콜백 핸들러 # LLM 모델 초기화 llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo") # 프롬프트 템플릿 정의 prompt = PromptTemplate.from_template("다음 질문에 대해 답변해줘: {question}") # 콜백 핸들러 설정 # StdOutCallbackHandler는 체인 실행 중 발생하는 이벤트를 콘솔에 출력합니다. handler = StdOutCallbackHandler() # 체인 생성 시 콜백 핸들러 전달 # callbacks 매개변수에 리스트 형태로 전달합니다. chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler]) # 체인 실행 response = chain.invoke({"question": "인공지능의 미래는 어떨까요?"}) print(f"최종 Chain 응답: {response['text']}")
결론
이 가이드를 통해 LangChain의 기본적인 개념부터 핵심 구성 요소(LLM/Chat Models, Prompts, Chains, Agents & Tools, Memory, Retrieval, Callbacks)까지 살펴보았습니다. LangChain은 복잡한 LLM 애플리케이션을 모듈화하고 효율적으로 개발할 수 있도록 돕는 강력한 프레임워크입니다.
LangChain을 활용하면 단순히 LLM을 호출하는 것을 넘어, 외부 도구와 연동하고, 대화 이력을 기억하며, 외부 지식을 검색하여 LLM의 한계를 극복하는 등 더욱 강력하고 지능적인 애플리케이션을 구축할 수 있습니다.
이 가이드가 LLM 기반 애플리케이션 개발에 첫걸음을 내딛는 데 도움이 되기를 바랍니다. LangChain은 활발히 발전하고 있는 프레임워크이므로, 공식 문서와 커뮤니티를 통해 지속적으로 학습하고 탐구하는 것이 중요합니다.