[대회/데이콘-새싹톤🌱] pre. 챗봇 만들기 학습(3) : LangChain 기본
1. Langchain
1.1. Langchain 이란
- 자연어 처리(NLP) 기능을 강화하고, 언어 모델을 응용 프로그램에 통합하기 위한 도구 및 프레임워크를 제공하는 라이브러리
- 개발자가 대화형 AI 시스템을 쉽게 구축할 수 있도록 설계되어 있다.
- 특히, 여러 AI 기술을 하나의 유연한 인터페이스에 결합하여, 복잡한 대화형 AI 시스쳄을 보다 쉽게 개발할 수 있도록 지원
1.2. Langchain 의 다양한 기능
프롬프트 템플릿 (Prompt templates)
: 효율적으로 언어모델에 문장을 전달
문서 로더(Document Loader)
: 다양한 형식의 문서를 불러올 수 있음
정보 검색(Retrieval)
: 대화형 AI 시스템이 필요한 정보를 효율적으로 찾아 사용자의 요구에 응답할 수 있게 하는 과정
백터 스토어(Vector stores)
: 고차원 벡터 데이터를 저장하고 검색할 수 있는 시스템
: 대략의 벡터 데이터에서 빠른 검색과 유사성 비교를 가능하게 함
체인(chain)
: LLM을 다른 기능들과 연결해 하나의 어플리케이션을 만든다
( 예 : 질문 이해 -> 정보 검색 -> 데이터 처리 -> 답변 생성 )
1.3. 설치할 라이브러리 소개
!pip install langchain-community
!pip install langchain-openai
langchain-community
: 이 라이브러리는 대규모 언어 모델(LLMs)을 활용한 애플리케이션 개발을 지원하는 LangChain 프레임워크의 일부
: 특히 이 묘듈은 LangChain 생태계 내에서 즉시 사용할 수 있는 다양한 서드파티 통합 기능을 제공
: 이러한 통합 기능들은 LangChain Core에서 정의한 기본 인터페이스를 구현해, 개발자들이 다양한 도구와 기능을 자신의 애플리케이션에 손쉽게 통합할 수 있게 도와줌
langchain-openai
: 이 패키지는 LangChain 프레임워크 내의 특정 통합 패키지로, OpenAI의 언어 모델과 상호 작용하도록 설계되었음
: LangChain을 기반으로 한 애플리케이션에 OpenAI의 API를 쉽게 통합할 수 있도록 하여, OpenAI의 고급 AI 모델을 활용한 맞춤형 기능을 제공
2. 인증키 생성
LangChain
LangChain’s suite of products supports developers along each step of their development journey.
www.langchain.com
2) 인증키 생성

