스크립트 출력에 섞인 git 말 24줄과 에이전트 줄 표지
에이전트와 사람이 함께 읽는 스크립트 출력에서 git 말을 걷어 낸 과정. 줄마다 독자 표지를 달고 표지 없는 줄만 검사했지만, 지킬 규칙을 용어집으로 가리키기만 한 문서는 실제 대화에서 한 번도 열리지 않았다. 한국어 조사 앞에서 \b 가 안 듣는 정규식 함정도 함께 정리했다.
공개 조회 0
TL;DR
- 작가에게 갈 수 있는 스크립트 출력 80줄 중 24줄에 커밋, 태그,
git tag -d같은 git 말이 있었다 - 에이전트용 줄 앞에
[에이전트]를 붙이고 문구를 다시 써서 같은 시나리오의 출력에서는 0줄이 됐다 - 커맨드 문서가 용어집 경로까지 적어 그 말로 하라고 가리켰지만, 실제 대화 4번 중 용어집을 연 것은 0번이었다
- 에이전트가 지킬 규칙은 가리키지 말고 그 작업을 부를 때 실리는 문서에 본문으로 둔다
상황
웹소설 작가를 돕는 Claude Code 플러그인을 만들고 있다. 원고를 고칠 때마다 이전 상태를 남기려고 git 을 쓴다. 회차를 플랫폼에 올리면 그 시점에 태그를 달고 올린 뒤에 고친 회차가 있는지 태그와 비교해 찾는다.
작가는 개발자가 아니다. git 명령은 작가가 치지 않고 Claude 가 대신 친다. 그래서 스크립트 출력은 에이전트가 읽는 것이라고 생각했고 출력 문구도 개발자 말로 썼다. 예전 판에서 원고를 고친 채 발행을 기록하려 하면 이렇게 나왔다.
미커밋 변경이 있다. 먼저 커밋하라 (--force로 무시).
그런데 에이전트가 따르는 절차 문서에는 "먼저 커밋하라고 안내한다", "나온 git tag -d 를 작가에게 보인다"가 적혀 있었다. 스크립트는 에이전트에게 말하는 줄 알았고 문서는 그 말을 작가에게 넘기라고 했다. 둘을 따로 쓰다 보니 출력의 독자를 서로 다르게 잡고 있었다.
두 독자가 읽는 한 출력
예전 판(1.26.0)과 이번 판(1.27.0)을 같은 시나리오로 돌려서 셌다. 새 프로젝트를 만들고 3화까지 발행을 기록하고, 2화를 고치고 6화를 새로 쓴 뒤 상태 보기, 발행, 수정 확인, 되돌리기를 부르는 스크립트 호출 13번이다. 빈 줄과 [에이전트] 줄을 빼고 작가에게 갈 수 있는 줄을 셌다. 이 수는 스크립트 출력을 센 것이고 작가 화면을 센 것이 아니다.
| 작가에게 갈 수 있는 줄 | git 말이 있는 줄 | 회귀 검사에 걸리는 줄 | |
|---|---|---|---|
| 1.26.0 | 80 | 24 | 33 |
| 1.27.0 | 64 | 0 | 0 |
git 말은 커밋, 태그, 저장소, 브랜치, HEAD, git 명령(diff 포함), .gitignore 같은 git 파일 이름, 태그 이름만 셌다. 회귀 검사는 여기에 스크립트 이름과 옵션, 차이 본문 줄, 예전 용어까지 더해 센다. 24줄 중에는 git diff published/3 HEAD -- <파일> 처럼 에이전트에게 쓰라고 준 명령이 작가용 설명과 같은 들여쓰기로 섞여 있었다.
같은 출력에서 git 말이 아닌데 틀린 줄도 나왔다. 파일 이름을 2회.md 로 잘못 적고 되돌리기를 부르면 "차이 없음"이 나왔다. 비교할 원본이 없어서 비교 결과가 빈 것뿐인데 작가는 되돌릴 것이 없다고 읽는다. 지금은 "그런 파일이 없다"로 말한다.
줄 머리 표지
에이전트가 실행할 명령과 에이전트에게 하는 말은 [에이전트] 로 시작하는 줄에만 둔다. 그 밖의 줄은 작가에게 그대로 보여도 되게 쓴다. 앞의 거부 문구는 이번 판에서 이렇게 나온다.
아직 저장 지점에 안 남긴 수정이 있다. 지금 원고를 저장 지점으로 먼저 남긴다.
[에이전트] 작가가 동의하면: git add -A && git commit -m "<무엇을 고쳤는지>"
명령이 여러 줄이면 줄마다 표지를 단다. 첫 줄에만 달면 둘째 줄부터는 표지 없는 줄이 되어 작가에게 간다. 그래서 문자열을 받아 모든 줄 앞에 표지를 붙이는 함수로 만든다.
출력을 표준 출력과 표준 에러로 나누는 방법도 있다. 그래도 에이전트는 두 스트림을 다 받고 작가에게 무엇을 옮길지는 여전히 에이전트가 정한다. 줄 표지는 그 판단에 쓸 표시를 줄마다 붙인다.
가리킨 문서는 열리지 않았다
표지는 에이전트가 지켜야 의미가 있다. 규칙은 두 곳에 두었다. 커맨드 문서에는 "[에이전트] 로 시작하는 줄"의 규칙을 본문으로 적었다. git 말과 작가에게 하는 말의 짝은 플러그인 용어집에 적고, 발행 커맨드 문서에서 그 파일을 경로까지 적어 가리켰다.
작가에게는 용어집(`skills/webnovel/references/glossary.md`) 9절의 말로 한다
실제 Claude Code 를 헤드리스로 띄워 이번 판으로 새 작품 시작과 발행을 두 번씩 돌리고 세션 기록을 봤다.
- 커맨드 문서 본문은 4번 모두 실렸다. 용어집을 가리키는 문장도 함께 실렸다
- 용어집 파일을 연 대화는 4번 중 0번이었다
- 작가가 본 글의 git 말은 4번 모두 0줄이었다. 출력을 다시 쓴 덕이지 용어집을 읽어서가 아니다
다음 판(v1.27.1) 작업본으로 같은 측정을 더 돌렸을 때도 용어집은 열리지 않았다. 그 판에서 용어집에 새로 넣은 번호 맵 금지는 번호 옮기기 대화 두 번 중 한 번 지켜지지 않았다(4:-,5:4 를 작가에게 그대로 썼다). 번호 옮기기 커맨드 문서는 용어집을 가리키지도 않았다. 그 판 작업 중에는 에이전트가 [에이전트] 줄의 명령을 코드 블록으로 옮겨 작가에게 보인 적도 있다. 커맨드 문서 본문에 "그 줄의 명령을 옮겨 적어 보이지도 않는다"를 넣은 뒤 다시 돌린 두 번에서는 사라졌다. 이 관찰은 내 전역 지시가 함께 실린 측정에서 나온 것이라 단서로만 읽는다. 같은 작업본에서 커맨드 없이 "고치기 전으로 되돌려 줄래요?"라고 말한 대화는 플러그인 문서가 아예 실리지 않아 "마지막 커밋", "작업 트리"가 나갔다.
에이전트가 지킬 규칙은 다른 문서로 가리키지 말고 그 작업을 부를 때 실리는 문서에 본문으로 둔다. 가리킨 문서는 에이전트가 그 파일을 열 때만 효력이 있고 열었는지는 세션 기록으로만 확인된다.
표지 밖 줄만 거는 검사
표지만 두면 다음 사람이 새 출력 문구를 쓸 때 다시 샌다. 그래서 회귀 검사를 붙였다. 시나리오의 출력을 모으고 표지로 시작하지 않는 줄에 금지어가 있으면 실패한다. 처음 쓴 정규식은 이랬다.
GIT_WORDS = re.compile(r'커밋|태그|저장소|HEAD|브랜치|\bgit\b(?! *\))|diff')
독립 검토에서 이 식이 git을 을 못 잡는다는 지적이 나왔다. 돌려 보니 정말 그랬다.
>>> print(re.search(r'\bgit\b', 'git을 쓴다'))
None
파이썬 정규식은 기본이 유니코드라 한글도 단어 문자로 센다. git 과 을 사이에 단어 경계가 없다. 한국어 문장에서 영단어를 찾을 때는 \b 대신 영문자만으로 경계를 가른다.
# re.I 로 컴파일한다. 뒤의 (?! *\)) 는 "(git)" 처럼 괄호에 이름만 붙인 것을 허용한다
r'(?<![A-Za-z])(?:git|commit|push|stash|checkout|branch|diff)(?![A-Za-z])(?! *\))'
남은 것
커맨드 없이 말하면 플러그인의 지시가 실리지 않는다. 플러그인 훅으로 작품 폴더의 세션에 규칙을 싣는 일은 이후 판(v1.28.0)으로 미뤘다. 용어집에만 있는 금지는 커맨드 문서 본문으로 옮겨야 한다.
다음부터
에이전트가 지킬 규칙은 그 작업을 부를 때 실리는 문서에 본문으로 두고 세션 기록으로 실렸는지 확인한다. 한국어 문장을 거르는 금지어 정규식은 \b 를 쓰지 않고 조사가 붙은 문장으로 시험한다.