지피터스 사례글 — 발행한 요약 1장을 지식관리 창고 기준으로 재검증하기

소개

삼성 삼성 삼성 샘 한국어 버전의 스크린샷

시도한 것

한 달 전에 만든 A4 1장짜리 요약 도해(에이전트 스킬을 어떻게 쪼개고 어떤 순서로 부르는가를 10칸 카드로 정리한 것)를, 그동안 쌓인 지식관리 문서를 기준으로 전면 재검증하는 작업을 했습니다.

왜 했나

발표 자료를 다시 쓸 일이 생겨 예전 도해를 열었는데, 읽다가 손이 멈췄습니다. 거기 적힌 설계가 지금 돌아가는 시스템과 달랐습니다. 노드 수도 달랐고, 검증 게이트의 판정 기준은 아예 다른 식으로 바뀌어 있었습니다.

문제는 그 사이에 제가 그 도해를 두 번 남에게 보여줬다는 것입니다. 틀린 걸 알고 보여준 게 아니라, 틀렸다는 걸 몰랐습니다. 요약물은 만든 순간부터 낡기 시작하는데, 원본 문서와 달리 요약물에는 "언제 기준인지"가 안 적혀 있어서 낡은 걸 알아챌 방법이 없었습니다.

그래서 두 가지를 같이 하기로 했습니다.

  1. 재검증 — 10칸을 지식관리 문서와 한 칸씩 대조해 낡은 칸을 찾아낸다

  2. 재발 방지 — 갱신본에는 "무엇을 근거로, 언제 기준으로 만들었는지"를 도해 안에 박아 넣는다

배경 한 줄

명리학 강의 자료를 AI가 검색·인용할 수 있게 만드는 개인 프로젝트를 하고 있고, 설계 변경이 생길 때마다 지식관리 문서 9건(전략서·로드맵 4종·통합가이드·반성문 총괄표 등)을 일괄 갱신하는 습관을 들여왔습니다. 이번엔 그 창고를 발행물 검증용 기준선으로 처음 써 봤습니다.

진행 방법

3-1. 사용 도구

도구

역할

Claude (프로젝트 지식 + 코드 실행)

지식관리 문서 검색 → 도해 칸별 대조 → HTML 생성 → PNG 렌더 → 육안검증까지 한 세션

프로젝트 지식(창고)

체크리스트 v1.0, 사이드카 DDL v1.0, 반성문 총괄표 v3.8, 전략서 v3.0 명세

Playwright + Chromium (headless)

HTML → PNG 렌더. 레티나 2배 스케일

Noto Sans CJK KR

한글 렌더 폰트 (컨테이너 기본 탑재분)

PPT 도구를 안 쓰고 HTML→PNG로 간 이유는, 도해를 텍스트(코드)로 관리하면 다음번 재검증 때 diff가 보이기 때문입니다. 이번에 크게 데인 게 "무엇이 바뀌었는지 알 수 없다"였는데, PPT 파일은 그걸 못 보여줍니다.

3-2. 작업 순서

① 원본 도해 1장을 올린다 (텍스트가 아니라 이미지로)
② 창고에서 관련 문서를 검색해 '지금 상태'를 확정한다
③ 10칸을 한 칸씩 대조 → 유지 / 갱신 / 교체 판정
④ 갱신본 HTML 작성 (원본 레이아웃 100% 유지)
⑤ PNG 렌더 → 육안검증 → 깨진 칸 수정 → 재렌더
⑥ 갱신 근거·기준일을 도해 안에 명시

③을 반드시 "칸 단위"로 한 것이 이번의 핵심입니다. 전체를 보고 "대충 맞네" 하면 낡은 칸이 그대로 살아남습니다. 열 번 물어보는 게 낫습니다.

3-3. 사용한 프롬프트 전문

[1] 재검증 지시 — 실제로 쓴 문장

첨부한 요약 도해 1장을, 최근 지식관리 창고를 활용해서 상세하게 수정해 줘.

