이전 내용
랭체인(LangChain) 이란?
출처: 위키백과
랭체인(LangChain)은 LLM(대형 언어 모델)을 사용하여 애플리케이션 생성을 단순화하도록 설계된 프레임워크이다. 언어 모델 통합 프레임워크로서 랭체인의 사용 사례는 문서 분석 및 요약, 챗봇, 코드 분석을 포함하여 일반적인 언어 모델의 사용 사례와 크게 겹친다.
랭체인은 LLM과 외부의 도구(웹 사이트, PDF reader, 계산기 등)를 체인으로 엮은 것처럼 결합해 주는 SDK(Software Develepmont Kit)의 한 종류다. 랭체인의 등장은 챗GPT의 등장 시기와 비슷하며, 챗GPT가 생겨난 후 수많은 LLM이 생겨나고 이 LLM을 활용한 애플리케이션을 만드는 데 랭체인의 역할이 중요해지게 되었다.
[랭체인의 주요 기능]
랭체인을 사용하여 생성형 AI를 활용하는 여러 가지 애플리케이션을 만들 수 있는데, 주로 챗봇 등을 개발할 때 문서 또는 정형화된 데이터를 사용하여 대화를 요약 및 분석하거나 생성할 수 있다. 물론 랭체인을 사용하지 않고도 LLM 만을 이용하여 서비스를 생성할 수도 있으나, 랭체인 활용 시 애플리케이션을 효율적이고 간편하하게 개발할 수 있다는 이점이 있다.
랭체인의 핵심 기능 중 하나는 LLM을 활용한 대화형 애플리케이션 제작 시 이전에 입력되거나 출력된 대화를 기억해 일관성 있는 대화를 하게 도와줄 수 있다는 것이며, 이를 활용해 챗GPT나 LLama2 등의 모델과 결합 후 완성도 높은 AI 애플리케이션을 만들 수 있다.
랭체인 설치와 환경 설정 (아나콘다 프롬프트)
필자의 경우, 이전에 아나콘다 프롬프트에서 생성한 가상환경에 랭체인 패키지를 설치했다.
pip install langchain
※ 추가! 랭체인 커뮤니티도 설치해 준다.
pip install langchain_community
만약, OpenAI 패키지가 설치되어 있지 않다면, OpenAI 패키지도 설치해야 한다.
pip install openai
설치가 완료된 후 OpenAI API 키를 사용하기 위해 주피터 노트북에 환경 설정을 한다.
import os
from openai import OpenAI
# OpenAI 클라이언트 설정
client = OpenAI(
api_key=os.environ['OPENAI_API_KEY'])
모델 I/O
모델 I/O 모듈은 랭체인에서 LLM과 상호 작용하는 데 사용하며, 프롬프트를 생성한 후 모델 API를 호출하고 모델이 추론한 결과를 효율적으로 출력하는 역할을 한다.
- Prompts: 모델에 입력을 템플릿화하고 동적으로 선택하고 관리
- Chat models: 언어 모델의 지원을 받지만, 채팅 메시지 목록을 입력으로 사용하고 채팅 메시지를 반환하는 모델
- LLMs: 텍스트 문자열을 입력으로 사용하고 텍스트 문자열을 반환하는 모델
- Output parsers: 모델 출력에서 정보 추출
1. LLMs
랭체인에서는 언어 모델을 두 가지로 구분한다.
- LLMs: 문자를 입력받아 문자를 아웃풋으로 리턴하는 언어 모델
- ChatModels: 메시지의 리스트를 인풋으로 받아 메시지를 리턴하는 언어 모델
◆ OpenAI LLMs 연결하기
여기서는 대화 기반으로 답변을 받는 것이 아닌, 일반적으로 질문 답변을 하는 OpenAI 모델 (gpt-3.5-turbo-instruct)을 랭체인을 통해 연결해 본다.
from langchain.llms import OpenAI
llm=OpenAI(model_name='gpt-3.5-turbo-instruct')
llm.predict('미국의 제1대 대통령은?')
※ LangChain 라이브러리에서는 BaseLLM.predict 메서드가 더 이상 권장되지 않으며, 대신 invoke 메서드를 사용해야 한다는 경고 메시지가 표시된다. 해당 경고 메시지에 맞춰 코드를 수정한 뒤 다시 실행해보면
from langchain.llms import OpenAI
llm=OpenAI(model_name='gpt-3.5-turbo-instruct')
llm.invoke('미국의 제1대 대통령은?')
▶ 좀 더 상세하게 나온다.
이번에는 temperature 매개변수를 통해 답변의 무작위성을 설정해 보는데, 이 값에는 0~1 사이의 값을 넣을 수 있으며, 1로 설정할수록 답변의 무작위성이 높아진다.
from langchain.llms import OpenAI
llm=OpenAI(model_name='gpt-3.5-turbo-instruct', temperature=1)
llm.invoke('미국의 제1대 대통령은?')
답변 결과가 길 경우 기다리는 시간이 길어지는데, StreamingStdOutCallbackHandler 를 사용하면 실시간으로 타이핑하듯이 답변이 나온다.
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
llm=OpenAI(model_name='gpt-3.5-turbo-instruct', streaming=True,
callbacks=[StreamingStdOutCallbackHandler()], temperature=0)
llm.invoke('서울에서 가장 유명한 K-POP 가수는?')
◆ 챗GPT Chatmodel 연결하기
OpenAI의 핵심은 채팅하듯이 답변해 주는 챗GPT 모델이다. 랭체인에서도 챗GPT와 연결하여 사용할 수 있으며, 챗GPT와 연결 시 모델에 역할을 부여하는 등의 기능도 넣을 수 있다. 랭체인에는 Chat 기능을 위한 스키마(Schema)를 사용하는데, 기능은 다음과 같다.
- SystemMessage: 챗GPT에게 해야 할 역할 설정
- HumanMessage: 유저가 챗GPT에게 입력한 채팅
- AIMessage: 챗GPT가 응답한 채팅
from langchain.chat_models import ChatOpenAI
from langchain.schema import AIMessage, HumanMessage, SystemMessage
chatgpt = ChatOpenAI(model_name='gpt-3.5-turbo')
messages = [
SystemMessage(
content="당신은 파이썬 프로그래머입니다."
),
HumanMessage(
content="파이썬에서 for 반복문의 역할은?"
),
]
result=chatgpt(messages)
print(result.content)
▶ 스키마 사용 시 메시지의 내용은 content 매개변수에 넣어 사용하며, 결괏값은 result.content에 저장된다.
2. 프롬프트 템플릿
LLM을 사용할 때 모델의 입력으로 사용되는 프롬프트를 생성하는 것은 매우 중요한 일이다.
예를 들어 "DUDE (필자가 예전에 운영했던 남성 쇼핑몰 - 지금은 없다.)"의 챗봇을 만들 때 " XXXX 제품이 몇 페이지에 있는 지 알려줘, 답변은 몇 페이지에 몇 번째에 있습니다로 해 주세요" 라는 프롬프트를 만들 때 앞에 XXXX 부분의 내용만 바뀌고 뒤에는 항상 같은 프롬프트로 입력해야 한다.
랭체인에서는 이러한 프롬프트를 생성하는 기능을 제공하고 있는데, 이러한 기능을 사용하면 챗GPT가 쓸데없이 긴 답변을 해 주는 것을 방지할 수 있다.
프롬프트 템플릿은 다음의 두 가지 템플릿을 제공한다.
- Prompt Template: 일반 LLM에 사용
- Chat Promprt Template: Chat LLM에 사용
◆ 프롬프트 템플릿 만들기
프롬프트 템플릿은 프롬프트를 생성할 때 중괄호({ })를 이용하여 매개변수를 생성할 수 있다.
from langchain.prompts import PromptTemplate
llm_prompt = PromptTemplate.from_template("{goods}의 소재에 대해 알려줘")
llm_prompt_result=llm_prompt.format_prompt(goods="무스탕 자켓")
print(llm_prompt_result)
llm_prompt_result.text를 출력하면 문자로 출력되며, 이렇게 만든 프롬프트는 llm에 chain으로 연결해 사용한다.
◆ Chat Prompt Template
Chat Prompt Template는 Chat LLM 모델에 사용되는 SystemMessage, HumanMessage 등에 입력하는 프롬프트를 생성하는 데 사용된다.
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
system_message = "당신은 {language} 선생님입니다. {language}로 대답해 주세요."
system_prompt = SystemMessagePromptTemplate.from_template(system_message)
human_template = "{text}"
human_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_prompt, human_prompt])
chat_prompt.format_messages(language="스페인어", text="대한민국의 보물1호는?")
◆ OpenAI 모델에 연결하기
먼저 프롬프트 템플릿을 통해 생성된 템플릿을 OpenAI에 적용해 본다.
기존에 책에 쓰여있던 코드는 오류가 발생하므로, 새로운 코드로 작성한다. (이거 해결하느라 시간 엄청 걸렸다.)
* 기존 코드 (오류 발생)
from langchain.prompts import PromptTemplate, ChatPromptTemplate
from langchain.llms import OpenAI
llm=OpenAI(model_name='gpt-3.5-turbo', temperature=0)
llm_prompt = PromptTemplate.from_template("{goods}의 소재에 대해 알려줘")
llm_prompt_result = llm_prompt.format_prompt(goods = "무스탕 자켓") llm.predict_messages(llm_prompt_result.to_messages())
from langchain.prompts import PromptTemplate
from langchain_community.chat_models import ChatOpenAI
from langchain.chains import LLMChain
# ChatOpenAI 모델 인스턴스 생성 (최신 모델 사용)
llm = ChatOpenAI(model_name='gpt-3.5-turbo', temperature=0)
# 프롬프트 템플릿 생성
prompt_template = PromptTemplate(template="{goods}의 소재에 대해 알려줘")
# LLM과 프롬프트 템플릿을 연결하는 체인 생성
chain = LLMChain(llm=llm, prompt=prompt_template)
# 실행할 데이터 설정
goods = "무스탕 자켓"
# 체인 실행 및 결과 출력
result = chain.run(goods=goods)
print(result)
[주요 변경 사항 설명]
1) ChatOpenAI 클래스 사용:
from langchain_community.chat_models import ChatOpenAI을 통해 ChatOpenAI 클래스를 import하고 사용.
2)PromptTemplate 초기화:
template 매개변수를 사용하여 PromptTemplate 객체 생성.
3) LLMChain 초기화 및 실행:
LLMChain 객체를 생성하고 run 메서드를 사용하여 결과 출력.
다음으로는 앞서 만든 Chat Prompt Template를 OpenAI ChatGPT에 적용해 본다.
from langchain_community.chat_models import ChatOpenAI
from langchain.prompts import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate
)
chatgpt = ChatOpenAI(model_name='gpt-3.5-turbo', temperature=0)
system_message = "당신은 {language} 선생님입니다. {language}로 대답해 주세요."
system_prompt = SystemMessagePromptTemplate.from_template(system_message)
human_template = "{text}"
human_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_prompt, human_prompt])
message = chat_prompt.format_messages(language="스페인어", text="대한민국의 보물1호는?")
response = chatgpt.invoke(message)
print(response.content)
스페인어로 요청했으나, 스페인어 출력이 안되어
영어로 수정하여 다시 요청하였다.
◆ 퓨샷(Few Shot)
퓨샷은 언어 모델을 사용하여 결괏값을 추론할 때 추론된 결괏값을 원하는 형태로 나타나게 하는 것을 의미한다.
퓨샷을 사용하기 위해서는 예시가 되는 프롬프트를 먼저 생성해야 한다.
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate
from langchain.llms import OpenAI
ex_qa = [
{
"question": "차은우에 대해 알려줘",
"answer": "나이: 29, 키: 183, 사는 곳: 대한민국"
},
{
"question": "데이비드 베컴에 대해 알려줘",
"answer": "나이: 45, 키: 178, 사는 곳: 영국"
}
]
ex_prompt=PromptTemplate(input_variables=["question", "answer"],
template="Question: {question}\n{answer}")
위에서 만든 ex_prompt를 이용하여 FewShotPromptTemplate를 만든다.
prompt=FewShotPromptTemplate(
examples=ex_qa,
example_prompt=ex_prompt,
suffix="Question: {input}",
input_variables=["input"]
)
llm = ChatOpenAI(model_name='gpt-3.5-turbo', temperature=0)
prompt_result=prompt.format(input="크리스티아누 호날두에 대해 알려줘")
response = llm.invoke(prompt_result)
print(response.content)
◆ 아웃풋 파서(Output Parser)
아웃풋 파서는 출력 형태를 지정한 형태로 출력할 수 있도록 해 주며, 핵심 기능은 아래와 같다.
- Format instructions: 원하는 출력 형태를 LLM에 전달
- Parser: 결괏값을 원하는 지정 형태로 추출
파서의 종류
- List Parser: 콤마(,)로 구분된 항목 목록 반환
- Date Time Parser: 출력을 Datetime 형식으로 반환
- Enum Parser: 열거형 형태로 반환
- AutoFixing Parser: 첫 출력 구문 분석기가 실패할 경우 다른 LLM을 호출하여 오류 수정
- Pydantic(JSON) Parser: 임의의 JSON 스키마를 만들고 스키마를 준수하는 JSON 출력에 대해 LLM을 쿼리
- Retry Parser: 원래의 프롬프트와 함께 이를 LLM에 다시 제출하여 보다 적절한 응답 생성
- Structured output Parser: 여러 필드를 반환하려는 경우에 사용
- XML Parser: XML 형식으로 결과 반환
이 중 List Parser를 사용하여 결괏값을 출력해 본다.
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
output_parser = CommaSeparatedListOutputParser()
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
template="{subject} 5개를 추천해줘.\n{format_instructions}",
input_variables=["subject"],
partial_variables={"format_instructions": format_instructions}
)
llm=OpenAI(temperature=0)
prompt_result = prompt.format(subject="겨울외투")
output = llm.invoke(prompt_result)
print(output)
이를 output_parser를 사용하여 파싱해 본다.
output_parser.parse(output)
▶ 리스트 안에 콤마로 구분된 결과를 확인할 수 있다.
다음 내용
[출처]
Hey, 파이썬! 생성형 AI 활용 앱 만들어줘
위키백과
랭체인 공식 홈페이지
https://brunch.co.kr/@topasvga/3902
'[파이썬 Projects] > <파이썬 Gen AI>' 카테고리의 다른 글
[Gen AI] 랭체인을 활용한 챗봇 업그레이드 - 3 (2) | 2024.12.13 |
---|---|
[Gen AI] 랭체인을 활용한 챗봇 업그레이드 - 2 (4) | 2024.12.13 |
[Gen AI] 그라디오로 제작한 챗봇 허깅 페이스에 업로드하기 (1) | 2024.12.13 |
[Gen AI] 그라디오로 챗봇 제작하기 - 3 (소설봇) (1) | 2024.12.12 |
[Gen AI] 그라디오로 챗봇 제작하기 - 2 (번역봇) (0) | 2024.12.12 |