refactor: audit-tail 정리 — FusionPolicy inline + dual-YAML 통일 + NLI required
ponytail-audit 의 작은 over-engineering 잔여 3건 (output/동작 불변):
1. FusionPolicy 1-arm enum 제거 — kebab-search 내부 전용(외부 importer 0)이던
`enum FusionPolicy { Rrf { k_rrf } }` 를 `HybridRetriever.k_rrf: u32` 로 inline.
parse_fusion 은 u32 반환. RRF 수식 `Σ 1/(k_rrf+rank)` byte-identical.
2. dual YAML 통일 — serde_yaml(0.9) 를 maintained fork serde_yaml_ng(0.10) 로 일원화.
k8s manifest chunker + eval golden loader 2 site 마이그레이션(API drop-in),
workspace dep 에서 serde_yaml 제거. parse 결과 불변.
3. NliVerifier::hypothesis_token_count 의 `Ok(0)` default 제거 → required.
prod OnnxNliVerifier 가 이미 override 라 동작 불변, MockNliVerifier 에 explicit 추가.
문서 동기화: search/eval/parse component README + ARCHITECTURE 의 FusionPolicy/
serde_yaml 참조를 현 상태로 갱신. net −37줄. 적대적 검증 2렌즈(output-identity +
completeness-build) 통과, 영향 crate 테스트 + clippy -D warnings 클린.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Mc6W1fgsrbFKTsqA6P8La
This commit is contained in:
@@ -105,7 +105,7 @@ flowchart LR
|
||||
## 주요 type / trait / 함수
|
||||
|
||||
**Loader** (`kebab-eval::loader`):
|
||||
- `load_golden_set(path: &Path) -> Result<Vec<GoldenQuery>>` — `serde_yaml` 위 YAML 파싱.
|
||||
- `load_golden_set(path: &Path) -> Result<Vec<GoldenQuery>>` — `serde_yaml_ng` 위 YAML 파싱.
|
||||
- `GoldenQuery { id, query, mode, k, must_contain, expected_doc_ids, ask }` — fixture 한 entry. `must_contain` 가 case-sensitive substring 검사.
|
||||
|
||||
**Runner** (`kebab-eval::runner`):
|
||||
@@ -133,7 +133,7 @@ flowchart LR
|
||||
## 외부 의존
|
||||
|
||||
- crate dep: `kebab-core` + `kebab-config` + `kebab-app` (facade only) + `kebab-store-sqlite` (SQLite 직접 read/write — `eval_runs` / `eval_query_results` 측). retrieval / embedding / LLM crate 직접 import **금지**.
|
||||
- 외부 lib: `serde_yaml` (golden YAML), `serde_json`, `uuid` (v7), `time`, `tracing`, `anyhow`.
|
||||
- 외부 lib: `serde_yaml_ng` (golden YAML), `serde_json`, `uuid` (v7), `time`, `tracing`, `anyhow`.
|
||||
- 외부 서비스: 없음 (facade 가 가져옴).
|
||||
|
||||
## 핵심 결정
|
||||
|
||||
@@ -114,7 +114,7 @@ flowchart LR
|
||||
|
||||
- crate dep:
|
||||
- 모든 parser → `kebab-core` (`Extractor` trait, `Block`, `Metadata`, `id_for_*`).
|
||||
- `kebab-parse-md` → `kebab-parse-types` (`ParsedBlock`/`ParsedPayload`/`Warning`), `pulldown-cmark`, `serde_yaml`.
|
||||
- `kebab-parse-md` → `kebab-parse-types` (`ParsedBlock`/`ParsedPayload`/`Warning`), `pulldown-cmark`, `serde_yaml_ng`.
|
||||
- `kebab-parse-pdf` → `lopdf`.
|
||||
- `kebab-parse-image` → `image` (decode), `kamadak-exif` (EXIF), `kebab-core::LanguageModel` (caption).
|
||||
- 외부 서비스:
|
||||
|
||||
@@ -30,16 +30,12 @@ classDiagram
|
||||
}
|
||||
class HybridRetriever {
|
||||
+new(cfg, lexical, vector) Self
|
||||
+with_policy(lex, vec, FusionPolicy, k)
|
||||
+with_policy(lex, vec, k_rrf, default_k)
|
||||
-lexical: Arc~dyn Retriever~
|
||||
-vector: Arc~dyn Retriever~
|
||||
-fusion: FusionPolicy
|
||||
-k_rrf: u32
|
||||
-default_k: usize
|
||||
}
|
||||
class FusionPolicy {
|
||||
<<enum>>
|
||||
Rrf{k_rrf}
|
||||
}
|
||||
class SearchMode {
|
||||
<<enum>>
|
||||
Lexical
|
||||
@@ -51,7 +47,6 @@ classDiagram
|
||||
Retriever <|.. HybridRetriever
|
||||
HybridRetriever --> LexicalRetriever
|
||||
HybridRetriever --> VectorRetriever
|
||||
HybridRetriever ..> FusionPolicy
|
||||
HybridRetriever ..> SearchMode : dispatch
|
||||
```
|
||||
|
||||
@@ -95,7 +90,7 @@ flowchart LR
|
||||
|
||||
**HybridRetriever** (`kebab-search::hybrid`):
|
||||
- `HybridRetriever::new(&Config, Arc<dyn Retriever> lex, Arc<dyn Retriever> vec) -> Self` — `config.search.hybrid_fusion` (`"rrf"`) + `config.search.rrf_k` 읽음. 두 retriever 의 `index_version` 가 다르면 `tracing::warn`.
|
||||
- `FusionPolicy::Rrf { k_rrf }` — default 60. `with_policy` 헬퍼로 explicit 지정 가능.
|
||||
- `k_rrf: u32` — default 60. `with_policy` 헬퍼로 explicit 지정 가능.
|
||||
- 상수: `DEFAULT_K = 10` (query.k == 0 fallback), `DEFAULT_K_RRF = 60`, `HYBRID_FANOUT_MULTIPLIER = 2`.
|
||||
- merge rule: 양측 등장 chunk 의 `snippet` / `citation` / `heading_path` 는 lexical 측에서 가져옴 (FTS5 highlight 가 vector 의 truncated text 보다 user-relevant).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user