- 먼저 창고(프로젝트 지식)를 검색해서 '지금 확정된 상태'를 확인할 것.
  기억이나 추정으로 채우지 말 것. 창고에 없으면 없다고 말할 것.
- 도해의 10칸을 한 칸씩 원본 ↔ 현재 상태로 대조해서
  유지 / 갱신 / 교체 중 하나로 판정할 것.
- 레이아웃(제목·진단 배너·5컬럼·10카드·하단 2박스·푸터)은 그대로 두고
  내용만 교체할 것. 서식을 새로 만들지 말 것.
- 갱신된 칸에는 눈에 띄는 표식을 달 것.
- 무엇을 근거로 갱신했는지(문서명·버전·날짜)를 도해 안에 적을 것.
- 렌더 후 반드시 이미지를 열어서 눈으로 확인하고,
  줄 넘침·정렬 깨짐이 있으면 고쳐서 다시 렌더할 것.

마지막 두 줄이 실제로 일을 했습니다. 첫 렌더에서 카드 두 개가 3줄로 넘쳐 라벨 정렬이 어긋났는데, 육안검증 지시가 없었으면 그대로 나갔을 겁니다.

[2] 창고 검색 쿼리 — 실제로 던진 것

헤르메스 7노드 N7 리뷰 하네스 사이드카 4객체 권한 3단 계약

검색어를 "무엇이 바뀌었나" 대신 "지금 무엇이 있나"로 던진 게 주효했습니다. 변경 이력을 찾으면 변경 이력만 나오는데, 현재 구성물을 찾으면 그 안에 변경 표시가 같이 들어 있습니다.

3-4. 대조 결과 — 10칸 중 6칸이 낡아 있었다

#

원본 카드

판정

지금 상태

1

책임 단위로 분해

갱신

6노드 → 7노드(리뷰 노드 신설)

2

입출력 계약 명시

유지

3

호출 트리 초안

유지

표현만 "초안" → "확정"

4

재작성 금지

갱신

원칙 서술 → "이번에도 한 줄도 안 고쳤다" 실적으로

5

선행 조건 표기

유지

6

출력 소비처 표기

갱신

소비처가 실제로 생김(로그 테이블 → 크론 → 주간 리뷰)

7

분기점에 게이트

유지

+ "자기개선 경로도 예외 없음" 한 줄 추가

8

게이트는 구조에

교체

판정식 자체가 바뀜 (아래 코드)

9

버전은 조립층에

교체

주제가 통째로 바뀜 → 권한 3단 계약

10

고칠 자리 지목

갱신

개념 → 카드 6요소 NOT NULL 강제로 구현됨

9번이 가장 큰 발견이었습니다. 원본은 "늘어날 때 버전을 어디서 관리할까"를 다뤘는데, 한 달 지나 보니 실제 문제는 버전이 아니라 권한 경계였습니다. 자동화가 어디까지 손대도 되는지가 진짜 관리 문제였고, 원본 도해에는 그 칸이 아예 없었습니다. 낡은 게 아니라 질문 자체가 틀렸던 칸입니다.

3-5. 실제로 바뀐 코드 — 검증 게이트 (8번 칸)

원본 도해가 "게이트는 프롬프트 문장이 아니라 구조에 박아야 한다"고 말했는데, 정작 그 게이트의 판정식이 허술했습니다.

python

# 변경 전 — 문서에는 "근거를 검증한다"고 적혀 있었으나
verified = bool(evidence)      # 배열이 비었는지만 검사

python

# 변경 후 — hermes/nodes/n6_verify.py   (layer: 규율)
import os, re

STRICT = os.getenv("HERMES_N6_STRICT", "1") == "1"
CITE   = re.compile(r"\[[^\]]+:\d+\]")          # [출처:슬라이드번호]

def n6_verify(state):
    sents = split_sentences(state["draft"])
    cited = [s for s in sents if CITE.search(s)]
    ratio = len(cited) / max(len(sents), 1)

    if STRICT and ratio < 1.0:
        state["hold_reason"] = f"근거 미부착 {len(sents)-len(cited)}문장"
        return {"verified": False, "rtype": "HELD", "cite_ratio": ratio}

    return {"verified": True, "rtype": state.get("rtype", "FULL"),
            "cite_ratio": ratio}

