Files
ai-g3sb-backman2.0/IMPACT_ANALYSIS.md
T

675 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Impact Analysis Report — 会话上文注入 Text2SQL
## 1. 改动概览
- **背景与目标**:在带 `session_id` 的 NL 对话中,将前几轮已落库的对话摘要注入选表、向量粗筛、SQL 生成与「无数据」说明,支持续问与指代消解。
- **涉及模块**:`api_server.py`、`backend/utils/dialog_context.py`(新)、`backend/utils/dialog_classifier.py`、`backend/agents/orchestrator.py`。
- **改动类型**:功能新增(向后兼容:无 `session_id` 或空历史时行为与原先一致)。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `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. 调用方与影响范围
- **调用方**:`/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. 风险与回滚
- **风险级别**:中(依赖会话中 assistant 内容为合法 JSON;解析失败时上文退化为截断原文或空段)。
- **额外成本**:带历史的请求 prompt 更长,token 与耗时可能上升。
- **回滚**:回退本提交即可;无配置开关。
**回滚方式是否简单**:是。
## 5. 验证与测试
- 已执行:`python -m py_compile` 对改动文件语法检查。
- 建议手工:创建 session → 首轮数据查询 → 次轮「按上个月再查一遍」类续问,确认走 TEXT2SQL 且 SQL 与上文一致。
## 6. 配置变更
- 无。
---
# Impact Analysis Report — 新增 OpenAI LLM Client(对话/JSON 输出)
## 1. 改动概览
- **背景与目标**:补齐 `backend/llm/openai_client.py`,提供 OpenAI(或 OpenAI 兼容网关)调用封装,支持同步/异步 `chat` 与 `chat_with_json`,便于与既有 prompt/JSON 输出链路复用。
- **涉及模块**:`backend/llm/openai_client.py`、`.env`(仅补充注释示例,不影响现有运行配置)。
- **改动类型**:功能新增。
## 2. 方法级改动分析
| 位置 | 变更 |
|------|------|
| `OpenAIClient.chat` | 新增:基于 `openai` SDK 的 Chat Completions 调用封装,支持覆盖 `temperature/max_tokens/top_p` 等参数。 |
| `OpenAIClient.chat_with_json` | 新增:抽取/解析 JSON(兼容 markdown code fence);解析失败时返回 `{"_json_decode_failed": true, "raw_content": ...}`。 |
| `create_openai_client` | 新增:从环境变量读取 `OPENAI_API_KEY`、可选 `OPENAI_BASE_URL`、`OPENAI_MODEL/OPENAI_CHAT_MODEL`。 |
## 3. 调用方与影响范围分析
- **调用方**:当前仓库运行链路仍默认使用 `DeepSeekClient`;本次新增仅提供可选能力,未修改既有编排器/接口路由。
- **破坏性变更**:否。
## 4. 风险与回滚
- **风险级别**:低(新增模块,不改变既有默认路径)。
- **回滚**:删除新增文件与对应文档/注释即可。
**回滚方式是否简单**:是。
## 5. 验证与测试
- 已执行:`python -m py_compile backend/llm/openai_client.py`。
## 6. 配置变更
- `.env`:补充 `OPENAI_MODEL/OPENAI_CHAT_MODEL` 注释示例(不修改现有真实配置)。
---
# Impact Analysis Report — DeepSeek/OpenAI 双模型切换(LLM_SERVICE_CODE)
## 1. 改动概览
- **背景与目标**:支持在 DeepSeek 与 OpenAI(或兼容网关)之间切换 LLM 调用来源,便于在不同环境/配额下切换推理服务。
- **涉及模块**:`backend/llm/router.py`(新)、`backend/agents/orchestrator.py`、`backend/main.py`、`api_server.py`、`.env`(新增开关)。
- **改动类型**:功能增强(可配置路由)。
## 2. 方法级改动分析
| 位置 | 变更 |
|------|------|
| `backend/llm/router.py` | 新增:`resolve_llm_service_code` + `create_llm_client`,按 `LLM_SERVICE_CODE` 或 Key 存在性创建 LLM Client。 |
| `Text2SQLOrchestrator.__init__` | 新增可选 `llm_client` 参数;若传入则作为 `self.deepseek` 使用(保留属性名避免大范围改动)。 |
| `backend/main.py` | `setup_environment` 增加 `LLM_SERVICE_CODE` 校验;`create_orchestrator` 通过 router 创建 LLM Client。 |
| `api_server.py` | 错误提示文案更新;编排器初始化保持通过 `create_orchestrator` 完成。 |
## 3. 调用方与影响范围分析
- **调用方**:CLI(`backend/main.py`)与 API(`api_server.py`)初始化编排器路径。
- **行为变化**:
- `LLM_SERVICE_CODE=openai`:使用 `OPENAI_*` 做 LLM 调用(意图分类 / 归一 / 选表 / 生成 / 说明等)。
- `LLM_SERVICE_CODE=deepseek` 或未设置但存在 `DEEPSEEK_API_KEY`:仍默认 DeepSeek(与历史一致)。
- **破坏性变更**:否(对外 API 入参/出参不变;仅初始化与内部客户端来源可切换)。
## 4. 风险与回滚
- **风险级别**:中(不同模型对 JSON 严格性/输出格式偏好不同,可能影响 `chat_with_json` 的解析成功率与稳定性;失败时仍会返回 `_json_decode_failed` 供上游处理)。
- **回滚**:将 `LLM_SERVICE_CODE` 切回 `deepseek` 或回退相关文件改动。
**回滚方式是否简单**:是。
## 5. 验证与测试
- 已执行:`python -m py_compile` 覆盖 `backend/llm/router.py`、`backend/agents/orchestrator.py`、`backend/main.py`、`api_server.py`。
## 6. 配置变更
| 配置项 | 含义 | 取值 |
|--------|------|------|
| `LLM_SERVICE_CODE` | 选择 LLM 路由 | `openai` / `deepseek`(留空自动按 Key 选择,优先 deepseek) |
---
# Impact Analysis Report — 适配前端参数(lang_code / model)
## 1. 改动概览
- **背景与目标**:前端请求会携带 `lang_code`(`zh`/`tc`/`en`)与 `model`(模型名覆盖);后端需接收并在对话分支/LLM 调用侧生效。
- **涉及模块**:`api_server.py`。
- **改动类型**:兼容性增强。
## 2. 方法级改动分析
| 位置 | 变更 |
|------|------|
| `NLChatRequest` | 新增 `model` 字段;保留 `lang_code`(规范化为 `zh/tc/en/auto`)。 |
| `nl_chat` / `_chat_stream_events` | 对话分支:空输入/默认引导文案按 `lang_code` 返回(中/繁/英)。 |
| `_maybe_override_orch_llm`(新) | 若请求带 `service_code/model`,临时覆盖 `orchestrator.deepseek` 为按请求创建的 LLM client;使用锁避免并发串改。 |
| `_run_generate` | 增加 `request` 参数,用于按请求覆盖 LLM client 后再生成。 |
## 3. 调用方与影响范围分析
- **调用方**:`/g3sb/api/nl/chat`、`/g3sb/api/nl/chat/stream`。
- **破坏性变更**:否(仅新增可选请求字段与内部适配;未提供时行为保持不变)。
## 4. 风险与回滚
- **风险级别**:中(带 `model/service_code` 的请求会串行化执行 LLM 调用,避免并发污染;在高并发时可能降低吞吐)。
- **回滚**:回退 `api_server.py` 的按请求覆盖逻辑即可。
**回滚方式是否简单**:是。
## 5. 验证与测试
- 已执行:`python -m py_compile api_server.py`。
# Impact Analysis Report — 方案A:新话题禁用 dialog_context(防上下文污染)
## 1. 改动概览
- **背景与目标**:同一会话内出现多个不同话题时,历史摘要(含上轮 SQL)注入 Text2SQL 易造成上下文污染,导致选表/条件串话。本次引入“续问判定”规则:仅在疑似续问时注入少量上文;新话题默认不注入上文。
- **涉及模块**:`api_server.py`、`backend/utils/dialog_context.py`。
- **改动类型**:缺陷修复 / 行为优化(仅影响带 `session_id` 且存在历史消息的请求)。
## 2. 方法级改动分析
| 位置 | 变更 |
|------|------|
| `backend/utils/dialog_context.py` `is_likely_follow_up` | 新增:基于用户文本的轻量续问判定(关键字/短句规则),用于决定是否需要注入上文。 |
| `api_server.py` `_load_session_text2sql_context` | 调整:新增 `user_text` 入参;根据 `is_likely_follow_up(user_text)` 选择 `max_pairs=2` 或 `0`,并据此构造 `dialog_context`。 |
| `api_server.py` 两个入口 | 调整:`/g3sb/api/nl/chat` 与 `/g3sb/api/nl/chat/stream` 调用 `_load_session_text2sql_context(request, text)`。 |
## 3. 调用方与影响范围分析
- **调用方**:`/g3sb/api/nl/chat`、`/g3sb/api/nl/chat/stream`(请求带 `session_id` 且历史不为空时生效)。
- **行为变化**:
- **新话题**(非续问):`dialog_context` 变为空(不再携带历史摘要),降低串话风险。
- **续问**:仅携带最近 **2** 轮(原默认最多 8 轮),降低旧话题回流概率。
- **破坏性变更**:否(对外 API 入参/出参未变;仅内部上下文组装策略变化)。
## 4. 风险与回滚
- **风险级别**:中(可能把少量“隐式续问”误判为新话题,导致指代消解能力下降;但能显著降低跨话题污染)。
- **回滚**:回退本次提交(或将 `max_pairs` 固定恢复为 8 / 去掉续问判定)。
**回滚方式是否简单**:是。
## 5. 验证与测试
- 建议手工:
- 同一 session:话题A生成 SQL → 话题B(无续问词)应不再引用 A 的表/条件。
- 同一 session:首轮查询 → 次轮“再/按上面/沿用口径”续问,应仍能沿用上轮 SQL 的业务口径。
## 6. 配置变更
- 无。
# Impact Analysis Report — 库探针追问与交付分支(追加)
## 1. 改动概览
- **目标**:对齐库探针语义:`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. 破坏性变更
- **否**(API 新增可选字段;未配置 `database_url` 时行为与原先一致)。
## 3. 风险
- **低~中**:探针为 `1` 时增加一次 LLM 调用(延迟与 token);失败时降级为仅返回 SQL。
## 4. 验证
- `python -m py_compile` 覆盖改动文件。
---
# Impact Analysis Report — Few-shot 写入 Chroma(追加)
## 1. 改动概览
- **目标**:将 `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. 破坏性变更
- **否**(默认 `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. 调用方与破坏性变更
- **调用方**:无运行时自动引用;需手工执行 `python scripts/md_workbuddy_to_jsonl.py` 或下游自行读 JSONL。
- **破坏性变更**:否。
## 4. 风险与回滚
- **风险**:低(生成物可被版本管理;`schema_info` 与含多段 SQL 的题目可能不完全一致,仍以 `all_samples` 为基线)。
- **回滚**:删除脚本与 JSONL,或从 Git 回退。
**回滚方式是否简单**:是。
## 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 处理) |
---
# Impact Analysis — 移除本地 Embedding(仅远程 API)
## 1. 改动概览
- **背景与目标**:不再维护本地 HuggingFace / PyTorch 推理路径;Embedding 统一为 OpenAI 兼容远程 `/v1/embeddings`。
- **涉及模块**:`backend/utils/embedding.py`、`backend/main.py`、`backend/agents/orchestrator.py`、`backend/utils/fewshot_selector.py`、`backend/config/settings.py`、`api_server.py`、`scripts/build_fewshot_chroma_index.py`、`pyproject.toml`、`requirements.txt`、`main.spec`、`README.md`、`.env` 注释。
- **改动类型**:功能删减 / 依赖精简。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `Qwen3Embedding`(原) | **删除**;本地 `transformers`+`torch` 编码路径移除。 |
| `get_embedder` | 仅构造 `OpenAICompatibleRemoteEmbedding`;前两个位置参数废弃保留以兼容旧调用。 |
| `clear_embedder` | 仅 `gc.collect()`,不再触碰 CUDA。 |
| `Text2SQLOrchestrator.__init__` | 移除 `embedding_model_path`;`FewShotSelector` 不再传模型路径。 |
| `FewShotSelector.__init__` | 移除 `embedding_model_path`。 |
| `setup_environment` | 删除 `USE_LOCAL_EMBEDDING` / `EMBEDDING_MODEL_PATH` 分支。 |
## 3. 调用方与影响范围
- **调用方**:所有原 `get_embedder(path)` 仍可运行(路径被忽略);`Text2SQLOrchestrator(..., embedding_model_path=...)` 需改为不传该参数(已改仓库内引用)。
- **破坏性变更**:**是**——不再支持 `USE_LOCAL_EMBEDDING=true` 与本地模型目录;`pyproject.toml` / `requirements.txt` 不再声明 `torch`/`transformers`/`sentencepiece`/`accelerate`/`safetensors`(若 `camel-ai[all]` 等仍带入部分传递依赖,以实际 lock 为准)。
## 4. 风险与回滚
- **风险级别**:中(仅使用本地 Embedding 的部署将失效;需改为远程 Key 与模型名)。
- **回滚**:回退提交并恢复依赖与 `embedding.py` 历史版本。
**回滚方式是否简单**:是(单提交回退)。
## 5. 验证与测试
- 建议:`python -m py_compile` 对改动 `.py`;在已配置 `OPENAI_*` 或 `MODELSCOPE_*` 的环境下跑一次 Schema 向量构建或 Few-shot 检索。
## 6. 配置变更
| 移除/失效项 | 说明 |
|-------------|------|
| `USE_LOCAL_EMBEDDING`、`EMBEDDING_MODEL_PATH` | 代码不再读取;`.env` 中可删去以免误解。 |
| CLI `--embedding-model` | 已删除。 |
---
# Impact Analysis Report — main.spec:向量持久化目录不落包(追加)
## 1. 改动概览
- **背景与目标**:在 PyInstaller 配置中明确约定「业务侧 Chroma/向量持久化目录」不加入 `datas`,避免误将 `data/embeddings` 等打入 onefile;实际打包行为与此前一致(`datas` 中本未包含上述目录)。
- **涉及模块**:`main.spec`。
- **改动类型**:配置说明 / 文档化。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `main.spec` 顶部注释与 `datas` | 写明 `VECTOR_DB_PATH`、`FEWSHOT_CHROMA_PATH` 对应目录外置;区分 chromadb **wheel 依赖**与**用户向量库文件**;`EXE` 处注释澄清 `a.datas` 含义。 |
## 3. 调用方与影响范围
- **调用方**:仅 `pyinstaller main.spec` 打包流程;运行时仍依赖环境变量或旁路目录提供向量库(与代码逻辑无变更)。
- **破坏性变更**:否。
## 4. 风险与回滚
- **风险级别**:低。
- **回滚**:还原 `main.spec` 对应注释块。
**回滚方式是否简单**:是。
## 5. 验证与测试
- 打包前确认 `datas` 无 `data/embeddings` 等元组;打包后 exe 旁按需放置向量目录并配置 `.env`。
---
# Impact Analysis Report — 前端默认 NL API 地址(追加)
## 1. 改动概览
- **目标**:前端开发与 UAT 打包默认后端 origin 改为 `http://0.0.0.0:8041`;同 host 解析时默认端口改为 `8041`。
- **涉及模块**:`ai-g3sb-backman-web/vite.config.ts`(`VITE_DEV_API_TARGET` 默认值)、`ai-g3sb-backman-web/src/api/packagedOrigin.ts`、`ai-g3sb-backman-web/src/api/config.ts`;`src/locales/{zh,tw,en}.ts` 中管理端 API 占位示例同步。
- **改动类型**:配置默认值变更。
## 2. 调用方与破坏性变更
- **调用方**:Vite 开发代理 `/g3sb`;非 test 构建注入的 `window.__BACKMAN_API_ORIGIN__` 与 `apiBase()` 默认打包 origin。
- **破坏性变更**:否(仍可通过环境变量 `VITE_DEV_API_TARGET`、`VITE_PACKAGED_API_ORIGIN`、`VITE_PACKAGED_API_PORT` 覆盖)。
## 3. 风险与回滚
- **风险级别**:低。说明:浏览器直连 `0.0.0.0` 在部分环境下可能不如 `127.0.0.1` 可靠;若遇连接问题可改用 `VITE_*` 覆盖为实际可访问地址。
- **回滚**:还原上述三处默认值或设置环境变量覆盖。
**回滚方式是否简单**:是。
## 4. 配置变更
| 项 | 说明 |
|----|------|
| `VITE_DEV_API_TARGET`(可选) | 未设置时默认 `http://0.0.0.0:8041`。 |
| `PACKAGED_API_ORIGIN` / `VITE_PACKAGED_API_ORIGIN` | 代码内默认改为 `http://0.0.0.0:8041`。 |
| `VITE_PACKAGED_API_PORT`(可选) | `same-host`/`auto` 时未设置则默认 `8041`。 |
---
# Impact Analysis Report — SchemaIndexer 持久化 Chroma(追加)
## 1. 改动概览
- **背景与目标**:原先 `SchemaIndexer` 固定使用 `EphemeralClient`,进程内集合恒为空,每次请求粗筛都会全量计算约 2500+ 张表的 embedding;用户已在 `data/embeddings/chroma` 等目录落盘向量库,应直接复用。
- **涉及模块**:`backend/schema/indexer.py`、`backend/agents/orchestrator.py`(日志与 `force_rebuild`)、`backend/utils/fewshot_chroma_store.py`(注释)、`main.spec`(打包说明注释)。
- **改动类型**:缺陷修复 / 行为优化(性能与成本)。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `SchemaIndexer.__init__` | 默认 `chromadb.PersistentClient(path=persist_dir)`,创建目录;`SCHEMA_INDEXER_EPHEMERAL=true` 或 `use_ephemeral=True` 时仍为 `EphemeralClient`。默认 `persist_dir` 与 `VECTOR_DB_PATH` 对齐为 `./data/embeddings/chroma`。 |
| `SchemaIndexer.get_statistics` | `chroma_mode` 区分 `persistent` / `memory`。 |
| `Text2SQLOrchestrator._coarse_filter` | 每次粗筛前调用 `SchemaIndexer.ensure_index_for_schema`:索引条数与当前 Schema 表数一致则跳过向量化;空库则构建;不一致则 `force_rebuild` 重建。 |
| `SchemaIndexer.ensure_index_for_schema`(新) | 对比 `collection.count()` 与 `len(schema_manager.get_tables())`,避免无意义重复向量化,并在 Schema 增删表后自动重载索引。 |
## 3. 调用方与影响范围
- **调用方**:`Text2SQLOrchestrator._get_vector_index()` 传入的 `persist_dir` 仍为 `vector_db_path` / 环境变量 `VECTOR_DB_PATH`;向量粗筛路径经 `ensure_index_for_schema`。
- **破坏性变更**:否。若依赖「每次进程冷启动强制空向量库」的测试,需设置 `SCHEMA_INDEXER_EPHEMERAL=true`。
## 4. 风险与回滚
- **风险级别**:低。说明:Embedding 模型或维度变更时,旧持久化向量与当前 encoder 不一致可能导致检索质量下降,需删除目录或调用带 `force_rebuild` 的构建逻辑重建。
- **回滚**:还原 `indexer.py` 相关提交或设置 `SCHEMA_INDEXER_EPHEMERAL=true`。
**回滚方式是否简单**:是。
## 5. 配置变更
| 项 | 说明 |
|----|------|
| `VECTOR_DB_PATH` | 既有;默认 `./data/embeddings/chroma`,现为 Schema Chroma 真实持久化根路径。 |
| `SCHEMA_INDEXER_EPHEMERAL`(可选) | 设为 `true`/`1`/`yes` 时使用内存 Chroma(与旧行为一致)。 |
---
# Impact Analysis Report — 中英文问句归一以提升 SQL 一致性(追加)
## 1. 改动概览
- **背景与目标**:同一业务语义分别用中文、英文提问时,原先仅对「纯英文」问句做英译中,中文问句原样进入检索/生成,导致与英文路径的表述不一致,向量粗筛与 SQL 可能分叉。
- **涉及模块**:`backend/config/prompts.py`(归一提示词 + SQL_GENERATOR 约束)、`backend/llm/deepseek_client.py`、`backend/agents/orchestrator.py`、`backend/main.py`(CLI 帮助文案)。
- **改动类型**:行为优化;默认仍受 `TRANSLATE_EN_TO_ZH` / `--no-translate-en` 控制。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `DeepSeekClient.normalize_nl_question_for_text2sql` | 新增:`temperature=0` 下将中/英问句归一为一句中文。 |
| `DeepSeekClient.translate_nl_question_to_zh` | 改为委托上述方法(兼容旧名)。 |
| `Text2SQLOrchestrator.generate` | 当 `translate_english_to_zh` 为 True 时,对**所有**非空问句调用归一(不再仅限 `looks_like_english_only`)。 |
| `SQL_GENERATOR_SYSTEM` | 新增硬性约束第 6 条:中英文同义时 SQL 逻辑须一致。 |
## 3. 调用方与破坏性变更
- **调用方**:所有经 `generate()` 的 Text2SQL 请求(含 `api_server` 默认 `TRANSLATE_EN_TO_ZH` 开启时)。
- **破坏性变更**:否。关闭归一:`TRANSLATE_EN_TO_ZH=false` 或 `--no-translate-en` / `Args.no_translate_en`,行为与改动前「中文不归一、英文仍可不译」一致。
## 4. 风险与回滚
- **风险级别**:低~中。每次成功归一增加一次 LLM 调用(延迟与 token);归一失败时回退原文(与旧失败策略一致)。
- **回滚**:关闭环境变量或还原相关文件。
**回滚方式是否简单**:是。
## 5. 配置变更
| 项 | 说明 |
|----|------|
| `TRANSLATE_EN_TO_ZH` | 语义扩展为「是否做问句归一中文」;`false` 关闭额外 LLM 归一步骤。 |
---
# Impact Analysis Report — Few-shot Chroma 默认读盘(追加)
## 1. 改动概览
- **问题**:`FEWSHOT_USE_CHROMA=true` 时 `FewShotChromaStore` 仍默认 `EphemeralClient`,进程内 `count` 恒为 0,每次启动从 JSONL 重算 embedding,忽略已灌库的 `data/embeddings/chroma_fewshot`。
- **模块**:`backend/utils/fewshot_chroma_store.py`。
- **类型**:缺陷修复。
## 2. 行为变更
| 项 | 说明 |
|----|------|
| 默认 | `persist_to_disk=None` 时默认使用 `PersistentClient`(`FEWSHOT_CHROMA_PATH` 或 `./data/embeddings/chroma_fewshot`)。 |
| 退出 | `FEWSHOT_CHROMA_EPHEMERAL=true` 或构造参数 `persist_to_disk=False` 时仍为内存 Chroma。 |
## 3. 破坏性变更
- **否**。灌库脚本显式 `persist_to_disk=True` 不变。
## 4. 配置
| `FEWSHOT_CHROMA_EPHEMERAL` | 可选;`true` 时与旧版「仅内存」行为一致。 |
---
# Impact Analysis Report — `/g3sb/api/nl/chat/stream` 分片 SSE(追加)
## 1. 改动概览
- **背景与目标**:前端 `chatStore` 按多次 `{ stage, stream_kind, content }` 累加 `chatText` / `sqlGenHtml`;原先后端在 `chat` / `sql_gen` 阶段各只发一条大包,网络侧无渐进感。
- **涉及模块**:`api_server.py`。
- **改动类型**:行为优化(SSE 事件形态不变,仅增加条数)。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `_sse_stream_text_chunks` | 新增:按字符窗口(默认 64,可用 `SSE_STREAM_CHUNK_CHARS` 覆盖)拆成多段 SSE;段间 `asyncio.sleep(0)` 让出事件循环。 |
| `_chat_stream_events` | `chat` / `sql_gen` 正文改为 `async for` 分片 `yield`。 |
## 3. 破坏性变更
- **否**(结束包 `code/msg/data` 仍与原先一致)。
## 4. 配置变更
| 项 | 说明 |
|----|------|
| `SSE_STREAM_CHUNK_CHARS` | 可选;每段 SSE 的 `content` 最大字符数,默认 `64`。 |
---
# Impact Analysis Report — API 日志落盘与可观测性(追加)
## 1. 改动概览
- **背景与目标**:终端日志偏少,难以排查 Text2SQL 全链路问题;需将更细粒度的日志写入仓库 `logs/`,且每次进程启动只保留一个 `.log` 文件。
- **涉及模块**:`api_server.py`、`backend/utils/repo_logging.py`(新)、`backend/agents/orchestrator.py`、`backend/schema/indexer.py`、`backend/utils/dialog_classifier.py`。
- **改动类型**:可观测性增强(行为对业务结果无影响)。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `configure_text2sql_api_logging` | 新建:清空 `logs/*.log`,创建 `logs/text2sql_api.log`(覆盖写);root 双 Handler(控制台简短格式 + 文件含 filename/lineno/funcName);关闭 Chroma/posthog 遥测 logger;`httpx`/`httpcore` 降为 WARNING。 |
| `api_server` 导入段 | 在 `from main import …` 之前调用上述配置;移除 `basicConfig`;`uvicorn.run(..., log_config=None)` 避免覆盖 root(勿用 `False`,否则会走 `fileConfig` 崩溃),并清空 uvicorn 自带 handler 改为 `propagate`。 |
| `_run_generate` / `nl_chat` / `_chat_stream_events` | 增加请求维度、对话上文长度、流式结束时的 valid/attempts/tables/SQL 摘要等 INFO 日志。 |
| `Text2SQLOrchestrator` | 向量粗筛输出表名+分数列表;选表输出 reasoning 预览;few-shot 注入 qid 与问题预览;生成 SQL 全文(超长截断至约 12k 字符);`_validate_sql` 返回前汇总 valid/errors/warnings/探针。 |
| `SchemaIndexer.search` | 检索结果由 DEBUG 改为 INFO,输出命中数与 top 表+分。 |
| `classify_dialog` 规则/hybrid 快路径 | DEBUG 改为 INFO,附用户输入预览;LLM 分支补充 reply 预览。 |
## 3. 调用方与影响范围
- **调用方**:仅通过 `python api_server.py`(或等价导入 `api_server`)启动 API 时生效;`backend/main.py` CLI 仍使用自身 `basicConfig`,不落盘到本 `logs/text2sql_api.log`(未改 CLI)。
- **破坏性变更**:否。
## 4. 风险与回滚
- **风险级别**:低。日志文件可能含用户查询片段与 SQL,需注意磁盘与隐私(内网演示场景可接受)。
- **回滚**:删除 `repo_logging` 调用与相关增强日志,恢复 `basicConfig` 与默认 `uvicorn.run` 即可。
**回滚方式是否简单**:是。
## 5. 验证与测试
- 建议:`python -m py_compile api_server.py backend/utils/repo_logging.py`;启动 `python api_server.py` 后确认生成 `logs/text2sql_api.log` 且重启后仅保留该文件。
## 6. 配置变更
- 无新增环境变量;日志路径固定为仓库根下 `logs/text2sql_api.log`。
---
# Impact Analysis Report — Chroma Few-shot 黄金 SQL 条件适配(追加)
## 1. 改动概览
- **背景与目标**:`data/embeddings/chroma_fewshot` 中存储的问答-SQL 视为已校验正确答案;当向量检索与当前问题足够相似时,不再仅作「风格示例」,而是以该 SQL 为骨架,仅让 LLM 调整 WHERE/HAVING 等与用户问题相关的**特殊条件**。
- **涉及模块**:`backend/config/prompts.py`(`GOLDEN_SQL_ADAPT_*`)、`backend/utils/fewshot_selector.py`(`select_best_with_score`、`is_chroma_backend`)、`backend/agents/orchestrator.py`(`_generate_sql_golden_adapt`、`_generate_sql` 分支)、`api_server.py`(响应中可选 `fewshot_golden`)。
- **改动类型**:生成策略增强(默认开启,可用环境变量关闭或调阈值)。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `FewShotSelector` | 新增 `_passes_filters`、`select_best_with_score`;`is_chroma_backend` 属性。 |
| `Text2SQLOrchestrator._generate_sql` | 在 Chroma 且满足阈值时调用 `_generate_sql_golden_adapt` 并设置 `_last_fewshot_golden`;否则沿用原 few-shot 注入 + 全量生成。 |
| `_generate_sql_golden_adapt` | 使用 `GOLDEN_SQL_ADAPT_SYSTEM/USER`,强调保留 JOIN/SELECT 结构、仅改条件。 |
| `generate` | `metadata` 增加 `fewshot_golden_reuse`、`fewshot_golden_qid`、`fewshot_golden_score`;失败路径亦回传(若曾走黄金分支)。 |
| `_nl_dict_from_generation` | 若存在黄金复用,增加 `fewshot_golden` 字段供前端展示/调试。 |
## 3. 破坏性变更
- **否**。未命中阈值时行为与原先「多示例风格参考」一致。
## 4. 配置变更
| 环境变量 | 含义 | 默认 |
|----------|------|------|
| `FEWSHOT_GOLDEN_REUSE` | 是否启用黄金 SQL 条件适配 | `true` |
| `FEWSHOT_GOLDEN_ONLY_CHROMA` | 是否仅在 Chroma 后端启用(与 `chroma_fewshot` 策略一致) | `true` |
| `FEWSHOT_GOLDEN_MIN_SCORE` | 最低相似度(1-距离,约等于余弦相似度) | `0.88` |
| `FEWSHOT_GOLDEN_SQL_PROMPT_MAX` | 写入提示词的标准答案 SQL 最大字符数 | `16000` |
## 5. 风险与回滚
- **风险**:阈值过低可能把不太相似的问题强行套在同一 SQL 上;过高则很少触发黄金分支。
- **回滚**:设 `FEWSHOT_GOLDEN_REUSE=false` 或回退相关提交。
**回滚方式是否简单**:是。
---
# Impact Analysis Report — 流式 SSE sql_gen 分片与节流
## 1. 改动概览
- **背景与目标**:前端约定每条 SSE 为 `data: {"stage":"sql_gen","stream_kind":"content","content":"..."}`;服务端需按 LLM 原生流式 delta 透传(默认不二次切分),并支持可选分片间隔。
- **涉及模块**:`api_server.py`(`/g3sb/api/nl/chat/stream`、`_iter_sql_gen_content_pieces`、`_sse_stream_text_chunks`)。
- **改动类型**:行为调整(默认分片粒度为 `delta`:不做二次切分;如确需更细粒度可配置 `char`)。
## 2. 方法级改动
| 位置 | 变更 |
|------|------|
| `NLChatRequest` | 新增可选 `sql_stream_granularity`(`sqlStreamGranularity`);明确 `streaming_throttle` 为相邻 content 间隔毫秒。 |
| `_iter_sql_gen_content_pieces` | 支持传入 `mode`;未设置时 `SSE_SQL_GEN_SPLIT` 默认 `delta`(不切分)。 |
| `_chat_stream_events` | sql_gen 循环按粒度拆分后对每条 `data` 可选 `asyncio.sleep(throttle)`;寒暄分支 `_sse_stream_text_chunks` 支持相同节流。 |
## 3. 调用方与影响范围
- **调用方**:仅 SSE 流式客户端;非流式 `/g3sb/api/nl/chat` 不变。
- **破坏性变更**:否。未传新字段时:粒度由 `SSE_SQL_GEN_SPLIT` 决定(默认 `delta`,事件条数与 LLM 原生一致);若需更细粒度可设 `SSE_SQL_GEN_SPLIT=char` 或请求体 `sqlStreamGranularity: "char"`。
## 4. 配置变更
| 环境变量 | 含义 | 默认 |
|----------|------|------|
| `SSE_SQL_GEN_SPLIT` | `delta`:与 LLM 增量一致;`char`:逐 Unicode 标量多条 SSE | `delta`(未设置 env 时由代码默认) |
## 5. 风险与回滚
- **风险级别**:低。`char` 模式下 SSE 条数增加,带宽与前端拼接次数上升。
- **回滚**:设 `SSE_SQL_GEN_SPLIT=delta` 或请求传 `sqlStreamGranularity: "delta"`(回到默认:不切分)。
**回滚方式是否简单**:是。
## 6. 验证与测试
- 已执行:`python -m py_compile api_server.py`。