[Langchain] 랭체인 컴포넌트

Hunie_07·2025년 3월 25일
0

Langchain

목록 보기
1/35

📌 Langchain의 개념 및 주요 컴포넌트

langchain_stack

1️⃣ 모델 (Models)

  • 다양한 모델을 지원 (OpenAI, Google, Ollama 등)
  • 텍스트 생성, 대화, 요약 등의 작업을 수행
from langchain_openai import ChatOpenAI

model = ChatOpenAI(model="gpt-4o-mini")
response = model.invoke("안녕하세요!")
response

- 출력

AIMessage(content='안녕하세요! 어떻게 도와드릴까요?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 10, 'total_tokens': 21, 'completion_tokens_details': ...})

  • token_usage : 토큰 사용량
# 답변 출력
print("답변: ", response.content)
print("메타데이터: ", response.response_metadata)

- 출력

답변:  안녕하세요! 어떻게 도와드릴까요?
메타데이터:  {'token_usage': {'completion_tokens': 11, 'prompt_tokens': 10, 'total_tokens': 21, ...

2️⃣ 메시지 (Messages)

  • 모델별 고유한 메시지 형식 관계없이 다양한 채팅 모델 활용 가능

1. HumanMessage

  • 사용자 입력을 처리
from langchain_core.messages import HumanMessage

# 사용자 메시지 생성
human_message = HumanMessage(content="Glory를 한국어로 번역해주세요.")

# 번역 요청
response = model.invoke([human_message])

# 답변 출력
print("답변: ", response.content)

- 출력

답변:  "Glory"는 한국어로 "영광"이라고 번역됩니다.

# 문자열을 입력하면, 자동으로 HumanMessage로 변환하여 요청
response = model.invoke("Glory를 한국어로 번역해주세요.")

# 답변 출력
print("답변: ", response.content)

- 출력

답변:  "Glory"를 한국어로 번역하면 "영광"입니다.

2. AIMessage

  • AI모델의 응답을 표현
# AI 모델의 응답 객체를 출력 
response

- 출력

AIMessage(content='"Glory"를 한국어로 번역하면 "영광"입니다.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': ...

# 모델 응답 텍스트 부분을 출력
response.content

- 출력

'"Glory"는 한국어로 "영광"이라고 번역합니다.'

# 토큰 사용량 출력
response.usage_metadata

- 출력

{'input_tokens': 17,
 'output_tokens': 18,
 'total_tokens': 35,
 'input_token_details': {'audio': 0, 'cache_read': 0},
 'output_token_details': {'audio': 0, 'reasoning': 0}}

3. SystemMessage

  • AI모델의 동작과 제약사항을 정의하는데 사용
from langchain_core.messages import SystemMessage 

# 시스템 메시지 생성
system_msg = SystemMessage(content="당신은 영어를 한국어로 번역하는 AI 어시스턴트입니다.")

system_msg

- 출력

SystemMessage(content='당신은 영어를 한국어로 번역하는 AI 어시스턴트입니다.', additional_kwargs={}, response_metadata={})

# 번역 요청
human_message = HumanMessage(content="Glory")

messages = [system_msg, human_message]

response = model.invoke(messages)

# 답변 출력
print("답변: ", response.content)

- 출력

답변:  영광

3️⃣ 프롬프트 템플릿 (Prompt Template)

  • 프롬프트 템플릿을 통해 일관된 입력 형식을 제공
  • 변수를 포함한 동적 프롬프트 생성이 가능
    - 딕셔너리 형태의 입력을 받아서 처리

1. 문자열 프롬프트 템플릿 (String PromptTemplate)

  • 가장 기본적인 형태로, 단일 문자열을 형식화하는데 사용
from langchain_core.prompts import PromptTemplate

# 템플릿 생성
template = PromptTemplate.from_template("{주제}에 대한 이야기를 해줘")

# 템플릿 사용
prompt = template.invoke({"주제": "고양이"})

# 출력
prompt

- 출력

StringPromptValue(text='고양이에 대한 이야기를 해줘')

2. 채팅 프롬프트 템플릿 (ChatPromptTemplate)

  • 여러 메시지를 포함하는 대화형 템플릿을 만들 때 사용
from langchain_core.prompts import ChatPromptTemplate

# 채팅 템플릿 생성
template = ChatPromptTemplate.from_messages([
    ("system", "당신은 도움이 되는 비서입니다"),
    ("user", "{subject}에 대해 설명해주세요")
])

# 템플릿 사용
prompt = template.invoke({"subject": "인공지능"})

# 출력
prompt

- 출력

ChatPromptValue(messages=[SystemMessage(content='당신은 도움이 되는 비서입니다', additional_kwargs={}, response_metadata={}), HumanMessage(content='인공지능에 대해 설명해주세요', additional_kwargs={}, response_metadata={})])

3. 메시지 플레이스홀더 (MessagesPlaceholder)

  • 기존 메시지 목록을 템플릿의 특정 위치에 삽입할 때 사용
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage

# 메시지 플레이스홀더가 있는 템플릿
template = ChatPromptTemplate.from_messages([
    ("system", "당신은 도움이 되는 비서입니다"),
    MessagesPlaceholder("chat_history")
])

# 템플릿 사용
prompt = template.invoke({
    "chat_history": [HumanMessage(content="안녕하세요!")]
})

# 출력
prompt.messages

- 출력

[SystemMessage(content='당신은 도움이 되는 비서입니다', additional_kwargs={}, response_metadata={}),
 HumanMessage(content='안녕하세요!', additional_kwargs={}, response_metadata={})]

4️⃣ 출력 파서 (Output Parser)

  • 모델의 텍스트 출력을 구조화된 데이터로 출력
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI

# 기본적인 문자열 파서 사용
parser = StrOutputParser()

# 프롬프트 템플릿 설정
prompt = PromptTemplate.from_template("도시 {city}의 특징을 알려주세요")

# 모델 정의
model = ChatOpenAI(model='gpt-4o-mini')

# 체인 구성
chain = prompt | model | parser

# 체인 실행
result = chain.invoke({"city": "서울"})

# 결과 출력
print(result)

- 출력

서울은 대한민국의 수도이자 가장 큰 도시로, 여러 가지 특징을 가지고 있습니다. 다음은 서울의 주요 특징들입니다:

1. **역사와 전통**: 서울은 ...

  • Groq 모델 이용
# Groq

from langchain_groq import ChatGroq

model = ChatGroq(model='llama-3.3-70b-specdec')

# 체인 구성
chain = prompt | model | parser

# 체인 실행
result = chain.invoke({"city": "서울"})

# 결과 출력
print(result)

- 출력

서울은 한국의 수도이자 가장 큰 도시입니다. 서울의 특징은 다음과 같습니다.

1. **역사와 문화**: 서울은 ...

5️⃣ 메모리 (Memory)

  • 대화기록 저장 및 관리
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import BaseMessage
from pydantic import BaseModel, Field
from typing import List

# 메모리 기반 히스토리 구현
class InMemoryHistory(BaseChatMessageHistory, BaseModel):
    messages: List[BaseMessage] = Field(default_factory=list)
    
    def add_messages(self, messages: List[BaseMessage]) -> None:
        self.messages.extend(messages)
    
    def clear(self) -> None:
        self.messages = []

# 세션 저장소
store = {}

# 세션 ID로 히스토리 가져오기
def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = InMemoryHistory()
    return store[session_id]
# 채팅 모델과 프롬프트 설정
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory

prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 {subject}에 능숙한 비서입니다"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{question}")
])

chain = prompt | ChatOpenAI(model='gpt-4o-mini')

# 히스토리 관리 추가
chain_with_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="question",
    history_messages_key="history"
)

