2월 26일 하루에 이런 커밋 세 개를 쌓았다.
02-26 fix: R5 review findings — isAdmin DB check, LLM rate limits02-26 fix: R6 review findings — adminProcedure, header stripping02-26 fix: R7 review findings — structured logging, bundle size리뷰 라운드 세 번, 발견된 이슈 수정, 커밋. 그런데 그날 밤 문득 자문해 보니, 나는 이 diff들을 거의 읽지 않았다. 리뷰는 에이전트가 했고, 수정도 에이전트가 했다. 내가 실제로 읽은 건 리뷰 리포트, 그리고 내가 에이전트에게 던진 프롬프트였다.
코드를 안 읽는 게 자랑은 아니다. 다만 내 리뷰 시간이 어디로 이동했는지는 기록해 둘 만하다고 생각했다. 결론부터 말하면, 코드에서 프롬프트로 옮겨 갔다.
계기: 내가 뭘 입력하는지 모른다
2월 2일에 oh-my-prompt를 시작했다. Claude Code나 Codex 같은 에이전트와 주고받는 모든 프롬프트를 캡처해서 쌓아두는 프롬프트 저널이다. 만든 이유는 단순했다. 하루에 수십, 수백 개의 프롬프트를 쓰는데, 정작 어떤 프롬프트가 좋은 결과를 냈는지 나는 전혀 몰랐다. 코드는 git이 전부 기억해 주는데 프롬프트는 세션이 닫히면 증발한다. 산출물은 버전 관리하면서 그 산출물을 만든 입력은 버리고 있었던 거다.
이 프로젝트 자체가 에이전트와 함께 만든 것이라 속도가 좀 이상했다. 2월 18일 하루에 세션 타임라인, 품질 점수 레이더 차트, 프롬프트 diff 뷰, 시맨틱 검색까지 PR 여덟 개(#8~#15)를 머지했다. 이 속도로 코드가 쏟아지는데 한 줄 한 줄 읽는 건 애초에 불가능하다. 리뷰 방식이 바뀐 건 무슨 철학이 있어서라기보다, 물리적으로 따라갈 수 없어서에 가깝다.
그렇게 한 달쯤 프롬프트를 쌓아놓고 보니 두 가지가 보였다.
첫째, 결과물의 품질은 거의 항상 입력의 품질을 따라갔다. 같은 모델, 같은 코드베이스인데 프롬프트에 목표·컨텍스트·제약이 담긴 날과 아닌 날의 diff 품질이 눈에 띄게 달랐다. Karpathy가 작년 6월 YC AI Startup School 강연 “Software Is Changing (Again)“에서 자연어 프롬프트가 곧 프로그램이 되는 시대를 Software 3.0이라고 불렀는데, 그 명명에 동의하든 안 하든 한 가지는 실감하고 있다. 프롬프트가 프로그램이라면, 리뷰도 프롬프트를 봐야 한다.
둘째, 그런데 내 프롬프트는 형편없었다.
내 프롬프트 로그를 열어본 소감
프롬프트 리뷰를 이야기하는 글이니 멋진 프롬프트 예시를 보여줘야 할 것 같지만, 내 로그의 실상은 이렇다.
“새 버전으로 npm 배포도 해야 할 것 같습니다. CLI 도구 포함”
목표 절반, 컨텍스트 없음, 제약 없음, 검증 기준 없음. 이런 한 줄짜리가 수두룩하다. 그런데도 대체로 돌아간다. 왜냐하면 프롬프트가 좋아서가 아니라, 그 프롬프트가 떨어지는 환경이 나머지를 메꿔주기 때문이다. CLAUDE.md와 AGENTS.md가 프로젝트 구조와 컨벤션을 매 세션 주입하고, 훅이 파일을 고칠 때마다 린트와 타입 체크를 돌리고, 반복 작업은 스킬로 묶여 있다.
그래서 “프롬프트 리뷰”라고 부르는 것의 절반은 사실 환경 리뷰다. 짧은 프롬프트로 에이전트가 자꾸 엉뚱한 짓을 하면, 프롬프트를 길게 쓰는 게 아니라 CLAUDE.md에 한 줄을 추가하는 게 맞는 수정일 때가 많다. 실제로 내 홈 디렉토리에는 ~/.agents/ 아래 보안 규칙이나 서비스 목록 같은 컨텍스트 파일이 따로 있고, 프로젝트마다 CLAUDE.md가 있다. 프롬프트를 되돌아보다가 “이 설명을 왜 매번 타이핑하고 있지?” 싶은 대목이 나오면, 그 내용은 프롬프트에서 이 파일들로 승격된다. 세 번 이상 반복해서 쓰는 컨텍스트는 프롬프트가 아니라 환경에 있어야 한다.
던지기 전에 보는 것
그래도 환경이 못 메꿔주는 부분이 있다. 이번 작업에서만 유효한 요구사항, 비즈니스 판단, 엣지 케이스 같은 것들. 프롬프트를 던지기 전에 스스로 확인하는 목록이 생겼고, 나중에 이걸 그대로 oh-my-prompt의 omp analyze 명령으로 옮겼다. 목표가 명시돼 있는가, 배경 컨텍스트가 있는가, 제약 조건이 있는가, 기대하는 출력 형태가 있는가, 참고할 예시가 있는가.
앞에서 보여준 npm 배포 프롬프트를 이 목록대로 다시 쓰면 이렇게 된다. “버전 올리고 npm 배포, CLI 포함. 배포 전에 테스트·빌드 통과를 확인하고, 배포 후 npx로 새 버전이 설치되는지 확인해줘.” 겨우 두 문장이 늘었지만, 검증 기준이 프롬프트 안에 있느냐 없느냐는 뭔가 잘못됐을 때 에이전트가 스스로 멈출 수 있느냐를 가른다. 그 판단을 밖에 두면 잘못된 결과를 사람이 사후에 발견해야 한다.
경험적으로 제일 위험한 단어는 “적절히”다. “적절한 에러 처리를 해줘”라고 쓰는 순간 그 판단은 통째로 에이전트에게 위임되고, 에이전트의 “적절함”은 내 기준과 다를 수 있다. 그 간극은 코드가 다 생성된 뒤에야 발견되고, 그때 고치는 비용이 프롬프트에 한 문장 더 쓰는 비용보다 항상 크다.
이 목록의 좋은 부수 효과는 프롬프트가 일회용이 아니게 된다는 점이다. 비슷한 작업을 다시 시킬 때 지난번 프롬프트를 불러와 고쳐 쓰게 되는데, 그러다 보니 oh-my-prompt에 프롬프트 diff 뷰까지 넣게 됐다. 프롬프트에도 버전이 생기니, 명세가 어느 지점에서 나아졌는지가 코드 히스토리처럼 남는다.
범위도 마찬가지다. 프롬프트 하나가 너무 많은 걸 요구하면 결과 diff가 검증 불가능한 크기로 나온다. 사람 PR이 크면 리뷰 품질이 떨어지는 것과 정확히 같은 이유로, 프롬프트의 범위가 곧 변경의 범위다. 이건 몇 번 수천 줄짜리 diff를 받아본 뒤에 몸으로 배웠다.
던진 후에 보는 것
사전 점검을 해도 구멍은 남는다. 그 구멍을 잡는 게 리뷰 라운드다. oh-my-prompt는 만들기 시작한 첫 달부터 리뷰 에이전트를 붙여 라운드를 돌렸는데, 2월 말까지의 커밋 로그에 그 흔적이 그대로 남아 있다.
02-12 fix: PR 리뷰 반영 — DB 싱글톤, prompt injection, UI 일관성02-24 fix: R4 — IDOR, 토큰 만료, batch UPDATE02-26 fix: R5 — isAdmin DB 체크, LLM rate limit02-26 fix: R6 — adminProcedure, 응답 헤더 정리02-26 fix: R7 — 구조화 로깅, 번들 사이즈, 데드 코드라운드는 리뷰로 끝나지 않는다. 리뷰 리포트가 같은 세션 안에서 그대로 수정 에이전트의 프롬프트가 되고, 다음 라운드가 그 수정이 진짜 됐는지 확인한다. R5부터 R7까지 하루에 세 라운드를 돌 수 있었던 건 이 루프 중간에 사람이 병목으로 끼어 있지 않아서다.
IDOR나 prompt injection 같은 이슈가 라운드마다 나왔다. 처음엔 “에이전트가 이런 것도 놓치네” 싶었는데, 리포트를 읽다가 거슬러 올라가 보면 대부분 뿌리가 내 쪽에 있었다. IDOR가 나온 건 에이전트가 멍청해서가 아니라, 내가 권한 모델을 어느 프롬프트에서도 설명한 적이 없어서였다. 관리자 확인을 DB에서 해야 한다는 요구는 내 머릿속에만 있었다. 리뷰 라운드가 찾아내는 건 결국 코드의 결함이라기보다, 내가 말해주지 않은 것의 목록이었다.
그래서 지금의 루프는 이렇게 생겼다. 내가 프롬프트를 점검해서 던지고, 에이전트가 구현하고, 훅과 테스트가 기계적인 검증을 하고, 리뷰 에이전트가 라운드를 돌고, 나는 리포트를 읽으며 우선순위를 판단한다. 그리고 반복해서 나오는 이슈 유형이 있으면 그건 다음 프롬프트나 CLAUDE.md에 반영한다. 코드 리뷰가 사라진 게 아니라, 사람이 하던 역할 중 기계가 할 수 있는 부분이 빠져나가고 남은 것 — 명세가 충분했는가, 방향이 맞는가 — 이 내 몫이 됐다.
이 관찰의 한계
여기까지 읽고 “코드 리뷰를 없애자”로 받아들이면 곤란해서, 유효 범위를 분명히 적어둔다.
이건 혼자서 여러 사이드 프로젝트를 굴리는 사람의 관찰이다. 팀의 코드 리뷰에는 결함 발견 말고도 지식 공유, 설계 합의, 온보딩 같은 기능이 있고, 그건 프롬프트 리뷰로 대체되지 않는다. 팀 환경에서 이 방식이 어디까지 통할지 나는 검증해 본 적이 없다.
정량적인 효과도 못 재고 있다. 리뷰 라운드 덕에 잡힌 이슈 개수는 셀 수 있지만, “프롬프트를 잘 써서 애초에 안 생긴 이슈”는 정의상 셀 수가 없다. 체감상 되돌리는 작업이 줄었다는 것 이상은 말하기 어렵다.
그리고 프롬프트로 잘 표현되지 않는 문제가 분명히 있다. 미묘한 동시성 이슈나 성능 최적화처럼 코드를 직접 들여다봐야 감이 오는 영역에서는 여전히 diff를 읽는다. 리뷰 에이전트의 리포트 자체를 얼마나 믿을 것이냐는 순환 문제도 아직 답이 없다. 지금은 서로 다른 관점의 에이전트가 독립적으로 같은 지점을 짚으면 신뢰도를 높게 치는 정도의 휴리스틱으로 버티고 있다.
마지막으로, 여기서 말한 프롬프트 리뷰는 아직 내가 쓰고 내가 읽는 리뷰다. 다른 사람이 내 프롬프트를 리뷰해 주는 단계는 못 가봤고, 그게 팀에서 어떤 모습이어야 하는지도 아직 상상만 하고 있다.
마무리
oh-my-prompt를 만들고 제일 먼저 한 일은 내 프롬프트들을 내가 만든 도구에 통과시켜 보는 것이었다. 결과는 위에서 본 대로다. 프롬프트를 리뷰하자는 글을 쓰는 사람의 로그에 “새 버전으로 npm 배포도 해야 할 것 같습니다”가 그대로 남아 있다.
도구는 빠르게 좋아지고 있는데 내 지시는 여전히 게으르다. 그 간극을 일단 보이게 만드는 것까지가, 지금 내가 하고 있는 프롬프트 리뷰다.
Comments
Loading comments...