➡️ 왼쪽 아래 '설정(톱니바퀴)' 클릭
2.2. OpenAI 인증키 발급 받기
발급 받은 인증키는 환경변수에 저장
프로젝트 진행을 위해 생성해야 할 환경 변수의 이름과 값
- 'LANGCHAIN_TRACING_V2' : true
- 'LANGCHAIN_ENDPOINT' : 'https://api.smith.langchain.com'
- 'LANGCHAIN_API_KEY' : Langchain API 인증키
- 'LANGCHAIN_PROJECT' : 프로젝트 이름
- 'OPENAI_API_KEY' : OpenAPI 인증키
2.3. 환경변수 셋팅
**윈도우 )
**리눅스, Mac OS )
.bashrc 파일을 편집기로 열고, 파일의 마지막에 export 명령을 추가
nano ~/.bashrc
파일에 다음과 같이 추가
export MY_VAR='hello'
변경사항을 적용하기 위해 터미널에서 다음 명령을 실행하거나, 세션을 재시작
source ~/.bashrc
2.4. 환경변수 셋팅 (python)
파이썬 내에서 임시로 환경변수 입력 : 파이썬 터미널 종료시 초기화
import os
# LangSmith API 키 설정
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'
os.environ["LANGCHAIN_API_KEY"] = ''
os.environ["LANGCHAIN_PROJECT"] = ''
os.environ["OPENAI_API_KEY"] = '인증키'
3. 프로젝트 생성
llm 모델을 실행해 프로젝트를 생성해 줍시다.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI()
llm.invoke("Hello, world!")
카드 등록 안 하고 이용했더니 뜨는 오류
- API 요청 한도 초과: 현재 API 사용량이 할당된 한도를 초과한 경우입니다.
- 유효하지 않은 API 키: API 키가 유효하지 않거나 만료된 경우입니다.
데이콘 측에서 제공한 API 를 이용하는 것이었는지
os.environ["OPENAI_API_KEY"] = '인증키' 부분을 입력하지 않자 성공
AIMessage(content='Hello! How can I assist you today?', response_metadata={'token_usage': {'completion_tokens': 9, 'prompt_tokens': 11, 'total_tokens': 20}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-9caf4a95-fcad-4178-9d2a-23566ae47f7a-0', usage_metadata={'input_tokens': 11, 'output_tokens': 9, 'total_tokens': 20})
4. 프롬프트(Prompt)
4.1. 문자열 프롬프트
** PromptTemplate : 기본적인 텍스트 프롬프트를 구성하는데 사용
- from_template : 프롬프트 생성에 쓰이는 함수
- 프롬프트 안에 변수를 포함시켜 동적으로 내용을 변경할 수 있게 한다.
프롬프트 탬플릿을 만들어 봅시다.
from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("{city}의 대표적인 자랑거리는 뭐야?")
final_prompt = prompt_template.invoke({"city": "서울시"})
print(final_prompt)
⬇️ 위의 코드 실행 결과 ⬇️
text='서울시의 대표적인 자랑거리는 뭐야?'
4.2. 대화형 프롬프트
** HumanMessage : 사람으로부터 온 메시지를 줄 때 이용
** SystemMessage : 대화형 AI 모델이 응답할 때 고려해야 하는 규칙이나 역할, 지침을 설정하는 메세지
** MessagePlaceholder
: LangChain의 대화형 프롬프트 구성에서 사용되는 특별한 개념
- 대화의 특정 지점에서 이전 메시지들의 컨텍스트를 유지하고, 새로운 메시지를 추가하는데 사용
** ChatPromtTemplates
: 메세지를 담고 있는 리스트를 위한 프롬프트 템플릿을 만들 때 사용
대화형 프롬프트 탬플릿을 만들어 봅시다.
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, SystemMessage
messages = [
SystemMessage(content="You are a helpful assistant! Your name is Bob."),
MessagesPlaceholder("chat_history"),
HumanMessage(content="{msgs}, What is your name?")
]
chat_history = [
{"role": "user", "content": "Tell me about the French Revolution."},
{"role": "assistant", "content": "The French Revolution was a period of radical social and political change in France from 1789 to 1799."}
]
msg_prompt_template = ChatPromptTemplate.from_messages(messages)
msg_prompt_template.invoke({"chat_history":chat_history, "msgs":"Hello"})
⬇️ 위의 코드 실행 결과 ⬇️
ChatPromptValue(messages=[SystemMessage(content='You are a helpful assistant! Your name is Bob.'), HumanMessage(content='Tell me about the French Revolution.'), AIMessage(content='The French Revolution was a period of radical social and political change in France from 1789 to 1799.'), HumanMessage(content='{msgs}, What is your name?')])
5. 벡터 스토어(Vector Stores)
벡터 스토어는 문서, 문장, 단어 등의 텍스트 데이터를 벡터 형태로 저장하고 관리하는 시스템입니다.
이를 통해 효율적으로 검색하고 유사성을 비교할 수 있습니다.
5.1. Langchain과 사용하는 벡터 스토어
Langchain은 다양한 벡터 스토어 라이브러리와 통합되어 사용할 수 있도록 설계되었습니다.
** Langchain에서 사용할 수 있는 벡터 스토어 라이브러리
- chroma : Chroma는 오픈소스 벡터 데이터베이스로, 빠르고 확장 가능한 벡터 검색을 제공
- Pinecone : Pinecone은 클라우드 기반 벡터 데이터베이스 서비스로, 실시간으로 확장 가능한 벡터 검색을 제공
- FAISS : FAISS는 Facebook AI Research에서 개발한 라이브러리로, 대규모 벡터 검색과 군집화를 효율적으로 수행 가능
- Lance : Lance는 벡터 검색과 클러스터링을 위한 라이브러리로, 특히 고성능 및 확장성을 중점으로 설계됨
5.2. FAISS 예제
FAISS 실행을 위해 라이브러리 설치
!pip install faiss-cpu
벡터 스토어 생성 및 실행 과정
- 벡터 스토어를 만들 때, 먼저 준비된 텍스트 파일을 불러온다.
- 문서의 텍스트를 작은 청크(chunk)로 분리한다. ** 청크 : 큰 텍스트를 다루기 쉽게 작은 단위로 나눈 것
- 텍스트를 벡터로 변환해줄 언어모델을 정의 ( 예시에서는 OpenAIEmbeddings를 사용 )
- FAISS를 이용해 벡터 스토어(Vector Stores)를 만들어준다.
파이썬 예시 코드
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
loader = TextLoader("./seoul.txt")
# 텍스트 정리
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(texts, embeddings)
# 실행코드
test_string = '대한민국의 수도'
similar_docs = db.similarity_search(test_string)
print(similar_docs[0].page_content)
⬇️ 위의 코드 실행 결과 ⬇️
6. 검색도구(Retriever)
6.1. 검색도구(Retriever) 란?
- 구조화 되지 않은 쿼리가 주어졌을 때, 문서를 반환하는 인터페이스
- 즉, 인간이 만든 자연스러운 언어를 입력받아, 문서를 반환
- 벡터 스토어는 검색도구의 핵심 구조로 사용할 수 있지만, 다른 유형의 검색도구를 사용할 수 있음
6.2. 검색도구(Retriever) 의 종류
- Vectorstore : 간단하게 만들 수 있다
- ParentDocument : 각 문서를 청크로 나누고, 부모 문서를 검색하여 검색
- Multi Vector : 문서에 대해 여러개의 벡터를 생성
- Self Query : 사용자의 입력을 의미적으로 조회할 뿐만 아니라, 메타데이터도 함께 참고합니다.
- Contextual Compression : 다른 검색기 위에 후처리 단계를 두어, 가장 관련성 있는 정보만 추출합니다.
- Time-Weighted Vectorstore : 의미의 유사성에 최근 데이커에 가중치를 부여해 문서를 가져옵니다.
- Multi-Query Retriever : LLM을 이용해 원래 쿼리에서 여러 쿼리를 더 생성합니다. 그리고 각 쿼리에 대한 문서를 가져옵니다.
- Ensemble : 여러 검색기에서 문서를 가져온 후, 이를 결합합니다.
- Long-Context Reorder : 기본 검색기에서 문서를 가져온 다음, 가장 유사한 문서가 시작과 끝에 오도록 재정렬 합니다.
6.3. 코드 예시
위에서 만든 벡터스토어를 이용해 검색도구를 만들기
retriever = db.as_retriever()
docs = retriever.invoke("대한민국의 수도는?")
7. LLM(Large Language Model)
7.1. 사용 가능한 모델
- Langchain 에서는 다양한 언어 모델(Language Model)을 사용할 수 있습니다.
- 예 : HuggingFace에 있는 오픈소스 모델, Chatgpt, Gemini, 사용자 커스텀 모델 등
Chatgpt에서 사용할 수 있는 모델
- gpt-4o
- gpt-4-turbo
- gpt-4
- gpt-3.5-turbo
7.2. 코드 예시
ChatOpenAI 상세 파라미터
- model : 모델 이름
- max_tokens : 생성할 토큰의 최대 개수
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model_name='gpt-3.5-turbo')
# max_tokens=None
# 다른 파라미터 . . . )
response = llm.invoke("Hello, world!")
response
⬇️ 위의 코드 실행 결과 ⬇️
AIMessage(content='Hello! How can I assist you today?', response_metadata={'token_usage': {'completion_tokens': 9, 'prompt_tokens': 11, 'total_tokens': 20}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-329c3d7e-0d23-46cd-930a-609a4e983f43-0', usage_metadata={'input_tokens': 11, 'output_tokens': 9, 'total_tokens': 20})
8. 체인(chain)
8.1. 체인(chain)이란
- 자연어처리에서 필요한 모델, 문서 검색기, 프롬프트 등의 다양한 구성요소를 결합해준다
- 사용자의 쿼리부터 모델의 출력에 이르기까지, 일련의 자동화된 작업
8.2. LCEL(Langchain Expression Language)
chain = prompt_template | llm
input_data = {"city": "서울시"}
chain.invoke(input_data)
⬇️ 위의 코드 실행 결과 ⬇️
AIMessage(content='서울시의 대표적인 자랑거리는 경복궁, 남산타워, 명동, 광화문 등 다양한 관광 명소와 문화 시설이 있습니다. 또한 한류 열풍을 타고 한류 관련 명소들도 많이 알려져 있습니다.', response_metadata={'token_usage': {'completion_tokens': 97, 'prompt_tokens': 27, 'total_tokens': 124}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-4c2556f0-7526-47b6-b257-00bea6912aaa-0', usage_metadata={'input_tokens': 27, 'output_tokens': 97, 'total_tokens': 124})