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

3장. LangChain 기본 구조와 LCEL

다양한 프롬프트 2: 퓨샷과 단계별 지시

처음 아르바이트를 하면 선배가 "주문은 이렇게 받아"라며 손님 응대 두어 번을 직접 보여 줍니다. 설명을 길게 듣는 것보다 본보기 두 번을 보는 편이 빨리 따라 합니다. 일이 복잡하면 "먼저 메뉴를 확인하고, 그다음 결제를 받고, 마지막에 번호표를 줘"처럼 순서를 일러 줍니다. 앞의 것이 퓨샷, 뒤의 것이 단계별 지시입니다.

예시 질문과 답을 보여 주는 퓨샷과 할 일을 순서대로 적는 단계별 지시를 견준 비교 그림

왼쪽 상자는 예시를 보여 주는 퓨샷, 오른쪽 상자는 순서를 적어 주는 단계별 지시입니다. 퓨샷은 답의 "꼴"을, 단계별 지시는 생각하는 "차례"를 잡아 줍니다. 여기서 선배가 보여 준 응대 두 번이 퓨샷의 예시이고, "먼저, 그다음, 마지막에"가 단계별 지시입니다. 비유와 다른 점은, 아르바이트생은 본보기의 뜻을 헤아리지만 모델은 본보기의 겉모양(길이, 머리말, 말투)까지 그대로 따라 하기 쉽다는 것입니다.

프롬프트의 갈래

갈래프롬프트에 넣는 것좋은 점아쉬운 점
제로샷지시와 질문만짧고 토큰이 적다답의 꼴이 들쭉날쭉하다
퓨샷예시 질문·답 몇 쌍 + 질문답의 꼴을 정확히 맞춘다예시만큼 토큰이 늘어난다
단계별 지시"먼저 ~, 그다음 ~" 순서 + 질문여러 단계의 일을 빠뜨리지 않는다답이 길어지기 쉽다

단계별 지시는 예를 들어 이렇게 적습니다. "먼저 손님의 상황(누구와, 언제)을 한 줄로 정리한다. 그다음 FAQ 에서 맞는 항목을 고른다. 마지막에 그 항목으로 답한다." 순서를 적으면 모델이 상황 정리 같은 앞 단계를 건너뛰지 않습니다.

짧은 예시

FewShotChatMessagePromptTemplate 은 Few-Shot(몇 번 보여 주기), Chat Message(채팅 메시지), Prompt Template 을 붙인 이름입니다. 예시 사전 목록과 예시 한 쌍의 틀을 받아, 예시를 human·ai 메시지 쌍으로 펼쳐 줍니다.

Python
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate

# 예시 두 쌍: 답 앞에 [의도] 를 붙이는 꼴을 보여 준다
examples = [
    {"question": "짐은 몇 개까지 되나요?", "answer": "[수하물] 국내선은 15kg 짐 한 개가 포함됩니다."},
    {"question": "카드 할부 돼요?", "answer": "[결제] 5만 원 이상이면 최대 6개월 할부가 됩니다."},
]
# 예시 한 쌍을 메시지 두 줄(human, ai)로 펼치는 틀
example_prompt = ChatPromptTemplate.from_messages([("human", "{question}"), ("ai", "{answer}")])
few_shot = FewShotChatMessagePromptTemplate(
    examples=examples,              # 보여 줄 예시 목록
    example_prompt=example_prompt,  # 예시 하나를 펼치는 틀
)

# 시스템 지시, 예시들, 진짜 질문 차례로 놓는다
prompt = ChatPromptTemplate.from_messages([
    ("system", "손님 질문에 [의도] 를 앞에 붙여 한 문장으로 답한다."),
    few_shot,
    ("human", "{question}"),
])
for m in prompt.invoke({"question": "강아지도 같이 가요?"}).to_messages():
    print(type(m).__name__, "|", m.content)
출력
SystemMessage | 손님 질문에 [의도] 를 앞에 붙여 한 문장으로 답한다.
HumanMessage | 짐은 몇 개까지 되나요?
AIMessage | [수하물] 국내선은 15kg 짐 한 개가 포함됩니다.
HumanMessage | 카드 할부 돼요?
AIMessage | [결제] 5만 원 이상이면 최대 6개월 할부가 됩니다.
HumanMessage | 강아지도 같이 가요?

예시 두 쌍이 사용자·어시스턴트 메시지 네 개로 펼쳐지고, 맨 끝에 진짜 질문이 붙었습니다. 모델은 앞의 대화에서 자기가 "[의도] 한 문장" 꼴로 답해 왔다고 보고, 강아지 질문에도 "[반려동물] …" 꼴로 답하기 쉽습니다.

코드가 의미하는 것

이 코드는 선배가 손님 응대를 두 번 보여 준 뒤 새 손님을 맡기는 일을 흉내 낸 것입니다. 본보기 두 쌍을 적고, 본보기를 펼칠 틀을 정하고, 시스템 지시와 본보기와 진짜 질문을 차례로 놓습니다.

코드하는 일챗봇에서 뜻하는 것
examples = [{"question": …, "answer": …}, …]예시 질문과 답을 사전 목록으로 둔다모델에게 보여 줄 본보기입니다. 답 앞의 [의도] 같은 꼴을 따라 하게 합니다
example_prompt예시 한 쌍을 human·ai 두 줄로 펼치는 틀본보기를 "손님이 묻고 챗봇이 답한" 대화처럼 꾸밉니다
FewShotChatMessagePromptTemplate(examples=…, example_prompt=…)예시 목록을 틀에 맞춰 메시지로 펼친다예시가 늘거나 바뀌어도 목록만 고치면 됩니다
from_messages([("system", …), few_shot, ("human", …)])지시, 예시, 진짜 질문을 차례로 놓는다모델은 앞의 대화를 보고 같은 꼴로 마지막 질문에 답합니다

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

  • 예시 두 쌍이 메시지 네 개가 됐습니다. 둘째 줄부터 다섯째 줄까지 HumanMessage 와 AIMessage 가 번갈아 나옵니다.
  • 진짜 질문은 맨 끝입니다. 마지막 줄의 강아지 질문 앞에 시스템 지시 하나와 예시 네 개가 함께 가므로, 예시만큼 보내는 토큰이 늘어납니다.

주의할 점

  • 예시는 실제로 받을 질문과 비슷한 것으로 고르고, 서로 다른 갈래를 섞습니다. 예시가 모두 수하물 질문이면 모델이 무엇을 물어도 수하물 이야기를 하려 합니다.
  • 예시는 요청마다 함께 보내지므로 토큰과 요금이 늘어납니다. 두세 쌍이면 꼴을 잡기에 대개 충분합니다.
← 이전 절3장 · 다양한 프롬프트 1: 역할·형식·제약 지시다음 절 →3장 · RunnablePassthrough·RunnableLambda·RunnableParallel 로 체인 넓히기