본문 바로가기
C.W.K.
Stream
Lesson 01 of 04 · published

청킹으로 검색의 원자 만들기

~12 min · chunking, offsets, atom, whole-document

Level 0꺼진 심지
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"찾고 싶은 것은 책 한 권이 아니라 그 안의 한 문단이야. chunking은 그 문단의 경계를 정하는 일이야."

문서 전체는 검색 결과로 너무 커

특정 아이디어를 찾았는데 만 단어짜리 에세이 전체를 돌려주면 관련 문장을 다시 찾아야 해. 임베딩 모델도 한 번에 읽을 수 있는 토큰 수가 정해져 있고. 그래서 문서를 chunk로 나눠. 답으로 보여줄 만큼 구체적이고 모델의 입력 범위에 들어갈 만큼 작되, 하나의 생각을 이해할 맥락은 남기는 크기여야 해.

검색과 인용이 다루는 최소 단위

색인되고 임베딩되고 순위에 오르며 인용되는 것은 모두 chunk야. 그렇다고 단순한 문자열 조각은 아니야. 어느 코퍼스의 어느 문서에서 왔는지, 문서 안의 정확한 범위가 어디인지, 내용이 변하지 않았는지 확인할 해시를 함께 가져야 해. 자기 출처와 주소를 설명할 수 있어야 검색 결과가 소문이 아니라 인용이 되거든.

문자 위치는 같은 정규 텍스트를 기준으로 삼아

char_startchar_end는 UTF-8로 디코드한 정규 텍스트의 문자 위치야. 바이트 위치는 한글처럼 여러 바이트를 쓰는 문자에서 어긋날 수 있고, 줄 번호는 개행 방식에 따라 흔들려. 문서 해시를 계산한 바로 그 텍스트에서 문자 범위를 기록하면 text[start:end]로 같은 chunk를 다시 자르고 해시를 확인할 수 있어.

검색의 원자를 정했다면 그 원자가 자기 주소를 갖게 해. 원문과 정확한 위치를 모르는 결과는 다시 검증할 수 없고, 다시 검증할 수 없는 결과는 인용할 수 없어.

문서가 바뀌면 chunk 세트 전체를 교체해

한 문장을 고쳤다고 영향받은 chunk만 찾아 수선하지 않아. 해당 문서의 옛 chunk를 전부 지우고 새로 계산한 세트를 하나의 트랜잭션으로 넣어. 개별 조각을 비교해 붙이면 경계와 문자 위치가 어긋나는 예외를 놓치기 쉬워. 문서 하나를 변경의 최소 안전 단위로 삼으면 쿼리는 언제나 완전한 옛 버전이나 완전한 새 버전 중 하나만 보고, 둘이 섞인 중간 상태를 만나지 않아.

chunk 크기도 profile에 이름 붙여 버전으로 남겨야 해. 너무 작으면 주장을 이해할 맥락이 사라지고, 너무 크면 관련성이 흐려지며 임베딩 입력 한도를 넘을 수 있어. 만능 숫자는 없으니 콘텐츠에 맞춰 선택하되, 나중에 규칙을 바꿀 때는 옛 인용을 지킬 수 있게 새 profile을 발행해야 해.

Code

청크마다 원문 속 위치를 정확히 기록해 검증할 수 있어·python
def chunk_document(text: str, profile) -> list[Chunk]:
    """Cut a document into chunks, each carrying its exact offsets into `text`."""
    chunks, cursor = [], 0
    for span in split_paragraphs(text, max_chars=profile.max_chars):
        start = text.index(span, cursor)      # character offset into canonical text
        end = start + len(span)
        chunks.append(Chunk(
            text=span,
            char_start=start,                  # re-sliceable: text[start:end] == span
            char_end=end,
            chunk_sha256=sha256(span),         # verifiable
        ))
        cursor = end
    return chunks

# On change: delete ALL of a document's chunks, reinsert the new set atomically.
# Never try to patch individual chunks — that's where offsets drift out of sync.

External links

Exercise

긴 문서 하나를 골라 문단처럼 자연스러운 경계에서 청크로 나눠봐. 각 청크의 시작과 끝 문자 위치를 적고 text[start:end]가 정확히 그 문장을 돌려주는지 확인해. 위치가 하나만 어긋나도 정규 텍스트의 문자 범위를 기록하고 해시로 검증해야 하는 이유가 보여. 작은 위치 오차 하나가 모든 인용을 말없이 깨뜨릴 수 있어.
Hint
좋은 청크 기록은 문서와 시작·끝 문자 위치만으로 정확한 청크를 다시 만들 수 있어야 해. '끝의 개행도 지웠지' 같은 별도 기억이 필요하다면 그 위치가 정규 텍스트를 제대로 가리키지 않는 거야. 검증은 바로 그런 틈에서 실패해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.