최근 대규모 언어 모델(LLM)의 발전은 인공지능 분야에 혁신을 가져왔습니다. 하지만 LLM을 실제 애플리케이션에 통합하고 복잡한 작업을 수행하도록 만드는 것은 여전히 도전적인 과제입니다. LangChain은 이러한 LLM 기반 애플리케이션 개발을 효율적이고 모듈화하여 수행할 수 있도록 돕는 강력한 프레임워크입니다. 이 가이드는 LangChain의 기본 개념부터 고급 활용법까지 다루며, LLM 개발자들이 더욱 쉽게 강력한 애플리케이션을 구축할 수 있도록 돕기 위해 작성되었습니다.
LangChain은 LLM을 기반으로 하는 애플리케이션을 개발하기 위한 프레임워크입니다. LLM의 추론 능력과 외부 데이터, 도구를 결합하여 복잡한 워크플로우를 구성할 수 있도록 지원합니다.
LangChain은 LLM을 활용한 애플리케이션 개발을 위한 도구 모음입니다. 다음은 LangChain의 주요 특징입니다.
LLM을 직접 사용하는 경우 다음과 같은 한계에 부딪힐 수 있습니다.
LangChain은 이러한 문제들을 해결하여 LLM의 잠재력을 최대한 활용할 수 있도록 돕습니다.
LangChain을 사용하기 위한 기본적인 설치 및 환경 설정 방법을 설명합니다.
LangChain은 Python 패키지로 제공되므로 pip
를 사용하여 쉽게 설치할 수 있습니다.
pip install langchain langchain-openai
langchain
: LangChain의 핵심 프레임워크입니다.langchain-openai
: OpenAI 모델을 사용하기 위한 통합 패키지입니다. 다른 LLM 제공자를 사용하려면 해당 패키지를 추가로 설치해야 합니다 (예: langchain-anthropic
).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>
<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>
LangChain은 여러 핵심 구성 요소로 이루어져 있으며, 이들을 조합하여 다양한 LLM 애플리케이션을 구축할 수 있습니다.
LangChain의 가장 기본적인 구성 요소는 LLM 자체입니다.
text-davinci-003
).
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}")
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}")
여러 LLM 호출과 다른 구성 요소(프롬프트, 파서 등)를 연결하여 복잡한 작업을 수행하는 워크플로우를 정의합니다.
LLMChain
: 가장 기본적인 체인으로, 프롬프트 템플릿과 LLM을 연결합니다.SequentialChain
: 여러 체인을 순차적으로 연결하여 각 단계의 출력이 다음 단계의 입력이 되도록 합니다.RouterChain
: 입력에 따라 다른 체인으로 라우팅합니다.|
) 연산자를 사용하여 구성 요소를 연결합니다.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}")
에이전트는 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']}")
LangChain의 메모리 컴포넌트는 LLM이 이전 대화 내용을 기억하고 활용할 수 있도록 돕는 핵심 기능입니다. 이는 대화형 애플리케이션에서 연속성을 유지하는 데 필수적입니다.
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": "내 이름이 뭐였지?"}))
LangChain의 검색(Retrieval) 컴포넌트는 LLM이 학습 데이터에 없는 외부 데이터를 활용할 수 있도록 돕는 핵심 기능입니다. 이는 RAG(Retrieval Augmented Generation) 패턴의 기반이 됩니다.
다음은 간단한 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")
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은 활발히 발전하고 있는 프레임워크이므로, 공식 문서와 커뮤니티를 통해 지속적으로 학습하고 탐구하는 것이 중요합니다.