스캔된 PDF가 운영 중인 나의 송장 에이전트를 망가뜨린 방법
요약
스캔된 PDF의 낮은 품질로 인해 송장 추출 에이전트가 잘못된 데이터를 생성하는 문제를 다룹니다. 모델의 성능 개선 대신 검증 레이어와 인간 검토 프로세스를 도입하여 시스템의 신뢰성을 확보하는 실무적인 해결책을 제시합니다.
핵심 포인트
- 모델의 확신(confidence)이 항상 정확성을 보장하지 않음
- 에이전트와 다운스트림 시스템 사이에 검증 레이어 구축 필요
- 금액 범위, 날짜 유효성, 합계 일치 여부 등 규칙 기반 검증 적용
- 검증 실패 시 인간이 개입하는 검토 편지함(review inbox) 운영
새로운 공급업체의 첫 번째 배치가 들어온 지 4일째 되던 날, 나의 송장 추출 에이전트(invoice extraction agent)가 금액의 소수점 위치가 어긋난 문서 31개를 제출했습니다. 아무런 에러도 발생하지 않았습니다. 다운스트림 시스템(downstream system)은 모든 레코드를 수락했습니다. 에이전트는 매번 200 상태 코드를 반환했습니다.
데모 단계에서는 깨끗한 PDF 5개로 실행되었습니다. 선명한 폰트, 적절하게 형식화된 날짜, 일관된 레이아웃을 갖추고 있었습니다. 추출 에이전트는 공급업체 이름, 금액, 납기일, 품목(line items)을 가져왔습니다. 모든 필드가 채워졌고, 모든 출력값은 유효했습니다. 이해관계자 회의를 위해 실행했을 때, 그것은 마치 바로 출시해도 될 것 같은 모습이었습니다.
3개월이 지났을 때, 에이전트는 불만 없이 약 800개의 송장을 처리했습니다. 그러다 한 새로운 공급업체가 스캔된 문서로 전환했습니다. 약간 회전되어 있고, 얇은 폰트였으며, OCR(광학 문자 인식)은 저하된 원본 자료를 바탕으로 최선을 다하고 있었습니다. 모델은 금액 및 날짜와 유사한 텍스트를 찾아냈고, 확신에 찬 구조화된 출력(structured output)을 반환했습니다. 1,247.50이 12,475.0으로 읽혔습니다. 납기일은 3년 뒤의 유효한 날짜로 결정되었습니다. 문제는 확신(confidence)이었습니다. 모델에는 불확실하다고 말할 수 있는 메커니즘이 없었습니다. 그저 답을 내놓을 뿐이었습니다.
4일 동안 아무도 이를 잡아내지 못했습니다.
이후에 내가 구축한 것
문제는 모델이 아니었습니다. 모델은 설계된 대로 작동했습니다. 텍스트에서 구조를 찾아 반환하는 것 말입니다. 입력에서 출력으로 이어지는 직선적인 파이프라인(pipeline)에는 검문소(gate)가 없었습니다.
해결책은 더 많은 프롬프팅(prompting)이나 더 나은 모델을 사용하는 것이 아니었습니다. 나는 에이전트 출력과 다운스트림 시스템 사이에 검증 레이어(validation layer)를 추가했습니다. 이는 동기식(synchronously)으로 실행되며, 약 80ms가 소요되고, 다음 네 가지를 확인합니다:
- 모든 필수 필드가 null이 아닌지 확인합니다.
- 금액이 해당 공급업체 유형에 대해 설정된 범위 내의 양수로 파싱(parse)되는지 확인합니다.
- 날짜가 향후 90일 이내의 범위에 있는지 확인합니다.
- 추출된 총액이 작은 허용 오차 범위 내에서 품목 합계와 일치하는지 확인합니다.
검증에 실패하는 모든 항목은 대기열(queue) 대신 검토 편지함(review inbox)으로 라우팅됩니다. 사람이 이를 확인하고, 필요한 경우 수정하며, 해결됨으로 표시합니다. 시스템은 어떤 검증이 트리거되었는지와 입력값이 어떤 모습이었는지를 로그에 기록합니다.
배포 후 첫 일주일 동안, 이 레이어(layer)는 약 1,400개의 문서 중 23개를 잡아냈습니다. 11개는 품질이 낮은 스캔본이었고, 7개는 모델이 이전에 본 적 없는 형식의 유효한 송장이었습니다. 5개는 상류(upstream) 단계에서 누락된 중복 문서였습니다. 이 23개는 모두 이 레이어가 존재하기 전이라면 문제없이 통과되었을 문서들입니다.
검토용 편지함(review inbox)은 대단한 것은 아닙니다. HTML 테이블과 텍스트 영역(textarea)으로 이루어져 있으며, 만드는 데 3시간밖에 걸리지 않았습니다. 하지만 제가 이를 배포한 이후로 모든 중대한 추출 실패(extraction failure)를 잡아냈습니다.
신뢰성(Reliability)이 유일한 기능이다
저는 Agent Enterprise (aienterprise.dk)에서 에이전트 운영을 하고 있으며, 이러한 패턴은 저희가 배포하는 모든 도메인에서 나타납니다. 모델의 능력(capability)은 대부분 문제가 되지 않습니다. 자동으로 개선되지 않는 것은 에이전트가 생성한 결과물과 하류(downstream) 시스템이 신뢰하는 것 사이의 경계입니다.
모든 배포에는 각기 다른 형태의 이러한 가드(guard)가 있습니다. 일정 예약 에이전트의 경우, 제안된 시간대가 실제로 비어 있는지 확인하는 체크 과정입니다. 분류(classification) 에이전트의 경우, 특정 임계값(threshold) 미만의 레이블은 자동으로 적용되는 대신 검토 단계로 넘어가도록 하는 것입니다. 패턴은 일정합니다. 에이전트가 무언가를 생성하면, 그 결과물이 시스템 내에서 하나의 사실(fact)이 되기 전에, 결정론적인(deterministic) 무언가가 그것이 타당한지 검증합니다.
데모는 에이전트가 '할 수 있음'을 증명합니다. 프로덕션(Production)은 에이전트가 나쁜 입력값에 대해서도, 회전된 스캔본에 대해서도, 아무도 지켜보지 않는 새벽 3시에도 '정확하게 해낸다'는 것을 증명합니다. 사용자가 관심을 갖는 것은 바로 그 두 번째 증명입니다. 그리고 그것은 모델로부터 나오는 것이 아닙니다.
검증 레이어(validation layer)를 배포하는 것은 흥미진진한 일은 아닙니다. 하지만 매번 내릴 수 있는 올바른 결정입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기