Ssul's Blog
[Langchain #1] 기본채팅부터 커스텀parser사용 본문
2024. 02월 버전으로 작업해 보자
#0. openai 셋팅
pip install openai
pip install langchain
pip install python-dotenv #.env파일 환경변수 가져올려고
- 주요 라이브러리 설치합니다
# 0. openai 셋팅
import os
from dotenv import load_dotenv
import openai
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
- openai의 api키를 설정합니다.
- .env에 넣고, 불러오기
#1. Langchain으로 시스템메세지 셋팅하고, 질문하고 응답받기
from langchain.chat_models import ChatOpenAI
from langchain.schema import SystemMessage, HumanMessage
llm = ChatOpenAI()
messages = [
SystemMessage(content="너는 AI번역 모델이다."),
HumanMessage(content="'뭐 마실래?' 이 문장이 영어로 뭐야?")
]
response = llm.invoke(messages)
print(response.content)
- ChatOpenAI로 openai api연결하고,
- 시스템메세지 설정
- HumanMessage 추가 후,
- llm.invoke로 메세지 리스트 전달
- response.content에 llm의 응답 들어 있음
#2. Prompt template사용 및 chain 적용
from langchain.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
human_message_prompt = "'{text}' 이 문장이 영어로 뭐야?"
human_message_prompt_template = HumanMessagePromptTemplate.from_template(human_message_prompt)
chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt_template])
print(chat_prompt_template)
chain = chat_prompt_template | llm
response = chain.invoke({"text": "뭐 마실래?"})
print(response.content)
#What do you want to drink?
- HumanMessagePromptTemplate > ChatPromptTemplate를 사용하여 프롬프트 템플릿 완성
- chat_prompt_template | llm을 통해 프롬프트템플릿과 llm모델 연결
- 연결된 모델에 변수에 원하는 내용 입력해서 전달
- 동일한 응답 받을수 있음
#3. Parser사용해서 원하는 결과만 가져오기
from langchain.schema import StrOutputParser
chain_with_output_parser = chat_prompt_template | llm | StrOutputParser()
response = chain_with_output_parser.invoke({"text": "뭐 마실래?"})
# StrOutputParser()는 스트링 객체만 가져오기
print(response)
#What do you want to drink?
- langchain에서 제공하는 StrOutputParser(결과값 중에 스트링 객체만 가져오기)
- 아까와 동일한 체인에 StrOutputParser 더해줌: chat_prompt_template | llm | StrOutputParser()
- 동일한 결과값에서 스트링 객체만 가져와서 response에 넣어줌 > llm의 응답이 바로 반환
#4. 커스텀 Parser를 사용해서 내가 원하는 형태로 반환받기
from langchain.schema import BaseOutputParser
class CustomOutputParser(BaseOutputParser):
# 콤마로 구분된 여러 단어를 리스트로 변환
def parse(self, text):
# 문자열 앞뒤 공백 제거후, 공백으로 split
return text.strip().split(" ")
chain_with_custom_output_parser = chat_prompt_template | llm | CustomOutputParser()
response = chain_with_custom_output_parser.invoke({"text": "뭐 마실래?"})
for word in response:
print(word)
- BaseOutputParser를 가져오고, 상속받기
- 입력받은 텍스트를 앞뒤 공백을 제거하고, 공백기준으로 쪼개기
- 동일하게 템플릿 + llm + 커스텀파서 연결
- 입력하면, 결과값은 단어가 쪼개진 형태로 나오게 됨
- openai의 function_call이랑 유사한 느낌. 물론 function_call은 ai의 똑똑한 판단으로 함수 호출여부를 결정해줌
#5. chain여러개 연결해서 응용
- 단어를 입력받아 > 3개의 영어문장 생성 후(chain1) > 한글로 번역하기(chain2)
# 5. chain 여러개 연결해서 응용
# 어떤 단어를 사용한 3가지 영어문장을 생성하고(chain1), 그 문장을 한국어로 번역(chain2)
# chain1. 어떤 단어를 사용한 3가지 영어문장을 생성
sentences_human_message_prompt = "'{text}' 이 단어를 사용한 3가지 영어문장을 만들어줘"
generated_human_prompt_template = HumanMessagePromptTemplate.from_template(sentences_human_message_prompt)
generated_chat_prompt_template = ChatPromptTemplate.from_messages([generated_human_prompt_template])
# chain2. 그 문장을 한국어로 번역
translate_human_message_prompt = "'{text}' 이 문장을 한국어로 번역해줘. 영어와 번역된 내용 함께 응답해줘"
translate_human_prompt_template = HumanMessagePromptTemplate.from_template(translate_human_message_prompt)
translate_chat_prompt_template = ChatPromptTemplate.from_messages([translate_human_prompt_template])
# str파서로 3가지 영어문장만 가져오기
generated_chain = generated_chat_prompt_template | llm | StrOutputParser()
generated_translated_chain = (
{"text": generated_chain}
| translate_chat_prompt_template
| llm
| StrOutputParser()
)
response = generated_translated_chain.invoke({"text": "breakfast"})
print(response)
- 위에서 배운 방식처럼 chain1을 생성. HumanMessagePromptTemplate, ChatPromptTemplate사용
- 두번째 chain은 첫번째 체인의 결과물을 받아서, 해당내용을 기반으로 번역실행
- generated_chain = generated_chat_prompt_template | llm | StrOutputParser(): 첫번째 체인 구성. 결과값은 스트링 객체만 가져와서 리턴
- 리턴된 스트링객체를 두번째 chain의 text로 입력
- response = generated_translated_chain.invoke({"text": "breakfast"})
첫번째 체인에 breakfast가 입력되어서 generated_chain실행 > 3개의 영어문장 출력
두번째 체인에 3개의 영어문장이 입력되어서 generated_translated_chain실행 > 결과에서 문자열만 가져오기
response를 출력하면 아래와 같은 결과값 출력
1. I had a delicious breakfast of scrambled eggs and toast this morning.
오늘 아침에 나는 맛있는 스크램블 에그와 토스트를 먹었습니다.
2. Breakfast is considered the most important meal of the day.
아침식사는 하루 중 가장 중요한 식사로 여겨집니다.
3. She always skips breakfast because she's never hungry in the morning.
그녀는 항상 아침식사를 거르는데, 아침에 배가 고요한 편이기 때문입니다.
정리. langchain을 사용하면, 순수하게 openai의 라이브러리만 사용하는 것 보다, 간단한 코드로 다양한 기능을 구사할 수 있음.
특히 |로 연결되는 체인이 핵심임.
'AI & ML > 사용하기' 카테고리의 다른 글
[ChatGPT] OpenAI임베딩 이용해서 RAG구현(langchain,vectordb) (0) | 2024.02.23 |
---|---|
[ChatGPT] openai 임베딩 사용해서 RAG구현(생코딩,csv파일) (1) | 2024.02.14 |
Fine-tuning with LoRA(PEFT)로 스팸문자 분류기 만들기 (2) | 2024.02.04 |
[ChatGPT] OpenAI function_call 제대로 이해하기 (0) | 2024.02.02 |
[ChatGPT] OpenAI의 function_call활용해서, 반말 챗봇 만들기 (0) | 2024.01.11 |