논문 자동 개선 루프의 핵심은 평가 기준이다

소개

AI로 논문 초안을 쓰는 건 이제 어렵지 않습니다. 문제는 그 다음입니다. "이 초안이 진짜 투고해도 되는 수준인지"를 어떻게 판단하느냐는 것이죠.

요즘 AI 자동화 루프가 많이 이야기됩니다. 코드를 쓰고 → 테스트하고 → 고치고 → 다시 테스트하는 루프. 코드에서는 이게 잘 작동합니다. 테스트가 통과하면 되니까요. 그런데 논문은요? "통과"의 기준이 뭔지가 애초에 불명확합니다. 리뷰어마다 다르고, 저널마다 다르고, 분야마다 다릅니다.

자동화 루프를 만들고 싶은데, 루프 안에 넣을 검증 기준을 어떻게 세우지? 이게 진짜 고민이었습니다.

그러다 Karpathy의 autoresearch(github.com/karpathy/autoresearch)를 자세히 들여다보게 됐습니다. ML 모델을 자동으로 개선하는 연구 루프인데, 구조 자체는 놀라울 정도로 단순합니다:

코드 수정 → 실행 → 지표(val_bpb) 측정 → 좋아졌으면 유지, 아니면 버림 → 반복

그런데 이 시스템을 깊이 뜯어볼수록, 결국 모든 것이 하나의 지표(val_bpb) 설정에 달려 있다는 걸 깨달았습니다. 루프 구조나 에이전트 설계보다, "무엇을 측정할 것인가" 가 이 시스템의 진짜 핵심이었습니다.

그래서 생각했습니다: 논문에도 이런 단일 평가 지표를 만들 수 있지 않을까?

진행 방법

Karpathy Autoresearch 구조 분석

먼저 autoresearch의 파일 구조를 봤습니다:

prepare.py   ← 평가 함수 (절대 수정 금지)
train.py     ← 수정 대상 (모델 코드)
program.md   ← 에이전트 지시문
results.tsv  ← 실험 로그

핵심 원칙이 세 가지였습니다:

  1. 단일 스칼라 지표: val_bpb 하나로 모든 판단을 압축

  2. 불변/가변 분리: 평가 함수(prepare.py)는 절대 안 건드림. 수정하는 건 train.py

  3. 래칫(ratchet): 지표가 좋아진 것만 유지하고, 나빠지면 즉시 롤백

이 세 원칙을 논문 도메인으로 번역하면 이렇게 됩니다:

Karpathy (ML)

내 버전 (논문)

val_bpb (낮을수록 좋음)

RSS (높을수록 좋음)

train.py (수정 대상)

논문 초안 draft.md

prepare.py (불변 평가)

eval-checklist.json

results.tsv

eval_log.tsv

5분 실험

~3분 평가 사이클

RSS (Rejection Surface Score) = 통과 항목 / 전체 항목 × 100

"reject 표면적"이라는 이름을 붙인 이유가 있습니다. "최고의 논문을 쓰겠다"가 아니라, "리뷰어가 꼬투리 잡을 수 있는 표면적을 줄이겠다" 가 더 현실적인 목표이기 때문입니다. 리뷰어 판단은 주관적이니까요. 우리가 통제할 수 있는 건 표면적을 최소화하는 것뿐입니다.

평가 체크리스트 설계: "대체 논문을 뭘로 평가하지?"

여기가 가장 고민이 많았던 부분입니다. ML에서는 val_bpb라는 객관적 수치가 있지만, 논문 품질은 그런 게 없으니까요.

접근법은 이랬습니다: 실제 게재된 논문을 분석해서, 공통적으로 갖고 있는 구조적 특성을 추출하자.

타겟 저널(CHB, MISQ, JBR) 논문 38편을 분석했습니다:

  • CHB 10편은 Python pdfplumber로 섹션 비율, 참고문헌 수, 단어 수 등 정량 분석

  • MISQ 5편, JBR 7편은 Gemini에게 정성적 패턴 분석을 시킴

  • TFSC 12편, DSS 4편으로 교차검증

