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 通过
57 lines
2.4 KiB
Python
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)
|