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

변환 결과까지 보존하는 어댑터

~12 min · captured, adapters, conversion, snapshot

Level 0꺼진 심지
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"글이 PDF 안에 갇히거나 HTML 태그에 싸여 있다면 먼저 꺼내야 해. 그리고 어떤 방식으로 꺼냈는지도 남겨야 하지."

텍스트가 바로 드러나지 않는 소스

PDF와 Word 문서, 슬라이드에는 읽을 글이 있지만 바이너리 형식 안에 들어 있어. 웹페이지의 본문은 HTML 태그와 속성 사이에 묻혀 있고. captured adapter는 이런 소스에 변환기를 적용해. 문서 파일은 마크다운으로 바꾸고 웹 콘텐츠는 본문만 추출해서, 검색할 수 있는 깨끗한 텍스트를 만들어.

원본 해시를 확인한 뒤 변환하고 보존해

먼저 원본 바이트의 source_sha256을 계산해 지난번 값과 비교해. 그대로라면 비싼 변환을 건너뛰어. 달라졌다면 소스를 변환하고 결과 텍스트를 내용 기반의 덧붙이기 전용 저장소에 스냅샷한 뒤 chunk로 나누어 색인해. 스냅샷의 해시가 doc_sha256이 되고 문자 위치도 모두 변환된 텍스트를 기준으로 삼아.

captured 코퍼스에서는 스냅샷이 문서야

referenced 코퍼스는 디스크 파일이 문서지만 captured 코퍼스는 변환 결과가 문서야. 인용과 chunk 해시, 문자 위치가 모두 스냅샷을 가리켜. 원본 PDF가 나중에 사라져도 이미 고정한 텍스트는 남아 있고, 그 소스를 어떤 버전의 변환기로 읽었는지도 설명할 수 있어. 캡처는 검색 가능하게 만드는 일과 특정한 읽기를 보존하는 일을 함께 맡아.

변환이 필요했다면 포인터만 남기지 말고 변환 결과를 지켜. 인덱스와 인용이 실제로 의존하는 것은 PDF 파일이 아니라 거기서 꺼낸 텍스트야. 다시 만들 수 있다는 희망에 맡기지 말고 그 결과 자체를 귀한 원본으로 보존해야 해.

깨진 파일 하나가 전체 수집을 멈추게 하지 마

현실의 문서에는 손상된 PDF와 지원하지 않는 형식이 섞여 있어. 수백 파일을 변환하다 하나가 실패했다고 실행 전체를 버리면 멀쩡한 나머지도 색인하지 못해. Lantern은 파일별 오류를 통계에 기록하고 다음 파일로 넘어가. 실행이 끝나면 몇 개를 변환했고, 몇 개는 바뀌지 않아 건너뛰었으며, 어느 파일이 왜 실패했는지 정직한 보고서를 얻어. 수집은 파일 하나가 실패해도 멈추지 않고 나머지를 끝까지 처리할 수 있어야 해.

Code

캡처형 어댑터는 변환하고 보존한 뒤 색인하며, 한 오류가 전체를 막지 않아·python
class CapturedAdapter:
    """The source needs conversion. Convert -> snapshot -> index; skip unchanged."""

    def reindex(self, corpus) -> dict:
        stats = {"converted": 0, "skipped": 0, "errors": []}
        for src in discover(corpus.roots, corpus.include_globs):
            source_sha = sha256(read_bytes(src))
            if source_sha == last_source_sha(corpus.id, src):
                stats["skipped"] += 1                     # unchanged: no re-convert
                continue
            try:
                text = self.converter.convert(src)        # PDF/DOCX/HTML -> clean text
                snap = snapshot_store.append(text)        # doc_sha256 == snapshot hash
                index_document(corpus.id, src, doc_sha=snap, source_sha=source_sha,
                               text=text)
                stats["converted"] += 1
            except ConversionError as e:
                stats["errors"].append((src, str(e)))     # one bad file != dead run
        return stats

External links

Exercise

PDF나 슬라이드, 웹페이지처럼 색인 전에 변환해야 하는 소스 하나를 골라 캡처 흐름을 그려봐. 어떤 변환기로 깨끗한 텍스트를 만들고 무엇을 스냅샷으로 보존할지 정해. 그런 다음 원본이 1년 뒤 사라져도 인덱스의 항목을 여전히 확인할 수 있는지 물어봐. 할 수 없다면 변환 결과를 캡처한 게 아니라, 사라질 수 있는 원본만 참조한 거야.
Hint
참조형과 캡처형의 차이는 변환 결과까지 보존하느냐에 있어. 인용을 확인하려고 이미 사라졌을지 모르는 원본에 변환기를 다시 돌려야 한다면, 캡처로 지켜야 할 것을 참조만 한 거야. 변환 결과를 스냅샷으로 남겨서 원본이 사라진 뒤에도 인용을 확인할 수 있게 해.

Progress

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

댓글 0

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

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