fix(chat): 重复追问被拦截时再多问一次模型

防重复问句会把整段回复削成「这一段我记住了。」只剩一句套话时,用带纠偏说明的 system 再调一次 LLM,尽量避免用户只看到干巴巴_ack。仍只重试一次,并打日志与 meta 标记 duplicate_question_guard_llm_retry。
This commit is contained in:
Kevin
2026-04-10 15:33:28 +08:00
parent 5ff495729e
commit ccf7125473
4 changed files with 159 additions and 28 deletions

View File

@@ -5,6 +5,9 @@ from __future__ import annotations
import re
from collections.abc import Iterable
# 与 `apply_duplicate_question_guard` 中整段替换句一致;用于判定是否需触发二次生成。
DUPLICATE_QUESTION_GUARD_FALLBACK_ZH = "这一段我记住了。"
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
from app.agents.stage_constants import STAGE_DISPLAY_ZH, STAGE_SLOT_KEYS
@@ -316,7 +319,7 @@ def apply_duplicate_question_guard(
if repeated:
sentences = [s.strip() for s in _SENTENCE_SPLIT_RE.split(text) if s.strip()]
kept = [s for s in sentences if "" not in s and "?" not in s]
replacement = kept[0] if kept else "这一段我记住了。"
replacement = kept[0] if kept else DUPLICATE_QUESTION_GUARD_FALLBACK_ZH
if not replacement.endswith(("", "", "")):
replacement += ""
cleaned.append(replacement)
@@ -324,10 +327,16 @@ def apply_duplicate_question_guard(
else:
cleaned.append(text)
if not cleaned:
cleaned = ["这一段我记住了。"]
cleaned = [DUPLICATE_QUESTION_GUARD_FALLBACK_ZH]
return cleaned, touched
def segments_are_only_duplicate_guard_fallback(segments: Iterable[str]) -> bool:
"""是否为「仅兜底_ack、无实质承接」——适合再打一枪模型。"""
parts = [str(s or "").strip() for s in segments if str(s or "").strip()]
return len(parts) == 1 and parts[0] == DUPLICATE_QUESTION_GUARD_FALLBACK_ZH
def stage_slot_hint_lines(stage: str) -> list[str]:
keys = STAGE_SLOT_KEYS.get(stage, ())
stage_zh = STAGE_DISPLAY_ZH.get(stage, stage)