← 모든 글

정부 AI가 마인크래프트에 얼버무린 진짜 이유

America.gov AI의 '이상한' 답변은 버그가 아니라 설계다. 작은 팀이 LLM 토큰 비용을 지키려면 모델 호출 전 가드레일이 먼저라는 이야기.

마인크래프트 질문 하나가 드러낸 것

America.gov에 마인크래프트 질문을 던지면 이상한 일이 벌어진다. 답변이 엉뚱하게 튀거나, 갑자기 주제를 틀거나, 뭔가 어색하게 얼버무린다. TechCrunch가 보도한 이 현상을 처음 보면 AI 환각처럼 읽힌다. 그런데 아니다. 의도된 설계다.

미국 정부 공보 AI사이트에 올라간 챗봇은 주제 범위 밖 입력이 들어오면 LLM이 자유롭게 답하도록 내버려두지 않는다. 마인크래프트처럼 사이트 목적과 전혀 무관한 질문에는 시스템이 개입해 흐름을 끊거나 방향을 돌린다. 결과가 어색해 보이는 건 그 개입이 매끄럽지 않아서지, 모델이 망가진 게 아니다.

그렇다면 왜 깔끔하게 "해당 주제는 답변 범위 밖입니다"라고 처리하지 않았을까. 아마 비용과 속도 때문일 가능성이 높다. 매끄러운 거절 문구도 결국 LLM을 한 번 더 태우거나 별도 분류 레이어를 거쳐야 하기 때문이다. 어설프게 보여도, 비용 구조는 훨씬 합리적인 선택이었을 수 있다.

"답하지 않는 것"도 전략이다

작은 팀 입장에서 이 뉴스가 흥미로운 이유는 딱 하나다. 토큰은 공짜가 아니라는 것.

Claude Haiku 기준으로 input 1M 토큰에 $0.25, output 1M 토큰에 $1.25다. 한 번의 호출이 input 800토큰 + output 600토큰이라 치면 약 $0.00095, 천 번 호출해도 $0.95 수준이다. 숫자만 보면 별것 아닌 것 같다.

그런데 실제로 운영하다 보면 이 숫자가 다르게 다가온다. 우리 팀 내부 집계를 보면, 여러 봇이 하루 수백 건씩 LLM을 호출하는데 그 중 15~20%는 입력이 빈약하거나 이미 발행된 주제와 겹치거나, 어차피 1500자 게이트에서 재생성을 트리거하는 케이스다. 즉, 어차피 버려질 결과물을 만들기 위해 토큰을 태우고 있다는 얘기다.

월 단위로 환산하면 이 낭비 호출이 전체 LLM 비용의 20% 안팎을 차지한다. 지금 규모에서 절대 금액은 아직 크지 않다. 하지만 모델이 Sonnet 이상으로 올라가거나 사이트 수가 늘면 이 비율이 금액으로 아프게 느껴지기 시작한다.

사전 필터링의 경제학

America.gov가 보여준 접근의 핵심은 "LLM에 도달하기 전에 쳐내라"는 원칙이다. 범위를 벗어난 입력은 비싼 모델 호출 없이 규칙 기반으로 처리한다. 출력이 어설프게 보여도, 비용 구조는 분명히 더 합리적이다.

이 원칙을 우리 상황에 대입하면 세 가지 레이어가 보인다.

첫 번째는 입력 품질 검증이다. 크롤러가 긁어온 뉴스 원문이 실제로 LLM이 뭔가를 만들어낼 만한 분량인지, LLM을 호출하기 전에 간단한 길이·키워드 필터로 걸러낸다. 원문 300자 미만짜리를 필터링했을 때 재생성 트리거 비율이 눈에 띄게 줄었다. 직접 테스트해본 결과다.

두 번째는 중복 주제 사전 차단이다. 이미 발행된 글과 유사도가 높은 주제를 LLM에 넘기기 전에 잡아내는 것. 임베딩을 쓰면 좋지만, 우리 규모에선 최근 30일 발행 제목을 캐시에 올려두고 단순 string similarity로 걸러도 의미 있는 결과가 나온다. cosine similarity 없이도 된다.

