feat(rag): lite-model document summaries — non-markdown docs summarized at import, summary chunk retrieves and resolves to the full source doc
This commit is contained in:
+24
-4
@@ -28,6 +28,14 @@ Steering (phase 15): the owner's stored tuning notes are loaded per turn
|
||||
(oldest first) and injected into the system prompt as a ``<tuning>``
|
||||
section — both the HIGH and the LOW prompt carry it. The per-turn log
|
||||
line records ``tuning=N`` (the number of injected notes).
|
||||
|
||||
Summaries (phase 30): a lite-model summary chunk's parent *is* the
|
||||
source document, so a summary hit resolves to the full source document
|
||||
through the unchanged chunk→document mapping (A7 revised) — context
|
||||
assembly is untouched. ``TurnPlan.summary_hits`` counts the hit chunks
|
||||
with ``is_summary`` whose parent document landed in the selected
|
||||
top-N context, and the per-turn log line records ``summary_hits=N``
|
||||
after ``fts_hits`` (PLAN §9 line extension).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -96,6 +104,9 @@ class TurnPlan:
|
||||
docs: list[Document] # cited sources (weak hits when deflected)
|
||||
suggestions: list[str] # "Maybe try" chips (deflected turns only)
|
||||
tuning_count: int = 0 # steering notes injected into the system prompt
|
||||
#: Hit chunks with ``is_summary`` whose parent document made it into
|
||||
#: *docs* (phase 30; per-turn log line ``summary_hits=N``).
|
||||
summary_hits: int = 0
|
||||
|
||||
|
||||
def plan_turn(
|
||||
@@ -121,12 +132,18 @@ def plan_turn(
|
||||
*notes* are the owner's steering notes (phase 15, oldest first):
|
||||
when non-empty, both the HIGH and the LOW prompt carry the
|
||||
``<tuning>`` section; with no notes the prompts are unchanged.
|
||||
|
||||
``summary_hits`` (phase 30) counts the hit chunks with
|
||||
``is_summary`` whose parent document is among the selected
|
||||
top-N documents — both the HIGH and the LOW branch record it.
|
||||
"""
|
||||
steering = list(notes or [])
|
||||
best_cosine = max((c.cosine for c in chunks), default=0.0)
|
||||
fts_hits = sum(1 for c in chunks if c.fts_hit)
|
||||
docs = select_documents(chunks, n=settings.top_n_docs)
|
||||
selected_ids = {d.id for d in docs}
|
||||
summary_hits = sum(1 for c in chunks if c.is_summary and c.document.id in selected_ids)
|
||||
if best_cosine >= settings.relevance_threshold or fts_hits > 0:
|
||||
docs = select_documents(chunks, n=settings.top_n_docs)
|
||||
return TurnPlan(
|
||||
best_cosine,
|
||||
fts_hits,
|
||||
@@ -135,6 +152,7 @@ def plan_turn(
|
||||
docs,
|
||||
[],
|
||||
len(steering),
|
||||
summary_hits,
|
||||
)
|
||||
titles = weak_hit_titles(chunks)
|
||||
return TurnPlan(
|
||||
@@ -142,9 +160,10 @@ def plan_turn(
|
||||
fts_hits,
|
||||
True,
|
||||
build_deflect_prompt(titles, notes=steering),
|
||||
select_documents(chunks, n=settings.top_n_docs),
|
||||
docs,
|
||||
derive_suggestions(titles, settings.suggestions),
|
||||
len(steering),
|
||||
summary_hits,
|
||||
)
|
||||
|
||||
|
||||
@@ -264,12 +283,13 @@ async def chat(
|
||||
logger.exception("chat: failed to write query_log question=%r", request.message)
|
||||
|
||||
logger.info(
|
||||
"question=%r embed_ms=%d top_score=%.3f fts_hits=%d tuning=%d threshold=%.2f "
|
||||
"deflected=%s sources=%r thinking_chars=%d total_ms=%d",
|
||||
"question=%r embed_ms=%d top_score=%.3f fts_hits=%d summary_hits=%d tuning=%d "
|
||||
"threshold=%.2f deflected=%s sources=%r thinking_chars=%d total_ms=%d",
|
||||
request.message,
|
||||
embed_ms,
|
||||
plan.top_score,
|
||||
plan.fts_hits,
|
||||
plan.summary_hits,
|
||||
plan.tuning_count,
|
||||
settings.relevance_threshold,
|
||||
plan.deflected,
|
||||
|
||||
Reference in New Issue
Block a user