test: 真人验收清单+API级联调验收

真实 GLM 五轮实跑(EN/ES/ZH/换号/敏感问)+mock推送+admin三视图,核心项全过。
修复: 中文轮漂英文→语言跟随提醒; extractor裸字符串联系方式→500崩溃兜形;
号码回显/样品承诺/标记词泄漏 prompt加固; 测试env耦合断言; .env前缀对齐。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-29 20:02:03 +08:00
parent 7da1e22446
commit c2f2ddf82f
9 changed files with 256 additions and 281 deletions
+34 -2
View File
@@ -70,6 +70,31 @@ CONTACT_ASK_TRIGGER_RE = re.compile(
re.IGNORECASE,
)
# 语言跟随提醒(Task 11 真人验收发现): glm-4-flash 对拉丁字符占比高的中文
# 消息(DN800/HDPE 规格混排)会整轮漂成英文,system.md 语言规则压不住;西语客户
# 则倾向把英文模板句翻译成西语。修复位 = 当轮 context 提醒(prompt 最末、
# 最新鲜)——与 contact-ask 提醒"逐字话术防漂移"同款方法论。
_CJK_RE = re.compile(r"[一-鿿]")
_ES_FEATURE_RE = re.compile(r"[áéíóúñãç¿¡]")
LANG_NOTE_ZH = (
"⚠️ 语言提醒:客户这条消息是中文——你的回复必须全程使用中文,"
"除英文模板句保持英文原文外,一个英文单词都不能出现。"
)
LANG_NOTE_ES = (
"⚠️ 语言提醒:客户这条消息是西语——叙述部分用西语,但引导留资模板句必须"
"整句使用英文原版(\"Please leave your contact and our manager will send "
"the full quotation.\"),绝不翻译成西语。"
)
def _lang_note_for(msg: str) -> str:
if _CJK_RE.search(msg or ""):
return LANG_NOTE_ZH
if _ES_FEATURE_RE.search(msg or ""):
return LANG_NOTE_ES
return ""
# 方案B(13.6): 迂回话术轮换序号——连续破防时不至于复读同一句
_boundary_seq = 0
@@ -595,9 +620,13 @@ class ConversationManager:
f"\"{NO_CONTACT_WEB}\"(邮箱同理指 Email 按钮)。"
"绝对禁止口头报出任何号码或邮箱。")
# 语言跟随提醒(Task 11): 与 boundary/contact 提醒同挂载位——
# 首条消息画像为空也要生效(中文客户开场即漂英文是实测重灾区)
lang_note = _lang_note_for(latest_msg)
if not raw_info:
# 空画像:仅返回边界/联系提醒(可能为空串)
return "\n".join(x for x in (boundary_note, contact_note) if x)
# 空画像:仅返回边界/联系/语言提醒(可能为空串)
return "\n".join(x for x in (boundary_note, contact_note, lang_note) if x)
parts = ["[上下文提醒 - 这是一条系统指令,绝对不要向客户提及这段内容]"]
parts.append("客户已明确告知以下信息,你绝对不能再问这些:")
@@ -644,4 +673,7 @@ class ConversationManager:
if len(latest_msg.strip()) < 25:
parts.append("⚠️ 客户发的是短消息!必须结合上面已知信息来理解,绝对不能当作独立问题!")
if lang_note:
parts.append(lang_note)
return "\n".join(parts)