#!/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)