판정식을 문서에 그대로 적어 두는 것이 이번 재발 방지책입니다. verified = (cite_ratio == 1.000) — 이 한 줄이 문서에 있으면, 다음에 도해를 검증할 때 코드와 대조할 대상이 명확합니다. "검증한다"고만 적혀 있으면 대조할 게 없습니다.

되돌림 스위치(HERMES_N6_STRICT=0)를 패치와 동시에 넣은 것도 규칙으로 굳혔습니다. 게이트를 조이는 변경은 조이는 순간 무엇이 멈출지 모르기 때문입니다.

3-6. "한 줄짜리 할 일"을 구조로 차단한 부분 (10번 칸)

"고칠 자리를 지목한다"가 개념에 머물지 않도록, 개선 후보 카드의 6요소를 NOT NULL로 강제했습니다.

sql

CREATE TABLE IF NOT EXISTS hermes.backlog_card (
  card_id         text PRIMARY KEY,              -- BL-YYYYMMDD-NN
  pattern_key     text NOT NULL UNIQUE,          -- 중복 접기 키
  title           text NOT NULL,
  source_runs     text[] NOT NULL                -- ① 출처 로그
                  CHECK (array_length(source_runs,1) >= 1),
  occurrences     integer NOT NULL DEFAULT 1     -- ② 반복 횟수
                  CHECK (occurrences >= 1),
  proposed_patch  text NOT NULL,                 -- ③ 제안 패치
  impact_scope    text NOT NULL,                 -- ④ 영향 범위
  verify_method   text NOT NULL,                 -- ⑤ 검증 방법
  rollback_method text NOT NULL,                 -- ⑥ 되돌림
  grade           text NOT NULL DEFAULT 'approval'
                  CHECK (grade IN ('immediate','approval','forbidden')),
  quotes          jsonb NOT NULL DEFAULT '[]'::jsonb,
  CHECK (jsonb_array_length(quotes) <= 5)        -- 인용 최대 5개
);

여섯 칸을 못 채우면 카드가 아예 생성되지 않습니다. "이거 개선하자" 같은 제목 한 줄짜리 할 일이 백로그에 쌓이는 걸 스키마 레벨에서 막은 것입니다. 되돌림 방법을 못 적겠으면 그건 아직 할 일이 아니라는 뜻이기도 합니다.

grade 컬럼이 9번 칸의 권한 3단 계약을 코드로 옮긴 자리입니다.

등급

대상

실행

즉시형

로그 적재 · 카드 생성 · 리포트 · 중복 접기

크론 자동

승인형

검색 청크 재분할 · 가드 규칙 · 골든셋 변경

후보만 자동, 반영은 사람 승인

금지

원본 데이터 UPDATE·DELETE · 기존 파이프라인 수정

자동화 불가

크론은 호출권이지 수정권이 아닙니다. 즉시형에 넣을 수 있었던 건 기록·정리·리포트뿐이었는데, 이유는 단순합니다. "이 결과가 좋아졌는가"를 기계가 판정할 수 없기 때문입니다. 그리고 규율층 파일은 승인형으로 고정했습니다 — 에이전트가 게이트 자체를 완화 대상으로 제안하는 경로를 막기 위해서입니다.

3-7. 렌더 스크립트

python

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    b  = p.chromium.launch()
    pg = b.new_page(viewport={"width":1480,"height":800}, device_scale_factor=2)
    pg.goto("file:///home/claude/case4_v2.html")
    pg.wait_for_timeout(800)

    # 콘텐츠 실제 높이로 뷰포트를 맞춘 뒤 촬영 → 하단 빈 여백 제거
    h = pg.evaluate("document.body.scrollHeight")
    pg.set_viewport_size({"width":1480, "height":int(h)})
    pg.wait_for_timeout(500)
    pg.screenshot(path="/home/claude/case4_v2.png")   # full_page 아님
    b.close()

