강좌
65개 강의 중 34번째 · Claude with Amazon Bedrock텍스트 청킹 전략
Sign in to save your progressYou can keep reading without an account, but completed lessons won't be saved.
Not nowSign in

텍스트 청킹(chunking)은 RAG(Retrieval Augmented Generation) 파이프라인을 구축할 때 가장 중요한 단계 중 하나입니다. 문서를 어떻게 나누는지는 전체 시스템의 품질에 직접적인 영향을 미칩니다. 청킹 전략이 부실하면 관련 없는 컨텍스트가 프롬프트에 삽입되어 AI가 완전히 잘못된 답변을 내놓을 수 있습니다.

다음 예시를 생각해 보세요: 의료 연구와 소프트웨어 엔지니어링에 관한 섹션이 있는 문서가 있습니다. 청킹이 부실하면 "올해 엔지니어들이 몇 개의 버그를 수정했나요?"라고 묻는 사용자가 의료 연구에 관한 정보를 받을 수 있는데, 이는 단순히 의료 섹션에 다른 맥락에서 "버그"라는 단어가 포함되어 있었기 때문입니다.

이는 청킹 전략이 왜 그렇게 중요한지를 보여줍니다. 목표는 의미적 일관성을 유지하고 검색되었을 때 유용한 컨텍스트를 제공하는 청크를 만드는 것입니다.

세 가지 주요 청킹 전략

텍스트를 청크로 나누는 데는 세 가지 주요 접근 방식이 있습니다:

  • 크기 기반(Size-based): 텍스트를 동일한 길이의 문자열로 나눕니다
  • 구조 기반(Structure-based): 문서 구조(헤더, 단락, 섹션)를 기준으로 분할합니다
  • 의미 기반(Semantic-based): NLP 기법을 사용하여 관련된 문장이나 섹션을 그룹화합니다

크기 기반 청킹

크기 기반 청킹은 가장 간단한 접근 방식입니다. 문서를 대략 동일한 문자 수 또는 단어 수의 청크로 나누기만 하면 됩니다. 구현이 쉽고 다양한 문서 유형에서 안정적으로 작동합니다.

하지만 이 접근 방식에는 명확한 단점이 있습니다:

  • 단어가 문장 중간에서 잘릴 수 있습니다
  • 청크가 주변 텍스트에서 중요한 컨텍스트를 잃게 됩니다
  • 관련된 내용이 여러 청크에 걸쳐 분할될 수 있습니다

오버랩 추가하기

컨텍스트 문제를 해결하기 위해 오버랩 전략을 구현할 수 있습니다. 각 청크는 인접한 청크의 일부 문자를 포함하여 추가적인 컨텍스트를 제공하고 청크 경계에서 중요한 정보가 손실되지 않도록 보장합니다.

이는 약간의 중복을 만들어내지만, 각 청크가 얻는 향상된 컨텍스트를 고려하면 대체로 그만한 가치가 있는 트레이드오프입니다.

구조 기반 청킹

문서가 일관된 형식(명확한 헤더가 있는 마크다운 등)을 갖추고 있다면, 구조 기반 청킹은 훌륭한 결과를 낼 수 있습니다. 헤더와 같은 구조적 요소를 기준으로 분할하여 문서의 자연스러운 구성에 맞는 청크를 만듭니다.

이는 잘 포맷된 문서에서는 훌륭하게 작동하지만 문서 구조에 대한 보장이 필요합니다. 일반 텍스트 파일이나 일관성 없이 포맷된 문서에서는 안정적으로 작동하지 않습니다.

구현 예시

다음은 구현할 수 있는 세 가지 실용적인 청킹 함수입니다:

문자 기반 청킹

python
def chunk_by_char(text, chunk_size=150, chunk_overlap=20):
    chunks = []
    start_idx = 0
    
    while start_idx < len(text):
        end_idx = min(start_idx + chunk_size, len(text))
        chunk_text = text[start_idx:end_idx]
        chunks.append(chunk_text)
        
        start_idx = (
            end_idx - chunk_overlap if end_idx < len(text) else len(text)
        )
    
    return chunks

문장 기반 청킹

python
def chunk_by_sentence(text, max_sentences_per_chunk=5, overlap_sentences=1):
    sentences = re.split(r"(?<=[.!?])\s+", text)
    chunks = []
    start_idx = 0
    
    while start_idx < len(sentences):
        end_idx = min(start_idx + max_sentences_per_chunk, len(sentences))
        current_chunk = sentences[start_idx:end_idx]
        chunks.append(" ".join(current_chunk))
        
        start_idx += max_sentences_per_chunk - overlap_sentences
        
        if start_idx < 0:
            start_idx = 0
    
    return chunks

섹션 기반 청킹

python
def chunk_by_section(document_text):
    pattern = r"\n## "
    return re.split(pattern, document_text)

올바른 전략 선택하기

청킹 전략의 선택은 전적으로 특정 사용 사례에 따라 달라집니다:

  • 문자 기반: 가장 신뢰할 수 있는 대안으로, 모든 문서 유형에서 작동합니다
  • 문장 기반: 프로즈(prose)에 대해 컨텍스트와 의미의 균형이 좋습니다
  • 섹션 기반: 구조화된 문서가 있을 때 훌륭한 결과를 제공합니다

포맷에 대한 보장이 없는 사용자 업로드 문서의 경우, 문자 기반 청킹이 가장 안전한 선택인 경우가 많습니다. 잘 구조화된 내부 문서의 경우, 섹션 기반 청킹이 더 우수한 결과를 제공할 수 있습니다. 문장 기반 청킹은 대부분의 프로즈에 잘 작동하지만 마침표를 예상치 못한 방식으로 사용하는 코드나 기술 문서에서는 어려움을 겪을 수 있습니다.

청킹은 종종 반복적인 과정이라는 점을 기억하세요. 간단한 접근 방식으로 시작하여 특정 문서와 사용 사례로 테스트한 다음, RAG 시스템에서 얻는 결과의 품질을 바탕으로 개선해 나가세요.