Claude Code에 review-loop를 붙이면 결과가 얼마나 나아지나
- 스킬 없이$0.14 · 기준 10개 통과
- review-loop$1.25 · 기준 10개 통과
기준 10개는 스킬 없이도 통과한다
review-loop는 작업이 끝나면 지금 대화 기록 없이 새로 뜬 서브에이전트를 리뷰어로 불러 결과물만 보여 주고, 10점 만점 점수와 지적을 받아 8점에 닿을 때까지 적어도 두 바퀴 고칩니다.
주문 목록을 엑셀용 CSV로 내보내는 toCsv 함수를 Opus 5.5에 스킬 없이·있이 3번씩 맡겼습니다. 결과는 작업 폴더 밖에 미리 둔 기준 테스트 열 개로 쟀습니다.
여섯 번 모두 기준 10개를 다 통과하고, review-loop 쪽은 리뷰어를 두세 번 부르며 비용과 시간이 중앙값으로 약 9배 듭니다. 기준 밖의 값 셋에서는 세 번 모두 두 조건이 갈립니다.
- 날짜: 스킬 없이는 UTC나
Date기본 문자열, review-loop는 엑셀이 날짜로 읽는2026-11-10 08:00:00 - 객체: 스킬 없이는
[object Object], review-loop는 JSON - 문자열 금액
"-5000": 스킬 없이는'-5000, review-loop는 부호 붙은 숫자로 보고 그대로
프로젝트 폴더에서 깝니다.
npx skills add 2dmurali/review-loop-skill -a claude-code -y.claude/skills/review-loop에 SKILL.md가 복사됩니다. 깔린 뒤에는 평소 요청 끝에 use review-loop를 붙입니다.
주문 목록을 엑셀에서 열 CSV로 내보내는 함수를 csv.js에 만들어 줘. export function toCsv(rows, columns) 꼴이고, columns는 [{ key: 'name', label: '주문자' }]처럼 열 순서와 머리글을 정한다. 테스트는 csv.test.js에 써서 node --test로 돌려 줘. use review-loop회차별 점수와 비용을 보려면
Claude Code v2.1.319에서 위 요청을 조건마다 3번 보냈습니다. 기준 열 개는 머리글 순서, 열 순서, 쉼표, 큰따옴표, 줄바꿈, 빈 값, 0과 false, 한글용 BOM, 수식 주입, 빈 목록입니다.
| 회차·조건 | 리뷰 점수 | 기준 통과(바퀴마다) | 비용 |
|---|---|---|---|
| 1 스킬 없이 | - | 10 | $0.16 |
| 1 review-loop | 7 → 8 | 10 → 10 | $0.94 |
| 2 스킬 없이 | - | 10 | $0.13 |
| 2 review-loop | 8 → 6 → 8 | 10 → 9 → 10 | $1.25 |
| 3 스킬 없이 | - | 10 | $0.14 |
| 3 review-loop | 6 → 7 → 8 | 10 → 10 → 10 | $1.42 |
걸린 시간은 중앙값으로 37초 대 5분 44초입니다. SKILL.md는 세 바퀴를 다 도는 데 한 번 짜는 시간의 1~2배를 잡으라고 하지만, 이 함수에서는 약 9배 걸립니다.
csv.js는 스킬 없이 30줄대, review-loop 첫 코드가 50줄대이고, 리뷰 지적을 고치며 87~117줄로 늘어납니다. 합격선을 넘긴 뒤의 마무리 손질은 리뷰를 다시 받지 않고 그중 3~10줄을 더합니다. 2회차는 이때 리뷰어가 일부 동아시아 엑셀에서 문제가 된다고 한 전각 + 방어를 더합니다.
리뷰어는 적어도 두 번 불린다
기본값에서는 1바퀴 점수가 합격선을 넘어도 고치고 리뷰어를 한 번 더 부릅니다.
1바퀴째는 8점이어도 고치고, 2바퀴째부터 8점이면 멈춘다
리뷰 항목은 작업한 Claude가 정합니다. 3회차 1바퀴는 배열 값 ['=1+1']이 수식 막기를 지나간다는 지적으로 6점을 받습니다. 내 기준은 문자열 값만 시험해 이 구멍을 못 잡고, 스킬 없이 한 3회차 결과에도 같은 구멍이 있습니다.
바퀴 수와 합격선을 바꾸려면
요청에 섞어 쓰면 기본값이 바뀝니다.
| 요청에 쓸 말 | 바뀌는 것 |
|---|---|
gate 9 | 합격선 9 |
max 5 loops | 최대 5바퀴 |
min 1 loops | 1바퀴에서 8점이면 바로 멈춤 |
quick | 최대 2바퀴, 합격선 6 |
금액 상한을 거는 말은 없어 바퀴 수로 줄입니다. quick이면 리뷰어를 꼭 두 번, min 1 loops, max 1 loops면 한 번만 부르고, claude -p로 돌릴 때는 --max-budget-usd로 금액을 막습니다. 테스트로 품질을 가를 수 있는 일은 review-loop를 쓰지 않을 일에 들어 있습니다.
같은 지적으로 두 바퀴 연속 점수가 오르지 않으면, 작업한 Claude가 더 센 모델로 바꾸자고 묻거나, 합격선을 잠시 낮추고 알리거나, 일을 쪼개 따로 돌립니다. 최대 바퀴를 넘겨 계속하려면 사용자 동의를 받습니다.
고친 코드가 기준을 깨기도 한다
review-loop 2회차는 1바퀴에서 이미 8점인데도 지적대로 고치다가 기준 하나를 깹니다. 리뷰어가 +82-10-… 전화번호에 작은따옴표가 보인다며 숫자·공백·괄호·점·하이픈만 든 문자열은 빼라고 권하자 작업한 Claude가 그대로 따릅니다. +로 시작하는 칸은 엑셀이 수식으로 읽을 수 있어 그 전화번호는 수식 주입 기준에서 떨어집니다.
| 리뷰 점수 | 기준 통과 | 다음 | |
|---|---|---|---|
| 1바퀴 | 8점 | 10개 | 1바퀴째라 고침 |
| 2바퀴 | 6점 | 9개 | 8점 미만이라 고침 |
| 3바퀴 | 8점 | 10개 | 멈춤 |
2바퀴 리뷰어가 이 회귀를 짚자, 작업한 Claude가 예외를 부호 붙은 숫자로 좁혀 3바퀴에서 다시 통과합니다. 1바퀴 리뷰어는 확인 스크립트를 돌릴 권한이 없어 코드만 읽고 그 처방을 냅니다.
리뷰어 처방은 받기 전에 그 값을 기준 테스트에 넣어 돌려 봅니다. 접힌 칸의 테스트 하나로 전화번호 회귀와 배열 우회가 모두 떨어집니다. 남길 고침은 내 요구에 맞는 것만 골라 이 테스트에 더해 둡니다.
리뷰어 처방을 돌려 볼 테스트
csv.js 옆에 criteria.test.js로 두고 node --test로 돌립니다. 스킬 없이 한 3회차 결과도 배열 값에서 떨어집니다.
import { test } from "node:test";import assert from "node:assert/strict";import { toCsv } from "./csv.js";test("=·+·-·@로 시작하는 값은 수식이 되지 않는다", () => { const values = ['=HYPERLINK("http://x","클릭")', "+82 10-1234-5678", "-1+2", "@SUM(A1)", ["=1+1"]]; for (const v of values) { const cell = toCsv([{ memo: v }], [{ key: "memo", label: "요청사항" }]).split(/\r?\n/)[1]; assert.match(cell, /^"?[^=+\-@]/, cell); }});