요약
Layer C 의 진입점 / 라우팅 분기 / stub 안내는 PR #51에서 이미 구현 완료 (retrieval/community_summary.py). 본 이슈는 stub 안내 응답을 진짜 답변으로 대체 — Leiden community detection + community summary 사전 생성 + map-reduce 합성.
Hybrid 로드맵 P4 📦 — multi-doc 영역 회복.
동기 — W6 측정에서 진단된 영향
| Pattern |
영향 건수 |
증상 |
multi_doc_trend |
10 (routing 100%) |
라우터가 Layer C 로 옳게 분기 → stub 응답 반환 → Correctness 1.0 |
summary |
4 |
corpus-wide 요약 필요 → BM25 chunk 검색 부적합 |
| 그 외 글로벌 질의 |
2 |
"전체 트렌드" / "주요 흐름" 패턴 |
총 16건의 부진이 Layer C 진짜 구현으로 회복 가능.
라우터는 정상 작동 (multi_doc_trend Routing Accuracy 100%) — 답변 단계만 박으면 됨.
현재 상태 — PR #51 박힘
# retrieval/community_summary.py — 이미 구현된 부분
@track
def community_summary(question: str) -> CommunitySummaryResult:
# 진입점 ✅
# @track Opik trace ✅
# CommunitySummaryResult 시그니처 박제 ✅
# is_stub=True 정직한 안내 응답 ✅
return CommunitySummaryResult(
question=question,
answer=_STUB_ANSWER_TEMPLATE.format(question=question),
is_stub=True, # ← 본 이슈로 False 전환
)
변경 사항 (예정)
1. kg/community_detection.py (신규)
Leiden 알고리즘 박힌 community detection:
def detect_communities(
*,
resolution: float = 1.0,
seed: int = 42,
) -> List[Community]:
"""Entity 노드 기반 Leiden community 추출.
Returns:
List[Community] — 각 community 는 entity_ids + level + score 박힘.
"""
# 1. Neo4j GDS 프로젝션 (entity 노드 + 관계)
# 2. Leiden 알고리즘 실행
# 3. Community 메타데이터 → Neo4j 노드 박기 (Community 라벨)
...
후보 라이브러리:
- Neo4j GDS (
gds.leiden.write) — Neo4j 내장, 가장 깔끔
- networkx + leidenalg — Python 단독 가능
2. kg/community_summary.py (신규)
각 community 의 LLM 요약 사전 생성 (indexing-time):
def build_community_summaries(
communities: List[Community],
*,
llm_config: LLMConfig,
) -> List[CommunityReport]:
"""각 community → LLM 요약 생성 → Neo4j 노드 박기 (CommunityReport 라벨).
각 report 박힘:
- entities: 해당 community 의 entity 목록
- relationships: community 내부 관계
- core_chunks: 핵심 chunk 텍스트 3~5개
- summary: LLM 생성 요약 (한국어, ~500 토큰)
"""
...
3. retrieval/community_summary.py (수정 — stub → 실제 구현)
@track
def community_summary(question: str) -> CommunitySummaryResult:
# 1. Map step — 모든 CommunityReport 에 대해 question 관련성 점수
relevant_reports = _map_step(question, llm_config)
# 2. Reduce step — top-K report 기반 최종 답변 합성
answer = _reduce_step(question, relevant_reports, llm_config)
return CommunitySummaryResult(
question=question,
answer=answer,
is_stub=False, # ← 진짜 구현
community_count=len(relevant_reports),
top_communities=[r.community_id for r in relevant_reports[:3]],
)
4. scripts/build_community_index.py (신규)
Indexing-time community 빌드 진입점:
uv run python scripts/build_community_index.py \
--algorithm leiden \
--resolution 1.0 \
--llm-model "moonshotai/kimi-k2.5"
5. retrieval/prompts/community_summary_v2.md (수정)
기존 placeholder 박힌 거 → 실제 map-reduce 프롬프트로 교체.
6. docs/adr/0007-community-detection.md (신규)
Leiden vs Louvain vs Label Propagation 의사결정 ADR.
DoD
검증 방법
# 1. P1 + P2 적용된 그래프 기반 community 빌드
uv run python scripts/build_community_index.py --algorithm leiden
# 2. Community 노드 audit
uv run python scripts/audit_communities.py
# Expected: Community 5~15개, 각 5~30 entities, summary 박혀있음
# 3. W4 R3 케이스 재실행
uv run python -m scripts.run_w4_eval --case R3
# Expected: is_stub=False, 답변에 corpus-wide 트렌드 박혀있음
# 4. 80 QA 재측정 (multi_doc_trend 10건 + summary 4건 회복 확인)
uv run python scripts/run_qa_eval.py --qa-set graphrag --tag layer_c_v2
예상 효과
| Pattern |
Before (W6, stub) |
After (P4, 진짜) |
회복 |
multi_doc_trend Correctness |
1.00 |
3.0+ |
10건 |
summary Correctness |
1.00 |
3.0+ |
4건 |
| Faithful (전체) |
5.0% |
+5%p 추가 |
6건 |
Trade-offs
| 항목 |
비용 |
| Indexing-time 빌드 시간 |
8 doc / 515 community → 약 1030분 |
| LLM 호출 (community 요약) |
5~15회 (community 당 1회) |
| Neo4j 저장소 |
CommunityReport 노드 추가 |
→ indexing-time 비용이라 query-time 영향 없음 (빠른 응답 유지).
의존 / 후속
레퍼런스
우선순위
📦 P4 — P1+P2 적용 후 진행. 2~3일 작업.
Refs #20, #51, #56, #57, W6 measurement results
요약
Layer C 의 진입점 / 라우팅 분기 / stub 안내는 PR #51에서 이미 구현 완료 (
retrieval/community_summary.py). 본 이슈는 stub 안내 응답을 진짜 답변으로 대체 — Leiden community detection + community summary 사전 생성 + map-reduce 합성.Hybrid 로드맵 P4 📦 — multi-doc 영역 회복.
동기 — W6 측정에서 진단된 영향
multi_doc_trendsummary총 16건의 부진이 Layer C 진짜 구현으로 회복 가능.
라우터는 정상 작동 (
multi_doc_trendRouting Accuracy 100%) — 답변 단계만 박으면 됨.현재 상태 — PR #51 박힘
변경 사항 (예정)
1.
kg/community_detection.py(신규)Leiden 알고리즘 박힌 community detection:
후보 라이브러리:
gds.leiden.write) — Neo4j 내장, 가장 깔끔2.
kg/community_summary.py(신규)각 community 의 LLM 요약 사전 생성 (indexing-time):
3.
retrieval/community_summary.py(수정 — stub → 실제 구현)4.
scripts/build_community_index.py(신규)Indexing-time community 빌드 진입점:
uv run python scripts/build_community_index.py \ --algorithm leiden \ --resolution 1.0 \ --llm-model "moonshotai/kimi-k2.5"5.
retrieval/prompts/community_summary_v2.md(수정)기존 placeholder 박힌 거 → 실제 map-reduce 프롬프트로 교체.
6.
docs/adr/0007-community-detection.md(신규)Leiden vs Louvain vs Label Propagation 의사결정 ADR.
DoD
scripts/build_community_index.py박혀서 community 빌드 성공community_summary(question)→is_stub=False, 실제 답변 박힘검증 방법
예상 효과
multi_doc_trendCorrectnesssummaryCorrectnessTrade-offs
15 community → 약 1030분→ indexing-time 비용이라 query-time 영향 없음 (빠른 응답 유지).
의존 / 후속
레퍼런스
우선순위
📦 P4 — P1+P2 적용 후 진행. 2~3일 작업.
Refs #20, #51, #56, #57, W6 measurement results