본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 31. 06:54

AI Slop 배포를 중단하세요: LLM 주변에 Anti-Slop Harness 구축하기

요약

LLM의 품질 저하 문제인 'AI Slop'을 해결하기 위해 프롬프트 수정 대신 시스템적 검증 계층(Harness)을 구축하는 방법을 제안합니다. 모델의 출력을 신뢰할 수 없는 의존성으로 취급하여 검증, 거부, 재시도 프로세스를 통해 품질을 관리해야 합니다.

핵심 포인트

  • AI Slop은 프롬프트 문제가 아닌 엔지니어링 시스템의 문제임
  • 모델 출력을 검증하고 거부하는 '하네스(Harness)' 구축 필요
  • 구조화된 출력(Structured Output)을 사용하여 실패 모드 최소화
  • 결정론적 코드를 활용해 빈 출력이나 스택 트레이스 등을 탐지

"AI slop(AI 쓰레기)"는 모델의 문제가 아닙니다. 그것은 당신이 해결하지 않기로 결정한 엔지니어링의 문제입니다.

Slop이란 당신의 LLM이 약 5%의 확률로 내뱉는 특징 없고, 어조가 맞지 않으며, 절반쯤 환각(Hallucination)이 섞였거나, 가끔은 그냥 에러 메시지에 불과한 텍스트를 말합니다. 그리고 그 5%가 바로 사용자들이 스크린샷을 찍는 부분입니다. 본능적으로 사람들은 프롬프트(Prompt)에서 이를 해결하려 합니다. "간결하게 작성할 것, 정확할 것, 내 어조에 맞출 것"과 같은 문장을 세 줄 더 추가하는 식이죠. 이는 확률론적(Stochastic) 시스템을 결정론적(Deterministic) 시스템인 것처럼 취급하는 것입니다. 그렇지 않습니다. 프롬프트만으로는 보장을 이끌어낼 수 없습니다.

실제로 효과가 있는 방법은 모델을 다른 신뢰할 수 없는 업스트림 의존성(Upstream dependency)처럼 취급하는 것입니다. 즉, 어떤 것이 사용자에게 도달하기 전에 검증(Validate)하고, 거부(Reject)하며, 재시도(Retry)하는 하네스(Harness)로 모델을 감싸는 것입니다. 모델은 제안하고, 하네스는 결정합니다. 그 구축 방법을 소개합니다.

Stop Shipping AI Slop: Build an Anti-Slop Harness Around Your LLM

Slop은 프롬프트 문제가 아니라 시스템의 문제입니다

제가 배포한 모든 프로덕션 LLM 기능은 동일한 형태를 띠었습니다. 모델은 파이프라인(Pipeline) 그 자체가 아니라, 파이프라인의 한 단계일 뿐입니다. 당신은 가공되지 않은 사용자 입력(Raw user input)을 신뢰하지 않는 것과 마찬가지로, 가공되지 않은 생성물(Raw generation)도 신뢰하지 않습니다. 당신은 그것을 파싱(Parse)하고, 코드로 표현할 수 있는 제약 조건에 따라 검증하며, 실패하는 모든 것은 사람이 보기 전에 자동으로 거부합니다.

핵심 통찰은 대부분의 slop은 "탐지 가능(Detectable)"하다는 것입니다. 빈 출력, 유출된 스택 트레이스(Stack trace), 잘못된 언어, 200단어를 요청했는데 900단어로 답하는 경우, "오늘날 급변하는 세상에서(in today's fast-paced world)"와 같은 금지된 문구 등은 모두 결정론적 코드(Deterministic code)로 확인할 수 있습니다. 이를 잡아내기 위해 판사 모델(Judge model)이 필요하지는 않습니다(물론 판사 모델은 마지막 단계에서 제 역할을 합니다). 당신에게 필요한 것은 모든 생성 단계에서 실행되고, 마이크로초 단위의 비용이 들며, 절대 지치지 않는 게이트(Gate)입니다.

이를 각기 다른 유형의 실패를 거부하는 5개의 계층으로 생각하십시오.

계층 1: 자유 형식 텍스트가 아닌 구조화된 출력 (Structured output)

Slop(쓰레기 콘텐츠)을 줄이는 가장 큰 방법은 구조를 요구할 수 있는 상황에서 산문(prose) 형태를 수용하기를 거부하는 것입니다. 이름이 지정된 필드와 스키마(schema)를 가진 JSON 객체를 요청하면, 실패 모드(failure modes)는 "무한대"에서 "열거 가능한 몇 가지"로 급격히 줄어듭니다.

제공업체의 네이티브 구조화된 출력(structured-output) / 도구 호출(tool-calling) 모드를 사용하고, 여러분의 스택이 지원하는 Pydantic, Zod, JSON Schema 등 실제 스키마를 연결하십시오. 이는 두 가지 역할을 합니다. 첫째, 모델이 특정 형태를 따르도록 강제하여, 장황한 서론("물론이죠! 여기 당신을 위한 멋진 답변이 있습니다...")을 제거합니다. 둘째, 명확하게 실패하는(fails loudly) 파싱(parse) 단계를 제공합니다. 만약 모델이 유효성 검사를 통과하지 못하는 값을 반환한다면, 그것은 단순한 경고가 아니라 재시도(retry)를 트리거하는 거부된 생성물입니다. 파싱 실패는 삼켜버려야 할 예외가 아니라 품질 신호입니다.

