feat:修改nl2sql功能

This commit is contained in:
2026-09-14 10:57:48 +08:00
parent a7f9e182a4
commit 67d5cfc2b8
15 changed files with 206 additions and 54 deletions
+35 -12
View File
@@ -97,6 +97,14 @@ def _not_ready(request: Request):
return agent_failure(_NOT_READY_CODE, _NOT_READY_MESSAGE, trace_id=_trace_id(request))
def _data_query_error_message(exc: QueryServiceError) -> str:
"""Expose dependency outages without leaking SQL or database details."""
message = str(exc)
if message.startswith("投顾 Agent 依赖服务不可用"):
return message
return "客户数据查询失败,请稍后重试"
def _advisor_runtime(request: Request):
app = request.scope.get("app")
return getattr(getattr(app, "state", None), "advisor_agent_runtime", None)
@@ -251,8 +259,8 @@ async def chat_stream(
payload = None
# 请求体只传问题时,从问题中解析客户;解析结果仍必须经过投顾关系授权校验。
if customer_id is None:
# 单客户范围且未传编号时,兼容从问题中解析客户;投顾范围查询不解析客户。
if chat_request.scope == "customer" and customer_id is None:
customer_id, resolve_error = await _resolve_customer_from_query(
db,
advisor_id=user.id,
@@ -276,7 +284,19 @@ async def chat_stream(
payload = None
# 不带客户编号时只提供通用基金问答,不读取客户画像,也不生成个性化草稿。
if customer_id is None:
if chat_request.scope == "advisor" and inferred_intent != AGENT_INTENT_DATA_QUERY:
payload = agent_failure(
ERR_CODE_FORBIDDEN_CUSTOMER,
"投顾范围查询仅支持客户数据查询",
trace_id=trace_id,
)
elif chat_request.scope == "advisor" and customer_id is not None:
payload = agent_failure(
ERR_CODE_FORBIDDEN_CUSTOMER,
"投顾范围查询不能指定单个客户",
trace_id=trace_id,
)
elif chat_request.scope == "customer" and customer_id is None:
if inferred_intent in {
AGENT_INTENT_RECOMMEND,
AGENT_INTENT_REBALANCE,
@@ -319,10 +339,12 @@ async def chat_stream(
headers={"X-Trace-Id": trace_id},
)
else:
customer_id = chat_request.customer_id
relation = await ensure_customer_access(
db, advisor_id=user.id, customer_id=int(customer_id)
)
relation = None
if chat_request.scope == "customer":
customer_id = chat_request.customer_id
relation = await ensure_customer_access(
db, advisor_id=user.id, customer_id=int(customer_id)
)
if inferred_intent == AGENT_INTENT_RECOMMEND:
memories = await _recall_advisor_memories(
request,
@@ -382,15 +404,16 @@ async def chat_stream(
result = await execute_advisor_data_query(
db,
advisor_id=user.id,
customer_id=int(customer_id),
customer_id=int(customer_id) if customer_id is not None else None,
scope=chat_request.scope,
question=chat_request.query,
trace_id=trace_id,
llm_client=getattr(_advisor_runtime(request), "llm_client", None),
)
except QueryServiceError:
except QueryServiceError as exc:
payload = agent_failure(
ERR_CODE_LLM_ERROR,
"客户数据查询失败,请稍后重试",
_data_query_error_message(exc),
trace_id=trace_id,
)
else:
@@ -507,10 +530,10 @@ async def advisor_data_query(
sort_by=body.sort_by,
sort_order=body.sort_order,
)
except QueryServiceError:
except QueryServiceError as exc:
return agent_failure(
ERR_CODE_LLM_ERROR,
"客户数据查询失败,请稍后重试",
_data_query_error_message(exc),
trace_id=trace_id,
)
result.pop("sql", None)
+20 -6
View File
@@ -119,14 +119,16 @@ def history_payload(history) -> dict:
async def enrich_query_result(question: str, result, *, llm_client):
"""为已脱敏结果补充摘要和安全的基础图表配置。"""
summary = await summarize_result(
question,
result.columns,
result.rows,
llm_client=llm_client,
)
return replace(
result,
summary=await summarize_result(
question,
result.columns,
result.rows,
llm_client=llm_client,
),
summary=summary,
answer=summary,
chart=build_chart_config(result.columns, result.rows),
)
@@ -301,6 +303,11 @@ async def query_data(
warnings=[*cached_result.warnings, "cache_hit"],
)
else:
parameters = (
{"advisor_id": user.id}
if ":advisor_id" in validated_sql.sql
else None
)
result = await execute_readonly_sql(
db,
validated_sql,
@@ -308,8 +315,14 @@ async def query_data(
trace_id=trace_id,
user_id=user.id,
masks=permission.get("masks"),
parameters=parameters,
)
else:
parameters = (
{"advisor_id": user.id}
if ":advisor_id" in validated_sql.sql
else None
)
result = await execute_readonly_sql(
db,
validated_sql,
@@ -317,6 +330,7 @@ async def query_data(
trace_id=trace_id,
user_id=user.id,
masks=permission.get("masks"),
parameters=parameters,
)
if result.summary is None:
result = await enrich_query_result(body.question, result, llm_client=llm)