[AI 실험실]/[개인 프로젝트] GraphRAG / GraphRAG | Observation aging의 registry preview 연결.md

GraphRAG | Observation aging의 registry preview 연결

조회

시리즈: GraphRAG 구축기 #20

이전: 19편 | 목록 | 다음: 21편

2026년 5월 19일 | 개인 프로젝트


Observation aging queue가 생긴 뒤로도 한 가지 찝찝한 지점이 남아 있었다. 오래 관찰 중인 profile을 따로 모아 두기는 했지만, 그 queue를 실제 registry preview 루틴에 넣으면 무엇이 바뀌어야 하는지가 아직 애매했다. `keep-observing`은 말 그대로 계속 보자는 신호고, 이것만으로 profile을 바로 승격하거나 비활성화하면 자동화가 너무 급하게 움직인다.

이번 GraphRAG 반복에서는 그 사이를 얇게 연결했다. aging report를 registry sync 입력으로 받을 수 있게 하되, status를 바로 바꾸지 않고 review-candidate라는 보수적인 action으로 접었다. 내가 원한 건 “이 profile을 지금 처리했다”가 아니라, “관찰이 길어졌으니 종료 조건을 검토할 차례다”라는 흔적을 registry 안에 남기는 것이었다.

GraphRAG observation aging action sync 흐름도

Figure 1. aging report를 registry preview에 연결하되, observe 상태는 유지하고 last_action provenance만 갱신하는 흐름

왜 바로 status를 바꾸지 않았나

지금 GraphRAG MVP의 profile registry에는 크게 세 종류의 상태가 있다. 안정적으로 쓸 profile은 active, 실험적으로 보되 아직 배포 후보는 아닌 profile은 observe, 반복적으로 문제를 만든 profile은 disabled다. 여기서 `path_bridge_probe`는 계속 observe 쪽에 남아 있다. 이유는 단순하다. 이 profile이 완전히 망가진 건 아니기 때문이다.

iter37 기준으로 `path_bridge_probe`는 WARN 상태가 길게 이어졌다. 하지만 top-k 안에는 기대 문서가 남고, hard-fail까지 가지도 않았다. 흔들리는 지점은 주로 `doc-bridges`와 `docs` 태그 쪽 warning이다. 이 상황에서 자동으로 disabled로 보내 버리면, 나중에 “어떤 warning을 줄이면 쓸 만해지는가”라는 실험 기회를 잃는다. 반대로 계속 observe로만 두면, 경고가 오래 누적되고 있다는 사실이 registry 한눈 보기에서는 잘 드러나지 않는다.

그래서 이번에는 status 전환보다 provenance를 먼저 택했다. aging report에 있는 `observation_followup=review-exit-condition`을 읽어서 registry preview의 `last_action`에 남긴다. status는 observe 그대로지만, 그 profile이 왜 다시 검토 후보인지, 어떤 warning scope 때문에 묶였는지, 어떤 종료 조건 후보를 봐야 하는지가 같이 따라온다.

작게 바꾼 코드

변경은 `profile_registry.py` 쪽에 들어갔다. 기존 registry sync는 `recommended_action`이나 `recommended_registry_action`이 있는 report를 입력으로 받았다. history stale origin action report나 observation review report는 이 형식에 맞았지만, 새로 만든 aging report의 중심 필드는 `observation_followup`이었다. 이 필드를 그대로 두면 sync 루틴 입장에서는 그냥 `keep-observing`만 보는 셈이 된다.

이번에는 `observation_followup`이 있으면 그것을 우선 읽도록 했다. `review-exit-condition`, `manual-review`, `consider-disable` 같은 follow-up은 모두 `review-candidate`로 정규화했다. 여기서 일부러 `consider-disable`도 바로 `disable-candidate`로 보내지 않았다. 이름만 보면 비활성화 후보처럼 보이지만, aging queue의 의도는 최종 판정이 아니라 “검토할 조건을 열어라”에 더 가깝다고 봤기 때문이다.

