fix(customer-service): 检索问句只在客户这一句说不清楚时才带上文
实测的答非所问:同一会话先问「季季盈90天的起投金额是多少」,再问「基金赎回几天到账」, 第二问答出的是季季盈的产品介绍。原因是 _search_query 无条件把上一轮客户问题拼进检索词, 客户换话题时旧话题的检索结果被带了回来。在金融场景里这比"引导转人工"糟得多:客户问 A 得到 B 的答案会直接失去对客服的信任,而"答不了"至少是诚实的。 改为只在两种真正需要上文的情况下拼接:句子里有明确指代词("这个产品""该基金"), 或短到不构成完整意图("那它风险高吗"只有 6 个字)。指代词刻意不收单字"它/他"——中文里 "其他产品"会被误判,而这类短句已经由长度规则覆盖。 验证:换话题场景第二问回到 FAQ-0016 的到账时间,指代追问仍命中季季盈产品块; ruff / mypy(113 文件) / 457 unit+contract 全绿。
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"""客服检索问句构造的单元测试:什么时候该带上文,什么时候绝不能带。
|
||||
|
||||
背景是实测出来的:**无条件**拼接上文会让客户换话题时答非所问——同一会话先问
|
||||
「季季盈90天的起投金额是多少」,再问「基金赎回几天到账」,第二问的检索词变成两句话的
|
||||
混合,结果命中季季盈的产品块、答出产品介绍,而客户问的是赎回到账时间。
|
||||
"""
|
||||
|
||||
from app.core.contracts import AgentRequest, ConversationTurn
|
||||
from app.service.agent.implementations.customer_service import CustomerServiceAgent
|
||||
|
||||
PREVIOUS = "季季盈90天的起投金额是多少"
|
||||
|
||||
|
||||
def _request(message: str, *history: str) -> AgentRequest:
|
||||
turns = tuple(
|
||||
ConversationTurn(role="user" if index % 2 == 0 else "assistant", content=text)
|
||||
for index, text in enumerate(history)
|
||||
)
|
||||
return AgentRequest(
|
||||
agent_type="customer_service",
|
||||
session_id="s",
|
||||
message=message,
|
||||
idempotency_key="1234567890123456",
|
||||
history=turns,
|
||||
)
|
||||
|
||||
|
||||
def test_topic_change_does_not_drag_previous_question_in() -> None:
|
||||
"""客户换话题时,检索词里不能出现上一轮的问题(实测的答非所问场景)。"""
|
||||
query = CustomerServiceAgent._search_query(_request("基金赎回几天到账", PREVIOUS))
|
||||
|
||||
assert query == "基金赎回几天到账"
|
||||
assert "季季盈" not in query
|
||||
|
||||
|
||||
def test_referring_phrase_brings_context_in() -> None:
|
||||
"""带明确指代词的问句要靠上文补全主语。"""
|
||||
query = CustomerServiceAgent._search_query(_request("这个产品的费率是多少", PREVIOUS))
|
||||
|
||||
assert PREVIOUS in query
|
||||
|
||||
|
||||
def test_very_short_question_brings_context_in() -> None:
|
||||
"""短到不构成完整意图的问句同样需要上文("那它风险高吗"只有 6 个字)。"""
|
||||
query = CustomerServiceAgent._search_query(_request("那它风险高吗", PREVIOUS))
|
||||
|
||||
assert PREVIOUS in query
|
||||
|
||||
|
||||
def test_first_turn_has_no_history_to_add() -> None:
|
||||
"""首轮没有历史可拼,检索词就是客户这一句。"""
|
||||
assert CustomerServiceAgent._search_query(
|
||||
_request("基金赎回几天到账")
|
||||
) == "基金赎回几天到账"
|
||||
Reference in New Issue
Block a user