8 minute read

🇺🇸 Read this post in English

안녕하세요. 임상 데이터, 유전체학, 머신러닝을 넘나들며 일하는 바이오인포매틱스 연구자 김가경입니다.

Claude Code로 일한 지 몇 달이 지나면서 에이전트 정의가 꽤 쌓였습니다. 논문을 쓸 때는 논문 비평 에이전트를, 보고서를 낼 때는 사실 대조 에이전트를, 블로그를 쓸 때는 문체 점검 에이전트를 만들었습니다. 검수 에이전트를 하나 만들 때마다 이제 검수가 붙었다고 생각했습니다.

지피터스 24기 스터디에서 생산과 검수를 나누라는 강의를 들으면서 정말 그런지 확인해 보고 싶어졌습니다. 3주 동안 세션 로그로 검수 에이전트가 실제로 불렸는지, 어떤 권한을 갖고 있었는지, 판정이 수정으로 이어졌는지를 쟀습니다. 이 글에는 그 측정 결과와, 결과를 근거로 에이전트 구성을 다시 정리한 과정을 적었습니다. 스터디에서 사례로 발표한 내용을 바탕으로 했고, 같은 작업을 다른 분도 따라 할 수 있게 명령과 되돌리는 방법까지 적었습니다.

정의 97개 중 실제로 불린 16개

