LangChain 챗봇4장 · 대화형 챗봇과 메모리 전략3 / 22← 이전목차다음 →MetaContents

4장. 대화형 챗봇과 메모리 전략

구조화된 출력이 필요한 까닭

여행사 상담원이 손님의 말을 메모지에 줄글로 적어 두었다고 해 봅시다. "제주도로 2박 3일, 어른 둘 아이 둘, 150만 원쯤". 나중에 다른 직원이 "이번 달 손님들의 평균 예산"을 구하려면 메모를 한 장씩 읽어 숫자를 골라내야 합니다. 상담 카드에 목적지 칸, 박수 칸, 예산 칸이 따로 있으면 다릅니다. 예산 칸만 쭉 모으면 됩니다.

줄글로 받은 답과 칸이 정해진 답을 나란히 놓고, 프로그램이 값을 꺼내기 쉬운 쪽을 견준 비교 그림

왼쪽은 모델이 쓴 줄글 답이고, 오른쪽은 열쇠와 값이 정해진 답입니다. 사람이 읽기에는 왼쪽도 괜찮지만, 프로그램이 값을 꺼내 계산하거나 화면의 칸에 넣으려면 오른쪽이어야 합니다. 여기서 메모지의 줄글이 3장까지 받은 글 답(StrOutputParser 의 결과)이고, 상담 카드가 구조화된 출력입니다. 비유와 다른 점은, 상담원은 카드의 칸을 알아서 채우지만 모델에게는 칸의 이름과 뜻을 우리가 알려 주어야 한다는 것입니다.

줄글과 칸으로 받기

견줄 것줄글 답구조화된 답
생김새"제주도로 2박 3일 가시는군요"{"목적지": "제주도", "박수": 2}
사람이 읽기편하다조금 딱딱하다
프로그램이 값 꺼내기글을 찾아 잘라야 한다열쇠 이름으로 바로 꺼낸다
계산하기글자를 숫자로 바꿔야 한다숫자 칸은 처음부터 숫자다
어울리는 곳손님에게 보여 줄 답예약 시스템, 표, 화면의 입력 칸

짧은 예시

같은 내용을 줄글과 사전으로 받았다고 보고, 박수와 1인당 예산을 꺼내 봅니다. 모델은 부르지 않습니다.

Python
answer_text = "제주도로 2박 3일, 어른 둘과 아이 둘이 가시는군요. 예산은 150만 원입니다."
answer_dict = {"목적지": "제주도", "박수": 2, "어른": 2, "아이": 2, "예산": 150}

# 줄글에서는 "박" 글자를 찾아 그 앞 글자를 잘라 내야 한다
at = answer_text.index("박")
print("줄글에서 꺼낸 박수:", answer_text[at - 1: at], type(answer_text[at - 1: at]).__name__)

# 사전에서는 열쇠 이름으로 바로 꺼내고, 숫자라서 바로 계산한다
print("사전에서 꺼낸 박수:", answer_dict["박수"], type(answer_dict["박수"]).__name__)
print("1인당 예산(만 원):", answer_dict["예산"] / (answer_dict["어른"] + answer_dict["아이"]))
출력
줄글에서 꺼낸 박수: 2 str
사전에서 꺼낸 박수: 2 int
1인당 예산(만 원): 37.5

줄글에서 꺼낸 "2"는 글자열(str)이라 계산하려면 다시 숫자로 바꿔야 합니다. "12박"처럼 두 자리가 되면 앞 글자 하나만 잘라 내는 이 코드는 틀린 값을 냅니다. 사전에서 꺼낸 2 는 처음부터 정수(int)라서 바로 나눗셈을 합니다.

코드가 의미하는 것

이 코드는 메모지의 줄글과 상담 카드에서 같은 값을 꺼내 보는 일을 흉내 냅니다. 같은 답을 두 모양으로 두고, 박수를 꺼내고, 계산까지 해 봅니다.

코드하는 일챗봇에서 뜻하는 것
answer_text = "제주도로 2박 3일, …"모델이 줄글로 답한 것을 둔다3장까지 StrOutputParser 로 받던 답의 모양입니다. 사람에게는 읽기 좋지만 프로그램에는 글자 덩어리일 뿐입니다
answer_dict = {"목적지": …, "박수": 2, …}같은 답을 열쇠와 값으로 둔다구조화된 출력으로 받은 답의 모양입니다. 실습 2에서 모델이 돌려줄 것이 이런 칸입니다
answer_text.index("박") 와 [at - 1: at]"박" 자리를 찾아 그 앞 글자를 잘라 낸다줄글 답에서 값을 꺼내려면 글의 생김새에 기대는 코드를 써야 합니다. 모델이 말투를 바꾸면 이 코드가 깨집니다
answer_dict["박수"]열쇠 이름으로 값을 꺼낸다칸 이름만 알면 답의 말투와 상관없이 같은 코드로 꺼냅니다
answer_dict["예산"] / (…)꺼낸 숫자로 바로 나눈다예약 시스템이나 표가 받아서 바로 쓸 수 있는 값이라는 뜻입니다

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

  • 같은 2, 다른 자료형. 줄글에서 꺼낸 2 는 str, 사전에서 꺼낸 2 는 int 입니다. 줄글 쪽은 계산하기 전에 한 번 더 바꿔야 합니다.
  • 칸으로 받으면 계산이 한 줄. 1인당 예산 37.5 는 사전의 값 셋만으로 구했습니다. 줄글이었다면 예산, 어른, 아이를 모두 글에서 찾아 잘라야 합니다.

주의할 점

  • 손님에게 보여 줄 답까지 모두 구조화할 필요는 없습니다. 프로그램이 값을 써야 하는 곳에만 씁니다. 이 장의 여행 비서도 대화는 줄글로, 여행 조건은 칸으로 받습니다.
  • 칸이 정해져 있어도 모델이 채운 값이 맞는지는 따로 확인해야 합니다. 칸이 맞는 것과 값이 맞는 것은 다른 일입니다. 실습 2에서 정답과 견줘 봅니다.
← 이전 절4장 · 용어 짚고 가기다음 절 →4장 · JSON 과 JsonOutputParser