당신의 LLM 출력 필터는 모델이 프롬프트를 그대로 따라 말하는 경우를 걸러냅니까?
Threads에 앱을 소개하는 짧은 훅 문구를 자동으로 만들어 게시하는 봇이 있습니다. claude -p에 앱 이름과 설명을 넣고 훅 한 줄을 받습니다. 프롬프트 끝에는 이렇게 규칙을 답니다.
규칙: 데이터에 없는 구체 예언/사건/수치를 지어내지 말 것. 호기심 유발,
40~80자, 이모지 1개 이내, 줄바꿈 없이 한 줄, 무료/60초 강조 가능.
훅 한 줄만 출력:초기 필터는 단순했습니다. 모델이 가끔 "훅:"이나 "훅 한 줄:" 같은 라벨을 앞에 붙이는데, 이런 라벨 에코는 짧으니까 길이 15자 이상인 줄만 훅으로 채택하면 걸러진다고 판단했습니다.
cands = [l for l in lines if len(l) >= 15]
line = cands[0] if cands else (lines[0] if lines else "")이 필터는 8일 넘게 조용히 통과했습니다. 훅이 짧은 라벨을 달고 나오는 실패 모드만 상상했기 때문입니다.
당신이라면?
모델이 규칙 자체를 훅으로 착각하고 되읽어 준다면, 그 문장이 15자보다 짧을까요, 길까요? "40~80자, 이모지 1개 이내로 작성하세요"는 19자입니다. 라벨보다 길고, 실제 훅보다도 깁니다. 길이 기준은 이 실패 모드를 걸러낼 수조차 없는 구조였습니다.
발견은 우연이 아니라 8월 25일 아침 점검에서였습니다. 그날 올라간 훅 하나가 문장으로서 뭔가 이상했습니다 — 특정 앱을 가리키지 않고, 지시형 어미로 끝났습니다. 규칙 문장 그 자체였습니다.
왜 라벨 필터는 이걸 못 잡았나
라벨 에코와 규칙 에코는 겉보기엔 같은 "군더더기 출력"이지만 실패 모양이 다릅니다.
- 라벨 에코:
"훅:","훅 한 줄:"— 짧고, 늘 앞에 붙는 접두사 패턴. - 규칙 에코: 프롬프트에 적힌 조건 문장을 모델이 답으로 착각해 그대로/paraphrase해서 냄 — 길고, 문장 형태를 완전히 갖춤.
길이 기준 하나로 두 실패 모양을 동시에 걸러낼 수는 없었습니다. 짧은 걸 걸러내는 필터는 긴 것에 무력하고, 긴 걸 의심하면 이번엔 진짜 훅(원래 40~80자를 요구했으니까요)까지 같이 죽습니다.
수정
수정은 필터를 하나 더 얹는 게 아니라, 규칙 문장에서만 나오는 패턴을 정규식으로 짚는 것이었습니다.
_RULE_ECHO = re.compile(r"\d+~?\d*자|이모지\s*\d*개|조건\s*충족")
cands = [l for l in lines if len(l) >= 15 and not _RULE_ECHO.search(l)]
if not cands:
return """40~80자", "이모지 1개" 같은 숫자+단위 조합은 실제 앱 소개 훅에는 나올 이유가 없는 패턴입니다. 그리고 후보가 전부 걸러지면 예전처럼 lines[0]으로 폴백하지 않고 빈 문자열을 반환하도록 바꿨습니다. 빈 문자열이 오면 호출부(make_hook)가 이미 준비돼 있던 고정 폴백 문구를 대신 씁니다. "뭐라도 훅을 내보내는 것"보다 "규칙을 훅으로 내보내지 않는 것"이 먼저였습니다.
자가진단
당신의 LLM 출력 필터를 셋 중 하나로 점검해 보세요.
- 필터 기준이 "짧다/길다" 하나뿐입니까? 실패 모양이 두 가지 이상이면 기준도 두 가지 이상이어야 합니다.
- 전부 걸러졌을 때 폴백이
lines[0]입니까, 빈 문자열입니까? 안전한 기본값이 없으면 "필터를 통과 못 한 후보"가 결국 채택됩니다. - 프롬프트에 적은 규칙 문장을, 모델의 실제 출력이라 가정하고 같은 필터에 통과시켜 보셨습니까? 이 테스트 한 번이면 이 버그는 배포 전에 잡혔을 겁니다.
프롬프트에 규칙을 길게 적을수록 모델이 그 규칙 자체를 "정답처럼 보이는 문장"으로 착각할 표면적도 넓어집니다. 마침표를 막고 고쳤다고 말했지만, 구멍은 그대로였습니다에서 마침표 하나를 막고 구멍이 그대로였던 것과 같은 결이었습니다 — 둘 다 "필터가 실제로 무엇을 잡고 있는지" 대신 "필터가 뭘 잡는다고 상상했는지"로 검증을 끝냈습니다. 제 테스트가 저를 속인 세 가지 방법도 같은 계열입니다: 테스트가 실제 실패 모양을 넣어보지 않으면, 초록불은 아무것도 증명하지 않습니다.
지금 당신의 LLM 출력 필터에, 프롬프트에 적힌 규칙 문장 그대로를 한 번 통과시켜 보세요. 걸러지지 않는다면, 언젠가 그 규칙이 콘텐츠로 게시됩니다.