Files
msgbot/debug_kb.py
T
youpaishidifu d87e482e1e 修复微信端知识库答非所问 + QQ OCR 漏消息(双 bug 修复)
knowledge_base.py(问题2:微信端答非所问):
- 文档级标题语义匹配改为 token 级(原仅字面子串匹配),OCR 丢失"php"只剩"管理员端默认"也能正确命中 phpadmin
- 新增"管理员+默认"组合强偏好:无"领地"时 phpadmin ×3.0、protect ×0.4,避免退化查询误选 protect/全局配置
- section 级重排新增 bonus +30:查询含"管理员+默认"时,偏好正文真正含"密码/登录/ypshidifu"的 section,压过"## 目录"目录项

monitor.py(问题1 + 问题2 上游):
- 新增 _split_and_denoise_segments:按消息边界预分割 + 分段噪声隔离,修复 Windows OCR 大杂烩把用户消息当噪声整段丢弃(QQ 漏消息)
- 候选行剥离 bot 自身旧回复文本:OCR 把用户新提问与屏上 bot 旧回复拼成一行时,先剥离旧回复再走过滤,消除答非所问的上游拼接根因

测试:新增 debug_kb.py 复现退化查询、test_kb.py 回归;跨主题回归全部正确,py_compile 通过
2026-08-03 20:52:08 +08:00

57 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""调试知识库搜索 — 打印每个 section 的分数,定位为什么返回错误结果"""
import sys, os, re
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import jieba
from knowledge_base import KnowledgeBase
def dump(query):
kb = KnowledgeBase("D:/桌面/源码/文档/docs")
kb.reload()
print(f"\n{'='*70}")
print(f"查询: {query!r}")
print(f"jieba tokens: {list(jieba.cut(query))}")
query_nouns = set(jieba.cut(query)) & {'密码','用户管理','领地','商品','CDK','工单','债券','在线'}
print(f"query core_nouns: {query_nouns}")
results = kb.search(query, top_k=3)
print("\n--- 最终返回结果 (top_k=3) ---")
if results:
for i,(doc,score) in enumerate(results):
print(f" [{i+1}] {doc['title']} | {score:.2f} | heading={doc['heading'][:50]!r}")
print(f" body={doc['body'][:80]!r}")
else:
print(" 无结果")
# 手动遍历所有 section,打印 combined_scores 近似(不精确,但看排序)
# 直接复用内部逻辑太复杂,这里只打印每个 doc 的 heading+body 片段供人工判断
print("\n--- 知识库所有 section(含'密码'/'管理员'关键词的优先)---")
matches = []
for d in kb.docs:
txt = d.get('heading','') + ' ' + d.get('body','')
if '密码' in txt or '管理员' in txt:
matches.append(d)
for d in matches:
print(f" [{d['title']}] heading={d['heading'][:40]!r}")
print(f" body={d['body'][:90]!r}")
if __name__ == "__main__":
for q in [
# 干净查询(对照组,应返回 phpadmin)
"PHP管理员端的默认密码是多少?",
# 假设 OCR 丢失"密码"二字
"PHP管理员端的默认是多少?",
"php管理员端默认",
"管理员端默认",
"php管理员端默认是多少",
# 假设 OCR 把"密码"拆成"密 码"或加了空格
"php 管理员 端 默认 密码 是 多少",
# 假设查询被拼接了 bot 可见的旧回复(全局配置)
"PHP管理员端的默认密码是多少?全局配置:管理员可通过该配置,配置默认用户拥有多少格领地,创建领地价格是多少",
# 假设 OCR 把 PHP 误读(大小写/空格)
"Php管理员端的默认密码是多少?",
"php 管理员端的默认密码是多少?",
]:
dump(q)