6.5 KiB
Phase 1 — Trafilatura 통합 (다음 작업자 핸드오프)
본 문서는 Phase 0이 완료된 시점에서 Phase 1 작업을 이어받는 AI 에이전트 또는 개발자가 즉시 작업을 시작하기 위한 핸드오프 노트다.
시작 전 확인 사항
- Phase 0 Acceptance Gate가 모두 ✅인가? PHASE0_ACCEPTANCE_GATE.md 참조. 통과 전에는 Phase 1 진행 금지.
tests/unit와tests/integration전체가 PASS인가?- git log에 Phase 0 commit들이 PR 단위로 분리되어 있는가? (0.1 vendored / 0.2 bug fix / 0.3 multi-file / 0.4 FastAPI / 0.5 config / 0.6 e2e tests / 0.7 gate)
Phase 1 목표
URL이 입력일 때 원본 페이지에서 본문, 제목, 저자, 날짜, 언어, canonical URL을 정확히 뽑아 OntoCast의 ContentUnit metadata에 채워 넣는다.
근거: 통합설계서 §5 Phase 1, Trafilatura 분석 §11~§17.
왜 Trafilatura를 가장 먼저 통합하는가: 가장 작은 통합 — 단일 함수 호출(bare_extraction)만으로 끝남. 의존성도 명확하며 라이선스 동일 (Apache 2.0).
작업 단위 (PR 분해)
1.1: Trafilatura 의존성 활성화
pyproject.toml에 이미 trafilatura[all]>=2.0.0이 명시되어 있다. 활성화 절차:
pip install -e ".[dev]" # 의존성 재설치 시 trafilatura 자동 설치
python -c "import trafilatura; print(trafilatura.__version__)"
확인: 2.0.0 이상이 출력되어야 한다.
1.2: web_extractor.py 어댑터 작성
위치: platform/core/extractors/web_extractor.py
근거: Trafilatura 분석 §17의 extract_for_ontology 함수를 거의 그대로 사용.
필수 동작:
- 입력:
html: str,url: str,lang: str | None = None - 출력:
ExtractedWebDocument(dataclass)url,title,author,date,sitename,descriptiontext(정제 본문)body_xml(TrafilaturaDocument.body)metadata(raw dict)fingerprint(SimHash)
- 실패 시
None반환
호출 옵션 (Trafilatura 분석 §12 권장값 그대로):
Extractor(
output_format="python",
url=url,
with_metadata=True,
comments=False,
tables=True,
formatting=True,
links=True,
images=True,
dedup=True,
lang=lang,
)
1.3: ContentUnit 모델 확장
OntoCast의 vendored/ontocast/ontocast/onto/content_unit.py를 직접 수정하지 말고, 우리 쪽에 wrapper 모델을 만든다.
위치: platform/models/content_unit.py
필드 (통합설계서 §7.1 참조):
- 기존 OntoCast 필드 (
text,index,doc_iri,graph,type,iri) 유지/위임 - 추가:
source_url,title,author,publish_date,language,sitename,fingerprint,content_hash,metadata,retrieved_at,extracted_by
호환성: 기존 OntoCast 코드가 받는 ContentUnit과 인터페이스 호환되도록 as_ontocast() 메서드 제공.
1.4: OntoCast ConverterTool 분기 추가 (URL/HTML 입력)
문제: OntoCast ConverterTool은 PDF/DOCX/MD만 처리. URL 또는 HTML 입력은 처리 못 함.
조치 옵션:
- 옵션 A (권장): OntoCast의
convert_document.py모듈에 새 분기 추가 —.html,.htm확장자 또는state.source_url이 있으면 Trafilatura로 처리. vendored 수정이지만 매우 작음. - 옵션 B: API 레이어(
platform/api/)에서 입력이 URL이면 미리 fetch + Trafilatura 처리한 뒤 그 결과를 JSON envelope로 ToolBox에 넘김.
권장: 옵션 B. vendored 수정을 늘리지 않고 platform 코드로 끝낼 수 있음.
새 endpoint:
POST /process/url— body:{"url": "...", "ontology_user_instruction": "...", ...}— 내부적으로web_extractor로 본문 추출 후 OntoCast workflow 실행.
1.5: Fingerprint 기반 dedup
tests/fixtures/에 같은 본문의 두 URL fixture 만들기web_extractor결과의fingerprint가 일치하면 OntoCast 처리 skip- 저장 위치: 일단 in-memory set (
platform/storage/dedup_cache.py), Phase 2에서 Redis로 이전
1.6: 한국어 페이지 3종 추출 검증
테스트 fixture 수집:
- 한국어 뉴스 1개 (예: 연합뉴스/조선/한겨레)
- 한국어 블로그 1개 (예: 네이버 블로그)
- 한국어 쇼핑 페이지 1개 (예: 쿠팡 상품 페이지)
각각 raw HTML을 tests/fixtures/korean/에 저장 (실제 fetch는 운영 환경에서 한 번만, 그 결과를 fixture로 박제).
테스트: tests/integration/test_web_extractor_korean.py
- 본문 길이 > 200자
- title 추출 성공
- language 감지:
ko - author 또는 date 중 하나 이상 추출
1.7: Acceptance Gate 1 체크
통합설계서 §5 Phase 1 Acceptance Gate 4개 항목:
- URL 입력 → 본문/메타데이터가 정확히 추출되어
ContentUnit에 저장됨 - 한국어 뉴스/블로그/쇼핑 페이지 각각 1개씩 본문 추출 정확도 수동 검증
- 동일 URL 재입력 시 fingerprint 기반 dedup으로 skip
- Phase 0의 모든 기능이 여전히 정상 동작 (회귀 없음)
Phase 0의 tests/unit/, tests/integration/ 전체가 여전히 PASS여야 함.
Phase 1에서 만들 새 산출물
platform/
core/
extractors/
web_extractor.py ← 1.2
models/
content_unit.py ← 1.3
storage/
dedup_cache.py ← 1.5
api/
routes/
url_ingest.py ← 1.4 (POST /process/url)
tests/
fixtures/
korean/ ← 1.6
news_yonhap.html
blog_naver.html
shop_coupang.html
unit/
test_web_extractor.py ← 1.2
test_dedup_cache.py ← 1.5
integration/
test_url_ingest.py ← 1.4
test_web_extractor_korean.py ← 1.6
docs/
phases/
PHASE1_ACCEPTANCE_GATE.md ← 1.7 (PHASE0과 동일 형식)
PHASE2_NEXT_STEPS.md ← 다음 작업자에게 넘김
작업 시 준수사항 (PHASE0과 동일)
- PR 단위 분리: 1.1~1.7 각각 별도 PR/커밋.
- PR 설명에 근거 인용: 예) "통합설계서 §5 Phase 1 (1.2)에 따라 Trafilatura adapter 작성. Trafilatura 분석 §17 인용."
- vendored/ontocast/ 수정 최소화. 본 Phase에서는 옵션 B 사용 시 vendored 수정 0건이 목표.
- Phase 2로 넘어가지 말 것: Acceptance Gate 1 통과 전까지 Crawl4AI 의존성을 코드에서 import하지 않는다.
Phase 2 이후 핸드오프
Phase 1 완료 후 다음 작업자에게 동일한 형식의 PHASE2_NEXT_STEPS.md를 작성한다. 통합설계서 §12 Phase 2 작업 단위(2.1~2.8)를 참조.