LangChain 챗봇3장 · LangChain 기본 구조와 LCEL6 / 21← 이전목차다음 →MetaContents

3장. LangChain 기본 구조와 LCEL

ChatPromptTemplate

연극 대본은 "해설:", "철수:", "영희:"처럼 줄마다 누가 말하는지 적혀 있습니다. 공연마다 배우 이름이나 장소 같은 몇 군데만 바꿔 씁니다. 채팅 모델에게 보내는 프롬프트도 대본처럼 역할이 붙은 줄의 목록입니다. ChatPromptTemplate 은 이 대본의 틀입니다.

system, human, ai 세 역할의 메시지 틀을 줄마다 적는 채팅 프롬프트 템플릿의 비교 그림

세 상자가 대본의 세 가지 줄입니다. system 줄에는 챗봇의 성격과 규칙을, human 줄에는 손님의 질문을, ai 줄에는 모델이 했다고 치는 답을 적습니다. ai 줄은 퓨샷처럼 예시 답을 보여 줄 때만 씁니다. 여기서 "해설:"이 system, 관객의 질문이 human, 배우의 대사가 ai 입니다. 1장에서 본 SystemMessage, HumanMessage, AIMessage 가 이 줄을 채운 결과입니다. 비유와 다른 점은, 대본의 배우는 대사를 그대로 읽지만 모델은 ai 줄을 "이런 꼴로 답하라"는 본보기로만 삼는다는 것입니다.

줄을 적는 법

줄적는 꼴채운 뒤쓰는 곳
system("system", "너는 {company}의 여행 비서다.")SystemMessage성격, 말투, 규칙
human("human", "{question}")HumanMessage손님의 질문
ai("ai", "{answer}")AIMessage예시 답(퓨샷), 앞의 대화

from_messages 는 "메시지들로부터 만든다"는 뜻으로, 이 줄들의 목록을 받아 틀을 만듭니다. 줄마다 빈칸을 넣을 수 있고, 모든 줄의 빈칸이 한 목록으로 모입니다.

짧은 예시

Python
from langchain_core.prompts import ChatPromptTemplate

# from_messages: (역할, 틀) 짝의 목록으로 채팅 프롬프트 틀을 만든다
prompt = ChatPromptTemplate.from_messages([
    ("system", "너는 {company}의 여행 비서다. {tone} 말투로 답한다."),
    ("human", "{question}"),
])
# 두 줄의 빈칸이 한 목록에 모인다
print(prompt.input_variables)

value = prompt.invoke({"company": "구름다리여행", "tone": "친절한", "question": "짐은 몇 kg 까지 되나요?"})
print(type(value).__name__)
# to_messages(): 프롬프트 값을 메시지 목록으로 꺼낸다
for m in value.to_messages():
    print(type(m).__name__, "|", m.content)
출력
['company', 'question', 'tone']
ChatPromptValue
SystemMessage | 너는 구름다리여행의 여행 비서다. 친절한 말투로 답한다.
HumanMessage | 짐은 몇 kg 까지 되나요?

채운 결과는 ChatPromptValue 이고, 안에는 1장에서 손으로 만들던 메시지 두 개가 들어 있습니다. 이제 메시지를 직접 만들지 않고 틀에 사전만 넣으면 됩니다.

코드가 의미하는 것

이 코드는 배우 이름만 비워 둔 연극 대본을 만들고, 공연 날 이름을 채워 넣는 일을 흉내 낸 것입니다. 역할이 붙은 줄 둘로 틀을 만들고, 빈칸을 보고, 채운 뒤, 메시지로 펼쳐 봅니다.

코드하는 일챗봇에서 뜻하는 것
ChatPromptTemplate.from_messages([("system", …), ("human", …)])역할과 틀의 짝 목록으로 채팅 프롬프트 틀을 만든다챗봇의 규칙(system)과 손님 질문(human)을 줄로 나눠 둔 대본입니다
prompt.input_variables모든 줄의 빈칸을 한 목록으로 모은다회사 이름, 말투, 질문을 한 번에 넣으면 대본이 완성됩니다
prompt.invoke({...})사전을 받아 ChatPromptValue 를 만든다채팅 모델에 그대로 넣을 수 있는 꼴입니다
value.to_messages()프롬프트 값을 메시지 목록으로 꺼낸다모델에게 실제로 가는 메시지를 눈으로 확인하는 방법입니다

결과에서 읽을 것은 두 가지입니다.

  • 두 줄의 빈칸이 한 목록에 모였습니다. 첫 줄의 ['company', 'question', 'tone'] 에는 system 줄의 빈칸 둘과 human 줄의 빈칸 하나가 함께 있습니다.
  • 채운 결과는 1차시의 메시지 객체입니다. 셋째, 넷째 줄의 SystemMessage, HumanMessage 가 1장에서 손으로 만들던 것과 같은 꼴입니다. 이제 틀이 대신 만들어 줍니다.

주의할 점

  • 역할 이름은 "system", "human", "ai" 로 적습니다. OpenAI 식 이름인 "user", "assistant" 도 받아 주지만, 한 교안 안에서는 한쪽으로 맞춥니다. 이 교안은 LangChain 식 이름을 씁니다.
  • 손님이 쓴 글은 human 줄의 빈칸에만 넣습니다. system 줄의 빈칸에 손님의 글을 넣으면, 손님이 "앞의 규칙은 무시해"라고 적었을 때 그 말이 규칙처럼 읽힐 수 있습니다.
← 이전 절3장 · PromptTemplate다음 절 →3장 · 모델 부품 ChatOpenAI 의 설정