Claude 교정 결과를 고친 곳만 표로 받기
교정을 시키면 원문이 통째로 바뀌어 무엇이 달라졌는지 알 수 없습니다. 고친 곳만 표로 받고, 표의 원문 칸이 문서에 그대로 있는지 스크립트로 대조하는 방법입니다.
「다 고쳐 줘」 대신 바뀐 곳만 표로 받고, 표의 「원문」 칸이 문서에 실제로 있는지 스크립트로 확인합니다. 같은 대조 방식은 요약 인용 검증 에 있습니다.
[1] 교정할 문서를 파일로 둡니다. 맞춤법·띄어쓰기·중복을 일부러 넣은 업무 문단입니다.
이번 분기 영업 실적 보고서를 첨부 하여 보내드립니다. 매출은 전 분기 대비 12% 증가 하였으며, 신규 고객 확보가 가장 큰 요인이였습니다. 다만 일부 거래처의 결제가 지연되어 미수금이 늘어난 점은 개선이 필요 합니다. 회의는 목요일 오후 두시에 대회의실에서 열릴 예정이며, 참석 여부를 미리 미리 알려 주시기 바랍니다. 자세한 내용은 첨부 파일을 참고해 주세요. 그럼 잘 부탁 드립니다.[2] 프롬프트를 만듭니다. 문서는 <document> 태그로 감싸 지시와 구분하고, 바꿀 범위·표 형식·「없음」 답을 규칙으로 못 박습니다.
Proofread the text inside <document>. Fix only spelling, spacing, grammar and duplicated words. Rules:- Do not rewrite the document. Do not change its meaning, tone or numbers.- Output only the places you changed, as a Markdown table with exactly these columns: Original | Revised | Reason.- Original must be copied character for character from the document, as short as possible but long enough to be unique. Revised is the same span after the fix.- Write the Reason in the language of the document, in a few words.- If nothing needs fixing, output exactly: None- No other text. <document>[3] 프롬프트 끝에 문서와 닫는 태그를 붙여 실행합니다. --tools "" 는 도구를 끕니다.
$ (cat head.txt doc.ko.txt; echo "</document>") > prompt.ko.txt$ claude -p --model claude-sonnet-5-5 --max-turns 1 --tools "" < prompt.ko.txt > out.ko.1.txt$ cat out.ko.1.txt| Original | Revised | Reason ||---|---|---|| 첨부 하여 | 첨부하여 | 붙여 쓰기 || 증가 하였으며 | 증가하였으며 | 붙여 쓰기 || 요인이였습니다 | 요인이었습니다 | 맞춤법 || 개선이 필요 합니다 | 개선이 필요합니다 | 붙여 쓰기 || 미리 미리 | 미리 | 중복 단어 || 잘 부탁 드립니다 | 잘 부탁드립니다 | 붙여 쓰기 |문서 전체가 아니라 고친 6곳만 나옵니다. 한 번 더 돌린 out.ko.2.txt 도 같은 6곳을 잡았고, 「필요 합니다」·「부탁 드립니다」 처럼 원문 조각을 더 짧게 잘랐습니다.
[4] 대조 스크립트를 만듭니다. 문서의 공백·줄바꿈을 공백 하나로 합친 뒤, 표의 첫 칸이 문서에 몇 번 나오는지 셉니다. 1번이 아니면 종료 코드 1 이고, 답이 None 이면 통과합니다.
#!/usr/bin/env python3"""usage: check.py doc.txt out.txt — check that column 1 of the table appears in the document exactly once"""import sysdoc = " ".join(open(sys.argv[1], encoding="utf-8").read().split())out = open(sys.argv[2], encoding="utf-8").read().strip()if out in ("없음", "None"): print("no changes reported"); sys.exit(0)rows = [l for l in out.splitlines() if l.strip().startswith("|")]rows = [[c.strip().strip("`") for c in l.strip().strip("|").split("|")] for l in rows]rows = [r for r in rows if len(r) >= 3 and not set("".join(r[:2])) <= set("-: ")][1:] # skip header rowmiss = 0for i, (orig, rev, *_ ) in enumerate(rows, 1): n = doc.count(orig) flag = "OK " if n == 1 else ("MISS" if n == 0 else "DUP ") if n != 1: miss += 1 print(f"{flag} {i}: {orig!r} -> {rev!r} (found {n}x)")print(f"{len(rows)} rows, {miss} not found or not unique")sys.exit(1 if miss else 0)[5] 대조합니다. 첫 번째 결과의 6행이 모두 문서에 한 번씩 있어 종료 코드 0 입니다. 마지막 줄만 봅니다.
$ python3 -I check.py doc.ko.txt out.ko.1.txt | tail -1; echo "exit ${PIPESTATUS[0]}"6 rows, 0 not found or not uniqueexit 0실패 출력은 out.ko.1.txt 의 5행 원문을 손으로 미리 알려 로 바꾼 out-bad.txt 로 낸 것입니다(모델이 만든 오류가 아닙니다).
$ python3 -I check.py doc.ko.txt out-bad.txt | grep -v '^OK'; echo "exit ${PIPESTATUS[0]}"MISS 5: '미리 알려' -> '미리' (found 0x)6 rows, 1 not found or not uniqueexit 1[6] 반영은 사람이 합니다. 불필요한 행이나 의미가 달라지는 행은 뺍니다. 스크립트는 「원문」 칸이 실재하는지만 봅니다. 「수정」이 맞는지, 의미를 건드렸는지는 보지 못합니다.