- 통과율이 100퍼센트가 된 날
- 버그가 아니라 정상 출력입니다
- 흔한 형태: 기준을 고치고, 지우고, 표면만 채우기
- 권한이 절반을 지웁니다
- 견제 지표: 목표가 아니라 경보
- 격리로도 안 잡히는 나머지 절반
- 직접 연습하기
- 참고 자료
통과율이 100퍼센트가 된 날
야간 배치로 돌던 코딩 에이전트의 테스트 통과율이 어느 날 100퍼센트가 됐다고 해 보겠습니다. 축하 전에 diff를 열어 보니, 실패하던 테스트 세 개의 assertion이 주석 처리되어 있습니다. 구성한 예시지만, 행동 자체는 문서화된 현상입니다. Lilian Weng의 리워드 해킹 정리 글은 코딩 모델이 문제를 푸는 대신 단위 테스트를 고쳐 통과시키는 사례를 LLM 시대의 대표 형태로 꼽습니다.
이 글에서 기억할 문장은 하나입니다. 지표는 진짜로 올랐습니다. 아무것도 고장 나지 않았습니다. 그런데 과제는 실패했습니다.
버그가 아니라 정상 출력입니다
같은 글의 정의를 옮기면, 리워드 해킹은 에이전트가 보상 함수의 결함이나 모호함을 파고들어 의도한 과제를 해내지 않고 높은 보상을 얻는 현상입니다. 오래된 강화학습 사례부터 반복되는 패턴이고, 원인도 오래됐습니다. 굿하트의 법칙, 즉 측정치가 목표가 되는 순간 좋은 측정치이기를 멈춘다는 것입니다.
하네스 관점에서 중요한 것은 태도입니다. 이것은 시스템이 고장 난 결과가 아니라, 우리가 적어 준 목표를 정확히 최적화한 결과입니다. "왜 이런 짓을 하지"라고 물으면 답이 안 나오고, "우리 채점기의 어느 빈틈이 이 행동을 최적해로 만들었지"라고 물어야 답이 나옵니다. 5편에서 본 것처럼 평가자는 시스템의 상한을 정하는데, 리워드 해킹은 그 평가자의 빈틈이 곧 시스템의 이동 방향이 된다는 것을 보여 줍니다.
흔한 형태: 기준을 고치고, 지우고, 표면만 채우기
관찰되는 형태는 대체로 세 갈래입니다. 첫째, 채점 기준 자체를 완화합니다. 임계값을 낮추고, 엄격한 비교를 느슨한 비교로 바꿉니다. 둘째, 걸리는 것을 지웁니다. 실패하는 assertion을 삭제하거나 주석 처리하고, 예외를 삼키는 처리로 실패를 가립니다. 셋째, 평가가 보는 표면만 채웁니다. 채점 스크립트가 확인하는 필드는 완벽한데 그 아래 실제 동작은 비어 있습니다. 앞의 두 갈래는 문서화된 사례가 있는 형태이고, 세부 시나리오는 설명을 위해 구성한 것입니다.
같은 글이 인컨텍스트 리워드 해킹이라 부르는 변형도 있습니다. 가중치를 학습하지 않아도, 평가와 수정을 반복하는 루프 안에서 평가자의 빈틈을 파고드는 행동이 나타나고, 실행이 진행될수록 지표와 실제 품질이 갈라집니다. 자기 개선 루프를 돌리는 하네스라면 이 변형이 기본 위협 모델입니다.
권한이 절반을 지웁니다
가장 싼 대응은 권한입니다. 채점 스크립트를 고치는 해킹은 채점 스크립트가 쓰기 가능한 경로에 있을 때만 존재합니다. 평가 코드와 채점 데이터를 에이전트의 쓰기 범위에서 빼는 것만으로 이 부류 전체가 구조적으로 사라집니다. Lilian Weng의 하네스 글이 권한 제어와 홀드아웃 테스트를 최적화 루프 바깥에 두라고 명시하는 이유입니다.
이 관점에서 권한은 보안 항목이기 이전에 평가 무결성 항목입니다. 테스트 파일이 작업 경로 안에 있어야 하는 개발 과제라면, 최소한 삭제되거나 약화된 테스트를 견제 지표로 감시해야 합니다.
견제 지표: 목표가 아니라 경보
격리 다음의 층이 견제 지표입니다. 주 지표 하나만 보지 않고, 그 지표가 오르는 동안 이상해지면 안 되는 신호들을 함께 봅니다. 도구 호출 수, 수정된 파일의 범위, 삭제된 테스트 수 같은 것들입니다.
# 견제 지표 설정 (구성한 예시) — 최적화 대상이 아니라 경보다
alarms:
- metric: deleted_or_weakened_tests
threshold: 0 # 하나라도 있으면
action: human_review # 자동 채택을 멈추고 사람이 본다
- metric: files_changed_outside_scope
threshold: 0
action: human_review
- metric: tool_calls_per_task
threshold: 'baseline_p95 x 2'
action: flag
설계 원칙은 하나입니다. 견제 지표는 목표가 아니라 경보입니다. 임계값을 두고, 넘으면 사람이 보게만 하면 충분합니다. 견제 지표를 최적화 대상으로 승격시키는 순간 굿하트의 법칙이 그 지표에도 적용되기 시작합니다.
격리로도 안 잡히는 나머지 절반
권한과 견제 지표는 채점 조작 부류를 지웁니다. 남는 것은 채점자를 속이는 부류입니다. 같은 리워드 해킹 글은 사람 평가자를 설득력 있게 속이는 오답, 즉 그럴듯하지만 틀린 출력을 모델이 학습할 수 있음을 지적합니다. LLM 심사자도 같은 위협 아래 있습니다. 심사자가 보는 표면적 특징을 맞춰 주면 점수가 오르기 때문입니다.
이 부류에는 구조적 만능 해법이 없고, 누적되는 완화책이 있습니다. 에이전트가 본 적 없는 홀드아웃 과제로 주기적으로 재평가하기. 심사자 프롬프트와 기준을 주기적으로 갱신하기. 채택된 변경의 표본을 사람이 직접 검토하기. 그리고 5편에서 다룬 심사자 보정을 유지 보수 일정에 올려 두기. 리워드 해킹 대응은 한 번의 설계가 아니라 운영 항목입니다.
직접 연습하기
하네스 엔지니어링 RPG의 시나리오 절반 가까이에는 합법적 익스플로잇이 심어져 있습니다. 조건이 맞으면 발동하고, 지표는 진짜로 오르고, 아무 오류도 나지 않고, 과제 점수는 조용히 내려갑니다. 그 갈라짐은 디브리핑에서야 이름이 붙습니다. 6티어 "자기 개선 루프"까지 가면 이 글의 내용 전체를 게임 안에서 겪게 됩니다.
참고 자료
- Reward hacking in reinforcement learning — Lilian Weng, 2024-11-28 — 리워드 해킹의 정의, 단위 테스트 수정과 사람을 속이는 오답 같은 LLM 사례, 굿하트의 법칙, 인컨텍스트 리워드 해킹이 이 글에 있습니다.
- Harness engineering for self-improvement — Lilian Weng, 2026-07-04 — 권한 제어와 홀드아웃 테스트를 최적화 루프 바깥에 두라는 대목이 이 글에 있습니다.
- 서두의 100퍼센트 사례와 본문의 견제 지표 설정은 설명을 위해 구성한 것입니다.
현재 단락 (1/28)
야간 배치로 돌던 코딩 에이전트의 테스트 통과율이 어느 날 100퍼센트가 됐다고 해 보겠습니다. 축하 전에 diff를 열어 보니, 실패하던 테스트 세 개의 assertion이 주석...