full_page=True로 찍으면 뷰포트 높이만큼 아래 여백이 붙습니다. scrollHeight를 재서 뷰포트를 맞춘 뒤 일반 스크린샷을 찍으면 딱 맞게 잘립니다.

(캡처 자리 ①) 원본 도해 — 10칸 중 6칸이 낡은 상태 (캡처 자리 ②) 갱신본 — 바뀐 칸에 빨간 표식, 상단에 갱신 근거·기준일 명시

결과와 배운 점

4-1. 결과

  • 10칸 중 6칸 갱신(갱신 4 · 교체 2), 레이아웃은 100% 유지

  • 갱신본에 갱신 근거 4건과 기준일을 도해 안에 명시 — 다음 사람이 낡음을 판정할 수 있게

  • 바뀐 칸에 표식을 달아 원본을 본 사람이 차이를 즉시 볼 수 있게

  • 부산물로 반성문 1건(제35호) 신설 — 아래 참조

4-2. 배운 점 & 나만의 꿀팁

① 요약물에는 반드시 "기준일 + 근거 문서"를 박아라. 이번 사태의 진짜 원인은 내용이 낡은 게 아니라 낡았다는 걸 알 방법이 없었다는 것입니다. 원본 도해에는 날짜도 근거도 없었습니다. 갱신본에는 상단에 한 줄 넣었습니다 — 근거 문서 4건과 기준일. 이 한 줄이 다음 재검증의 출발점이 됩니다.

② 재검증은 반드시 "칸 단위"로 물어라. 전체를 놓고 "맞나?" 하면 눈이 익숙한 것만 보고 넘어갑니다. 10칸을 하나씩 유지/갱신/교체로 판정하게 하니 6칸이 걸렸습니다. 처음 훑었을 땐 저도 2~3칸쯤이라고 생각했습니다.

③ 가장 위험한 칸은 틀린 칸이 아니라 "질문이 바뀐 칸"이다. 9번 칸이 그랬습니다. 내용이 틀린 게 아니라 그 질문이 더 이상 중요하지 않게 됐습니다. 이런 칸은 대조로는 안 잡히고, "지금 이 자리에서 실제로 뭐가 문제였나"를 다시 물어야 잡힙니다. 낡음에는 두 종류가 있습니다 — 답이 낡은 것과 질문이 낡은 것.

④ 문서에 "검증한다"고 쓰지 말고 판정식을 써라. 이게 이번에 얻은 제일 값진 문장입니다. "N6이 근거를 검증한다"는 서술은 코드와 대조가 안 됩니다. verified = (cite_ratio == 1.000)이라고 써 두면 코드를 열어 한 줄로 확인됩니다. 기능명은 검증할 수 없고 판정식은 검증할 수 있습니다.

⑤ 되돌림 스위치는 패치와 같은 커밋에. 게이트를 조이는 변경은 무엇이 멈출지 모른 채 나갑니다. 환경변수 하나로 원상복구되게 만들어 두면 겁내지 않고 조일 수 있습니다.

⑥ 도해는 이미지가 아니라 코드로 관리하라. HTML로 두니 이번 갱신이 diff로 남았습니다. 다음 재검증 때 "지난번에 뭘 바꿨더라"를 파일이 대답합니다. PPT였으면 또 눈으로 찾았을 겁니다.

4-3. 시행착오

반성문 제35호 — "문서에 적힌 검증을, 코드가 실제로 하는지 확인하지 않음". 설계 문서에는 검증 노드가 근거를 확인한다고 적혀 있었고, 실제 코드는 배열이 비었는지만 봤습니다. 근거 없는 문장이 섞인 결과가 "검증 통과"로 나갔습니다. 실행 1건을 End-to-End로 돌려 로그를 대조하고서야 발견했습니다. 기존에 없던 유형이라 패턴 18 "기능명과 실제 동작의 불일치 미검증"으로 새로 등재했습니다.

