기술

옆 프로젝트에 파서 문제를 알렸더니, 3년 전 견적서가 올해 문서로 색인돼 있었습니다

2026.10.068분 읽기

사내 문서를 긁어 파싱하고 청크로 잘라 검색에 태우는 도구를 두 곳에서 각자 만들고 있었습니다. 한쪽은 이미 운영 중인 사내 문서 지식그래프 검색 도구였고, 다른 한쪽은 같은 구조를 뒤늦게 다시 푸는 새 플랫폼이었습니다. 포맷별 파서, OCR, 청크 가드라는 똑같은 판을 서로 모르게 두 번 깔고 있었던 셈입니다.

하루 동안 뒤에 선 쪽이 파서 넷을 갈아엎었습니다. 그 과정에서 나온 발견을 먼저 선 쪽에 그때그때 알렸고, **그 알림이 오간 자리에서만 나온 결과가 따로 있었습니다.** 한쪽 혼자서는 못 찾았을 결함이 양쪽에서 각각 나왔습니다.


변환이 값을 바꾸는데 파서는 성공으로 끝납니다

바꾼 것 자체는 단순합니다. 포맷마다 오피스 변환기로 PDF 를 한 번 거쳐 읽던 경로를 걷어내고, 전용 리더로 원본을 직접 읽게 했습니다. 중간 포맷 하나를 뺀 것뿐인데 추출량이 포맷마다 수 배에서 수십 배로 달라졌습니다.

포맷

전 (변환 경유)

후 (전용 리더)

표계산 옛 포맷

표 줄 0

표 줄 243 · 값 오류 셀 0

프레젠테이션

표 줄 1,077 · 표가 잡힌 문서 55건

표 줄 37,823 · 표가 잡힌 문서 104건

워드 문서

표 줄 173

표 줄 1,051

프레젠테이션 쪽이 약 35배입니다. 표가 납작하게 뭉개져 들어가고 있었다는 뜻이고, 검색이 표 안의 수치를 못 집던 이유가 거기 있었습니다.

그런데 가장 값진 발견은 양이 아니었습니다. 오피스 변환기로 표계산 파일을 다른 포맷으로 옮기면 **수식이 다시 계산됩니다.** 오늘 날짜를 반환하는 함수가 변환한 날로 밀리고, 그 값을 참조하던 금액 수식은 오류값으로 깨집니다. 그리고 **파서에는 에러가 안 납니다** — 정상 종료하고, 깨진 값이 그대로 색인됩니다.

이것은 앞의 표와 등급이 다른 문제입니다. 표 줄이 덜 잡히는 것은 검색 품질 문제고, 값이 바뀌는 것은 오답 문제입니다. 같은 파서 이슈 목록에 섞어 두면 우선순위가 갈립니다.

변환기가 수식을 다시 계산하는 대목은 따로 한 번 더 파 봤습니다.

오피스 변환을 거치면 날짜 함수가 재계산되어 금액이 오류값으로 깨지는데 파서는 정상 종료하는 흐름


알림 한 줄이 옆 코퍼스의 전수 조사 질의가 됐습니다

값이 깨진다는 사실을 먼저 선 쪽에 알렸습니다. 그쪽은 그 말을 고치라는 요구로 받지 않고 **자기 코퍼스 전체에 같은 질의를 돌렸습니다.** 오류값 셀이 들어간 표를 전부 찾아낸 결과, 3년 전 견적서가 올해 문서로 색인돼 있었습니다. 오류값 셀 32개, 값이 바뀐 문서 20건이 재색인 대상으로 잡혔습니다.

남이 자기 버그를 찾아 준 것이 아닙니다. **남의 발견이 자기 질의가 된 것입니다.** 혼자였으면 그 질의를 던질 이유가 없었습니다. 색인은 돌고 있었고 검색도 결과를 냈고, 연도가 밀린 문서는 밀렸다는 표시를 어디에도 남기지 않았습니다.

반대 방향 왕복도 같은 모양이었습니다. 뒤에 선 쪽이 같은 문구가 반복되며 붕괴하는 청크를 3건 발견해 알렸습니다. 앞에 선 쪽이 전수로 세니 52건이 나왔고, 그 숫자를 보고 뒤쪽이 다시 전수로 셌습니다.

뒤쪽이 눈에 걸린 3건을 알립니다

앞쪽이 자기 코퍼스를 전수로 세어 52건을 찾습니다

그 숫자를 보고 뒤쪽이 다시 전수로 세니 7건, 합쳐 82,608자였습니다

7건 중 절반이 OCR 을 거친 문서가 아니라 원래 글자층이 있는 문서였습니다

마지막 줄이 중요합니다. 처음 발견한 3건은 전부 OCR 결과물이었습니다. 거기서 멈췄으면 가드를 OCR 경로에만 붙였을 것이고, 그러면 절반을 못 잡았을 겁니다. 전수로 다시 센 덕에 가드가 붙을 자리가 **OCR 경로가 아니라 청크를 만드는 한 자리**로 옮겨졌습니다. 적용 뒤 '반복 붕괴'는 0건입니다.

