기술

표에 다 있는 요구사항을 LLM에게 다시 찾게 했습니다 — 12만 청크에 $246

2026.09.129분 읽기

지난 제안 문서를 그래프에 올려 「이런 요구가 왔을 때 우리는 뭐라고 답했나」에 답하게 하는 사내 제안서 지식검색 도구를 손보고 있었습니다. 이전 추출 방식은 단순했습니다. 문서를 잘게 쪼개 전부 LLM 에 밀어 넣는 것입니다. 12만 청크가 들어갔고 종량 요금으로 $246 이 나왔습니다.

청구서를 정리하다 확인한 것이 있습니다. 그때 뽑으려던 요구사항은 공공조달 제안요청서의 표준 요구사항 분류 코드 표에 이미 행 단위로 들어 있었습니다. SFR·DAR·SER 같은 코드가 붙은 그 표입니다. 표를 읽으면 되는 것을 문장에서 다시 찾게 시킨 셈입니다.


같은 일을 두 번 시키고 있었습니다

폴더명·파일명·표·머리글·양식은 사람이 이미 분류해 둔 결과입니다. 제안요청서를 쓴 담당자가 요구사항을 코드별로 나눠 표에 적어 넣었고, 문서를 폴더에 넣은 사람이 연도와 사업을 구분해 두었습니다. 그 위에 대고 본문을 처음부터 읽히면 사람이 한 번 끝낸 분류를 모델에게 다시 시키는 것이 됩니다.

손해는 돈에서 끝나지 않습니다. 문서가 늘면 청구액이 선형으로 늘고, 답이 매번 달라 재현이 안 되고, 틀려도 왜 틀렸는지 추적이 안 됩니다. 세 가지가 같은 원인에서 나옵니다.

한 필드에 대해서는 이 순서를 이미 적용한 적이 있습니다. 발신자를 뽑을 때 헤더와 정규식으로 먼저 깎고 남은 것만 모델에 보냈습니다. 이번에 한 일은 그 순서를 파이프라인 전체로 넓힌 것입니다.


세 층으로 나눠 위에서부터 깎습니다

같은 파이프라인의 다음 단계를 짜기 전에 순서를 먼저 규칙으로 못 박기로 했습니다. 온톨로지 정의 파일과 설계 문서에 3층 채우기 원칙을 한 절로 적었습니다. 코드가 아니라 문서에 적은 이유는 다음에 필드를 추가하는 사람이 같은 순서를 밟게 하기 위해서입니다.

무엇으로 깎나

종량 비용

1층 구조 파싱

폴더명·파일명·표

0원

2층 사전 조회

용어 lookup

0원

3층 단발 LLM

위 둘로 안 깎인 것만

호출한 만큼

핵심은 각 층에서 얼마나 깎였는지를 세는 것입니다. 안 세면 위층을 넓힐 가치가 있는지 판단할 근거가 없습니다. 위층을 건너뛰면 그만큼이 그대로 아래층 청구서가 됩니다.

619-1.jpg


층마다 얼마나 깎였는지 셉니다

첫 배치는 문서 종류 분류였습니다. 제안요청서인지 제안서인지 결과보고서인지를 3,083건에 대해 정하는 일입니다. 층별로 세어 보면 이렇습니다.

처리 층

건수

비중

이미지 제외 (1층)

264건

9%

규칙 적중 (1층)

1,291건

42%

단발 LLM (3층)

1,528건

50%

합계

3,083건

100%

모델을 한 번도 부르지 않고 끝나는 비율은 처음에 30% 였습니다. 규칙만으로 1,291건이 잡히는 것을 확인하고 파일명 규칙을 넓혔더니 그 비율이 50% 가 됐습니다 — 위 표의 264건과 1,291건을 합친 1,555건입니다. 이 결정은 숫자를 세었기 때문에 나왔습니다. 세지 않았으면 규칙을 손볼 가치가 있는지 알 방법이 없습니다.

남은 1,528건은 구독 인증 REST 창구로 보냈습니다. 20.9분에 끝났고 오류 0건, 목록 적중률 99.5%, 동시 3, 레이트리밋 응답 0건입니다. 종량 요금은 0원입니다.

다음은 요구사항이었습니다. 표준 코드 표에서 그대로 파싱해 1,451개를 적재했고 LLM 호출은 0회입니다. 사업 120개 중 34개에 그 표가 있었습니다. 폴더명 규칙은 120건 전부 적중해 연도가 공짜로 나왔습니다.

일부 사업에는 수용조건표도 있습니다. 제안서를 쓰면서 우리가 만든 요구와 대응의 대조표입니다. 사업 11개·코드 157개가 여기 걸렸고, 대응 103개 중 요구사항과 짝이 맞는 85개를 적재했습니다. 처음에는 표의 머리행과 분류 머리행이 데이터로 섞여 들어와 오염률이 17% 였는데, 두 종류를 걸러 0% 가 됐습니다.

