16장. 멀티턴 대화와 세션 관리
왜 멀티턴이 필요한가 — "그거"가 뭔지 모른다
한 줄 요약
지금까지 만든 에이전트는 개별 문의에는 답할 수 있지만, 이전 대화의 내용을 기억하지 못합니다. 고객이 앞서 말한 상품을 "그거"라고 부르면 무엇을 가리키는지 알기 어렵습니다. 이번 장에서는 대화 이력을 저장하고 새로운 질문과 함께 모델에 전달해, 앞선 내용을 바탕으로 대화를 이어 가는 방법을 배웁니다.
1. 상담은 한 문장으로 끝나지 않는다
실제 상담은 이렇게 흘러갑니다.
고객: 7월 11일에 주문한 손목 보호대 배송 상태 알려주세요.
하루: 손목 보호대 2개입은 7월 14일에 배송이 완료되었습니다.
고객: 그거 다른 색상도 있어요?
사람에게 "그거"는 물을 것도 없이 방금 말한 손목 보호대입니다. 그런데 우리 상담원에게 두 번째 문의만 보내면 이렇게 답합니다.
고객: 그거 다른 색상도 있어요?
하루: 고객님, 방금 말씀하신 '그거'가 어떤 상품을 말씀하시는지 제가 정확히 알 수 없어 확인이 어렵습니다.
찾으시는 상품의 이름이나 키워드를 알려주시면, 다른 색상이 있는지 바로 조회해 드리겠습니다.
모델이 둔해서가 아닙니다. 이 호출에서 모델이 받은 글은 저 한 문장이 전부였습니다.
2. 원인 — LLM은 상태가 없다
LLM은 앞선 호출을 기억하지 않습니다. 이 성질을 상태 없음(stateless) 이라고 부릅니다. 호출 하나하나가 모델에게는 처음 만남입니다.
우리는 이 성질을 이미 두 번 다뤘습니다.
| 어디서 | 무엇을 했나 | 기억이 살아 있는 범위 |
|---|---|---|
| 5장 | 모델의 도구 결정과 도구 결과를 contents에 담아 다시 보냈다 |
문의 하나를 처리하는 동안 |
| 9장 | 루프를 돌며 contents를 계속 쌓았다 |
문의 하나를 처리하는 동안 |
| 이번 장 | 문의가 끝나도 contents를 버리지 않는다 |
대화가 이어지는 동안 |
5장과 9장에서는 답변을 돌려주는 순간 쌓아 둔 내용을 버렸습니다. 그래서 다음 문의는 늘 백지에서 시작했습니다. 이번 장에서 바꾸는 것은 그 한 가지입니다. 버리지 않고 들고 있다가 다음 문의 앞에 붙여 보냅니다.
문의 하나와 그에 대한 답 한 번을 턴(turn) 이라고 하고, 턴이 여러 번 이어지는 대화를 멀티턴(multi-turn) 대화라고 합니다.
3. 이걸 모르면 무엇을 판단하지 못하는가
- 챗봇이 앞의 말을 잊을 때 모델 탓인지 우리 코드 탓인지 가려내지 못합니다. 대부분 우리가 이력을 보내지 않은 것입니다.
- 대화가 길어질수록 왜 한 마디의 비용이 비싸지는지 설명하지 못합니다.
- 긴 대화에서 이력을 얼마나 들고 있을지를 무엇을 보고 정해야 하는지 알지 못합니다.
- 고객 A의 대화에 고객 B의 내용이 섞이는 사고를 어디서 막아야 하는지 알지 못합니다.
4. 이번 장에서 만드는 것
| 만드는 것 | 한 줄 설명 |
|---|---|
| 대화 이력 | 지금까지 오간 메시지 전체. 우리가 보관하고 매번 다시 보낸다 |
| 스레드 | 서로 섞이면 안 되는 대화 하나의 단위 |
| trim | 이력이 너무 길어지면 오래된 턴부터 버리는 관리법 |
이번 장의 산출물은 ChatSession 클래스입니다. 대화 하나의 이력을 들고 있다가, 새 문의가 올 때마다 이력 전체와 함께 모델에 보냅니다. 표준 질문 Q7("그거 혹시 지금 취소하면 환불은 언제 들어와요?")에 답할 수 있게 되는 것이 목표입니다.
핵심 정리
- LLM은 상태가 없습니다. 앞선 호출을 기억하지 않습니다.
- "그거"를 못 알아듣는 것은 모델의 결함이 아니라 우리가 앞의 대화를 보내지 않았기 때문입니다.
- 5장·9장에서 문의 하나 안에서 하던
contents누적을 문의와 문의 사이로 넓히는 것이 멀티턴입니다. - 이번 장의 산출물은 대화 이력을 관리하는
ChatSession입니다.