발견 3건이 전수 조사 52건을 부르고 다시 전수 재계수 7건으로 돌아와 가드 위치가 바뀌는 왕복 구조


발견은 가져오고 기본값은 가져오지 않았습니다

참고한다는 말이 그대로 따른다는 뜻은 아닙니다. 이미 운영 중인 쪽의 설정은 검증된 값처럼 보이지만, **그쪽 코퍼스에 맞춰진 값**입니다. 가져오기 전에 자기 자료로 한 번 재 봤고, 두 건이 다 손해였습니다.

프레젠테이션을 오피스 변환 경유로 읽는 기본 설정 — 그대로 따랐으면 표 줄 35배를 놓쳤을 겁니다

아이콘을 걸러내려고 둔 최소 픽셀 기준 — 가져왔으면 뒤쪽 문서 8건을 통째로 버렸을 겁니다. 그 8건은 전부 글자가 든 가로 띠 캡처라 작은 이미지로 분류됩니다

두 번째가 특히 아슬아슬했습니다. 아이콘이 실제로 많은 자료라면 그 기준은 맞는 선택입니다. 설정이 틀린 것이 아니라 **코퍼스가 다른 것**이고, 그 차이는 자기 자료에 대 보기 전에는 안 보입니다.

OCR 은 기준을 하나로 모았습니다. 사내 GPU 에 올린 오픈 모델과 외부 상용 멀티모달 API 가 섞여 있으면 어느 모델이 낸 글자인지에 따라 품질이 갈립니다. 353건 1,503쪽을 전량 다시 전사해 한쪽으로 통일했습니다. 종량제 창구라 회차마다 비용이 드는데, 두 모델의 결과가 섞인 상태를 남기는 쪽이 더 비쌀 것으로 봤습니다.

파서를 바꾸면 추출량이 늘어나는 것 자체가 품질 개선인지는 따로 재 봐야 합니다.


공유는 메시지가 아니라 파일로 남겼습니다

오간 내용이 대화 메시지로만 남으면 다음 세션에 사라집니다. 그래서 공용 참고문서를 저장소로 만들어 커밋했습니다. 안에 든 것은 네 가지입니다.

포맷별 결정표 — 어느 포맷을 어느 리더로 읽는지, 왜 그렇게 정했는지

검색 적재 규칙 — 청크를 만드는 자리와 거기 붙은 가드

두 프로젝트 대조표 — 같은 항목에서 양쪽 설정이 어떻게 다른지

주고받기 — 질문과 답을 파일로 남깁니다. 세션 메시지는 만료되기 때문입니다

그리고 양쪽 에이전트 메모리에 이 저장소를 등록했습니다. **다음 세션이 파서를 건드리기 전에 읽게** 하는 것이 목적입니다. 읽는 시점을 강제하지 않으면 결정표는 있어도 안 읽히고, 다음 사람이 같은 함정을 다시 밟습니다.

회귀 15문항으로 확인했습니다. 14/15 유지, 나빠진 문항 0, 그리고 **근거 파일이 더 맞는 자료로 바뀐 것이 11문항**입니다. 점수는 그대로인데 답의 출처가 달라진 것이 이번 작업의 실제 결과입니다.

상대의 발견은 전수 조사 질의로 가져오고 상대의 기본 설정은 자기 자료로 재 본 뒤 버리는 두 갈래 판단


같은 일을 두 곳에서 할 때 점검할 것

중간 포맷을 거치는 구간이 있는지 — 변환은 양만 줄이는 것이 아니라 값을 바꿉니다

정상 종료를 성공으로 읽고 있는지 — 조용히 틀리는 변환은 에러를 안 냅니다

상대가 알려 온 발견을 전수 조사 질의로 바꿔 봤는지 — 눈에 걸린 건수가 전체 건수는 아닙니다

상대의 기본 설정을 자기 자료로 재 봤는지 — 운영 중이라는 사실이 내 코퍼스에 맞다는 근거는 아닙니다

결정이 만료되는 채널에 남아 있는지 — 세션 메시지에 남긴 결정은 다음 세션에 사라집니다

이 왕복에는 비용이 듭니다. 서로 알리고 다시 세는 데 시간이 들고, 발견의 등급이 표가 조금 덜 잡히는 수준이면 과합니다. 발견이 '값이 틀린다' 등급일 때만 값을 합니다.

그리고 코퍼스가 닮아야 대 보는 값이 나옵니다. 도메인과 포맷 분포가 완전히 다르면 상대의 수치는 소음입니다. 이번에는 둘 다 사내 문서 검색이라 성립했습니다. 공용 문서도 유지 비용이 들어서, 참여가 늘거나 한쪽이 멀어지면 결정표가 낡습니다. 낡은 결정표는 없는 것보다 나쁩니다.

#문서파싱#코퍼스품질#RAG#교차검증#조용한실패