LangChain 이란?
랭체인(LangChain)은 대형 언어 모델(LLM)을 더 효과적으로 활용할 수 있도록 도와주는 프레임워크 이다
단순히 LLM에 프롬프트를 입력하고 답변을 받는 방식에서 벗어나, 데이터 검색, 메모리 저장, API 연동, 체인(Chain) 구성 등을 가능하게 해 준다.
랭체인의 기본요소
- 프롬프트
- LLM
랭체인의 기본은 LLM 에 프롬프트를 넣어주는 것이다
써보면서 익히는게 빠르니 바로해보자
먼저 라이브러리 설치와 환경설정부터 한다
pip install langchain-openai
import os
import getpass
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
from langchain_openai import ChatOpenAI
# model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt
prompt = "안녕"
# chain 실행
answer = model.invoke(prompt)
print(answer)
- invoke : LangChain 에서 Chain 또는 Agent 를 실행 하는 함수
이러면 이제 llm 모델을 불러와서 쓸 수 있는것이다.
프롬프트의 정형화 - ChatPromptTemplate
- ChatPromptTemplate 은 랭체인에서 프롬프트템플릿을 정형화 하고 동적으로 데이터를 삽입하는데 사용하는 클래스
- 챗봇과 같은 대화형 모델에서 사용되는 프롬프트를 관리하고 쉽게 구성할 수 있게 해주는 클래스 이다.
ChatPromptTemplate의 역할
- 프롬프트 템플릿화: 여러 프롬프트에 대해 반복적인 부분을 정형화하고, 필요한 변수나 값을 동적으로 삽입할 수 있게 해줍니다.
- 동적 입력값 처리: 프롬프트에 들어갈 변수를 동적으로 할당할 수 있어서 더 효율적으로 프롬프트를 생성하고 관리할 수 있습니다.
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
# LLM model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt 템플릿 생성
# prompt = "말티즈의 고향은?"
prompt = ChatPromptTemplate.from_template("{dog_breeds_input}들의 고향은 어디야?") # 틀
# chain 생성
chain = prompt | model
# chain 실행
answer = chain.invoke({"dog_breeds_input": "말티즈"}) # 변수 안에 들어갈것만 그때그때 설정해주면, 템플릿이 자동으로 프롬프트를 완성해준다!
print(answer)
answer = chain.invoke({"dog_breeds_input": "골든리트리버"}) # 붕어빵
print(answer)
answer = chain.invoke({"dog_breeds_input": "시츄"})
print(answer)
또한 템플릿을 사용하면
프롬프트 = 개발자의 템플릿 + 사용자의 입력
이 될 수 있다.
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
# LLM model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt 템플릿 생성
prompt = ChatPromptTemplate.from_template("너는 흉악한 조폭 만득이야. 그리고 나는 너의 보스야. \
무조건 말을 할때 앞에 '네 햄!!!!' 을 붙여야해. 너는 나를 '햄님'이라고 불러.\
내가 무슨 말을 하던, 너는 무조건 과장되게 맞장구를 쳐야해. \
너는 나와의 의리를 가장 중요하게 여겨. \
나의 말에 대답하도록 해.\
나의 말 : {input}") # 프롬프트에 독을탑니다..쿡쿡..
# chain 생성
chain = prompt | model
# 입력받기
user_input = input("입력: ")
# chain 실행
answer = chain.invoke({"input": user_input})
print(answer)
또한 페르소나를 부여해 특정 컨셉의 챗봇을 만들 수도 있다.
보통 너는 ㅇㅇㅇ야. 너는 ㅇㅇㅇ해야해. ㅇㅇㅇ로만 대답해. 너는 ㅇㅇㅇ한 성격이야
라고하면 된다
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
# LLM model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt 템플릿 생성
prompt = ChatPromptTemplate.from_template("너는 {personality}한 성격의 조폭 만득이야. 그리고 나는 너의 보스야. \
무조건 말을 할때 앞에 '네 햄!!!!' 을 붙여야해. 너는 나를 '햄님'이라고 불러.\
내가 무슨 말을 하던, 너는 무조건 과장되게 맞장구를 쳐야해. \
너는 나와의 의리를 가장 중요하게 여겨. \
나의 말에 대답하도록 해.\
나의 말 : {input}") # 프롬프트에 독을탑니다..쿡쿡..
# chain 생성
chain = prompt | model
# 입력받기
user_input = input("입력: ")
# chain 실행
personality = "의외로 수줍" # 각 챗봇에 맞는 성격을 변수로 정의하기
answer = chain.invoke({"input": user_input, "personality" : personality})
print(answer)
LCEL (LangChain Expression Language) -> |
위 예시코드를 보면 처음보는게 나왔다.
chain = prompt | model
answer = chain.invoke({"input": user_input})
바로 | 이것인데 체인 안에 요소들을 연결해 주는것이다.
이 | 사이사이 있는 것들은 컴포넌트 이며 각 컴포넌트는 자신의 결과를 다음 컴포넌트로 넘겨준다
- 이전 컴포넌트의 결과값 -> 다음 컴포넌트의 입력값
이러한 모습이 마치 체인과 같아서 LangChain 이라는 이름이 붙은 것이다
그렇다면 이 | 파이프 속에 아무거나 들어갈 수 있을까?
| 파이프 사이에 연결될 수 있는 컴포넌트
- Runnable 인터페이스
- '조건'을 만족하는 함수
위에 prompt 나 model 은 랭체인 안에 있는
ChatpromptTemplate 와 ChatOpenAI 로 만든것인데
랭체인이 처음부터 Runnable 인터페이스로 만든것이라 | 파이프 속에 들어갈 수 있는 것이다.
그렇다면 '조건' 을 만족하는 함수는 무엇인가?
- 입력을 받고 출력을 반환하는 형태의 함수
- 이전 체인의 출력과 데이터 타입이 호환되어야 함
- 다음 체인의 입력돠 데이터 타입이 호환되어야 함
'''올바른 예시'''
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
# LLM model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt 템플릿 생성
prompt = ChatPromptTemplate.from_template("{dog_breeds_input}들의 고향은 어디야?")
def my_print(string) :
return string.content
# chain 생성
chain = prompt | model | my_print
# chain 실행
answer = chain.invoke({"dog_breeds_input": "말티즈"})
print(answer)
자주 쓰이는 runnable component: StrOutputParser()
- 간단한 모델 출력에서 content 만 그대로 출력할 때
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
# LLM model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt 템플릿 생성
prompt = ChatPromptTemplate.from_template("{dog_breeds_input}들의 고향은 어디야?")
# chain 생성
chain = prompt | model | StrOutputParser() # 깔끔하게 출력된다.
# chain 실행
answer = chain.invoke({"dog_breeds_input": "말티즈"})
print(answer)
자주 쓰이는 runnable component: RunnablePassthrough()
- 입력을 변환하지 않음 : 입력 데이터를 그대로 반환
- 데이터 검증 또는 테스트용 : 파이프라인에서 데이터 흐름을 확인하거나 테스트할 때 유용
- 복잡한 체인에서 간단한 연결 구성 : 변환이 필요 없는 경우 체인의 일부로 사용된다.
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
# LLM model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt 템플릿 생성
prompt = ChatPromptTemplate.from_template("{dog_breeds_input}들의 고향은 어디야?")
# RunnablePassthrough 객체 생성
passthrough = RunnablePassthrough()
# chain 생성
#chain = prompt | model | StrOutputParser() # 깔끔하게 출력된다.
chain = prompt | model | passthrough | passthrough | StrOutputParser()
# chain 실행
answer = chain.invoke({"dog_breeds_input": "말티즈"})
print(answer)
이 RunnablePassthrough 를 상속받아 커스텀 컴포넌트를 만들 수 있다.
import time
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
# LLM model 생성
model = ChatOpenAI(model="gpt-4o-mini")
# prompt 템플릿 생성
prompt = ChatPromptTemplate.from_template("{dog_breeds_input}들의 고향은 어디야?")
# 처리 시간을 기록하는 Custom RunnablePassthrough
class TimingRunnablePassthrough(RunnablePassthrough):
def invoke(self, input, *arg):
start_time = time.time() # 시작 시간 기록
output = super().invoke(input) # 기존 Passthrough 동작 수행
end_time = time.time() # 종료 시간 기록
# 처리 시간 출력
processing_time = end_time - start_time
print(f"Processing time: {processing_time:.6f} seconds")
return output
# Custom RunnablePassthrough 객체 생성
timed_passthrough = TimingRunnablePassthrough()
# chain 생성
chain = prompt | timed_passthrough | model | timed_passthrough | StrOutputParser() | timed_passthrough
# chain 실행
answer = chain.invoke({"dog_breeds_input": "말티즈"})
print(answer)
'AI > LLM' 카테고리의 다른 글
[LangGraph] LangGraph 란 무엇인가? (0) | 2025.03.19 |
---|---|
[LLM] LangChain 의 유용한 기능들 (0) | 2025.02.28 |
[LLM] RAG (0) | 2025.02.27 |