(
query: str,
top_k: int,
chapter: str = "",
section: str = "",
semantic_weight: float = 0.86,
)
| 82 | |
| 83 | |
| 84 | def _score_results( |
| 85 | query: str, |
| 86 | top_k: int, |
| 87 | chapter: str = "", |
| 88 | section: str = "", |
| 89 | semantic_weight: float = 0.86, |
| 90 | ) -> list[dict[str, Any]]: |
| 91 | store = _load_store() |
| 92 | model = _load_model(store.manifest["model"]) |
| 93 | |
| 94 | q = model.encode( |
| 95 | [query], |
| 96 | normalize_embeddings=True, |
| 97 | convert_to_numpy=True, |
| 98 | show_progress_bar=False, |
| 99 | )[0].astype(np.float32) |
| 100 | |
| 101 | semantic_scores = store.embeddings @ q |
| 102 | |
| 103 | chapter_filter = chapter.strip().lower() |
| 104 | section_filter = section.strip().lower() |
| 105 | w_sem = float(semantic_weight) |
| 106 | w_lex = 1.0 - w_sem |
| 107 | |
| 108 | scored: list[tuple[float, int]] = [] |
| 109 | for i, ch in enumerate(store.chunks): |
| 110 | ch_chapter = (ch.get("chapter") or "").lower() |
| 111 | ch_section = (ch.get("section") or "").lower() |
| 112 | if chapter_filter and chapter_filter not in ch_chapter: |
| 113 | continue |
| 114 | if section_filter and section_filter not in ch_section: |
| 115 | continue |
| 116 | |
| 117 | lex_text = lexical_overlap_score(query, ch["text"]) |
| 118 | lex_head = lexical_overlap_score(query, ch.get("heading_path") or "") |
| 119 | meta_boost = 0.08 * lex_head |
| 120 | score = (w_sem * float(semantic_scores[i])) + (w_lex * lex_text) + meta_boost |
| 121 | scored.append((score, i)) |
| 122 | |
| 123 | scored.sort(key=lambda x: x[0], reverse=True) |
| 124 | out: list[dict[str, Any]] = [] |
| 125 | for score, idx in scored[:top_k]: |
| 126 | ch = store.chunks[idx] |
| 127 | out.append( |
| 128 | { |
| 129 | "score": float(score), |
| 130 | "chunk_id": ch["chunk_id"], |
| 131 | "section_id": ch.get("section_id"), |
| 132 | "page_start": int(ch.get("page_start") or -1), |
| 133 | "page_end": int(ch.get("page_end") or -1), |
| 134 | "chapter": ch.get("chapter") or "", |
| 135 | "section": ch.get("section") or "", |
| 136 | "heading_path": ch.get("heading_path") or "", |
| 137 | "text": ch["text"], |
| 138 | } |
| 139 | ) |
| 140 | return out |
| 141 |
no test coverage detected