C.W.K.
Stream
Lesson 03 of 04 · published

Captured Adapter

~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 태그에 싸였으면, 그대로는 색인 못 해. 먼저 풀어줘야 하고 — 어떻게 풀었는지 기억해야 해."

수집의 어려운 절반

captured adapter 는 텍스트가 드러나 있지 않은 소스를 다뤄. PDF, Word 문서, 슬라이드 덱 — 글은 진짜지만 바이너리 포맷 안에 잠겨 있어. 웹페이지 — 글이 HTML 태그 덤불에 묻혀 있어. captured adapter 는 변환기를 돌려: 바이너리 포맷엔 문서-to-마크다운 단계, 태그 오염엔 prose 추출기. 깨끗한 텍스트가 나오고, 그 깨끗한 텍스트가, 원본이 아니라, 문서가 돼.

변환, 스냅샷, 색인

captured 흐름엔 referenced 흐름엔 없는 추가 박자 하나가 있어. 소스를 읽고 바이트를 source_sha256 으로 해시해. 그 해시가 지난번과 맞으면 건너뛰어 — 비싼 변환이 다시 안 돌아. 아니면 소스를 깨끗한 텍스트로 변환하고, 그 텍스트를 append-only content-addressed 저장소로 스냅샷하고, 스냅샷을 chunk 하고 색인해. 스냅샷의 해시가 문서의 doc_sha256 이 돼서, 모든 chunk offset 이 변환된 텍스트를 가리켜; source_sha256 은 원본이 언제 바뀌는지 감지하려고만 옆에 둬.

스냅샷이 곧 문서야

이게 referenced 코퍼스에서의 핵심 사고 전환이야. referenced 파일은 문서가 곧 파일이야. captured 소스는 문서가 곧 변환이야 — 온 PDF 가 아니라 깨끗한 텍스트의 스냅샷. offset, chunk 해시, citation 전부 스냅샷을 가리켜. 원본 PDF 가 내일 사라져도 모든 chunk 가 여전히 보존된 스냅샷에 resolve 돼. capture 는 소스를 색인만 하는 게 아냐; 그 소스의 특정하고 버전 매겨진 읽기를 보존해.

소스를 변환할 땐, 포인터만이 아니라 변환을 보존해. 소스 수집이 변환을 뜻하면, 변환된 출력이 네 인덱스와 citation 이 실제로 의존하는 거야 — 그러니 그 출력은 바뀌거나 사라질 수 있는 소스에서 요구 시 재생성되는 게 아니라 capture 되고 보존돼야 해. 변환의 스냅샷이 captured 코퍼스의 진짜 ground truth 고; 귀하게 다뤄, 다른 무엇도 그걸 재생성 못 하니까.

파일별 실패가 실행을 절대 중단시키지 않아

현실 문서를 변환하는 건 지저분해 — 어떤 PDF 는 malformed 고, 어떤 포맷은 미지원이고, 어떤 변환은 그냥 실패해. 수백 파일에 대한 captured 재색인이 200번 파일이 깨진 스캔이라고 죽으면 안 돼. 그래서 파일별 변환 실패는 실행의 에러 stats 에 기록되고 순회는 계속 가. 전부-아니면-전무 크래시 대신 정직한 리포트를 얻어 — 이만큼 변환됨, 이만큼 안 바뀜으로 건너뜀, 이 특정 파일들이 에러남. 강인한 수집은 실행별이 아니라 파일별로 degrade 해.

Code

captured adapter: 변환, 스냅샷, 색인 — 에러가 중단 안 시켜·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, 슬라이드 덱, 웹페이지. 그것의 captured 흐름을 스케치해: 어떤 변환기가 깨끗한 텍스트로 바꾸고, 뭘 스냅샷할래? 그다음 보존 질문에 답해: 그 원본 소스가 1년 뒤 삭제되면, 네 인덱스가 여전히 resolve 될까? 아니라면, 변환을 capture 안 한 거야 — 사라질 수 있는 소스를 reference 만 한 거야.
Hint
reference 와 capture 의 차이는 변환된 출력을 지키냐야. citation 에 답하려고 (아마 사라진) 소스에 변환기를 다시 돌려야 한다면, capture 해야 할 걸 reference 한 거야. 변환을 스냅샷해서 citation 이 소스를 살아남게.

Progress

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

댓글 0

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

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