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

675 lines
34 KiB
Markdown
Raw Normal View History

# Impact Analysis Report — 会话上文注入 Text2SQL
2026-04-14 10:28:22 +08:00
## 1. 改动概览
- **背景与目标**:在带 `session_id` 的 NL 对话中,将前几轮已落库的对话摘要注入选表、向量粗筛、SQL 生成与「无数据」说明,支持续问与指代消解。
- **涉及模块**:`api_server.py`、`backend/utils/dialog_context.py`(新)、`backend/utils/dialog_classifier.py`、`backend/agents/orchestrator.py`。
- **改动类型**:功能新增(向后兼容:无 `session_id` 或空历史时行为与原先一致)。
2026-04-14 10:28:22 +08:00
## 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 提示含上文。 |
2026-04-14 10:28:22 +08:00
## 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` 的关键字参数)。
2026-04-14 10:28:22 +08:00
## 4. 风险与回滚
- **风险级别**:中(依赖会话中 assistant 内容为合法 JSON;解析失败时上文退化为截断原文或空段)。
- **额外成本**:带历史的请求 prompt 更长,token 与耗时可能上升。
- **回滚**:回退本提交即可;无配置开关。
**回滚方式是否简单**:是。
2026-04-14 10:28:22 +08:00
## 5. 验证与测试
- 已执行:`python -m py_compile` 对改动文件语法检查。
- 建议手工:创建 session → 首轮数据查询 → 次轮「按上个月再查一遍」类续问,确认走 TEXT2SQL 且 SQL 与上文一致。
2026-04-14 10:28:22 +08:00
## 6. 配置变更
2026-04-14 10:28:22 +08:00
- 无。
2026-04-14 10:28:22 +08:00
---
# 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 — 库探针追问与交付分支(追加)
2026-04-14 10:28:22 +08:00
## 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`(摘要)。
2026-04-14 10:28:22 +08:00
## 2. 破坏性变更
2026-04-14 10:28:22 +08:00
- **否**(API 新增可选字段;未配置 `database_url` 时行为与原先一致)。
2026-04-14 10:28:22 +08:00
## 3. 风险
2026-04-14 10:28:22 +08:00
- **低~中**:探针为 `1` 时增加一次 LLM 调用(延迟与 token);失败时降级为仅返回 SQL。
2026-04-14 10:28:22 +08:00
## 4. 验证
2026-04-14 10:28:22 +08:00
- `python -m py_compile` 覆盖改动文件。
2026-04-14 10:28:22 +08:00
---
# Impact Analysis Report — Few-shot 写入 Chroma(追加)
2026-04-14 10:28:22 +08:00
## 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` 扩展参数与分支逻辑。
2026-04-14 10:28:22 +08:00
## 2. 破坏性变更
2026-04-14 10:28:22 +08:00
- **否**(默认 `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.`
2026-04-14 10:28:22 +08:00
## 3. 调用方与破坏性变更
- **调用方**:无运行时自动引用;需手工执行 `python scripts/md_workbuddy_to_jsonl.py` 或下游自行读 JSONL。
- **破坏性变更**:否。
2026-04-14 10:28:22 +08:00
## 4. 风险与回滚
- **风险**:低(生成物可被版本管理;`schema_info` 与含多段 SQL 的题目可能不完全一致,仍以 `all_samples` 为基线)。
- **回滚**:删除脚本与 JSONL,或从 Git 回退。
2026-04-14 10:28:22 +08:00
**回滚方式是否简单**:是。
## 5. 验证
- 已执行:`python scripts/md_workbuddy_to_jsonl.py`;校验 50 行且 `question_en` 均非空。
## 6. 配置变更
2026-04-14 10:28:22 +08:00
- 无。
---
# 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`。 |
2026-04-16 10:53:10 +08:00
---
# 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`。