619-2.jpg


3층은 에이전트가 아니라 단발 호출입니다

3층을 에이전트로 두는 쪽이 편해 보입니다. 도구를 물려주고 알아서 찾게 하면 되기 때문입니다. 배치에서는 그쪽이 손해입니다.

같은 프롬프트로 두 창구를 재봤습니다.

창구

입력 토큰

지연

에이전트 CLI

4,040

7.1초

REST 단발

49

2.7초

입력 기준 82배입니다. 에이전트 CLI 는 매 호출마다 도구 정의·스킬·프로젝트 지시문을 싣고 부팅합니다. 문장 한 줄을 분류하면서 그 값을 다 냅니다. 3천 건이면 3천 번 냅니다.

토큰만의 문제도 아닙니다. 루프가 있으면 같은 입력에도 답이 매번 달라집니다. 3천 건짜리 배치에서 그것은 검증이 불가능하다는 뜻입니다. 배치에 필요한 것은 예측 가능하고 재현되고 싼 것이고, 셋을 다 만족하는 쪽이 단발 호출입니다. 에이전트가 필요한 자리는 사람이 물어보는 답변 시점 하나였습니다.

619-3.jpg

창구를 재는 김에 하나가 더 나왔습니다. 설정은 한 제공자를 가리키고 있었는데, 실행 경로에 그 CLI 바이너리가 없어 매번 다른 모델로 조용히 폴백하고 있었습니다. 에러가 안 나서 아무도 몰랐습니다. 위층이 아래층을 감싸는 구조에서는 폴백이 일어났다는 사실 자체를 밖으로 드러내야 합니다.


위층이 항상 이기지는 않습니다

「표가 있으면 공짜」라는 말은 뒤집으면 「표를 만든 사람이 있어야 공짜」입니다.

적재한 대응 85개 중 77개가 한 사업에서 나왔습니다. 한 공공 발주처 건인데, 그 사업만 수용조건표를 꼼꼼히 채워 뒀습니다. 나머지 28개 사업은 요구사항 정의표만 있어서 대응은 제안서 본문에서 찾아야 합니다. 1·2층으로 갈 수 있는 거리가 여기서 끝났습니다.

알려진 결함도 있습니다. 코드 체계가 사업마다 달라 우연히 겹칩니다. 한 코드에서 요구는 측정 기준에 관한 것인데 대응은 전혀 다른 도메인 분석이 붙어 있는 건을 실제로 확인했습니다. 정확도를 더 끌어올리는 대신 대응의 출처 문서명을 함께 저장했습니다. 자동 추출의 신뢰는 「몇 퍼센트냐」보다 「틀린 걸 나중에 찾을 수 있느냐」에서 나옵니다.

규칙을 넓히는 비용도 공짜가 아닙니다. 무료 처리 비율을 30% 에서 50% 로 올린 일에는 사람 시간이 들어갔습니다. 건수가 작으면 규칙을 짜는 것보다 그냥 모델에 보내는 쪽이 쌉니다. 분기점은 건수와 재실행 빈도입니다.

여기서 아낀 종량 요금 0원은 구독 정액을 이미 내고 있다는 전제 위에 있습니다. 순수한 절감이 아니라 이미 낸 돈을 쓴 것입니다.


파이프라인을 짜기 전에 확인할 것

뽑으려는 값이 폴더명·파일명·표·머리글에 이미 들어 있는지 먼저 확인합니다

층마다 몇 건이 깎였는지 셉니다. 안 세면 위층을 넓힐지 아래층을 키울지 판단할 근거가 없습니다

배치에 쓰는 호출이 에이전트인지 단발인지 구분합니다. 「LLM 을 쓴다」는 말로는 이 둘이 안 갈립니다

위층이 실패해 아래층으로 넘어간 사실이 로그에 남는지 확인합니다

자동으로 뽑은 값에는 출처를 같이 저장해 나중에 되짚을 수 있게 둡니다


순서를 바꾸면 청구서가 바뀝니다

비용은 모델을 바꿔서가 아니라 순서를 바꿔서 줄었습니다. 단가를 반으로 깎는 것보다 호출 건수를 절반으로 깎는 쪽이 확실하고, 후자는 규칙 몇 줄입니다.

3층으로 실제로 내려간 것은 「표가 없는 28개 사업의 제안서 본문」 하나뿐입니다. 처음부터 3층만 있었다면 이 전부가 3층 대상이었을 겁니다. 3층이 필요 없다는 이야기가 아니라, 3층에 무엇을 남길지를 위층이 정한다는 이야기입니다.

외부 LLM 이 한도에 걸려 429 를 뱉기 시작했을 때도 결론은 같았습니다. 탈출구는 더 싼 모델이 아니라 부르는 순서였습니다.

#LLM비용#배치처리#구조파싱#추출파이프라인#단발호출