54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
"""NL2SQL 查询结果 → 客服口吻回复的渲染器。
|
|||
|
|
|
||
|
|
不调用 LLM:自然语言摘要由 execute_query 的 summary_llm 生成(result.summary),
|
||
|
|
这里只负责把摘要 + Markdown 表格组装成客服回复,保证确定性降级。
|
||
|
|
"""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from nl2sql.contracts import DataQueryResult
|
||
|
|
|
||
|
|
# 表格最多渲染的行数:超出部分提示"仅展示前 N 条",避免回复过长
|
||
|
|
_MAX_TABLE_ROWS = 20
|
||
|
|
|
||
|
|
_EMPTY_ANSWER = "暂时没有查到相关数据,您可以换个问法,或者问我基金知识、开户流程~"
|
||
|
|
|
||
|
|
|
||
|
|
def render_markdown_table(columns: list[str], rows: list[dict[str, Any]]) -> str:
|
||
|
|
"""把结果行列渲染为 Markdown 表格;无数据返回空串。"""
|
||
|
|
if not columns or not rows:
|
||
|
|
return ""
|
||
|
|
shown = rows[:_MAX_TABLE_ROWS]
|
||
|
|
header = "| " + " | ".join(str(column) for column in columns) + " |"
|
||
|
|
separator = "| " + " | ".join("---" for _ in columns) + " |"
|
||
|
|
lines = [header, separator]
|
||
|
|
for row in shown:
|
||
|
|
cells = [str(row.get(column, "")) for column in columns]
|
||
|
|
lines.append("| " + " | ".join(cells) + " |")
|
||
|
|
return "\n".join(lines)
|
||
|
|
|
||
|
|
|
||
|
|
def render_query_answer(result: DataQueryResult) -> str:
|
||
|
|
"""组装最终客服回复:摘要开头 + 数据表格 + 截断/收尾提示。"""
|
||
|
|
if result.row_count == 0 or not result.rows:
|
||
|
|
return _EMPTY_ANSWER
|
||
|
|
|
||
|
|
parts: list[str] = []
|
||
|
|
summary = (result.summary or "").strip()
|
||
|
|
if summary:
|
||
|
|
parts.append(summary)
|
||
|
|
|
||
|
|
table = render_markdown_table(result.columns, result.rows)
|
||
|
|
if table:
|
||
|
|
parts.append(table)
|
||
|
|
|
||
|
|
if result.truncated or result.row_count > len(result.rows):
|
||
|
|
shown = min(len(result.rows), _MAX_TABLE_ROWS)
|
||
|
|
parts.append(f"结果较多,本次为您展示 {shown} 条(共 {result.row_count} 条),您可以缩小查询范围再看。")
|
||
|
|
|
||
|
|
if not summary and len(result.rows) <= _MAX_TABLE_ROWS:
|
||
|
|
parts.append(f"共为您查到 {result.row_count} 条记录。")
|
||
|
|
|
||
|
|
return "\n\n".join(part for part in parts if part).strip() or _EMPTY_ANSWER
|