먼저 홈 폴더 아래의 모든 .claude/agents/*.md를 찾아 이름별로 묶고, 로컬 세션 로그에서 Agent 도구 호출을 셌습니다.

항목 값
에이전트 정의 고유 이름 97개 (파일로는 160개)
모든 세션에 늘 올라오는 전역 정의 32개
Agent 호출 526회
그중 정의 없이 부른 범용 에이전트 404회 (77%)
한 번이라도 불린 정의 97개 중 16개
검수 역할 정의가 불린 횟수 11회

파일이 이름보다 훨씬 많은 것은 같은 정의가 백업이나 복사본 폴더에 여러 벌 들어 있어서입니다. 경제 브리핑과 논문 브리핑처럼 클라우드 예약 실행으로 매일 돌아가는 프로젝트의 에이전트는 로컬 로그에 남지 않아 0회로 보였습니다. 이것을 “안 쓴다”로 읽으면 틀립니다.

정작 검수 정의는 대부분 호출 기록이 없었습니다. 비슷한 역할의 검수자가 프로젝트마다 따로 생겼고, 만든 뒤에는 거의 불리지 않았습니다.

검수가 불린 곳의 공통점

반대로 검수가 꾸준히 불린 곳도 있었습니다. 스터디에서 배운 멀티에이전트 도구는 일을 맡을 팀(도구에서는 부서라고 부릅니다)을 만들면 작성자와 함께 리뷰어가 자동으로 붙고, 단계마다 역할 지침을 넣어 줍니다. 이 도구가 역할 지침을 넣은 54번 가운데 29번이 리뷰어를 부르는 단계였습니다. 작성 에이전트와 점검 에이전트를 처음부터 한 폴더에 짝으로 정의한 프로젝트에서도 작성 11번 뒤에 점검이 6번 따라왔습니다.

두 기록은 세는 단위가 달라 직접 비교하지는 않았습니다. 다만 리뷰어가 불린 곳에는 공통점이 있었습니다. 부르는 순서가 구조로 정해져 있었습니다. “필요하면 검수를 부른다”고 걸어 두면, 필요를 판단하는 제가 빠뜨렸습니다.

판정만 해야 할 검수자의 쓰기 권한

강의는 리뷰어가 고치지 않고 판정만 하고, 고치는 일은 생산자가 맡는 편성을 권했습니다. 그렇다면 검수 에이전트에는 파일을 고치는 도구가 없어야 맞습니다.

첫 주부터 같은 범위로 센 검수 정의 14개 가운데 11개가 Edit나 Write 도구를 갖고 있었습니다. 다행히 그 11개는 한 번도 불리지 않았고, 실제로 불린 두 개는 읽기 전용이었습니다. 검수자가 검사 대상 파일을 직접 고친 경우도 0번이었습니다. 사고는 없었지만, 고칠 수 있는 권한이 점검 없이 열려 있었습니다.

판정이 수정으로 이어졌는지도 봤습니다. 검수를 부른 뒤 30분 안에 파일이 고쳐진 비율은 이름 있는 검수 에이전트가 27%, 범용 에이전트에게 맡긴 검수가 40%, Codex 검토가 50%였습니다. 비교 기준인 검수가 아닌 호출 뒤에도 40%는 30분 안에 수정이 있었습니다. 검수를 받았다고 평소보다 더 고치지는 않았습니다. 다만 30분 안의 수정이 검수 때문인지는 이 방법으로 가를 수 없습니다. 판정과 반영은 따로 이어 봐야 한다고 판단했습니다.

측정 도구 자체의 집계 오류

재는 동안 제 숫자도 검수 대상이었습니다. 가장 크게 틀린 것은 측정 스크립트였습니다.

저는 서브에이전트에게 일을 맡겨도 출력 토큰의 95.7%를 메인 세션이 낸다고 측정했고, 이 숫자를 전역 규칙의 근거로 적어 두었습니다. 그런데 다른 측정을 하다가 서브에이전트가 쓴 글자 수에 비해 출력 토큰이 지나치게 적다는 것이 눈에 띄었습니다. 로그를 열어 보니 응답 하나가 스트리밍 중에 여러 줄로 나뉘어 저장되는데, 스크립트는 첫 줄의 중간값만 세고 있었습니다. 메시지별 최댓값을 쓰도록 고쳐 다시 재니 69.9%였고, 서브에이전트 출력은 약 20만에서 221만 토큰으로 늘었습니다.

검수 에이전트를 점검하던 도구가 정작 검수를 받지 않고 있었습니다. 규칙 파일의 숫자도 같이 고쳤습니다.

에이전트 구성 정리

측정을 근거로 실제로 구성을 바꿨습니다. 원칙은 셋이었습니다. 정의를 지우지 않고, 바꾸기 전에 백업하고 되돌리는 방법부터 시험하며, 스킬이 부르는 이름은 치우기 전에 확인합니다.

갈래 기준 결과
전역 상시 자주 부르거나 여러 스킬이 같이 부름 13개
플러그인 묶음 특정 스킬과만 같이 쓰고 가끔 씀 논문, PRD, 디자인 시스템 셋 (에이전트 14개, 스킬 14개)
보관 호출 0회이고 어떤 스킬도 이름으로 부르지 않음 7개
프로젝트 전용 그 저장소에서만 의미 있음 손대지 않음

처음 계획은 전역 7개였습니다. 해커톤과 논문 작업이 같이 쓰는 조사, 방법론 에이전트를 플러그인으로 옮기면 해커톤 쪽 스킬이 깨진다는 것을 이름 검색으로 확인하고 6개를 전역에 남겼습니다. 분석 에이전트는 보관 후보였다가 논문 작성 스킬이 부르는 것을 확인하고 남겼습니다.

검수 셋을 읽기 전용으로

사실 대조(fact-checker)와 문체 검수(style-critic)를 전역 에이전트로 새로 만들고, 기존 논문 비평(paper-critic)과 함께 판정 형식을 맞췄습니다. 셋 다 도구는 읽기만 가능하게 두었습니다.

{"verdict": "ACCEPT|REVISE|BLOCK|ESCALATE",
 "justification": "한두 문장",
 "evidence": [{"claim": "...", "ref": "파일:줄 또는 URL", "verified": true}],
 "issues": [{"id": "F1", "where": "파일:줄", "problem": "...", "fix_hint": "..."}],
 "missing": ["확인하지 못한 것"]}

점수 필드는 두지 않았습니다. 근거를 확인했다고 적으려면 파일과 줄을 반드시 달게 했습니다.

정리하다가 호출 0회의 이유 하나를 더 찾았습니다. 제 문체 규칙 파일은 style-critic을 부르라고 적혀 있었는데, 그 정의는 한 프로젝트 폴더 안에만 있었습니다. 다른 폴더에서는 호출할 수 없는 에이전트를 호출하라고 적어 두었습니다.

가끔 쓰는 묶음은 플러그인으로

논문, PRD, 디자인 시스템 작업은 몇 주에 한 번 쓰는데, 그 에이전트들이 모든 세션의 목록에 늘 올라와 있었습니다. 이 셋을 로컬 플러그인으로 만들어 평소에는 꺼 두고 쓸 때만 켭니다.

~/.claude/local-plugins/                  # 로컬 마켓플레이스
  .claude-plugin/marketplace.json
  plugins/paper/
    .claude-plugin/plugin.json
    agents/*.md
    skills/<스킬>/SKILL.md
claude plugin validate ~/.claude/local-plugins
claude plugin marketplace add ~/.claude/local-plugins
claude plugin install paper@kk-local
claude plugin disable paper@kk-local   # 평소에는 꺼 둔다
claude plugin enable  paper@kk-local   # 쓸 때 켜고, 열린 세션은 /reload-plugins

플러그인 안으로 들어가면 이름 앞에 플러그인 이름이 붙습니다(write-paper가 /paper:write-paper로). 그래서 묶음 안팎에서 옛 이름으로 부르던 곳을 바꿔야 했고, 묶음 안 175곳과 묶음 밖 6곳을 스크립트로 고쳤습니다. 이때 밟은 함정이 둘 있었습니다.

  • “readiness-reviewer가”처럼 한글 조사가 바로 붙은 이름을 놓쳤습니다. 정규식의 \w에는 한글도 들어가서 단어 경계가 잡히지 않습니다. 경계를 영문, 숫자, 하이픈으로만 잡아 고쳤습니다.
  • 이동 스크립트를 zsh에서 돌렸더니 아무것도 옮겨지지 않았습니다. zsh는 ${목록//,/ }를 공백으로 나누지 않아 반복문이 한 번만 돕니다. bash로 다시 돌렸습니다.

옮긴 뒤에는 새 세션을 띄워 확인했습니다. 플러그인을 켜면 prd:prd-author가 목록에 보이고 호출에 성공했고, 끄면 같은 질문에 아무것도 나오지 않았습니다.

판정 기록과 관문 확인

첫 주 측정에서 정의를 늘리는 것만으로는 검수가 불리지 않는다는 것을 확인했습니다. 그래서 산출물과 같은 폴더의 .review/verdicts.jsonl에 판정을 한 줄씩 남기고, 관문 스크립트가 지금 내용에 대한 통과 판정이 있는지 확인하게 했습니다. 판정에는 글의 해시를 함께 적어서, 판정 뒤에 글이 바뀌면 다시 받아야 합니다.

python3 review_gate.py 글.md --need style-critic            # 경고만
python3 review_gate.py 글.md --need style-critic --strict   # 통과 못 하면 막음

상태는 통과, 판정 없음, 판정 뒤 글이 바뀜, 닫히지 않은 이슈 넷입니다. 검사 7개를 먼저 쓰고 7개가 실패하는 것을 본 뒤 구현했습니다. 처음 돌리자마자 제 사례글에 판정이 없다는 경고가 떴습니다. 지금은 2주 동안 경고만 내고, 그 뒤에 막기 모드로 바꿀지 정할 계획입니다.

멈춘 상주 작업 정리

예전에 쓰던 멀티에이전트 도구는 워커 창에 메시지를 쳐 넣고 엔터를 보내는 방식으로 일을 넘겼습니다. 메시지는 들어갔는데 엔터가 안 눌려 멈추는 일이 잦았고, 하루에 막힌 큐를 푸는 복구가 511번 실행된 날도 있었습니다. Codex를 워커로 쓰다가 요금제 한도를 금방 써 버린 것도 손을 놓게 된 이유였습니다.

그런데 그 도구의 상주 프로세스 셋이 두 달째 돌고 있었습니다. 동결 상태라 모델은 부르지 않았지만, 다시 켜지면 멈춘 창마다 독촉 메시지를 보내고 독촉 한 번에 세션 전체(약 33만 토큰)를 다시 읽습니다. launchd 등록을 해제해 껐고, 설정 파일은 남겨 두어 명령 한 줄로 다시 켤 수 있게 했습니다.

검수 쪽 설계는 그 도구에서 가져왔습니다. 리뷰어는 고치지 않고 판정만 하고, 판정 형식과 근거 표기를 정해 두며, Claude와 Codex를 섞어 같은 실수를 함께 놓치지 않게 하는 규칙을 가져왔습니다. 일을 넘기는 방식만 키 입력이 필요 없는 Agent 도구와 codex exec 한 번 실행으로 바꿨습니다.

되돌리는 방법

~/.claude는 모든 세션이 같이 쓰는 설정이라 잘못 고치면 다른 작업까지 영향을 받습니다. 그래서 고치기 전에 백업부터 만들고, 되돌리는 스크립트를 먼저 시험했습니다.

cd ~/.claude
tar -czf backups/20261022_agents_restructure.tgz agents rules skills settings.json

한글 파일 이름은 압축했다 풀면 정규화 방식(NFC와 NFD)이 바뀌어 diff -r이 전부 다르다고 표시합니다. 이름을 NFC로 맞춘 뒤 내용을 비교하니 505개 중 다른 파일은 0개였습니다.

되돌리는 스크립트는 이번에 바꾼 것만 되돌리고, 백업 뒤 다른 작업이 만든 파일은 건드리지 않게 했습니다. 기본은 할 일만 보여 주고, 부분만 되돌릴 수도 있습니다.

bash restore.sh                          # 할 일만 출력
bash restore.sh --apply                  # 전부 되돌림
bash restore.sh --apply --only plugins   # 플러그인만 (archive, critics, refs, jarvis도 가능)

실행할 때마다 그 시점의 상태를 먼저 압축해 두어서, 되돌린 뒤에 원래 상태로 복원할 수도 있습니다. 시험은 ~/.claude 사본에 claude와 launchctl을 가짜 명령으로 바꿔 두고 했습니다. 처음 만든 판은 스킬 폴더를 통째로 지우고 백업으로 덮는 방식이었는데, 그러면 백업 뒤 다른 세션이 만든 스킬까지 사라집니다. 시험하면서 이 문제를 발견해 바꾼 것만 되돌리는 방식으로 다시 짰습니다.

발표 뒤 질의응답

스터디에서 이 내용을 발표한 뒤 나온 질문 가운데 셋이 글의 주제와 이어졌습니다.

첫 질문은 검수 에이전트를 어디에 어떻게 붙이느냐였습니다. 같은 Claude 세션의 서브에이전트로 부를 수도 있고, 검수만 하는 작업 공간을 따로 만들 수도 있고, 멀티에이전트 도구나 에이전트 SDK에 검수자를 여러 개 붙일 수도 있습니다. 저는 그때그때 작업 공간 안에서 “논문용 비평가를 만들어 줘”, “숫자가 틀리지 않았는지 보는 검수자를 만들어 줘” 하는 식으로 용도마다 만들었다고 답했습니다. 정의가 97개까지 쌓이고 비슷한 검수자가 프로젝트마다 따로 생긴 이유가 이 답에 그대로 있었습니다.

둘째 질문은 검수 오류가 왜 그렇게 많이 나왔느냐였습니다. 질문하신 분은 원자료에서 뽑은 보고서에 원인과 결과를 뒤집는 식의 오류 여덟 가지를 일부러 심고, 에이전트 구성 셋으로 24번 시험했는데 검수자가 모두 찾았다고 했습니다. 제가 실제 작업에서 겪은 오류는 종류가 달랐습니다. 로그 변환을 두 번 적용하거나, 로그 변환한 값을 변환하지 않은 원본 파일과 비교하거나, 하겠다고 말한 처리와 실제로 처리한 파일이 다른 경우였습니다. 부분적인 결과를 크게 주장하는 것도 있었습니다. 문장에 심은 오류는 원본과 대조하면 드러나지만, 계산 과정과 처리 순서에서 생긴 오류는 결과 문장만 읽어서는 잘 보이지 않습니다.

스터디장님이 두 가지를 덧붙였습니다. LLM은 자료가 많이 공개된 분야일수록 논리 오류를 잘 찾고, 데이터가 적은 전문 분야일수록 놓치는 것이 많아지므로 그런 분야에서는 도메인 전문가의 검수 기준을 하네스에 넣어 줘야 한다고 했습니다. 또 검수자가 작성 과정의 맥락을 이미 보고 있으면 그 맥락에 맞춰 통과시켜 버릴 수 있으니, 검수자를 작성 맥락에서 떼어 놓아야 한다고 했습니다. 제가 논문 심사 에이전트를 비평 에이전트에 합치지 않고 따로 둔 이유도 같았습니다. 심사 에이전트는 분석 과정을 보지 않고 완성된 원고만 읽게 되어 있습니다.

배운 점

검수 에이전트는 부르는 순서가 정해져 있어야 불립니다. 정의를 하나 더 만드는 것보다 판정 기록을 남기고 관문이 확인하게 하는 편이 실제 호출로 이어졌습니다.

검수자에게는 판정만 맡깁니다. 고칠 권한을 주지 않으면 판정과 수정이 섞이지 않고, 판정이 실제로 반영됐는지를 따로 셀 수 있습니다.

참값이 파일에 있으면 검사로, 없으면 검수로 보냅니다. 설정과 문서가 어긋나는지, 금지한 표현이 남았는지는 스크립트로 막을 수 있습니다. 주장의 수위나 인과 해석처럼 참값이 파일에 없는 것만 검수에 맡깁니다.

측정 도구도 검수 대상입니다. 규칙의 근거로 삼은 숫자가 서브에이전트 출력을 열 배 넘게 적게 세고 있었습니다. 숫자가 이상하면 원본 로그를 열어 보는 것이 가장 빨랐습니다.

다음

  • 2주 경고 뒤 관문을 막기 모드로 바꿀지 정합니다.
  • Codex는 검수에만 쓰고 하루 10회 상한을 둡니다.
  • 4주 뒤 같은 스크립트로 다시 재서, 전역 정의 수와 판정 원장의 건수, 판정 이슈가 닫힌 비율을 비교합니다.

Updated: