2026년 7월 7일 | 개인 프로젝트 · GraphRAG
GraphRAG의 profile registry가 점점 운영 기록처럼 변하고 있다. 처음에는 문서에서 엔티티와 관계를 뽑고, TF-IDF 점수와 graph score를 더해 검색 순위를 보는 작은 MVP였다. 그런데 profile이 늘어나고 quality gate가 붙으면서, 이제는 어떤 profile을 계속 관찰하고 어떤 profile을 접을지 판단하는 루프가 더 중요해졌다. 이번 회차에서는 지난번에 registry metadata로만 남겨 둔 narrow-warning-scope action을 실제 scoring profile 후보로 한 칸 더 밀어 넣었다.
metadata에서 후보 profile로 넘어가기
지난 회차의 핵심은 일부러 보수적이었다. `path_bridge_probe`가 warning band에 오래 남아 있었고, exit policy preview report는 `narrow-warning-scope`를 제안했다. 하지만 그 제안을 registry에 곧바로 반영하면 너무 많은 일이 한 번에 섞인다. 그래서 나는 profile 상태를 바꾸지 않고, 수동 확인된 action과 blocking scope만 `last_action`에 남겼다. 이번에는 그 기록을 입력으로 받아 새 scoring profile 후보를 만드는 작은 경로를 붙였다.
새 명령은 registry snapshot과 기존 `path_bridge_probe` profile을 같이 읽는다. 그리고 `last_action.recommended_action`이 `narrow-warning-scope`인지, manual confirmation이 실제로 끝났는지 먼저 본다. 확인이 없으면 멈추고, 확인이 있으면 기존 profile을 덮어쓰지 않고 `path_bridge_probe_narrowed` 후보를 따로 만든다. 여기서 중요한 점은 운영 profile과 실험 후보를 분리했다는 것이다.
이번 후보가 실제로 바꾼 숫자
조정 규칙은 일부러 단순하게 잡았다. warning scope가 `top1_hit_rate`와 `full_coverage_rate` 쪽에 붙어 있으면 coverage 신호를 올리고, `doc-bridges`와 `docs` 쪽에 붙어 있으면 path와 bridge 보너스를 조금 낮춘다. 그래서 후보 profile에서는 `coverage_weight`가 0.30에서 0.65로, `full_coverage_bonus`가 0.00에서 0.25로 올라갔다. 반대로 `path_weight`는 0.55에서 0.45로, `max_path_score`는 1.00에서 0.90으로, `query_bridge_bonus`는 0.25에서 0.15로 내려갔다.
나는 이런 조정을 아직 튜닝이라고 부르기엔 이르다고 본다. 더 정확히는 후보 생성 규칙이다. 사람이 확인한 preview action을 숫자 diff로 바꿔 보고, 그 다음 같은 query set과 quality gate로 다시 돌려 보는 단계다. profile 파일 안에는 provenance도 같이 넣었다. 어떤 registry snapshot에서 왔고, 어떤 action을 근거로 만들었고, 어떤 blocking scope 때문에 값이 바뀌었는지 나중에 다시 읽히게 하려는 장치다.
profile_eval 결과는 절반만 좋아졌다
같은 6개 query로 기존 `path_bridge_probe`와 새 `path_bridge_probe_narrowed`를 나란히 돌렸다. 결과는 아주 깔끔한 성공은 아니었다. 기존 probe는 `avg_top_score=4.1476`, `avg_covΔ=-0.9167`, `top1_hit=83%`, `full_coverage=83%`, `quality_gate=WARN`이었다. narrowed 후보는 `avg_top_score=4.4032`, `avg_covΔ=-0.3778`까지는 좋아졌지만, `top1_hit=83%`, `full_coverage=83%`, `quality_gate=WARN`은 그대로였다.
이 숫자를 보고 살짝 허무했다. coverage penalty는 분명 줄었는데, 내가 가장 고치고 싶었던 `manual-incident` query의 top-1 flip은 그대로 남았다. `GraphRAG overview`가 올라와야 하는 자리에서 여전히 `Retrieval planner`가 위로 올라온다. 즉 이번 후보는 점수 모양을 덜 나쁘게 만들었지만, ranking 오류의 핵심 원인을 직접 건드리지는 못했다.
그래도 이번 실패가 쓸모 있는 이유
이번 결과가 마음에 드는 지점은 실패가 좁게 남았다는 것이다. 막연히 “profile이 warning이다”가 아니라, coverage를 올리고 path 보너스를 낮춰도 `manual-incident` rank flip이 남는다는 사실이 생겼다. 그러면 다음 질문은 훨씬 작아진다. coverage weight를 더 올릴 것인가가 아니라, 그 query에서 어떤 edge evidence가 `Retrieval planner`를 과하게 밀어 올리는가를 보면 된다.
또 하나는 registry action과 scoring diff 사이의 선이 생겼다는 점이다. 전에는 preview report가 “이 action을 생각해 보라”고 말하는 데서 멈췄다. 이제는 그 action이 실제 후보 profile로 어떻게 번역됐는지, 그리고 그 후보가 기존 query set에서 어떤 실패를 여전히 남겼는지까지 이어진다. GraphRAG처럼 점수와 근거가 같이 움직이는 시스템에서는 이 연결선이 꽤 중요하다.
테스트와 커밋
코드 쪽에서는 profile registry CLI에 scoring profile adjustment 경로를 추가했다. 수동 확인이 없는 action은 후보 생성을 거절하고, 확인된 `narrow-warning-scope`만 후보 profile과 adjustment report를 만들게 했다. 테스트는 profile registry, profile eval, 기본 pipeline 묶음을 같이 돌렸고 55개 테스트가 통과했다.
이번 커밋에는 adjustment builder, CLI option, 새 후보 profile, iteration note가 같이 들어갔다. 실험 bundle은 로컬 trace로 남겼고, 문서에는 어떤 값이 바뀌었는지와 어떤 지표가 그대로 남았는지를 같이 적었다. 다음 세션에서 바로 `manual-incident` rank flip만 열어 보면 되도록 하기 위해서다.
다음은 edge evidence 비교다
다음 반복에서는 `manual-incident` query만 따로 잘라 보려고 한다. 지금은 coverage와 path weight를 만져도 top-1이 바뀌지 않았으니, 남은 후보는 relation type weight나 cluster-specific guard 쪽이다. 특히 `docs/path-shift` 성격의 query에서 Product Manual, Incident Report, GraphRAG overview가 어떤 edge로 연결되는지 먼저 보고 싶다.
GraphRAG MVP가 커질수록 기능 하나를 더 붙이는 것보다, 잘못된 profile을 빨리 알아보고 좁게 실험하는 일이 더 중요해지고 있다. 이번 회차는 화려한 성능 개선은 아니었지만, 나는 이런 종류의 작은 실패가 마음에 든다. 실패 범위가 좁아졌고, 다음에 열어 볼 파일과 query가 분명해졌기 때문이다.
'[AI 실험실] > [개인 프로젝트] GraphRAG' 카테고리의 다른 글
| GraphRAG | 문서 브리지 질의의 Full-Coverage 순위 보정 (0) | 2026.07.14 |
|---|---|
| GraphRAG | 1위 결과 전환의 엣지 근거 비교 (0) | 2026.07.10 |
| GraphRAG | Exit Policy preview action 적용 (0) | 2026.07.03 |
| GraphRAG | Exit Policy action preview 리포트 (0) | 2026.06.30 |
| GraphRAG | Exit Policy 조건 리포트 (0) | 2026.06.26 |