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

3장. LangChain 기본 구조와 LCEL

PromptTemplate

은행 창구의 입금표에는 "받는 분 ____, 금액 ____ 원"처럼 빈칸이 있습니다. 양식은 미리 인쇄해 두고, 손님마다 빈칸만 채웁니다. 프롬프트도 같습니다. "○○에서 ○일 동안 할 일을 추천해 줘"를 손님마다 새로 쓰지 않고, 빈칸이 있는 틀을 하나 만들어 두고 값만 바꿔 넣습니다.

빈칸이 있는 틀에 값을 넣어 완성된 글을 만드는 프롬프트 템플릿의 흐름도

왼쪽 상자가 중괄호로 빈칸을 표시한 틀, 가운데 상자가 넣을 값, 오른쪽 상자가 값이 채워진 완성된 글입니다. 여기서 인쇄된 입금표가 PromptTemplate, 손님이 쓰는 금액과 이름이 변수의 값입니다. 비유와 다른 점은, 입금표는 빈칸을 비워 내도 은행이 받아 주지만 프롬프트 템플릿은 빈칸 하나라도 비면 오류를 낸다는 것입니다.

틀을 다루는 방법

하는 일코드돌려주는 것
틀 만들기PromptTemplate.from_template("{place}에서 …")빈칸 있는 틀
빈칸 이름 보기template.input_variables빈칸 이름 목록(가나다·알파벳 차례)
글로 채우기template.format(place="강릉", days=2)보통 글자열
부품으로 채우기template.invoke({"place": "경주", "days": 3})프롬프트 값(StringPromptValue)
일부만 먼저 채우기template.partial(days=2)빈칸이 줄어든 새 틀

format 은 이름표 인자로 값을 받고, invoke 는 사전 하나로 받습니다. 체인 안에서는 invoke 가 쓰이므로, 체인에 넣는 입력도 사전입니다.

짧은 예시

Python
from langchain_core.prompts import PromptTemplate

# from_template: 글 속의 {이름} 을 빈칸으로 읽어 틀을 만든다
template = PromptTemplate.from_template("{place}에서 {days}일 동안 할 일을 세 가지 추천해 줘.")
print(template.input_variables)

# format: 빈칸에 값을 넣은 글자열을 돌려준다
print(template.format(place="강릉", days=2))

# invoke: 사전을 받아 프롬프트 값을 돌려준다. to_string() 으로 글을 꺼내 본다
value = template.invoke({"place": "경주", "days": 3})
print(type(value).__name__, "|", value.to_string())

# partial: days 만 먼저 채워 둔 새 틀. 이제 place 만 넣으면 된다
two_days = template.partial(days=2)
print(two_days.input_variables, two_days.format(place="여수"))
출력
['days', 'place']
강릉에서 2일 동안 할 일을 세 가지 추천해 줘.
StringPromptValue | 경주에서 3일 동안 할 일을 세 가지 추천해 줘.
['place'] 여수에서 2일 동안 할 일을 세 가지 추천해 줘.

input_variables 는 글에 나온 차례가 아니라 이름의 차례(days, place)로 늘어놓습니다. partial 로 days 를 채운 틀은 빈칸이 place 하나만 남았습니다.

코드가 의미하는 것

이 코드는 입금표 양식 한 장을 인쇄해 두고 빈칸을 여러 방식으로 채워 보는 일을 흉내 낸 것입니다. 틀을 만들고, 빈칸 이름을 보고, 두 가지 방법으로 채우고, 한 칸만 먼저 채운 새 양식을 만듭니다.

코드하는 일챗봇에서 뜻하는 것
PromptTemplate.from_template("{place}에서 …")글 속의 중괄호를 빈칸으로 읽어 틀을 만든다손님마다 프롬프트를 새로 쓰지 않고, 틀 하나를 두고 값만 바꿉니다
template.input_variables빈칸 이름 목록을 보여 준다이 틀을 채우려면 무엇을 넣어야 하는지 알려 주는 목록입니다
template.format(place=…, days=…)채운 보통 글자열을 돌려준다사람이 눈으로 확인할 때 쓰기 좋습니다
template.invoke({...})사전을 받아 프롬프트 값을 돌려준다체인 안에서 쓰이는 채우기입니다. 그래서 체인에 넣는 입력도 사전입니다
template.partial(days=2)일부만 채운 새 틀을 만든다늘 같은 값은 미리 채워 둡니다. 실습 1에서 FAQ 를 이렇게 넣습니다

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

  • 빈칸 이름은 이름 차례로 찍힙니다. 첫 줄 ['days', 'place'] 는 글에 나온 차례가 아닙니다.
  • format 과 invoke 는 꼴이 다릅니다. 둘째 줄은 글자열이고, 셋째 줄은 StringPromptValue 입니다. 글은 같아도 체인에 넘기는 것은 프롬프트 값입니다.
  • partial 뒤에는 빈칸이 줄어듭니다. 넷째 줄의 ['place'] 처럼 남은 빈칸만 채우면 됩니다.

주의할 점

  • 빈칸을 빠뜨리고 invoke({"place": "경주"}) 처럼 부르면 KeyError 가 나고, 오류 글에 "missing variables {'days'}"(빠진 변수)가 적힙니다. 오류 글을 읽으면 어느 빈칸이 비었는지 바로 압니다.
  • 프롬프트에 중괄호를 글자 그대로 쓰고 싶으면 {{ 와 }} 처럼 두 번 겹쳐 적습니다. 한 번만 쓰면 빈칸으로 읽힙니다. JSON 예시를 프롬프트에 넣을 때 자주 걸립니다.
← 이전 절3장 · Runnable 과 invoke·batch·stream다음 절 →3장 · ChatPromptTemplate