지시어·생략이 섞인 모호한 질문을, 대화 맥락을 이용해 그 자체로 이해되는 독립된 질문(standalone question)으로 바꾸는 검색 전처리입니다. 맥락으로도 의도를 확정할 수 없으면 추측하지 않고 사용자에게 되묻는 것까지 포함합니다.
반대로 질문이 이미 완결돼 있으면 건너뜁니다. 모든 질문에 LLM 재작성을 거는 건 지연과 표류 위험만 늘립니다.
LangChain에서는 이 패턴을 create_history_aware_retriever(v1부터 langchain-classic 패키지)로 제공하지만, 프롬프트 한 번이면 되는 일이라 직접 구현하는 경우가 많습니다.
| 맥락 | 원 질문 | 명확화된 질문 |
|---|---|---|
| 직전 턴: "나이키 에어맥스 90 270mm 주문했어요" | 그거 배송 언제 와요? | 나이키 에어맥스 90 주문 건의 배송 예정일 |
현재 페이지: 상품 P-1234 (무선 청소기 X9) | 이거 A/S 받을 수 있어요? | 무선 청소기 X9의 A/S 정책과 신청 절차 |
| 직전 턴: 환불 정책 안내 | 교환은요? | 교환 정책과 교환 신청 절차 |
| 직전 턴: "주문한 지 일주일 됐어요" | 안 오는데요 | 주문 후 7일이 지나도 배송되지 않을 때 확인 방법과 문의 절차 |
| 맥락 없음 | 이거 얼마예요? | (확정 불가 → "어떤 상품의 가격을 알려드릴까요?"로 되묻기) |
| 맥락 없음 | 저거 환불 되나요? | (확정 불가 → 일반 환불 정책으로 검색하되 답변에서 대상 상품을 확인) |
| 장점 | 단점 |
|---|---|
| 멀티턴 대화에서 검색 품질이 크게 오름 (검색기는 이력을 모르므로 사실상 필수) | 턴마다 LLM 호출 1회 → 지연·비용 증가 |
| 사용자가 다시 묻지 않아도 올바른 문서를 참조 | 재작성이 틀리면 이후 검색·리랭크가 틀린 방향으로 정확해짐 |
| 재작성 결과를 로그로 남기면 "시스템이 어떻게 이해했는지" 디버깅 가능 | 맥락이 길어지면 오래된 주제를 잘못 끌어옴 |
| 되묻기로 불확실한 추측 답변을 줄임 | 되묻기가 잦으면 사용자 경험이 나빠짐 |
⚠️ 함정 — 근거 없는 구체화: 맥락이 없는데 "이거 얼마예요?"를 "이 제품의 가격은 얼마인가요?"로 바꾸는 건 명확화가 아닙니다. 지시어를 "이 제품"으로 옮겼을 뿐 대상은 여전히 모릅니다. 대상은 대화 이력·화면 상태에서만 가져오고, 없으면 되묻습니다.
⚠️ 함정 — 조건 창작: "환불 돼요?"를 "구매 후 7일 이내 환불 조건"으로 바꾸면 사용자가 말하지 않은 조건이 검색을 좁힙니다. 명확화는 대상 채우기까지만 하고, 조건은 추가하지 않습니다.
⚠️ 함정 — 원 질문 폐기: 재작성 질문만으로 검색하면 재작성 실패가 곧 시스템 실패가 됩니다. 원 질문 경로를 항상 함께 돌리고, 재작성 결과의 검색 점수가 낮으면 원 질문으로 롤백하세요.
⚠️ 함정 — 캐시 오염: 같은 "그거 환불 돼요?"도 대화마다 뜻이 다릅니다. 검색 캐시 키를 원 질문으로만 만들면 다른 사용자의 결과가 섞입니다. 재작성 결과·사용자 범위·맥락 출처를 키에 포함하세요.