결론적으로: 파서(parser) 주변에 절대 try/except: pass를 사용하지 마십시오. 삼켜버린 파싱 에러는 불을 끈 채로 방치된 Slop와 같습니다.

계층 2: 모델이 몰래 끼워 넣는 에러 문자열 거부하기

이 부분은 사람들을 놀라게 합니다. 모델은 인터넷 전체를 학습하며, 여기에는 수많은 에러 메시지, 사과 문구(apology boilerplate), 거절 언어가 포함되어 있습니다. 압박을 받는 상황(모호한 입력, 검색 실패, 잘린 컨텍스트 등)에서 모델은 때때로
구문론적으로는 유효하지만(syntactically valid) 의미론적으로는 쓰레기인(semantically garbage) 텍스트를 내뱉습니다: "죄송합니다, 해당 파일에 접근할 수 없습니다", "Error: undefined", "AI 언어 모델로서 저는 ...할 능력이 없습니다", 또는 {{variable}}가 그대로 남아 있는 반쯤 렌더링된 템플릿 같은 것들 말입니다.

이러한 것들은 스키마에는 잘 부합하기 때문에 구조화된 출력만으로는 잡아낼 수 없습니다. 모든 필드에 대해 에러 형태의 문자열과 패턴을 검사하는 명시적인 차단 목록(denylist)이 필요합니다. 다소 투박하지만 효과적입니다. 스팸 필터를 관리하듯 이를 유지하십시오. 새로운 형태의 쓰레기가 운영 환경에 도달할 때마다 차단 목록에 한 줄을 추가해야 합니다.

계층 3: 목소리 및 제약 조건 검사

이 단계는 출력을 일반적인 것이 아닌 _당신만의 것_으로 만드는 요소들을 인코딩하는 곳입니다. 대부분은 결정론적(deterministic)이며 비용이 저렴합니다:

  • 길이 제한 (Length bounds). 필드당 단어 또는 토큰 범위를 지정합니다. 900단어짜리 답변이나 한 줄짜리 답변을 거부합니다.
  • 금지 문구 (Banned phrases). 동기 부여식 결론의 상투적인 문구, "delve"와 같은 표현, 이모지 뭉치, 기업 특유의 모호한 회피 표현 등을 포함합니다. 정규 표현식 (regex) 검사를 수행합니다.
  • 필수 언어 (Required language). 저처럼 이중 언어(TR/EN) 도구를 구축한다면, 터키어 응답이 실제로 터키어로 작성되었는지 확인해야 합니다. 간단한 스크립트 비율 계산이나 언어 식별 (language-ID) 체크를 통해 모델이 문단 중간에 언어를 전환 (code-switching) 하는 것을 잡아낼 수 있습니다.
  • 형식 불변성 (Format invariants). 마크다운 (Markdown) 헤딩이 존재하는지, 시스템 프롬프트 (system-prompt) 조각이 유출되지 않았는지, 플레이스홀더 (placeholder) 토큰이 없는지 확인합니다.

다음은 이러한 계층들을 제한된 재시도 루프 (bounded retry loop)로 엮어내는 하네스 (harness)의 핵심입니다.

import re
from pydantic import BaseModel, ValidationError

...

하네스가 거부 시 수행하는 동작에 주목하십시오. 하네스는 _구체적인 실패 원인 (specific failures)_을 다음 시도에 다시 전달합니다. 모델은 추상적인 결함을 피하는 것보다 명시된 결함을 수정하는 데 훨씬 더 뛰어납니다. 또한 루프가 제한되어 있다는 점에 주목하십시오. max_attempts에 도달하면 결과물을 배포하는 대신 에러를 발생시킵니다. 실패 시 차단하는 것 (Failing closed)이 이 작업의 핵심입니다.

계층 4: 결정론적 품질 게이트 (Deterministic quality gates)

계층 1~3은 형식 및 표면적인 결함을 잡아냅니다. 계층 4는 작업에 특화되어 있으면서도 코드로 검증 가능한 의미론적 (semantic) 불변성을 잡아냅니다. 요약을 생성한다면, 인용된 모든 숫자가 원문에 존재하는지 단언 (assert) 하십시오. SQL을 생성한다면, 모델의 확신도 (confidence)에 의존하지 말고 파서 (parser)와 EXPLAIN을 통해 실행해 보십시오. 코드를 생성한다면, 컴파일하고 린터 (linter)를 실행하십시오. 번역을 생성한다면, 고유 명사 (named entities)가 그대로 유지되었는지 확인하십시오.

이러한 게이트에는 도메인 지식 (domain knowledge)이 담겨 있습니다. 이는 화려하지 않은 assert 문들이지만, 데모와 제품을 가르는 차이점입니다. 규칙은 다음과 같습니다: 기계적으로 검증할 수 있는 모든 것은 반드시 검증해야 합니다. 왜냐하면 모델은 결국 틀릴 것이고, 당신은 사용자가 아닌 게이트가 그 오류를 잡아내기를 원하기 때문입니다.

계층 5: 배포 전 검증 (Verify before ship)

마지막 계층은 다른 모델을 사용할 수 있는 유일한 계층이며, 코드가 진정으로 판단할 수 없는 항목들, 즉 충실도 (faithfulness), 관련성 (relevance), 톤 일치 (tone-match)를 위해서만 사용됩니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0