Enhance dialog context handling for Text2SQL queries by integrating session history. Introduce new methods for summarizing previous assistant messages and determining if the last interaction was a data query. Update environment configuration for embedding options and improve error handling in SQL generation. Add user-facing delivery messages for successful SQL execution. This update supports more coherent follow-up questions and improves user experience in conversational interactions.
This commit is contained in:
+118
-63
@@ -1,109 +1,164 @@
|
||||
# Impact Analysis Report — NL2SQL 确定性(temperature)
|
||||
# Impact Analysis Report — 会话上文注入 Text2SQL
|
||||
|
||||
## 1. 改动概览
|
||||
|
||||
- **背景与目标**:同一中文问题多次请求时,选表与生成 SQL 因 LLM 采样(默认 `temperature=0.3`)出现不一致。
|
||||
- **涉及模块**:`backend/llm/deepseek_client.py`(选表、校验、便捷 `generate_sql`)、`backend/agents/orchestrator.py`(编排器内 SQL 生成)。
|
||||
- **改动类型**:缺陷修复 / 行为稳定性增强(非功能扩展)。
|
||||
- **背景与目标**:在带 `session_id` 的 NL 对话中,将前几轮已落库的对话摘要注入选表、向量粗筛、SQL 生成与「无数据」说明,支持续问与指代消解。
|
||||
- **涉及模块**:`api_server.py`、`backend/utils/dialog_context.py`(新)、`backend/utils/dialog_classifier.py`、`backend/agents/orchestrator.py`。
|
||||
- **改动类型**:功能新增(向后兼容:无 `session_id` 或空历史时行为与原先一致)。
|
||||
|
||||
## 2. 方法级改动
|
||||
|
||||
| 位置 | 原行为 | 新行为 |
|
||||
|------|--------|--------|
|
||||
| `DeepSeekClient.select_tables` | 使用配置默认 `temperature`(如 0.3) | `setdefault(temperature=0.0, top_p=1.0)` 后调用 `chat_with_json`;调用方仍可通过 `**kwargs` 覆盖 |
|
||||
| `DeepSeekClient.validate_sql` | 同上 | 同上 |
|
||||
| `DeepSeekClient.generate_sql` | 同上 | 同上 |
|
||||
| `Text2SQLOrchestrator._generate_sql` | `chat(messages)` 使用默认温度 | 显式 `temperature=0.0, top_p=1.0` |
|
||||
|
||||
与原有逻辑差异:选表、校验、SQL 文本生成在相同 prompt 下更趋确定;若上游 API 在 `temperature=0` 下仍存在极小浮动,属于服务商实现范畴。
|
||||
| 位置 | 变更 |
|
||||
|------|------|
|
||||
| `LiteNlStore` | 无变更;仍由 `_append_session_if_needed` 在应答后写入。 |
|
||||
| `_load_session_text2sql_context`(api_server) | 新增:读 `get_messages`,构造上文块,并判断上一轮是否为数据查询。 |
|
||||
| `classify_dialog` | 新增可选关键字参数 `last_turn_was_data_query`;为 True 时在非寒暄/非元问题下将输入倾向判为 TEXT2SQL。 |
|
||||
| `messages_to_text2sql_context` 等 | 新工具:消息列表 → 可读摘要;解析 assistant JSON。 |
|
||||
| `Text2SQLOrchestrator.generate` | 新增可选 `dialog_context`;粗筛/选表/续问 broker 优先/生成/无数据反馈使用该上文。 |
|
||||
| `_generate_sql` / `_validate_sql` | 接收 `dialog_context`,Few-shot 检索问题与生成 user 提示含上文。 |
|
||||
|
||||
## 3. 调用方与影响范围
|
||||
|
||||
- **调用方**:`orchestrator._llm_select_tables` → `deepseek.select_tables`;`orchestrator._generate_sql` → `deepseek.chat`;校验链路 → `validate_sql`;脚本或其它代码若直接调用 `generate_sql`/`select_tables`/`validate_sql` 并传入自定义 `temperature`,**仍以调用方 kwargs 为准**(`setdefault` 不覆盖已传值)。
|
||||
- **输入输出**:接口签名未变;返回 JSON/SQL 文本的**内容分布**更集中,极端情况下可能从「多种可接受 SQL」收敛到其中一种。
|
||||
- **破坏性变更**:否(未改公开方法签名;仅默认采样参数与编排器单次 `chat` 参数)。
|
||||
- **调用方**:`/g3sb/api/nl/chat`、`/g3sb/api/nl/chat/stream`(仅当请求带有效 `session_id` 且会话内已有历史消息时生效)。
|
||||
- **CLI `backend/main.py` `single_query`**:现传入 `llm_client`;当 `DIALOG_INTENT_CLASSIFIER=rules` 时与旧规则行为一致。
|
||||
- **破坏性变更**:否(新增可选参数与默认 `False` 的关键字参数)。
|
||||
|
||||
## 4. 风险与回滚
|
||||
|
||||
- **风险级别**:低。可能略微降低「多解探索」多样性;对 Text2SQL 通常可接受。
|
||||
- **回滚**:恢复上述文件中的 `setdefault` / 显式 `temperature` 改动,或于环境变量/配置层为 DeepSeek 提高默认 `temperature`(若未来抽到配置项)。
|
||||
- **回滚方式是否简单**:是(单提交回退即可)。
|
||||
- **风险级别**:中(依赖会话中 assistant 内容为合法 JSON;解析失败时上文退化为截断原文或空段)。
|
||||
- **额外成本**:带历史的请求 prompt 更长,token 与耗时可能上升。
|
||||
- **回滚**:回退本提交即可;无配置开关。
|
||||
|
||||
**回滚方式是否简单**:是。
|
||||
|
||||
## 5. 验证与测试
|
||||
|
||||
- **建议**:对固定中文问题连续请求 5~10 次,比对日志中 `LLM精筛选中表` 与最终 SQL 是否一致。
|
||||
- **说明**:Few-shot / 向量粗筛若存在非确定性实现,仍可能导致差异;本次改动仅消除 **LLM 采样** 主导的不一致。
|
||||
- 已执行:`python -m py_compile` 对改动文件语法检查。
|
||||
- 建议手工:创建 session → 首轮数据查询 → 次轮「按上个月再查一遍」类续问,确认走 TEXT2SQL 且 SQL 与上文一致。
|
||||
|
||||
## 6. 配置变更(temperature 项)
|
||||
## 6. 配置变更
|
||||
|
||||
- 无新增环境变量或配置文件项;未改 `.env`。
|
||||
- 无。
|
||||
|
||||
---
|
||||
|
||||
# 增补:英文问句先译中文再走 Text2SQL(2026-04)
|
||||
# Impact Analysis Report — 库探针追问与交付分支(追加)
|
||||
|
||||
## 1. 改动概览
|
||||
|
||||
- **目标**:缓解「同一意图中英文提问选表/SQL 不一致」——在无 CJK 的英文问句进入粗筛、选表、few-shot、SQL 生成前,先经 DeepSeek 译为中文。
|
||||
- **涉及模块**:`backend/utils/question_locale.py`(新建)、`backend/config/prompts.py`、`backend/llm/deepseek_client.py`、`backend/agents/orchestrator.py`、`backend/main.py`、`api_server.py`。
|
||||
- **目标**:对齐库探针语义:`0` 无行时返回 SQL + 问题分析 + 固定追问引导重生成;`1` 有行时由 LLM 生成简短交付说明并返回 SQL;`-1` 失败时明确文案并走既有重试。
|
||||
- **涉及模块**:`backend/agents/orchestrator.py`、`backend/llm/deepseek_client.py`、`backend/config/prompts.py`、`api_server.py`(`DataQueryResult` 字段)、`backend/utils/dialog_context.py`(摘要)。
|
||||
|
||||
## 2. 方法级改动
|
||||
## 2. 破坏性变更
|
||||
|
||||
| 符号 | 说明 |
|
||||
|------|------|
|
||||
| `looks_like_english_only` | 无中日韩/假名/韩文且拉丁字母≥3 时视为「可译英文」 |
|
||||
| `DeepSeekClient.translate_nl_question_to_zh` | 一次 `chat(temperature=0)`,返回单行中文问句 |
|
||||
| `Text2SQLOrchestrator.generate` | 开头若开启且命中启发式则译问句,后续全流程使用中文;`metadata` 含 `question_original`、`question_zh_normalized` |
|
||||
| `_nl_dict_from_generation` | 若有译句,响应增加 `query_normalization: { original, zh }` |
|
||||
- **否**(API 新增可选字段;未配置 `database_url` 时行为与原先一致)。
|
||||
|
||||
## 3. 调用方与破坏性变更
|
||||
## 3. 风险
|
||||
|
||||
- **调用方**:所有 `orchestrator.generate()`;API 层无签名变更。
|
||||
- **破坏性变更**:否。默认开启;关闭后行为与旧版一致。英文请求多一次 LLM 调用(延迟与费用略增)。
|
||||
- **低~中**:探针为 `1` 时增加一次 LLM 调用(延迟与 token);失败时降级为仅返回 SQL。
|
||||
|
||||
## 4. 配置变更
|
||||
## 4. 验证
|
||||
|
||||
| 变量 | 含义 | 默认 |
|
||||
|------|------|------|
|
||||
| `TRANSLATE_EN_TO_ZH` | `false`/`0`/`off` 关闭英译中 | 开启 |
|
||||
|
||||
CLI:`python backend/main.py --no-translate-en` 关闭。
|
||||
|
||||
## 5. 风险与回滚
|
||||
|
||||
- **风险**:翻译偏差导致表意偏移;专有名词若未保留可能被误译。
|
||||
- **回滚**:`TRANSLATE_EN_TO_ZH=false` 或 `--no-translate-en`;或回退相关提交。
|
||||
- **回滚方式是否简单**:是。
|
||||
- `python -m py_compile` 覆盖改动文件。
|
||||
|
||||
---
|
||||
|
||||
# 增补:库探针状态码 0 / 1 / -1 语义对齐(2026-04)
|
||||
# Impact Analysis Report — Few-shot 写入 Chroma(追加)
|
||||
|
||||
## 1. 改动概览
|
||||
|
||||
- **目标**:与业务约定一致——**1** 表示查询返回至少一行数据;**0** 表示执行成功但**行数为 0**(含「有列无行」的 SELECT);**-1** 表示执行失败并触发重新生成,且重试提示携带数据库错误摘要。
|
||||
- **涉及模块**:`backend/db/dbhub_tools.py`、`backend/agents/orchestrator.py`、`backend/llm/deepseek_client.py`(注释)、`backend/main.py`(CLI 展示无行说明)、`backend/db/__init__.py`、`tools/dbhub_tools.py`、`tools/__init__.py`。
|
||||
- **目标**:将 `all_samples.jsonl` 写入 Chroma 持久化向量库;`FEWSHOT_USE_CHROMA=true` 时 `FewShotSelector` 从 Chroma 检索,否则仍用内存 + `.npy` 缓存。
|
||||
- **新增**:`backend/utils/fewshot_chroma_store.py`、`scripts/build_fewshot_chroma_index.py`;`.env` 增加注释说明;`FewShotSelector` 扩展参数与分支逻辑。
|
||||
|
||||
## 2. 方法级改动
|
||||
## 2. 破坏性变更
|
||||
|
||||
| 符号 | 说明 |
|
||||
|------|------|
|
||||
| `probe_sql_execution_status_ex` | 新增;返回 `(status, error_message)`,`-1` 时第二项为异常字符串 |
|
||||
| `probe_sql_execution_status` | 仍返回 `int \| None`,内部委托 `_ex`,**语义变更**:由「有列或行即 1」改为「**至少一行数据**为 1」 |
|
||||
| `Text2SQLOrchestrator._validate_sql` | `-1` 错误信息附带库端详情;状态 `0` 时在 LLM 反馈外增加固定前缀,引导用户核对 SQL 并补充条件 |
|
||||
| `single_query` | 验证通过且存在 `db_empty_feedback` 时打印「探针 0」说明块 |
|
||||
- **否**(默认 `FEWSHOT_USE_CHROMA` 未开启时行为不变)。
|
||||
|
||||
## 3. 风险
|
||||
|
||||
- **中**:Chroma metadata 对单字段长度有限制,超长 SQL/说明在入库时截断;换 Embedding 模型后应 `--force` 重建索引。
|
||||
|
||||
## 4. 验证
|
||||
|
||||
- `python -m py_compile` 已通过相关文件。
|
||||
|
||||
**追加(Chroma 优先、JSONL 可选)**:`FEWSHOT_USE_CHROMA=true` 且未设置 `FEWSHOT_DATA_PATH` 时,编排器默认不再读 JSONL;`FewShotSelector` 支持无文件 + Chroma 检索;`get_stats` / `get_tagged_examples` 在无内存样本时从 Chroma 全量导出统计。
|
||||
|
||||
**追加(Embedding 默认远程)**:移除对 `data/models/Qwen3-Embedding-0.6B` 的默认依赖;`USE_LOCAL_EMBEDDING` 默认视为 `false`;`get_embedder` / `setup_environment` / `EMBEDDING_MODEL_PATH` 与文档对齐为「远程 OpenAI 兼容等优先,本地仅显式开启」。
|
||||
|
||||
---
|
||||
|
||||
# Impact Analysis Report — Workbuddy Markdown → JSONL(追加)
|
||||
|
||||
## 1. 改动概览
|
||||
|
||||
- **目标**:将 `data/常问问题对应SQL_50个问题知识库_Workbuddy生成.md` 转为与 `data/experiences/all_samples.jsonl` 同结构的 JSONL,并保证每条含 `question_en`(英文题干)。
|
||||
- **新增**:`scripts/md_workbuddy_to_jsonl.py`;产出 `data/experiences/workbuddy_50_questions.jsonl`(50 行)。
|
||||
- **改动类型**:数据与脚本(可重复生成)。
|
||||
|
||||
## 2. 方法级说明
|
||||
|
||||
- 解析 Markdown 中 `## Qn` 节:`### 问题`(中英分行)、全部 `` ```sql `` 块(去重拼接)、`### SQL执行结果` / 内联结果、`### SQL理由`、`### SQL准确度评分`。
|
||||
- 与 `all_samples.jsonl` 按 `qid` 合并 `schema_info`、`tags`、`difficulty`;正文覆盖 `question_zh`、`question_en`、`sql`、`explanation`、`rating`、`result_note`。
|
||||
- 写出 JSONL 时字段顺序固定为:`question_zh` 后紧跟 **`question_en`**(便于在极长单行里肉眼看到英文题干)。
|
||||
- **Q50**:Markdown 仅有中文问题;脚本补充 `question_en`:`List all client trade records for today.`
|
||||
|
||||
## 3. 调用方与破坏性变更
|
||||
|
||||
- **调用方**:仅编排器直接调用探针;对外 API 仍通过 `GenerationResult.metadata` 的 `db_execution_status` / `db_empty_feedback` 表达结果。
|
||||
- **破坏性变更**:是(**语义**)。此前「SELECT 返回 0 行但有列名」会被判为 **1**;现改为 **0**,会走无数据说明分支而非「直接可交付」。
|
||||
- **调用方**:无运行时自动引用;需手工执行 `python scripts/md_workbuddy_to_jsonl.py` 或下游自行读 JSONL。
|
||||
- **破坏性变更**:否。
|
||||
|
||||
## 4. 风险与回滚
|
||||
|
||||
- **风险**:低~中。更多查询会落入「无数据行」分支,多一次 `empty_result_user_feedback` LLM 调用;但更符合「无数据则请用户补充」的产品逻辑。
|
||||
- **回滚**:恢复 `probe_sql_execution_status` 内基于「列或行非空」判定 1 的旧实现,并回退编排器与 CLI 改动。
|
||||
- **回滚方式是否简单**:是。
|
||||
- **风险**:低(生成物可被版本管理;`schema_info` 与含多段 SQL 的题目可能不完全一致,仍以 `all_samples` 为基线)。
|
||||
- **回滚**:删除脚本与 JSONL,或从 Git 回退。
|
||||
|
||||
## 5. 配置变更
|
||||
**回滚方式是否简单**:是。
|
||||
|
||||
## 5. 验证
|
||||
|
||||
- 已执行:`python scripts/md_workbuddy_to_jsonl.py`;校验 50 行且 `question_en` 均非空。
|
||||
|
||||
## 6. 配置变更
|
||||
|
||||
- 无。
|
||||
|
||||
---
|
||||
|
||||
# Impact Analysis Report — 对话意图 hybrid + LLM(追加)
|
||||
|
||||
## 1. 改动概览
|
||||
|
||||
- **背景与目标**:纯规则在「上一轮为数据查询」时把「结果不对」等反馈误判为 TEXT2SQL;改为默认 **hybrid**:明显查数词/寒暄/元问题仍走规则,其余由 **LLM 输出 JSON** 判定 `text2sql` / `conversation`。
|
||||
- **涉及模块**:`backend/utils/dialog_classifier.py`、`backend/config/prompts.py`(`DIALOG_INTENT_CLASSIFIER_*`)、`api_server.py`、`backend/main.py`。
|
||||
- **改动类型**:功能调整(默认多一次小 LLM 调用;可配置关闭)。
|
||||
|
||||
## 2. 方法级改动
|
||||
|
||||
| 位置 | 变更 |
|
||||
|------|------|
|
||||
| `classify_dialog` | 新增可选参数 `dialog_context`、`llm_client`;引入 `_classify_dialog_rules`、`_classify_dialog_llm`;读环境变量 `DIALOG_INTENT_CLASSIFIER`。 |
|
||||
| `api_server` 流式/非流式 NL | 在分类前 `get_orchestrator()`,用 `asyncio.to_thread(classify_dialog, ..., llm_client=orch.deepseek)` 避免阻塞事件循环。 |
|
||||
| `single_query` | `classify_dialog(question, llm_client=orchestrator.deepseek)` 与 API 对齐。 |
|
||||
|
||||
## 3. 调用方与影响范围
|
||||
|
||||
- **调用方**:`/g3sb/api/nl/chat`、`/g3sb/api/nl/chat/stream`、`single_query`。
|
||||
- **破坏性变更**:否;`DIALOG_INTENT_CLASSIFIER=rules` 时与原先规则路径一致(无 LLM 意图调用)。
|
||||
|
||||
## 4. 风险与回滚
|
||||
|
||||
- **风险级别**:中(每轮非「快速命中」类输入增加一次短 LLM 调用:延迟与费用;JSON 异常时回退规则)。
|
||||
- **回滚**:设 `DIALOG_INTENT_CLASSIFIER=rules` 或回退代码提交。
|
||||
|
||||
**回滚方式是否简单**:是。
|
||||
|
||||
## 5. 验证与测试
|
||||
|
||||
- 建议手工:`hybrid` 下首轮查数 → 次轮「这个结果不正确呀」应判为 conversation 并返回引导文案,不跑选表/SQL 链路。
|
||||
|
||||
## 6. 配置变更
|
||||
|
||||
| 配置项 | 含义 | 默认 |
|
||||
|--------|------|------|
|
||||
| `DIALOG_INTENT_CLASSIFIER` | `hybrid`:规则快速路径 + LLM;`rules`:仅规则 | `hybrid`(未设置时按 hybrid 处理) |
|
||||
|
||||
Reference in New Issue
Block a user