# 체인 실행
response = chain_with_history.invoke(
    {"subject": "수학", "question": "1+2는 얼마인가요?"},
    config={"configurable": {"session_id": "user1"}}
)

# 결과 출력
print(response)

- 출력

content='1 + 2는 3입니다.' additional_kwargs={'refusal': None} response_metadata= ...

# 세션 ID로 히스토리 가져오기
get_session_history("user1").messages

- 출력

[HumanMessage(content='1+2는 얼마인가요?', additional_kwargs={}, response_metadata={}),
 AIMessage(content='1 + 2는 3입니다.', additional_kwargs={'refusal': None}, response_metadata= ...)]

# 히스토리 이용해서 대화 진행
response = chain_with_history.invoke(
    {"subject": "수학", "question": "여기에 숫자 2를 곱하면 얼마인가요?"},
    config={"configurable": {"session_id": "user1"}}
)

# 결과 출력
print(response)

- 출력

content='3에 2를 곱하면 6입니다. (3 x 2 = 6)' additional_kwargs={'refusal': None} response_metadata= ...}

# 세션 ID로 히스토리 가져오기
get_session_history("user1").messages

- 출력

[HumanMessage(content='1+2는 얼마인가요?', additional_kwargs={}, response_metadata={}),
 AIMessage(content='1 + 2는 3입니다.', additional_kwargs={'refusal': None}, response_metadata= ...),
 HumanMessage(content='여기에 숫자 2를 곱하면 얼마인가요?', additional_kwargs={}, response_metadata={}),
 AIMessage(content='3에 2를 곱하면 6입니다. (3 x 2 = 6)', additional_kwargs={'refusal': None}, response_metadata= ...)]

0개의 댓글