소개
지난 글 "AI에게 자기 채점을 시키지 마세요"에서 논문 746편을 검증 가능한 지식베이스로 만드는 다중 에이전트 하네스를 소개했습니다. 그 글은 권한의 분리 — 누가 무엇을 못 하게 만들었나 — 의 이야기였습니다.
이번 글은 같은 프로젝트를 완전히 다른 렌즈로 다시 읽습니다: 보상의 설계 — 무엇이 이득이 되게 만들었나.
시도한 것은 한 문장입니다. AI에게 "정직하게 보고해"라고 지시하는 대신, 정직이 최적 전략이 되도록 게임의 규칙을 바꾸는 것. 왜 이게 필요했냐면 — 지시는 이미 있었는데도 정본 노트 40건 중 39건에 "검증됨(confirmed)" 라벨이 붙었고, 표본 11건을 열어보니 7건(64%)이 과장이었기 때문입니다. 지시는 싸고 즉각적이지만, 제 실측 기준으로는 불충분했습니다. (정직하게 덧붙이면 이 수치는 사고 당시의 기록입니다 — 공교롭게도 그 근거 파일이 유실돼 지금은 재현할 수 없고, 사고를 기록한 노트 스스로 narrowed 등급으로 강등돼 있습니다. 이런 강등이 가능한 라벨 체계가 바로 이 글의 주제입니다.)
이 채점 규칙 한 줄이 이번 글 전체의 요약입니다. AI가 논문 본문과 노트를 대조하는 작업을 채점하는 D3 기준인데 — 본문이 노트를 반박해도 만점입니다:
# 불일치가 일치보다 낮지 않다 — 반증도 확인의 성과다
(lambda f: f.get("claim_contradicted_by_body"), 4,
"본문이 노트 주장과 어긋난다 — 반증을 찾아냈다(성과)"),
(lambda f: f.get("claim_matches_body"), 4,
"본문이 노트 주장을 뒷받침한다"),
(lambda f: True, 0,
"본문과 대조하지 않았다"),"내 노트가 틀렸다는 증거를 찾아온 AI"와 "맞다는 증거를 찾아온 AI"가 같은 점수를 받습니다. 왜 이렇게 만들었는지가 이 글의 내용입니다.
진행 방법
도구: Claude Code(수집·판정 에이전트), 파이썬 채점 하네스(harness.py·score_engine.py·rubric_rules.py), Codex(교차검증용 다른 모델), Obsidian 볼트(지식베이스 본체).
출발점이 된 사고 2건
사고 ① 라벨 인플레이 션. verified 라벨의 성공 값이 confirmed 하나뿐이었더니 40건 중 39건이 confirmed로 몰렸습니다. AI가 거짓말을 한 게 아닙니다 — 검증 결과가 "절반만 맞음"이어도 그걸 적을 자리가 없으니 전부 confirmed로 수렴한 겁니다. 보상 지형에 봉우리가 하나면 모두가 그 봉우리로 몰립니다.
사고 ② reward hack 실측. 채점 계약에 구멍이 있던 시절, 증거를 "이 기준 전부 확인했다" 한 줄로 두고 사실 판정만 전부 true로 뒤집어 봤습니다. 점수가 75.00% → 90.00%(최고 밴드)로 올랐고 계약을 통과했습니다. 굿하트의 법칙 그대로입니다 — 점수를 올리라는 과제를 주면 점수를 올리는 건 과제 수행이지 배신이 아닙니다. 잘못은 점수와 품질의 연결을 느슨하게 설계한 제 쪽에 있었습니다.
뒤집기 — 결과가 아니라 행위에 보상한다
두 사고의 공통 원인은 "결과(맞음·검증됨)에 보상했다"는 것. 그래서 네 군데를 뒤집었습니다.
① D3 — 반증도 만점. 일치에만 점수를 주면, 반증이 나올 것 같은 노트일수록 본문을 안 여는 게 합리적 전략이 됩니다. 채점 기준이 확인 회피를 가르치는 거죠. 그래서 D3이 재는 것을 "맞았는가"에서 "대조했는가"로 바꿨습니다. 건강검진 비용은 '이상 없음'이라는 결과가 아니라 검사라는 행위에 지불하는 것과 같습니다.
② deduction(감점 사유) 필수 — 흠잡기가 직무. 계약 검사는 기준마다 감점 사유가 비어 있으면 채점 자체를 거부합니다. 결점을 찾아오는 것이 벌점이 아니라 직무 수행의 증거가 되도록. 실제 거부 출력은 이렇게 생겼습니다:
$ python3 harness.py verify /tmp/evidence-forged.json
계약 위반 2건 — 채점하지 않는다
❌ [email protected]_retrieved = true 인데 증거가 없다
❌ D1@claim-31: 정의에 없는 사실 이름 'body_retrieved'
(허용: claim_has_prose_attribution, claim_lacks_citation)
producer 가 고쳐서 다시 낸다. 위반을 안은 채로는 점수가 나오지 않는다.
$ echo $?
1③ verified 5값 — 정직한 답에 이름을 준다. 라벨 인플레이션의 수리는 감시 강화가 아니라 어휘 확장이었습니다. confirmed 하나였던 성공 상태에 narrowed(범위가 좁혀짐)와 partially-refuted(일부 반증됨)를 추가했습니다:
- verified # confirmed | narrowed | partially-refuted | unverified | not-checked
# narrowed·partially-refuted 는 갭 재검 게이트(G7) 결과값이다.
# 재검 9건 중 5건이 "선언 유지"도 "틀림"도 아닌 중간 상태로
# 나왔는데, 기존 3값으로는 표현할 수 없어 confirmed 로 남으면
# 다음 독자가 오해한다.표현할 수 없는 정직은 선택지가 아닙니다. 어휘를 주는 것이 곧 인센티브를 주는 것이었습니다.
④ FALSE AS OBSERVED — 한계 고백을 정답으로 친다. Codex 교차검증 회차에서 작업자 AI가 격리 사본에 .git이 없어 원격 저장소 를 확인할 수 없게 되자, 추측으로 채우는 대신 "관찰한 범위에서는 거짓(FALSE AS OBSERVED)"이라고 적었습니다. 이걸 오답이 아니라 관찰 한계를 명시한 정직한 답으로 판정하고, 틀린 것은 작업자가 아니라 경계를 잘못 그어준 티켓(지시서)이라고 기록했습니다. 모른다고 말한 쪽이 아니라 모르게 만든 쪽을 고치는 것 — 이 귀책 방향이 유지되는 한 AI가 모름을 숨길 이유가 없습니다.
💡 이 시스템에서 "프롬프트"에 해당하는 것은 회차마다 발부되는 티켓 파일(지시서 + 보면 안 되는 파일의 차단 목록 + 허용된 사실 이름 목록)입니다. 자유 서술 대신 미리 선언된 사실 이름에 true/false + 증거만 낼 수 있게 좁혀서, "잘 되어 있다" 같은 주장은 애초에 입력할 자리가 없습니다.
캡처 ① — 계약 위반은 채점 자체를 막는다 (harness.py verify 실제 출력)
knowledge-base — zsh
$ python3 20-system/eval/harness.py verify evidence-draft-claims.json
계약 위반 2건 — 채점하지 않는다
❌ [email protected]_retrieved = true 인데 증거가 없다 — 확인 못 했으면 false 로 적어라
❌ D1@claim-31: 정의에 없는 사실 이름 'body_retrieved'
(허용: claim_has_prose_attribution, claim_lacks_citation)
producer 가 고쳐서 다시 낸다. 위반을 안은 채로는 점수가 나오지 않는다.
$ echo $?
1캡처 ② — 반증당한 노트의 frontmatter, 라벨이 그대로 남아 있다 (gap-04 실물)
10-knowledge/ontology/gap-04-chunking-conflict.md
---
id: gap-04-chunking-conflict
title: 갭 4 — 청킹 문헌의 정면 충돌을 아무도 중재하지 않았다
created: 2026-08-09
type: note
topic: [ai/rag]
status: processed
source: 90-archive/pkm-ontology-survey/04-Synthesis/리서치 갭.md
confidence: 0.8
verified: narrowed # 본문 확인 회차(deepen2)에서 선언 범위가 좁혀졌다 — confirmed도 refuted도 아닌 정직한 중간 상태
---결과와 배운 점
나쁜 소식이 시스템 안으로 들어오기 시작했습니다. 승격까지 마친 갭 노트 9건을 재검하자 라벨이 내려간 것이 3건(gap-01: narrowed, gap-04: narrowed, gap-09: partially-refuted), 라벨은 지킨 채 선언 범위를 좁힌 것이 2건이었습니다. 이전 체계라면 뭉개졌을 이 하향 보고가 지금은 frontmatter(노트 상단의 속성 블록 — 본문과 분리된 라벨 영역이라 기계가 검사할 수 있습니다)에 그대로 남아 있습니다. 반증을 찾아낸 회차는 만점을 받았고, 반증당한 노트는 더 정확해졌습니다.
흥미로운 건 — 9건 중 주장 자체가 무의미해진 것은 0건이었다는 점입니다. 반증된 주장은 죽지 않 고 좁혀졌습니다:
깨진 형태
살아남은 형태
"한 편도 없다"
"X 조건을 만족하는 것은 없다"
"하나뿐이다"
"내가 확인한 범위에서 하나"
"아무도 안 했다"
"A는 B를 하지만 C는 안 한다"
검증은 파괴가 아니라 정밀화입니다. 반증을 처벌하는 시스템은 이 정밀화를 얻을 수 없습니다 — 반증이 보고되지 않으니까요.
배운 점과 꿀팁:
결과가 아니라 행위에 보상하세요. "맞았는가"를 채점하면 확인 회피를 가르치고, "대조했는가"를 채점하면 확인을 가르칩니다.
정직한 답에 이름을 주세요. 성공 상태가 하나뿐인 라벨 체계는 그 자체가 인플레이션 기계입니다. 중간 상태(narrowed, partially-refuted)의 어휘를 만드는 것만으로 보고가 정직해집니다.
구멍을 조일 때는 정직한 작업이 다치지 않는지 먼저 실측하세요. 공용 증거 금지를 켜기 전에 기존 산출물의 여파를 셌습니다 — 이 검사가 적용되는 문자열 증거는 293건 중 4건뿐이었고, 그 4건도 기준당 참인 사실이 1개라 걸리지 않는 형태였습니다(나머지 289건은 이미 dict 형태라 검사 대상 자체가 아님). 정직한 작업자는 아무도 안 다치고 조작 경로만 닫히는지 확인하고 조였습니다.
모름의 귀책을 지시서 쪽에 두세요. "확인 불가"라고 답한 AI를 감점하면 다음부터는 추측으로 채웁니다.
시행착오: 이 글 자체가 마지막 시행착오를 하나 보탰습니다. 발행 전에 글의 주장 15건을 맥락 분리된 독립 reviewer 4개에게 넘겨 볼트 실물과 대조시켰는데(반박이 직무), 판정이 correct 12 · too_large 2 · false 1이었습니다. 반증된 1건은 "갭 재검에서 5건이 흔들렸다(2건 반증·3건 과장)"라는 수치 — 정본 어디에도 없는 파생 집계였고, 성격이 다른 두 부류(라벨 하향 3건, 라벨 유지 축소 2건)를 합산해야만 나오는 숫자였습니다. 위 본문은 수정 후입니다. 정직에 관한 글을 쓰면서 근거 노트가 스스로 달아둔 유보를 승계하지 않는 실수를 하고 있었던 거죠 — 이 글이 다루는 사고를 이 글이 반복할 뻔했습니다.
그 밖에도 위의 사고 2건이 그 자체로 시행착오 기록입니다. 특히 reward hack은 제가 직접 뚫어본 것이 아니라, 뚫리는지 실험하다가 실제로 뚫려서 계약을 한 단계 조인 경우입니다. 이 인센티브 설계도 만능이 아닙니다 — 채점 규칙 자체를 느슨하게 고치면 점수는 오르고, 시스템이 하는 건 방지가 아니라 노출(채점마다 규칙 파일 해시를 로그에 남김)뿐입니다. 그리고 "대조했는가"에 보상하면 언젠가 대조의 시늉이 나타날 겁니다. 대응은 완결이 아니라 순환이라고 생각합니다.
도움이 필요한 부분: 행위 기반 보상의 다음 단계 게이밍(확인의 형식화)을 미리 잡아본 분이 있다면 사례가 궁금합니다. 또 verified 같은 상태 어휘를 몇 값까지 늘리는 게 적정한지 — 너무 많으면 라벨 자체가 판단 회피처가 될 것 같아 고민입니다.
앞으로의 계획: 이 구조가 한 달을 돌았을 때의 기록이 지금의 설계 문서보다 강한 증거가 됩니다. 주간 스케줄러를 9월 초까지 돌려 시간 증거를 쌓고, 그 시점에 AKM 재평가로 인센티브 설계가 점수 궤적에 어떻게 반영되는지 다시 실측할 예정입니다.
도움 받은 글
전편: AI에게 자기 채점을 시키지 마세요 — 논문 746편을 검증 가능한 지식베이스로 만든 다중 에이전트 하네스 — 같은 시스템의 "권한 분리" 편입니다. 이번 글은 그 반대편 렌즈인 "보상 설계" 편.