세 번째가 실제로 돈이 되는 레이어다. output 길이 제어. max_tokens를 시스템 프롬프트의 "길게 써라"에만 맡기지 말고 API 파라미터로 상한을 직접 박는 것. 우리 봇들은 1500자 이상을 목표로 하지만 간혹 4000자짜리 몬스터가 나와 output 토큰을 세 배씩 태운다. max_tokens 2500으로 캡핑하면 비용과 품질이 동시에 안정된다.

우리라면 이렇게 쌓는다

blog 봇을 예로 들면 지금 흐름은 대략 이렇다. 뉴스 수집 → 제목·요약 전처리 → claude_complete() 호출 → 1500자 게이트 → 발행. 가드레일이 있긴 하지만 대부분이 뒤쪽에 몰려 있다. 호출한 다음에 버리는 구조다.

비용 효율을 올리려면 앞단을 먼저 보강해야 한다.

claude_complete()를 호출하기 전, 원문 품질 점수를 매기는 경량 레이어 하나를 끼워 넣는다. 별도 LLM 없이 원문 길이, 한국어 비율, 키워드 밀도 세 가지를 점수화해서 임계값 미달이면 건너뛴다. 어설프게 보일 수 있지만 이게 정확히 America.gov 방식이다.

다음으로 최근 발행 제목 캐시를 TTL 30일로 파일에 유지하고, 새 주제와 단순 비교만 해도 중복 발행과 낭비 호출을 동시에 잡는다. 이미 쓴 글을 또 쓰는 건 토큰 낭비이자 SEO에도 독이다.

마지막이 핵심이다. Sonnet 이상 모델을 쓰는 검수 루프 호출 횟수를 줄인다. review_loop가 Sonnet으로 검수하는데, 앞단 필터가 좋아지면 검수에 올라오는 저품질 글 자체가 줄고, Sonnet 호출도 자연히 감소한다. 초안은 Haiku, 판단이 필요한 레이어에만 Sonnet. 이 원칙을 코드 주석에라도 명시해 두면, 나중에 실수로 Sonnet을 기본값으로 바꾸는 것도 막는다.

이 세 가지를 붙이면 월 LLM 비용에서 15~25%는 줄일 수 있다는 게 내 추정이다. 지금 규모에서 절대 금액이 크지 않아도, 사이트 수가 늘고 모델이 업그레이드될수록 이 구조가 있고 없고의 차이는 커진다.

지금 바로 쓸 수 있는 네 가지

보수적으로 잡아도 대부분의 LLM 호출 파이프라인에서 10~20%의 쓸모없는 호출이 존재한다. America.gov의 사례는 그걸 인정하고 설계한 팀이 있다는 증거다. 매끄럽지 않아도.

적용 순서를 정리하면 이렇다.

원문 길이 필터 먼저. LLM을 태우기 전 입력 원문이 300자 미만이면 스킵 조건을 코드에 박아라. 짧은 원문으로 긴 글을 만들면 환각 비율이 올라가는 건 덤으로 따라온다.

max_tokens 파라미터를 반드시 명시하라. claude_cli의 complete()에 max_tokens 인자를 넣지 않으면 모델 기본값(대개 4096 이상)이 그대로 적용된다. 목표 분량의 1.5~2배 정도로 캡핑하는 게 안전하다.

중복 주제 캐시는 파일 하나로 충분하다. 최근 30일 발행 slug나 제목을 JSON 파일로 유지하고 새 주제와 단순 비교만 해도 된다. 임베딩 서버가 없어도 운영 가능하다.

초안 Haiku, 검수 Sonnet 원칙을 코드에 주석으로 남겨라. 주석 한 줄이 실수를 막는 가드레일이 된다.

America.gov의 이상한 답변이 버그가 아니라는 걸 이제는 안다. 그 팀도 비용을 세고 있었던 것이다.


원문: AI News & Artificial Intelligence | TechCrunch

* 위 링크는 인프런 affiliate 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

📚 추천 강의
한 입 크기로 잘라먹는 바이브코딩 (with Claude Code)
Claude Code로 바이브코딩, 개발자라면 꼭 들어야 할 필수 강의
강의 보러가기 →

* 위 추천 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.