feat:修复客服agent功能
This commit is contained in:
@@ -24,12 +24,43 @@ from repositories.fin_holdings import FinHoldingsRepo
|
||||
from repositories.fin_product import FinProductRepo
|
||||
|
||||
|
||||
def enrich_customer_rows(
|
||||
rows: list[dict[str, Any]],
|
||||
columns: list[str],
|
||||
name_by_id: dict[int, str],
|
||||
) -> dict[str, Any]:
|
||||
"""为查询结果补充客户姓名,并生成可直接展示的姓名摘要。"""
|
||||
id_keys = ("customer_id", "客户ID", "客户编号", "客户_id")
|
||||
enriched = [dict(row) for row in rows]
|
||||
names: list[str] = []
|
||||
for row in enriched:
|
||||
customer_id = next((row.get(key) for key in id_keys if row.get(key) is not None), None)
|
||||
try:
|
||||
customer_id = int(customer_id)
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
name = name_by_id.get(customer_id)
|
||||
if name:
|
||||
row["客户姓名"] = name
|
||||
names.append(f"客户{customer_id}({name})")
|
||||
output_columns = list(columns)
|
||||
if any("客户姓名" in row for row in enriched) and "客户姓名" not in output_columns:
|
||||
insert_at = next(
|
||||
(index + 1 for index, column in enumerate(output_columns) if column in id_keys),
|
||||
len(output_columns),
|
||||
)
|
||||
output_columns.insert(insert_at, "客户姓名")
|
||||
return {"rows": enriched, "columns": output_columns, "name_summary": "、".join(dict.fromkeys(names))}
|
||||
|
||||
|
||||
def _is_current_holdings_query(question: str) -> bool:
|
||||
text = "".join((question or "").split())
|
||||
return any(term in text for term in ("当前持仓", "目前持仓", "现有持仓", "持仓明细", "持仓情况"))
|
||||
|
||||
|
||||
async def _query_current_holdings(db, *, customer_id: int, trace_id: str) -> dict[str, Any]:
|
||||
async def _query_current_holdings(
|
||||
db, *, customer_id: int, trace_id: str, customer_name: str | None = None
|
||||
) -> dict[str, Any]:
|
||||
holdings = await FinHoldingsRepo(db).list_by_customer(customer_id, status="持有中")
|
||||
product_repo = FinProductRepo(db)
|
||||
rows: list[dict[str, Any]] = []
|
||||
@@ -60,7 +91,8 @@ async def _query_current_holdings(db, *, customer_id: int, trace_id: str) -> dic
|
||||
"truncated": False,
|
||||
"summary": f"当前持仓共 {len(rows)} 条记录。",
|
||||
"answer": (
|
||||
f"当前持有 {len(rows)} 只基金,总市值约 {total_value:.2f} 元。"
|
||||
(f"客户{customer_id}({customer_name})" if customer_name else f"客户{customer_id}")
|
||||
+ f"当前持有 {len(rows)} 只基金,总市值约 {total_value:.2f} 元。"
|
||||
+ (f"包括:{'、'.join(names[:6])}。" if names else "")
|
||||
),
|
||||
"sql": None,
|
||||
@@ -108,11 +140,25 @@ async def execute_advisor_data_query(
|
||||
await ensure_customer_access(db, advisor_id=advisor_id, customer_id=customer_id)
|
||||
customer_ids = [customer_id]
|
||||
|
||||
name_by_id: dict[int, str] = {}
|
||||
try:
|
||||
relation_rows = await CustomerRelationRepo(db).list_customer_rows(
|
||||
advisor_id=advisor_id, limit=max(len(customer_ids), 100)
|
||||
)
|
||||
name_by_id = {
|
||||
int(account.id): account.real_name
|
||||
for _relation, account, _profile in relation_rows
|
||||
if account.real_name
|
||||
}
|
||||
except Exception: # noqa: BLE001 姓名增强失败不阻断数据查询
|
||||
pass
|
||||
|
||||
if scope == "customer" and _is_current_holdings_query(question):
|
||||
return await _query_current_holdings(
|
||||
db,
|
||||
customer_id=customer_id,
|
||||
trace_id=trace_id,
|
||||
customer_name=name_by_id.get(customer_id),
|
||||
)
|
||||
permission = await load_query_permission(db, advisor_id)
|
||||
if not permission.get("can_query", False):
|
||||
@@ -168,6 +214,12 @@ async def execute_advisor_data_query(
|
||||
except (EmbeddingError, LLMFailError) as exc:
|
||||
raise QueryServiceError("投顾 Agent 依赖服务不可用,请检查 LLM/Embedding 服务连接") from exc
|
||||
payload = asdict(result)
|
||||
enriched = enrich_customer_rows(payload.get("rows", []), payload.get("columns", []), name_by_id)
|
||||
payload["rows"] = enriched["rows"]
|
||||
payload["columns"] = enriched["columns"]
|
||||
if enriched["name_summary"]:
|
||||
existing_answer = payload.get("answer") or payload.get("summary") or ""
|
||||
payload["answer"] = f"{existing_answer.rstrip('。')}。客户姓名:{enriched['name_summary']}。"
|
||||
payload["sql"] = None
|
||||
payload["customer_id"] = customer_id
|
||||
return payload
|
||||
|
||||
Reference in New Issue
Block a user