Ctrl K
ComunidadGuías…

scripts/xkb_evict_report.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""Report current demotion from namespace-scoped relevance verdicts. Legacy cosine statistics remain in knowledge_usage and do not drive this report."""
from __future__ import annotations

import argparse
import json
import sqlite3
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))

import xkb_console
import xkb_eviction as ev
import xkb_frontmatter
import xkb_paths
from xkb_evidence import IDENTITY_PREFIX, identity_source

xkb_console.use_utf8()


def describe(record_id: str) -> tuple[str, str]:
    """record_id 的標題與**真正的**分類。

    record_id 的前綴是檔案放在哪個 bookmarks 資料夾(`02-seo-geo/2032...`),而那
    不是這張卡的分類——1,754 筆書籤裡有 650 筆的 frontmatter `category` 跟所在目錄
    不一致,而召回、wiki 路由、健檢讀的全都是 frontmatter。目錄只是位址。

    2026-09-12 我自己就被這個前綴騙過:看到 `02-seo-geo/` 就推論那張卡「被歸錯類
    所以被 SEO 問題撈出來」。它其實是日文的 AI 生圖 prompt 合集,frontmatter 寫
    04-ai-tools-agents,而它被撈出來是內容嵌入弱相關,跟資料夾毫無關係。報告印出
    前綴卻不印真正的分類,就是在邀請這個推論。
    """
    record_id = identity_source(record_id)
    stem = record_id.rsplit("/", 1)[-1]
    card = xkb_paths.CARDS_DIR / f"{stem}.md"
    if not card.is_file():
        return "", ""
    try:
        text = card.read_text(encoding="utf-8", errors="replace")
    except OSError:
        return "", ""
    title = ""
    for line in text.splitlines():
        if line.startswith("# "):
            title = line[2:].strip()
            break
    return title, (xkb_frontmatter.get(text, "category") or "")


def load_rows(namespace: str = "private") -> list[dict]:
    """Read the versioned merged-recall counters, never infer from cosine."""
    if not xkb_paths.SERVICE_DB.exists():
        return []
    from contextlib import closing
    with closing(sqlite3.connect(f"file:{xkb_paths.SERVICE_DB}?mode=ro", uri=True)) as db:
        db.row_factory = sqlite3.Row
        if not db.execute("SELECT 1 FROM sqlite_master WHERE name='recall_usage'").fetchone():
            return []
        return [dict(r) for r in db.execute(
            "SELECT * FROM recall_usage WHERE namespace=? AND record_id LIKE ? ORDER BY judged_count DESC", (namespace, IDENTITY_PREFIX + "%"))]


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--json", action="store_true")
    parser.add_argument("--namespace", default="private")
    parser.add_argument("--after", type=int, default=ev.DEMOTE_AFTER_CONSIDERED)
    parser.add_argument("--limit", type=int, default=20)
    args = parser.parse_args()
    rows = load_rows(args.namespace)
    demoted = [r for r in rows if ev.is_demoted(r["judged_count"], r["relevant_count"], after=args.after)]
    if args.json:
        print(json.dumps({"measurement_basis": "explicit_relevance_v2", "namespace": args.namespace,
                          "after": args.after, "tracked": len(rows), "demoted": len(demoted),
                          "records": demoted}, ensure_ascii=False, indent=2))
        return 0
    print(f"Tracked {len(rows)} records; {len(demoted)} repeatedly judged irrelevant.")
    for r in demoted[:args.limit]:
        title, category = describe(r["record_id"])
        print(f"{r['judged_count']} judgements / {r['returned_count']} returned: [{category}] {title or r['record_id']}")
    print("A relevant verdict revives the record. Returned does not imply used in an answer.")
    return 0


import xkb_usage  # noqa: E402  — 量測誰在跑,見 scripts/xkb_usage.py

if __name__ == "__main__":
    xkb_usage.record(__file__)
    raise SystemExit(main())