From ee9de1b5206a3178e76775e299b60ced904ef53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=BF=E4=BA=91=E7=A7=8B=E6=9C=88?= <15273589815@163.com> Date: Thu, 10 Sep 2026 22:35:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(customer-service):=20FAQ=20=E5=9E=8B?= =?UTF-8?q?=E5=9B=9E=E7=AD=94=E4=B8=8D=E8=83=BD=E6=8A=8A"=E9=97=AE"?= =?UTF-8?q?=E5=AD=97=E5=BD=93=E6=88=90=E8=BF=BD=E9=97=AE=E7=9A=84=E4=B8=BB?= =?UTF-8?q?=E8=AF=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 给 C1-C5 补 FAQ 之后暴露的连带问题:FAQ 型回答的首行是"问:C1 客户能买什么产品?", _topic_of 取冒号前的内容会拿到一个孤零零的"问"字,客户追问时检索词被污染成 "问 那它能买基金吗"。 改为"问"/"答"这类纯标签直接判为取不出主语,退化成只查当前这一句。 另附一条实测结论(**没有改代码**):在 FAQ 型回答之后追问「那它能买基金吗」仍会转人工, 这是安全且合理的——上一轮回答里没有可指代的产品实体,而"C1 能不能买基金"本身取决于 那只基金的风险等级,知识库没有、也不该有这种一概而论的答案。按金融场景的原则, "答不了"好过"答错"。 --- app/service/agent/implementations/customer_service.py | 6 +++++- tests/unit/service/test_customer_service_search_query.py | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/service/agent/implementations/customer_service.py b/app/service/agent/implementations/customer_service.py index ba717bb..4bcb605 100644 --- a/app/service/agent/implementations/customer_service.py +++ b/app/service/agent/implementations/customer_service.py @@ -262,7 +262,11 @@ class CustomerServiceAgent(BaseAgent): first = next((line.strip() for line in answer.splitlines() if line.strip()), "") first = first.lstrip("#").strip() topic = first.split(":", 1)[0].strip() if ":" in first else first - if not topic or len(topic) > 20 or "," in topic or "。" in topic: + # FAQ 型回答的首行是"问:C1 客户能买什么产品?",冒号前只有一个"问"字; + # 拿它当主语只会把检索词污染成"问 那它风险高吗"。 + if not topic or topic in {"问", "答"}: + return "" + if len(topic) > 20 or "," in topic or "。" in topic: return "" return topic diff --git a/tests/unit/service/test_customer_service_search_query.py b/tests/unit/service/test_customer_service_search_query.py index cf63daf..745ec71 100644 --- a/tests/unit/service/test_customer_service_search_query.py +++ b/tests/unit/service/test_customer_service_search_query.py @@ -51,6 +51,13 @@ def test_fallback_answer_yields_no_topic() -> None: assert CustomerServiceAgent._topic_of("") == "" +def test_faq_style_answer_yields_no_topic() -> None: + """FAQ 型回答首行是"问:…",冒号前只有一个"问"字,不能当主语。""" + assert CustomerServiceAgent._topic_of( + "问:C1 客户能买什么产品?\n答:C1(保守型)客户可以购买 R1、R2 等级的产品。" + ) == "" + + def test_topic_change_does_not_drag_previous_question_in() -> None: """客户换话题时,检索词里不能出现上一轮的痕迹(实测的答非所问场景)。""" query = CustomerServiceAgent._search_query(_request("基金赎回几天到账", PREVIOUS, ANSWER))