범용 문서 변환기가 배운 교훈: '모든 문서를 처리한다'는 것은 들어본 적 없는 파일 형식까지 지원해야 함
요약
범용 문서 변환 API를 구축하며 파일 형식 처리의 어려움을 경험했다. 단순 확장자 검사나 MIME 스니핑만으로는 RTF 같은 레거시 형식을 다루기 어렵다는 것을 알게 되었다. 진정한 '범용성'은 모든 형식을 지원하는 것이 아니라, 지원하지 못할 때 명확한 오류를 반환(fail loudly)하는 것임을 강조한다.
핵심 포인트
- 단순 확장자 검사 방식으로는 구형/독점 파일 처리가 불가능하다.
- MIME 스니핑은 개선된 방법이나, RTF 같은 레거시 형식은 여전히 난제다.
- '범용적'이라는 것은 모든 형식을 아는 것이 아니라 실패를 명확히 알리는 것이다.
- RAG 파이프라인 구축 시에는 실제 프로덕션 데이터의 엣지 케이스 테스트가 필수적이다.
제가 범용적인 문서-Markdown API를 구축했을 때, 핵심 콘셉트는 간단했습니다. 어떤 문서 URL이나 바이트 데이터를 보내도 LLM(대규모 언어 모델)이 바로 사용할 수 있는 Markdown을 돌려주는 것입니다. 유형은 자동으로 감지됩니다. 선택할 별도의 엔드포인트가 필요 없었습니다.
하지만 구현 과정은 결코 단순하지 않았습니다.
처음 만든 검출기는 파일 확장자를 확인하는 방식이었습니다. ".pdf"는 PDF 파서, ".docx"는 DOCX 파서를 사용하면 끝이었습니다. 그러다가 사용자가 2003년의 구형 바이너리 Word 형식인 ".doc" 파일을 보내왔습니다. 제 변환기는 어깨를 으쓱하며 쓰레기 같은 결과물을 돌려주었습니다. 또 다른 사용자는 Apple의 독점 형식인 ".pages" 파일을 보냈고, 결과는 같았습니다.
그래서 저는 MIME 스니핑(MIME sniffing) 방식으로 전환했습니다. 처음 몇 바이트를 읽어 마법 숫자(magic numbers)를 확인하는 방식입니다. 'PK\x03\x04'는 ZIP 기반의 오피스 형식을 의미하고, '%PDF'는 PDF를 의미합니다. 이 방법으로 명백한 케이스들은 해결되었습니다.
그다음부터가 이상한 파일들이었습니다. LibreOffice의 형식인 OpenDocument Text(.odt) 파일은 괜찮았습니다. ZIP 기반이라 처리할 수 있었습니다. 하지만 Rich Text Format(RTF) 파일은 달랐습니다. 1987년에 제정된, 유니코드보다 앞선 사양입니다. 이 부분이 어려웠습니다. RTF는 문서 형식이 아니라 타자기 시절부터 내려온 이스케이프 시퀀스로 이루어진 '제어 언어의 혼합물'에 가깝습니다.
진짜 교훈은 이것이었습니다: '범용적(universal)'이라는 것이 '모든 형식을 안다'는 의미가 아니라는 것입니다. 그것은 '지원하지 못할 때는 크게 실패한다(fail loudly)'는 의미입니다. 이제 제 변환기는 지원하지 않는 파일을 만나면, 단순히 빈 Markdown을 생성하는 대신 감지된 유형과 함께 명확한 오류를 반환합니다. 이 API를 호출하는 에이전트들은 '성공적으로 변환됨'과 '도대체 이게 뭔지 모르겠다' 사이의 차이를 알아야 합니다.
만약 RAG(검색 증강 생성) 파이프라인에 문서를 투입한다면, 데모에서 사용된 파일뿐만 아니라 실제 파일을 가지고 테스트해야 합니다. 엣지 케이스는 항상 프로덕션 데이터에 존재합니다.
가장 이상한 파일들을 시험해보고 싶다면, API는 https://x402.freeq.one/tools/document_to_markdown.html에서 사용할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기