이렇게 도출한 항목이 4개 Layer, 39개 binary(pass/fail) 기준입니다:

Layer

항목 수

가중치

보는 것

Structure

10

1.0x

섹션 비율, 참고문헌 수, 분량

Logic

10

1.5x

기여도, 갭→RQ 체인, 이론 근거

Rigor

13

2.0x

방법론, 강건성, 참고문헌 진위

Presentation

6

0.5x

학술 문체, 헤징

가중치는 reject 사유의 심각도를 반영합니다. "방법론이 부실하다"(Rigor)로 reject당하는 빈도가 "서론이 짧다"(Structure)보다 훨씬 높으니까요.

자동 루프 실행

체크리스트가 준비되면 루프는 간단합니다. Claude Code에 이런 프롬프트를 줍니다:

당신은 학술 논문 품질 평가 에이전트입니다.

## 입력
- draft.md: 현재 논문 초안
- eval-checklist.json: 39개 평가 기준 (수정 금지)

## 절차
1. draft.md를 모든 항목으로 평가 → 각 항목 PASS/FAIL + 근거 1줄
2. RSS = PASS 수 / 전체 × 100 계산
3. FAIL 항목 중 가중치가 높은 Layer부터 수정
4. 수정 후 재평가 → RSS가 올랐으면 유지, 내렸으면 롤백
5. RSS ≥ 90% 또는 3회 반복 시 종료

## 제약
- eval-checklist.json은 절대 수정 금지 (Karpathy의 prepare.py 원칙)
- 참고문헌을 새로 지어내지 말 것 (검증된 것만 사용)
- 기존 통과 항목을 깨뜨리지 말 것

실제 진행 중인 논문 1편에 돌려봤습니다:

Iteration

RSS

주요 변경

0 (baseline)

40%

초안 그대로 측정

1

57%

Rigor 집중 — 강건성 검증 4종, 효과 크기, 통제변수

2

95%

Structure 보강 — Abstract, 참고문헌 21→52편

3번의 iteration.

참고문헌 검증: 예상 못한 함정

루프를 돌리면서 가장 무서웠던 발견이 있습니다. LLM이 참고문헌을 지어냅니다. 저자명, 저널, 권호까지 그럴듯하게요.

실제 발견한 사례:

  • Kramer et al. (2015): 존재하지 않는 논문이 원본 초안에 이미 들어가 있었음

  • Welten et al. (2012): 논문은 존재하지만 권호 번호가 틀림 (26(8) → 실제 26(5))

  • AI가 추가한 21편: "있을 것 같다"고 추측해서 넣은 미확인 출처들

가짜 참고문헌은 desk rejection 사유입니다. 그래서 체크리스트에 critical gate 3개(R11, R12, R13)를 넣었습니다. 이 중 하나라도 FAIL이면 RSS가 아무리 높아도 투고 불가로 막습니다.

결과와 배운 점

자동화 루프의 진짜 어려운 부분은 루프가 아니라 평가 기준입니다.

Karpathy autoresearch를 보면서 가장 크게 배운 건, 루프 구조나 에이전트 설계보다 "무엇을 측정할 것인가" 가 전부라는 점입니다. 평가 기준이 허술하면 루프를 100번 돌려도 의미 없습니다. 실제로 tier_1만 있던 v1 체크리스트에서는 뼈대만 있는 초안이 80%를 찍었습니다. 기준이 잘못된 거죠.

솔직한 현재 수준

물론 원하는 수준까지는 아직 아닙니다. RSS 95%를 찍었다고 해도 아직 draft수준입니다. 하지만 "AI가 쓴 러프한 초안"을 "사람이 다듬기 좋은 탄탄한 draft"로 끌어올리는 용도로는 충분히 쓸만합니다. 예전에는 초안을 받아서 어디부터 고쳐야 할지 막막했는데, 이제는 체크리스트가 우선순위를 알려줍니다.

도움 받은 글 (옵션)

참고한 지피터스 글이나 외부 사례를 알려주세요.

1
1개의 답글

뉴스레터 무료 구독

👉 이 게시글도 읽어보세요