원문 대신 정형 데이터를 먹였다

정기보고서 원문의 15%만 읽히고 있었고, LLM 입력의 55%를 먹으면서 결과는 표지 재진술이었다. 원문 대신 공시 API의 확정 수치 6계정을 넣으니 입력이 1/40로 줄고 요약에 숫자가 생겼다

공시 요약 서비스는 기업 공시를 받아 LLM으로 요약하고 주간 피드로 내보낸다. LLM 호출을 자체 GPU에서 구독 CLI로 옮기려고 토큰을 계산하다가, 호출당 오버헤드는 크게 줄였는데 정작 본문이 줄지 않아 막혔다. 줄일 데를 더 찾는 대신, 지금 모델에 무엇이 읽히고 있는지를 먼저 봤다.

하려던 것

전날 저녁에 계산부터 시켰다. 공시 요약 서비스의 LLM 호출을 자체 GPU 대신 구독 CLI로 옮기면 토큰을 얼마나 먹는지. 장비를 중고로 팔 생각이 반쯤 있었다. 호출당 오버헤드는 33,090토큰에서 248토큰으로 줄였는데, 본문 자체는 줄지 않았다.

생각보다 토큰을 많이 못 줄이고, 구독형으로 쓰기엔 쉽지 않은 것 같은데 맞아? 근데 내가 진짜 값어치만큼 쓰고 있는지가 의문이긴 해.

그래서 질문이 바뀌었다. 무엇을 줄이느냐가 아니라, 지금 뭘 분석하고 있느냐.

어떻게 시켰나

프로덕션 최근 30일 호출을 분류별로 실측시켰다.

분류월 호출입력 비중평균 길이
정기보고서2,41355.3%23,835자
기타(노이즈)6,57334.4%5,442자
의미 이벤트3,00710.3%3,561자

LLM 비용의 90%가 제품이 노이즈로 분류하는 공시에 쓰이고 있었다. 사업보고서, 반기보고서, 분기보고서가 입력의 절반 넘게 먹으면서 주간 피드에 기여하는 건 32건이었다.

어디서 막혔나

정기보고서 원문은 중앙값 158,089자다. 최대는 124만 자. 모델 입력은 앞 16,000자와 뒤 8,000자로 잘라 넣고 있었으니 원문의 15%만 읽힌다. 정기보고서의 99.3%가 이 한계까지 밀어넣고 있었다.

문제는 잘리는 위치다. 앞부분은 목차, 회사 개요, 종속회사 목록이다. 매출과 영업이익은 문서 한가운데 있어서 통째로 빠진다. 결과가 표지 재진술이었다. 어느 금융지주의 반기보고서 요약은 “연결대상 종속회사 412개 현황 공시”였고, 어느 공기업은 “2026년 상반기 경영 현황 및 사업 보고”였다. 틀린 말은 아니지만 아무 정보도 없다.

“아예 요약에서 빼는 것도 방법이야? 사람들은 정기보고서 요약을 좋아하지 않을까?”라고 물었다. 답은 직관이 맞다는 것이었다. 문제는 지금 그 요약을 만들고 있지 않다는 것.

어떻게 풀었나

LLM은 계속 쓰되 먹이는 걸 바꿨다. 공시 API에는 같은 키로 무료로 받는 확정 재무 수치가 있다. 매출액, 영업이익, 당기순이익, 자산·부채·자본총계 여섯 계정과 전기 대비 증감률을 코드로 결정적으로 계산해 400~600자로 만든 뒤 그걸 모델에 넣는다. 갈아끼울 지점은 제출 로직의 한 줄이고, 비동기 제출과 폴링과 팩트체크는 그대로다.

PR 하나로 끝났지만 함정이 있었다. 사전 리뷰 에이전트 24개가 실제 API를 호출하며 검증해 17건, 코드 리뷰 5라운드에서 5건 더 고쳤다. 손익은 누적 금액을 써야 한다. 반기의 당기 금액은 3개월치라 실적이 절반으로 보인다. “전기”의 뜻이 표마다 다르다. 손익은 전년 동기, 재무상태는 직전 결산일이다. 금액 절사는 1.79억을 “1억원”으로 만들어 44%를 깎는다. 그리고 조회 키가 회사·연도·보고서 종류뿐이라 API는 항상 최신 정정본을 돌려준다. 응답의 접수번호가 대상과 다르면 원문 경로로 폴백하게 했다.

결과는 건당 입력 24,000자에서 약 400자, 전체 LLM 입력 54% 감소다. 오후에 기존 정기보고서 8,429건 중 6,830건을 1시간 42분에 재분석했고 재무 경로 성공률은 99.6%였다. 어느 지주회사의 요약이 “투자부문과 IT 서비스 중심 운영”에서 “매출 122조 7,033억, 영업이익 1조 8,185억, 각각 −0.6%, −24.1%“로 바뀌었다.

전날 밤에도 비슷한 종류의 사고가 하나 있었다. 정정 공시에서 원본 링크를 찾는 백필 13,437건을 돌리는데 86% 시점에 실패 598건이 전부 첨부정정이었다. 뷰어의 정정 체인 목록에 자기 자신이 있어야 정상 페이지라는 자기 확인 방어를 뒀는데, 첨부정정은 본문이 아니라 첨부 제출이라 그 목록에 없었다. 실패가 한 종류에만 몰리면 데이터가 아니라 코드다. 확인 범위를 첨부 목록까지 넓혀 634건을 회수했고 최종 13,436/13,437이었다.

배운 점