"찾고 싶은 것은 책 한 권이 아니라 그 안의 한 문단이야. chunking은 그 문단의 경계를 정하는 일이야."
문서 전체는 검색 결과로 너무 커
특정 아이디어를 찾았는데 만 단어짜리 에세이 전체를 돌려주면 관련 문장을 다시 찾아야 해. 임베딩 모델도 한 번에 읽을 수 있는 토큰 수가 정해져 있고. 그래서 문서를 chunk로 나눠. 답으로 보여줄 만큼 구체적이고 모델의 입력 범위에 들어갈 만큼 작되, 하나의 생각을 이해할 맥락은 남기는 크기여야 해.
검색과 인용이 다루는 최소 단위
색인되고 임베딩되고 순위에 오르며 인용되는 것은 모두 chunk야. 그렇다고 단순한 문자열 조각은 아니야. 어느 코퍼스의 어느 문서에서 왔는지, 문서 안의 정확한 범위가 어디인지, 내용이 변하지 않았는지 확인할 해시를 함께 가져야 해. 자기 출처와 주소를 설명할 수 있어야 검색 결과가 소문이 아니라 인용이 되거든.
문자 위치는 같은 정규 텍스트를 기준으로 삼아
char_start와 char_end는 UTF-8로 디코드한 정규 텍스트의 문자 위치야. 바이트 위치는 한글처럼 여러 바이트를 쓰는 문자에서 어긋날 수 있고, 줄 번호는 개행 방식에 따라 흔들려. 문서 해시를 계산한 바로 그 텍스트에서 문자 범위를 기록하면 text[start:end]로 같은 chunk를 다시 자르고 해시를 확인할 수 있어.
문서가 바뀌면 chunk 세트 전체를 교체해
한 문장을 고쳤다고 영향받은 chunk만 찾아 수선하지 않아. 해당 문서의 옛 chunk를 전부 지우고 새로 계산한 세트를 하나의 트랜잭션으로 넣어. 개별 조각을 비교해 붙이면 경계와 문자 위치가 어긋나는 예외를 놓치기 쉬워. 문서 하나를 변경의 최소 안전 단위로 삼으면 쿼리는 언제나 완전한 옛 버전이나 완전한 새 버전 중 하나만 보고, 둘이 섞인 중간 상태를 만나지 않아.
chunk 크기도 profile에 이름 붙여 버전으로 남겨야 해. 너무 작으면 주장을 이해할 맥락이 사라지고, 너무 크면 관련성이 흐려지며 임베딩 입력 한도를 넘을 수 있어. 만능 숫자는 없으니 콘텐츠에 맞춰 선택하되, 나중에 규칙을 바꿀 때는 옛 인용을 지킬 수 있게 새 profile을 발행해야 해.