최근 대규모 언어 모델(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은 활발히 발전하고 있는 프레임워크이므로, 공식 문서와 커뮤니티를 통해 지속적으로 학습하고 탐구하는 것이 중요합니다.