URL을 Markdown으로 변환하는 API가 내비게이션 메뉴를 'article'로 제공한 문제점 파악 및 개선
요약
URL을 Markdown으로 변환하는 API가 빈 콘텐츠를 반환하여 RAG 파이프라인에 내비게이션 메뉴 같은 불필요한 정보를 삽입하는 문제를 발견했습니다. 이 문제는 SPA 쉘 페이지에서 발생했으며, 추출 임계값 설정, 메타 디스크립션 활용 등 여러 개선책을 적용하여 데이터의 신뢰성을 크게 높였습니다.
핵심 포인트
- 추출된 콘텐츠가 빈 경우 명시적인 low_content 플래그를 제공해야 합니다.
- SPA 쉘 페이지에서는 og:description과 meta description을 요약으로 사용하는 것이 효과적입니다.
- CSS 선택자 옵션을 추가하여 호출자가 기사 컨테이너를 직접 지정할 수 있게 했습니다.
- 헤드리스 Chromium 사용은 비용 및 지연 시간 측면에서 현재 트래픽 규모에 적합하지 않습니다.
제가 만든 URL-to-Markdown API는 처음에 간단한 가독성(readability) 검사 과정이었습니다. 즉, URL을 가져와 네비게이션/광고/사이드바를 제거하고 깨끗한 Markdown 형태로 반환하는 것이었죠. 이 방식은 제가 테스트했던 모든 블로그, 문서 사이트, 뉴스 기사에서 완벽하게 작동했습니다. 그러다 제가 직접 요청 로그를 감사하다가 아무도 불평하지 않는 실패 모드를 발견했습니다. 왜냐하면 오류(error)가 나지 않기 때문입니다.
6개 URL 중 약 1개가 60단어 미만으로 돌아왔습니다. 이것은 오류가 아니었습니다. 200 OK 상태 코드, 유효한 Markdown, 기술적으로는 올바른 출력물이었습니다. 하지만 그 '콘텐츠'는 Skip to content / Home / About / Sign in과 푸터(footer)뿐이었습니다. 저는 사람들의 RAG 파이프라인에 은밀하게 내비게이션 메뉴를 삽입하고 있었던 것입니다. 유효한 출력물이었지만, 정보가 전혀 없었고 심지어 예외 상황보다 더 나빴는데, 그 이유는 다운스트림 시스템에서 아무도 이를 감지하지 못했기 때문입니다.
원인은 SPA(Single Page Application) 쉘 페이지였습니다. 서버는 대부분 비어있는 루트 div를 가진 실제 HTML을 반환하고, 기사 내용은 클라이언트 측에서 조립됩니다. 제 추출 과정은 찾을 실제 콘텐츠가 없었기 때문에, 단순히 보일러플레이트(boilerplate) 코드를 마치 기사처럼 보이도록 잘라냈던 것입니다.
제가 영향도 순으로 수정한 내용들은 다음과 같습니다:
-
추출 임계값 (Extraction floor). 단어 수가 특정 임계값 이하로 떨어지거나 보일러플레이트 비율이 너무 높은 경우, 자신감 있는 쓰레기 데이터 대신 명시적인
low_content플래그와 함께 단어 수를 반환하도록 했습니다. 이것이 가장 큰 개선점이었는데, 실패를 눈에 보이게 만들었기 때문입니다. -
폴백 계층 (Fallback ladder). 쉘 페이지의 경우,
og:description과 메타 디스크립션(meta description)을 시도하고, 이를 요약(summary)으로 명확하게 표시합니다. 정직한 40단어짜리 요약이 산문처럼 위장하는 메뉴 40단어보다 훨씬 낫습니다. -
탈출구 (Escape hatch). CSS 선택자 옵션을 추가하여, 사이트를 잘 아는 호출자들이 기사 컨테이너를 직접 지정할 수 있게 했습니다. 인쇄 보기(Print views)나 RSS 엔드포인트는 메인 페이지에 없는 전체 텍스트를 담고 있는 경우가 많습니다.
-
제가 의도적으로 하지 않은 것: 헤드리스 Chromium을 추가하는 것이었습니다. 제가 벤치마킹해 봤는데, 동시 렌더링당 수백 MB의 RAM과 p95 지연 시간이 약 800ms에서 6초 이상으로 늘어났습니다. 제 트래픽 규모에서는 비싸고 절반만 렌더링하는 것보다 시끄럽지만 저렴한 실패가 더 나았습니다. 만약 쉘 페이지가 대다수가 된다면 재검토할 것입니다.
플래그가 배포된 후, 제 재시도 로직은 빈 문자열을 임베딩하는 대신 쉘 페이지를 다른 곳으로 라우팅하도록 변경되었고, useful-content는 500-URL 샘플에서 약 83%에서 96%로 향상되었습니다. 솔직히 말씀드리자면, SSR도 메타 태그도 없는 순수 클라이언트 렌더링 페이지는 결코 잘 추출되지 않을 것입니다. 핵심은 더 많이 추출하는 것이 아니라, 무엇이 반환되었는지에 대해 절대 거짓말을 하지 않는 것입니다.
결국 저는 강화된 버전을 URL-to-Markdown API로 패키징했습니다: https://x402.freeq.one/tools/markdown.html
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기