본문 바로가기
Natural Language Processing

[SeSac] LangChain 1 - 기본 LLM 체인 및 멀티체인

by 자몽먹은토끼 2024. 7. 14.
728x90
반응형
기본체인 (Prompt + LLM)

 

: 사용자의 입력(프롬프트)을 받아 LLM을 통해 적절한 응답이나 결과를 생성하는 구조

> 프롬프트를 통한 입력된 지시문을 LLM에게 전달하고, LLM은 전달받은 프롬프트 내용에 맞추어 질문에 대한 답변을 만드는 구조

 

기본 체인의 구성 요소
  1. 프롬프트(Prompt) : 사용자 또는 시스템에서 제공하는 입력. LLM에게 작업을 수행하도록 요청하는 지시문
  2. LLM(Large Language Model) : GPT나 Gemini등의 대규모 언어모델. 프롬프트를 바탕으로 적절한 응답을 생성

 

일반적인 작동 방식
  1. 프롬프트 생성 : 원하는 명령이나 지시사항을 입력하거나, 시스템에게 역할을 부여하거나, 혹은 여러 조건들을 작성해 LLM에게 전달하기 위한 지시문.
    ( 프롬프트를 그냥 gpt같은 생성형 모델과 대화하는 것이라고 생각했는데, 냉정하게 정의하자면 그냥 텍스트 그 자체이다)
  2. LLM 처리 : gpt 모델을 예시로 들자면, OpenAI API를 사용하여 GPT와 같은 LLM 모델을 불러와 앞선 프롬프트를 수행하여 답변을 생성하는 것이다.
  3. 응답 반환 : LLM에 의해 생성된 응답은 다양한 형태로 변환되어 사용자에게 제공된다. 예를들어, 생성된 텍스트 그대로를 제공할 수도 있지만, 요약한 정보나 csv형태 처럼 입맛에 맞게 변환하여 제공할 수 있다.
import os

os.environ['OPENAI_API_KEY'] = 'OPENAI_API_KEY'

> OPENAI API 사용을 위해 키를 발급받고

 

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# prompt + model + output parser
prompt = ChatPromptTemplate.from_template("You are an expert in astronomy. Answer the question. : {input}")
llm = ChatOpenAI(model="gpt-3.5-turbo-0125")
output_parser = StrOutputParser()

# LCEL chaining
chain = prompt | llm | output_parser

# chain 호출
chain.invoke({"input": "지구의 자전 주기는?"})

> Prompt + LLM 모델 + 응답 반환 까지 랭체인으로 연결한 코드이다.

> 여기서 | 기호가 연결을 의미하게 되고, invoke 함수에서 key로 들어가있는 변수가 프롬프팅의 변수 포맷팅 되어있는 부분으로 들어가게 된다.

> StrOutputParser() : 출력을 str의 형태로 반환 (출력 형태 그대로 반환)

 

 

 

멀티체인 (Multi-Chain)

 

: 여러 개의 기본체인을 연결하거나 복합적으로 작용하는 것

> 복잡한 데이터 처리가 가능

 

순차적인 체인 연결

: 2개의 체인을 정의하고, 순차적으로 체인을 연결하여 수행

 

  1. 첫번째 체인
    : 한국어 단어를 입력받아 영어로 번역

  2. 두번째 체인
    : 영어 단어를 입력받아 이 영단어를 한국어로 설명
prompt1 = ChatPromptTemplate.from_template("translates {korean_word} to English.")
prompt2 = ChatPromptTemplate.from_template(
    "explain {english_word} using oxford dictionary to me in Korean."
)

llm = ChatOpenAI(model="gpt-3.5-turbo-0125")

chain1 = prompt1 | llm | StrOutputParser()

# chain1.invoke({"korean_word":"미래"})

chain2 = (
    {"english_word": chain1}
    | prompt2
    | llm
    | StrOutputParser()
)

chain2.invoke({"korean_word":"미래"})

주석한 코드는 주석을 해도 chain1과 chain2가 한번에 처리되는지 시도해보지 못해서 .. 근데 주석해도 될거 같은데!

 

 

 

 

 

 

> 의문이 들었던 점이 하나 있었는데

파이썬에서 문자열 포맷팅을 사용할 때는

str= f"이 변수의 값은 {val} 이다"
val= 24

print(str)
# 이 변수의 값은 24 이다

이와 같이 앞에 f를 붙여줘야 중괄호 안의 변수가 포맷팅 되는데, 위 프롬프트에서는 f를 붙여주지 않음,,

근데도 결과물을 보면 잘 들어가는거 같단 말이야?

 

결론적으로 from_template함수를 사용하면 내부적으로 템플릿 문자열에서 중괄호 내의 변수를 치환하도록 설계가 되어있다고 한다. 이 메서드 자체가 문자열 템플릿을 처리한다는 의미다.

= 뭐 신경쓰지 않아도 된다는 뜻❗

728x90
반응형