렌더 넘침 2건. 첫 PNG에서 카드 두 개의 본문이 3줄로 넘쳐 하단 라벨 정렬이 어긋났습니다. 육안검증 후 문장을 2줄로 줄여 재렌더했습니다. 자동 검증(파일 생성 성공)은 통과했는데 눈으로만 잡히는 종류였습니다.

지표 방향을 안 정해서 개선을 악화로 읽을 뻔했습니다. 참고한 외부 실험 틀은 낮을수록 좋은 지표를 쓰는데, 제 지표는 높을수록 좋습니다. 실험 기록표에 direction 필드를 필수로 넣어 막았습니다.

멈춘 게 늘어난 걸 실패로 오해했습니다. 게이트를 조이자 보류 판정이 늘었는데, 처음엔 나빠진 줄 알았습니다. 전에는 근거 없이 통과하던 답이 이제 멈추는 것이므로 성공입니다. 지표 해석 방향을 문서에 먼저 적어 두기로 했습니다.

4-4. 도움이 필요한 부분

① 발행물 낡음을 자동으로 감지할 방법. 지금은 제가 우연히 열어봐서 발견했습니다. 근거 문서의 버전이 올라가면 그 문서를 참조한 발행물에 표시가 뜨는 식의 경량 추적을 만들고 싶은데, 개인 규모에서 과하지 않게 하는 방법이 궁금합니다. 발행물 목록에 참조 문서와 버전을 적어 두는 정도로 충분할까요.

② "질문이 낡은 칸"을 찾는 절차. 답이 틀린 칸은 대조로 잡히는데, 질문 자체가 더 이상 중요하지 않게 된 칸은 대조로 안 잡힙니다. 지금은 감으로 찾았습니다. 이걸 절차로 만든 분이 계시면 배우고 싶습니다.

③ 실측 대조가 밀려 있습니다. 누적 건수가 문서마다 다르게 적혀 있는 걸 발견했는데(2,387 / 2,700 / 9,733), 서버 실측 전이라 전부 NOT_VERIFIED로 두고 있습니다. 이런 전 문서 수치 불일치를 한 번에 동기화하는 실무 요령이 있으면 듣고 싶습니다.


< 앞으로의 계획 >

순위

항목

완료 조건

1

서버 반영

사이드카 객체 4개 + 뷰 2개 생성. 작업 전후 원본 테이블 COUNT 일치가 유일한 성공 기준

2

골든셋 4건 → 50건

질문 유형 10종 × 5건. 게이트가 실제로 무엇을 잡는지 재기 위해

3

크론 1주기 수동 실행

"후보 없음"과 "못 읽음"이 다른 메시지로 나오는지 확인(조용한 실패 방지)

4

검색 정밀도 실험 A~D

한 번에 한 가지만 바꾸고, 원본 색인은 건드리지 않고 복제 색인에서만

5

발행물 재검증 정례화

요약물 전체를 분기 1회 창고 기준으로 대조

5번이 이번 사례의 진짜 결론입니다. 한 번 갱신하는 것보다 "언제 다시 볼지"를 정해 두는 게 낫습니다. 이번에도 한 달을 몰랐던 건, 다시 볼 시점을 안 정해서였습니다.

도움 받은 글 (옵션)

  • 지피터스 에이전트 하네스반 2~4주차 강의자료 — 스킬 3계층(규율·판단·조립), 인터페이스 카드의 MUST NOT 필드, 판정 어휘 고정, 성장 루프 6칸, "검증 영수증" 개념. 이번 재검증의 관점 전부가 여기서 나왔습니다.

  • (내부) 지식관리 수정대상 체크리스트 v1.0 — 설계 변경 1건이 문서 9건 중 어디를 건드리는지 추적하는 관리 문서

  • (내부) 사이드카 DDL v1.0 — 신규 객체를 별도 스키마에만 만들고, 원복은 스키마 하나 삭제로 끝내는 구성

  • (내부) 반성문 총괄표 v3.8 — 35건·18패턴 누적. 이번 제35호가 여기에 들어갔습니다

2개의 답글
밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.