- Implemented `_merged_items` and `_merged_memory_text` functions to consolidate consult and chitchat memories, improving context awareness in intent classification and response generation. - Updated intent prompts to include recent dialogue history, aiding in the resolution of ambiguous user queries. - Enhanced `search_knowledge` tool to utilize context window for better query understanding, addressing issues with omitted references in user inputs. - Fixed existing test cases to reflect changes in intent constants and ensure accurate context handling during tests. This update significantly improves the handling of multi-turn dialogues, ensuring a more coherent and contextually aware interaction for users.
96 lines
3.2 KiB
Python
96 lines
3.2 KiB
Python
"""Wave 2:客户 Agent prompt 常量与关键词快路由纯函数测试(不依赖 DB/LLM)。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from app.service.customer_prompts import (
|
|
DATA_QUERY_INTENTS,
|
|
INTENT_SYSTEM,
|
|
PROFILE_EXTRACT_SYSTEM,
|
|
REJECT_BY_KIND,
|
|
VALID_INTENTS,
|
|
keyword_route,
|
|
)
|
|
|
|
|
|
def test_intent_constants():
|
|
assert len(VALID_INTENTS) == 14
|
|
assert len(DATA_QUERY_INTENTS) == 5
|
|
# 数据查询意图均在合法集内
|
|
assert DATA_QUERY_INTENTS <= VALID_INTENTS
|
|
# 意图分类 prompt 覆盖标签
|
|
for intent in VALID_INTENTS:
|
|
assert intent in INTENT_SYSTEM
|
|
|
|
|
|
def test_profile_prompt_delegates_to_slots():
|
|
"""抽槽 prompt 由槽位表派生,包含高敏规则。"""
|
|
assert "basic.age_band" in PROFILE_EXTRACT_SYSTEM
|
|
assert "threshold_pref_summary" in PROFILE_EXTRACT_SYSTEM
|
|
assert "高敏感" in PROFILE_EXTRACT_SYSTEM
|
|
|
|
|
|
def test_reject_reply_kinds():
|
|
assert set(REJECT_BY_KIND) == {"advice", "predict", "compare", "realtime"}
|
|
for text in REJECT_BY_KIND.values():
|
|
assert "游客" not in text # 客户视角话术不得出现"游客"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"message,expected_intent",
|
|
[
|
|
("我的持仓怎么样", "holding_query"),
|
|
("我买了什么基金", "holding_query"),
|
|
("最近亏了多少", "holding_query"),
|
|
("最近的交易记录", "transaction_query"),
|
|
("我上个月申购了啥", "transaction_query"),
|
|
("我的风评是什么", "risk_assessment_query"),
|
|
("风险测评过期了吗", "risk_assessment_query"),
|
|
("我能买R3产品吗", "suitability_check"),
|
|
("这个基金适合我买吗", "suitability_check"),
|
|
],
|
|
)
|
|
def test_keyword_route_data_queries(message, expected_intent):
|
|
result = keyword_route(message)
|
|
assert result is not None
|
|
intent, reply = result
|
|
assert intent == expected_intent
|
|
assert reply == ""
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"message,expected",
|
|
[
|
|
("转人工", ("transfer_human", "")),
|
|
("我要投诉", ("transfer_human", "")),
|
|
("推荐个稳赚的基金", ("reject", "advice")),
|
|
("建议买什么好", ("reject", "advice")),
|
|
("这个基金明天会涨吗", ("reject", "predict")),
|
|
("和其他平台比哪个好", ("reject", "compare")),
|
|
("现在实时净值多少", ("reject", "realtime")),
|
|
("我能买什么产品", ("suitability_check", "")),
|
|
("005827的净值是多少", ("nav_query", "")),
|
|
],
|
|
)
|
|
def test_keyword_route_transfer_and_reject(message, expected):
|
|
assert keyword_route(message) == expected
|
|
|
|
|
|
def test_keyword_route_reject_priority_over_suitability():
|
|
""""R3会涨吗"含预测关键词,应 reject 而非适当性查询。"""
|
|
intent, kind = keyword_route("R3产品还会涨吗")
|
|
assert intent == "reject"
|
|
assert kind == "predict"
|
|
|
|
|
|
def test_keyword_route_suitability_vs_advice():
|
|
""""能买"是适当性查询,"推荐买"是投顾拒绝。"""
|
|
assert keyword_route("R3我能买吗")[0] == "suitability_check"
|
|
assert keyword_route("推荐我买R3")[0] == "reject"
|
|
|
|
|
|
def test_keyword_route_no_hit():
|
|
assert keyword_route("今天天气不错") is None
|
|
assert keyword_route("") is None
|