RAG 프롬프트의 각 [근거] 청크 머리에 출처/trust 라벨을 붙이고 (`[#n] source=jira trust=secondary doc=…`), system prompt 에 "저신뢰 출처를 권위 출처와 충돌 시 discount 하고 [#번호]로 귀속" 2규칙을 더한다. 출처 필터 (`--source`/`--trust-min`)가 못 잡는 생성 측 실패 — 저신뢰(jira) 청크가 권위(wiki) 청크를 답변에서 덮어쓰는 것 — 를 다룬다. - SearchHit 에 source_id/trust_level(additive optional). lexical/vector build_hit 가 documents 조인에서 채움(both 동일: trust_level lowercase TEXT → serde lowercase round-trip, doc_summary read-back 과 동형). hybrid fusion 전파. - pack_context 라벨 렌더(버전 무관 항상). SYSTEM_PROMPT_RAG_V4 = rag-v3 8규칙 verbatim + 2규칙. config 기본 rag-v3→rag-v4. multi-hop synth 도 2규칙 → rag-multi-hop-v1→v2(prompt 변경 = 버전 bump, design §9). - wire: search_hit.v1 에 두 필드 optional additive(required 아님, skip_serializing_if=None → 구 소비자 무영향, v2 bump 아님). - source_id 는 RAG 헤더에 렌더되므로 validate_sources 에 [A-Za-z0-9._-] char 검증. - opt-out: rag-v3 핀 = v3 system prompt 선택(discount 지시 빠짐, 라벨은 무해히 잔존). 검증: kebab-core/search/rag/config/eval 전 테스트 green(25 바이너리), clippy 0. 독립 코드 리뷰 APPROVE(7위험 PASS — trust round-trip 실 DB 확인; MEDIUM rag-v3 opt-out doc + multi-hop 버전 / LOW source_id 검증 반영). 도그푸딩: 라벨 메커니즘 end-to-end 검증(search --json 이 competing 쿼리에 wiki/primary + jira/secondary 둘 다 정확 라벨로 노출). LLM-judge(답변 비교)는 instruction LLM 부재로 보류(.2/.47 다운 + lemonade /api/generate it-model template 미적용) — 인프라, .2 복구 시 측정. 버전 bump 은 follow-up 들과 배치 릴리스에서 일괄. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Mc6W1fgsrbFKTsqA6P8La
52 lines
3.1 KiB
JSON
52 lines
3.1 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://kb.local/wire/v1/search_hit.schema.json",
|
|
"title": "SearchHit v1",
|
|
"description": "Stub schema — declares the schema_version label and the required top-level fields per design §2.2.",
|
|
"type": "object",
|
|
"required": [
|
|
"schema_version",
|
|
"rank",
|
|
"score",
|
|
"chunk_id",
|
|
"doc_id",
|
|
"doc_path",
|
|
"heading_path",
|
|
"snippet",
|
|
"citation",
|
|
"retrieval",
|
|
"index_version",
|
|
"chunker_version",
|
|
"indexed_at",
|
|
"stale"
|
|
],
|
|
"properties": {
|
|
"schema_version": { "const": "search_hit.v1" },
|
|
"rank": { "type": "integer", "minimum": 1 },
|
|
"score": { "type": "number", "description": "canonical ranking score. 의미는 `score_kind` 가 선언 (rrf/bm25/cosine). single-mode 에서는 fusion 미실행 → `retrieval.fusion_score` 와 동일." },
|
|
"score_kind": {
|
|
"type": "string",
|
|
"enum": ["rrf", "bm25", "cosine"],
|
|
"description": "p9-fb-38: kind of `score` value. `rrf` = RRF normalized [0,1] (hybrid mode); `bm25` = raw BM25 score (lexical-only); `cosine` = raw cosine similarity (vector-only). Older clients that omit this field can treat absence as `rrf` (the historical default)."
|
|
},
|
|
"chunk_id": { "type": "string" },
|
|
"doc_id": { "type": "string" },
|
|
"doc_path": { "type": "string" },
|
|
"heading_path": { "type": "array", "items": { "type": "string" } },
|
|
"section_label": { "type": ["string", "null"] },
|
|
"snippet": { "type": "string" },
|
|
"snippet_full_text": { "type": "boolean" },
|
|
"citation": { "type": "object" },
|
|
"retrieval": { "type": "object", "description": "retrieval detail. `fusion_score` / `lexical_score` / `vector_score` / `lexical_rank` / `vector_rank` 가 여기 안에 있다 (top-level 아님). hybrid 에서만 `fusion_score` 가 RRF normalized 값." },
|
|
"index_version": { "type": "string", "description": "v0.20.2 (Todo #7): lexical (FTS5) index version (예 \"fts5-v009-korean-morphological\"). schema.v1 의 `models.index_version` (vector store / LanceDB, 예 \"v1\") 과는 다른 의미." },
|
|
"embedding_model": { "type": ["string", "null"] },
|
|
"chunker_version": { "type": "string" },
|
|
"indexed_at": { "type": "string", "format": "date-time" },
|
|
"stale": { "type": "boolean" },
|
|
"repo": { "type": ["string", "null"] },
|
|
"code_lang": { "type": ["string", "null"] },
|
|
"source_id": { "type": ["string", "null"], "description": "rag-provenance-label: id of the `[[workspace.sources]]` entry the source doc was ingested from (`documents.source_id`; `default` when absent). Additive optional — omitted when unknown (older wire / synthetic hits)." },
|
|
"trust_level": { "type": ["string", "null"], "enum": ["primary", "secondary", "generated", null], "description": "rag-provenance-label: source doc's `documents.trust_level`. Additive optional — omitted when unknown. Feeds the per-chunk provenance label in the rag-v4 prompt so the LLM can discount low-trust sources on conflict." }
|
|
}
|
|
}
|