修复bot多段回复与表格全文回调:强化相关性+表格只取上下文
- Fix A: auto_reply._get_answer 含表格正文不再返回整段section,改为 提取表格+紧邻上文(最多2行),丢弃表格后无关图文,截断到800字符 - Fix A: 清理答案中的HTML <br> 标签,避免原形显示 - Fix B: 强化 _has_content_relevance,要求查询与文档共享有区分度核心词 (去停用词),动作类查询额外要求正文命中,防牛头不对马嘴 - Fix B: gui._search_and_log 从 top_k 结果中选取首个通过相关性校验的文档 发送,不再永远取 results[0],保证一条消息只回复一段精准内容
This commit is contained in:
@@ -940,8 +940,6 @@ class MsgBotApp(ctk.CTk):
|
||||
lines = [f"[{platform.upper()}] {msg}"]
|
||||
|
||||
if results:
|
||||
answer_title = results[0][0]["title"]
|
||||
answer_score = results[0][1]
|
||||
lines.append(f" 🔍 找到 {len(results)} 条相关结果:")
|
||||
|
||||
for i, (doc, score) in enumerate(results):
|
||||
@@ -963,32 +961,41 @@ class MsgBotApp(ctk.CTk):
|
||||
if i == 0:
|
||||
lines.append(f" 完整内容片段: {content[:200].replace(chr(10), ' ')}...")
|
||||
|
||||
# 诊断日志:记录自动回复触发条件
|
||||
# 从 top_k 结果中选取【第一个通过内容相关性校验】的文档发送,
|
||||
# 避免永远只取 results[0] 导致"牛头不对马嘴"的错误文档被发送。
|
||||
# 一条消息只回复一段(选中最相关且语义匹配的那一条),不触发 N 段回复。
|
||||
chosen = None
|
||||
if self.ar.enabled:
|
||||
for idx, (doc, sc) in enumerate(results):
|
||||
if sc < self.ar.min_score:
|
||||
continue
|
||||
rel = self.ar._has_content_relevance(cleaned_msg, doc, sc)
|
||||
logger.debug(
|
||||
f"[{platform}] 相关性候选[{idx}]: title={doc.get('title', '')!r} "
|
||||
f"score={sc:.2f} relevance={rel}"
|
||||
)
|
||||
if rel:
|
||||
chosen = (doc, sc)
|
||||
break
|
||||
|
||||
if not self.ar.enabled:
|
||||
lines.append(" ⚠ 自动回复已关闭,不触发回复")
|
||||
elif answer_score < self.ar.min_score:
|
||||
lines.append(f" ⚠ 匹配度 {answer_score:.2f} < 阈值 {self.ar.min_score},跳过")
|
||||
elif chosen is None:
|
||||
lines.append(" ⚠ 所有结果均未通过内容相关性/阈值检查,跳过回复")
|
||||
else:
|
||||
# 检查内容相关性
|
||||
has_relevance = self.ar._has_content_relevance(msg, results[0][0], answer_score)
|
||||
|
||||
# 详细调试日志:记录内容相关性检查结果
|
||||
logger.debug(f"[{platform}] 内容相关性检查: msg={msg!r}, has_relevance={has_relevance}")
|
||||
logger.debug(f"[{platform}] 内容相关性检查: doc标题={results[0][0].get('title', '')!r}")
|
||||
logger.debug(f"[{platform}] 内容相关性检查: doc heading={results[0][0].get('heading', '')[:50]!r}")
|
||||
|
||||
if not has_relevance:
|
||||
heading = results[0][0].get("heading", "")[:40]
|
||||
lines.append(f" ⚠ 内容相关性检查失败 (heading={heading!r}),跳过")
|
||||
else:
|
||||
lines.append(" ✅ 匹配通过,准备发送自动回复")
|
||||
lines.append(" ✅ 匹配通过,准备发送自动回复")
|
||||
|
||||
# 自动回复:队列到主线程执行(daemon 线程不能可靠 SetForegroundWindow)
|
||||
reply_data = self.ar.get_reply_data(platform, msg, results[0][0], results[0][1])
|
||||
if reply_data:
|
||||
self._reply_queue.put(reply_data)
|
||||
if chosen is not None:
|
||||
reply_data = self.ar.get_reply_data(
|
||||
platform, msg, chosen[0], chosen[1], cleaned_msg=cleaned_msg
|
||||
)
|
||||
if reply_data:
|
||||
self._reply_queue.put(reply_data)
|
||||
else:
|
||||
lines.append(" ⚠ get_reply_data 返回 None(重复命中或内部检查失败)")
|
||||
else:
|
||||
lines.append(" ⚠ get_reply_data 返回 None(重复命中或内部检查失败)")
|
||||
reply_data = None
|
||||
else:
|
||||
lines.append(" ❌ 知识库中未找到相关答案")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user