[개발 일기] / GraphRAG | Action report 기반 registry 갱신.md

GraphRAG | Action report 기반 registry 갱신

조회

시리즈: GraphRAG 구축기 #15

이전: 14편 | 목록 | 다음 없음

2026년 5월 13일 | 개발 일기


GraphRAG profile registry가 action report를 읽는 쪽까지 연결됐다. 지난 반복에서는 실행할 profile 목록을 configs/profile_registry.json에 묶어 두고, active, observe, disabled 상태를 나눴다. 그런데 여전히 찜찜한 구석이 있었다. history-stale-origin-actions.json이 “이 profile은 관찰 후보”라고 말해도, 그 판단이 registry 안에는 자동으로 남지 않았다.

그래서 이번에는 검색 점수식을 건드리지 않고, 운영 장부를 이어 붙이는 쪽으로 작게 갔다. 이름은 registry action sync라고 붙였다. stale-origin action report를 읽어서 profile registry의 statuslast_action 메타데이터에 반영하는 얇은 CLI다. 성능이 갑자기 좋아지는 기능은 아니지만, 다음 실험을 열 때 “왜 이 profile이 observe 상태였지?”를 다시 추리하지 않아도 된다.

GraphRAG registry action sync 흐름도
iter33에서는 action report의 판단을 registry의 last_action 기록으로 고정했다.

1. report와 registry 사이의 틈

최근 GraphRAG 루프는 “좋은 profile을 찾자”보다 “나쁜 profile을 계속 다시 읽지 않게 하자”에 가까웠다. quality gate로 PASS/WARN/HARD-FAIL을 가르고, history status streak로 같은 상태가 몇 run째 이어지는지 봤고, stale origin action queue에서 exclude-candidateobserve-candidate를 나눴다.

iter32에서는 그 위에 registry allowlist를 얹었다. path_bridge_focus처럼 장기 HARD-FAIL이 난 profile은 disabled로 보류하고, relation_weight_densepath_bridge_probe만 sweep에 올렸다. 여기까지 오면 실행 대상은 꽤 명확해진다. 문제는 action report의 최신 판단이 registry에 남는 방식이었다.

예를 들어 iter32의 action report는 path_bridge_probe를 다시 observe-candidate로 표시했다. 실제 registry도 이미 observe였으니 상태를 바꿀 필요는 없었다. 그래도 나는 이 판단의 출처가 registry에 같이 남아야 한다고 봤다. 그렇지 않으면 며칠 뒤 파일을 열었을 때 “이 observe는 언제, 어떤 run에서 온 거지?”를 다시 summary와 report를 뒤져야 한다.

2. sync는 일부러 보수적으로

새로 만든 모듈은 profile_registry다. action report의 profiles[]를 읽고, registry 안의 기존 profile과 이름 또는 경로로 맞춘다. 매칭된 항목에만 action을 반영한다.

  • exclude-candidatedisabled로 바꾼다.
  • observe-candidatereview-candidateobserve로 둔다.
  • registry에 없는 action은 자동으로 새 profile로 추가하지 않고 unmatched_actions에만 남긴다.
  • 반영된 항목에는 last_action을 붙여 action reason, blocking scopes, source report path, 적용 시각을 저장한다.

마지막 규칙은 일부러 넣었다. action report는 이전 run의 산출물이라, 임시 실험 profile이나 경로 표기가 섞일 수 있다. 그런 항목을 registry에 조용히 append하면 실행 계약이 오염된다. registry는 다음 sweep의 allowlist에 가깝기 때문에, 모르는 profile은 “못 맞췄다”고 보고만 하는 편이 안전하다.

3. iter33 결과

이번 구현 뒤 테스트를 다시 돌렸고, 총 39개 테스트가 통과했다. 기존 profile evaluation 테스트 위에 registry sync 전용 테스트 3개를 추가했다. 그 다음 iter32의 history-stale-origin-actions.json을 현재 registry에 반영하고, 같은 profile set으로 iter33 bundle을 다시 만들었다.

항목 iter33 값 해석
matched_profile_count 1 path_bridge_probe action이 registry와 매칭됨
status_changed_profile_count 0 이미 observe였기 때문에 상태 변경은 없음
action_counts observe-candidate:1 이번에는 제외가 아니라 계속 관찰 신호
profile-registry active=2, disabled=1 실행 대상 구성은 iter32와 동일

status_changed_profile_count=0은 처음 보면 허무하다. 나도 로그를 보고 잠깐 “뭔가 안 바뀐 건가?” 싶었다. 하지만 이번 반복의 목적은 상태를 억지로 바꾸는 게 아니라, action report의 판단을 registry에 고정하는 것이었다. 그래서 실제로 중요한 변화는 path_bridge_probe 항목에 last_action이 생긴 부분이다.

4. 실행 결과보다 provenance가 먼저인 작업

sync 뒤 profile_eval을 다시 돌리면 결과 자체는 예상대로 크게 달라지지 않는다. defaultrelation_weight_densePASSx9를 유지했고, path_bridge_probeWARNx9로 계속 남았다. action report도 다시 observe-candidate:1을 냈다.

이런 변경은 겉으로 보기에 밋밋하다. 랭킹이 뒤집히지도 않았고, top1 hit가 올라가지도 않았다. 그래도 GraphRAG 같은 실험 루프에서는 꽤 필요하다. profile을 제외하거나 관찰 대상으로 남기는 판단은 다음 run의 입력을 바꾼다. 입력을 바꾸는 판단이라면, 그 판단의 출처도 실행 가능한 설정 옆에 있어야 한다.

나는 이 지점을 종종 놓친다. report를 만들고 나면 뭔가 끝난 것처럼 느끼는데, 사실 report가 다음 실행의 계약으로 넘어가지 않으면 반쪽짜리다. 이번 sync는 그 사이를 아주 얇게 잇는다. action report는 “이번 run에서 본 것”이고, registry는 “다음 run에서 따를 것”이다. 둘이 서로 다른 파일이더라도 최소한 한쪽에서 다른 쪽의 출처를 가리키게 만들었다.

5. 다음은 운영 query set 분리

이제 남은 큰 찜찜함은 sample query set이다. 지금 WARNx9로 남은 path_bridge_probe는 샘플 질문 묶음 기준이다. 이 상태가 실제 운영 질문에서도 같은 의미인지 아직 확신하기 어렵다. 다음 반복에서는 sample query set과 operational query set을 분리해서, observe-candidate가 정말 계속 관찰할 가치가 있는지 다시 봐야 한다.

또 하나는 exclude-candidate가 다시 등장했을 때다. 이번 iter33에서는 observe action만 있었기 때문에 status 변경이 0이었다. 나중에 action report가 hard-fail profile을 다시 잡으면, sync가 registry status를 disabled로 바꾸고 그 이유를 남기는지 운영 run에서 한 번 더 확인할 생각이다.

작은 변경이지만 마음은 조금 가벼워졌다. 이제 profile registry를 열면 실행 대상뿐 아니라 최근 action report의 판단까지 같이 보인다. 검색 모델을 더 세게 만드는 일은 아니어도, 같은 실패를 계속 다시 해석하는 시간을 줄이는 일이다. 요즘 GraphRAG 쪽에서는 이런 장부 정리가 생각보다 큰 진전처럼 느껴진다.

시리즈: GraphRAG 구축기 #15

이전: 14편 | 목록 | 다음 없음

댓글

홈으로 돌아가기

검색 결과

"" 검색 결과입니다.