1 파일 = 1 청크로 만든 노하우와, Top-k에서 막혔던 이야기
요약
본 글은 Dify를 활용하여 워크플로우 기반의 지식 검색 시스템을 구축한 노하우와 발생했던 문제 해결 과정을 공유합니다. 질문과 답변 쌍이 분리되지 않도록 파일 단위로 청크를 관리하고, 식별자 설정 및 Top-k 값 확인 등 구체적인 기술적 팁을 제공합니다.
핵심 포인트
- FAQ는 질문 1건당 파일 1개로 등록하여 데이터 손실 방지
- 식별자는 데이터에 절대 등장하지 않는 문자열을 사용해야 함
- 질문과 답변이 세트로 검색되도록 청크 분할 전략 수립
- Top-k 설정은 워크플로우와 지식 등록 쪽 두 곳에서 확인 필요
지난 글에서는 블랙박스였던 챗봇을 처리 과정을 단계별로 확인할 수 있는 '워크플로우형'으로 전환하고 싶다는 내용을 작성했습니다.
이번에는 실제로 Dify를 이용해 워크플로우와 지식(ナレッジ)을 어떻게 만들었는지, 어떤 노하우가 있었고 어디서 막혔는지를 정리합니다.
일단 다음 흐름으로 구성했습니다.
- 질문을 받는다
- 인사말인 경우, 다시 질문을 듣는다
- 질문이 이 챗봇의 대응 범위 내에 있는지 판별한다
- 범위 내라면, 지식을 검색하여 답변한다
이전 시스템에서는 이 모든 것을 하나의 프롬프트에 담았습니다. 이번에는 단계를 나누었기 때문에, 각 단계가 무엇을 출력했는지 개별적으로 확인할 수 있습니다.
지식으로 등록한 것은 다음 두 가지입니다.
- 과거 질문과 답변을 Markdown 형식으로 작성한 FAQ
- 용어집
【용어집을 넣은 이유. 예: 약어나 전문 용어의 오차 대응 등을 위해서】
FAQ는 질문 1건당 파일 1개로 등록했습니다. 서식은 다음과 같이 통일했습니다.
## 질문
(질문 내용)
## 답변
...
Dify의 지식에는 청크를 분할하는 위치를 정하는 식별자(識別子) 를 설정할 수 있습니다. 여기서 한 가지 주의할 점이 있습니다. 식별자로 지정한 문자는 분할될 때 청크에서 제거됩니다.
따라서, 예를 들어 식별자를 ##로 설정하면, ## 질문과 ## 답변 위치에서도 분할되어 질문과 답변이 별개의 청크가 되어버립니다.
일반 모드에서는 검색으로 히트한 청크가 그대로 LLM에 전달됩니다. 만약 질문만 히트하고 답변을 포함하지 않은 청크가 전달되면, AI는 답을 받을 수 없습니다.
그래서 식별자에는 abababababababa와 같이 데이터 안에 절대 등장하지 않는 문자열 을 지정했습니다. 식별자로 인해 분할되지 않기 때문에, 질문과 답변이 반드시 세트로 검색 결과에 나타납니다.
식별자로 분할하지 않는 대신, 최대 청크 길이를 초과한 부분은 강제로 분할됩니다. 그래서 최대 청크 길이를 4000자로 설정했습니다. FAQ 1건이 이 길이에 들어오면, 파일 1개가 그대로 하나의 청크가 됩니다.
즉, '파일 단위'를 그대로 '검색의 단위'로 만든 것입니다.
정확도 검증을 하다가 막힌 부분이 있었습니다.
지식 검색의 Top-k 설정 위치가 총 2군데에 있었던 것입니다.
저는 정확도 검증할 때, 워크플로우 내의 Top-k를 변경하며 결과를 비교했습니다. 그런데 변경했는데도 그대로 반영되지 않는 경우가 몇 번 있었습니다.
원인은 아직 단정하기 어렵지만, 지식 등록 쪽 설정이 우선하고 있을 가능성이 높다고 생각합니다 (확인 필요).
마찬가지로 Top-k를 조정해서 '바꿨는데 동작이 바뀌지 않는다'면, 지식 쪽 설정도 확인해 보세요.
- 워크플로우는 먼저 최소 구성으로 만들고, 단계별로 확인할 수 있는 형태로 만들었다.
- FAQ는 1건당 파일 1개로 하고, 식별자에는 데이터에 등장하지 않는 문자열을 지정하여 질문과 답변이 분할되지 않도록 했다.
- 식별자로 사용한 문자는 청크에서 제거되고, 최대 청크 길이를 초과하면 강제 분할된다는 점에 주의한다.
- Top-k는 워크플로우 내부와 지식 등록 쪽 설정의 2군데가 있다. 변경이 반영되지 않을 때는 양쪽 모두 확인해야 한다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기