대신 정보는 꽤 많이 보존했다. `followup_reason`은 `action_reason`으로 승격했고, `exit_condition_candidates`는 그대로 `last_action`에 넣었다. `warning_scopes`와 `hard_fail_scopes`는 기존 방식대로 `blocking_scopes`로 접었다. 이렇게 해 두면 registry preview만 열어도 다음 판단에 필요한 최소 정보가 보인다.

이번 preview에서 확인한 것

실제 iter37의 `registry-observation-aging.json`을 이번 sync 루틴에 넣어 봤다. 결과는 의도한 대로 보수적이었다.

  • matched profile: 1
  • unmatched action: 0
  • status changed: 0
  • action count: review-candidate 1
  • registry status: active 1, observe 1, disabled 1

대상은 `path_bridge_probe` 하나다. preview registry에서 이 profile의 status는 여전히 observe다. 대신 `last_action.recommended_action`이 `review-candidate`로 바뀌고, `observation_followup=review-exit-condition`이 붙는다. 여기에 `promote-after-pass-streak`, `disable-after-hard-fail-streak`, `manual-review-if-warning-streak-persists`, `narrow-warning-scope-before-next-run` 같은 exit condition 후보가 같이 남는다.

이 작은 차이가 꽤 중요하다. 예전에는 “계속 observe”라는 결론만 남았다면, 이제는 “왜 계속 observe인지”와 “언제 observe를 끝낼지”가 같은 registry preview 안에 붙는다. profile 수가 세 개뿐인 지금은 큰 차이가 없어 보일 수 있지만, 나중에 profile이 열 개 이상으로 늘어나면 이런 provenance가 없으면 금방 헷갈린다.

테스트에서 고정한 기준선

테스트는 기존 profile registry 테스트에 하나를 더했다. aging follow-up report를 넣었을 때 `path_bridge_probe`가 observe 상태를 유지하면서도 `review-candidate` last action을 받는지 확인했다. 그리고 warning scope가 `blocking_scopes`로 옮겨지는지, exit condition 후보가 보존되는지도 같이 고정했다.

전체 테스트는 42개가 통과했다. 직전 기준선이 41개였으니 새 케이스 하나가 추가된 셈이다. 이 숫자를 굳이 적어 두는 이유는, 이번 변경이 ranking 품질을 직접 올리는 기능이 아니라 운영 계약을 다듬는 기능이기 때문이다. 이런 레이어는 눈으로 볼 때는 별것 아닌데, 테스트가 없으면 다음에 report 형식이 조금 바뀌었을 때 조용히 끊기기 쉽다.

이번 변경의 의미

GraphRAG 프로젝트를 계속 만지다 보니, 검색 점수 자체보다도 “판단을 어디까지 자동화할 것인가”가 더 자주 문제로 올라온다. 자동화가 약하면 매번 사람이 trace를 열어야 하고, 자동화가 세면 애매한 profile을 너무 빨리 제외한다. 이번 레이어는 그 중간에 있다. 판단을 대신하지는 않지만, 판단을 미루고 있다는 사실을 숨기지 않는다.

나는 이 방향이 마음에 든다. MVP 단계에서는 똑똑한 최종 판정기보다, 나중에 내가 다시 봐도 납득할 수 있는 얇은 기록이 더 중요할 때가 많다. `path_bridge_probe`도 지금은 버릴 대상이 아니라 warning band를 좁혀 봐야 하는 대상에 가깝다. 그러니 registry에 남길 문장도 “비활성화”가 아니라 “종료 조건 검토”가 맞다.

다음에는 이 `review-candidate`가 반복되는 profile만 다시 모으는 queue를 하나 더 둘지 보려고 한다. 여기까지 가면 observe profile은 단순히 “계속 보는 것”이 아니라, 어떤 조건을 만족하면 승격하고 어떤 조건이면 끊을지까지 조금씩 실행 계약으로 내려올 수 있다.

시리즈: GraphRAG 구축기 #20

이전: 19편 | 목록 | 다음: 21편

댓글

홈으로 돌아가기

검색 결과

"" 검색 결과입니다.