fix(ai): 财务助手动态回答、对话新增列并统一模型配置 #13

Merged
jianwel merged 5 commits from codex/deepseek-assistant-fix into main 2026-11-01 04:44:48 +00:00
Owner

背景

此前启用 AI 后只用模型解析查询意图,助手最终仍返回固定模板;公式工作簿的列设计则绕过页面配置,使用环境变量和硬编码 OpenAI 地址。本次按 docs/ai-assistant-deepseek-execution-plan.html(T0–T5)执行修复。

本次修改

  • 动态回答:服务端先按权限计算聚合结果,再把白名单聚合交给同一份组织模型配置生成回答;显示实际模型名,支持最多 5 轮已完成的连续追问;普通问答不改变页面,只有显式的总览/异常/下钻/明细才导航。
  • 对话新增分析列:助手意图新增 design_column;信息不足先追问,完整后展示列名、含义、表达式、适用范围与缺失策略;用户确认后才保存到定义库并加入当前表格。同名替换保留原位置、最多 10 列、失败保留预览、保存中禁用重复提交;确认前不写定义/导出。
  • 统一模型接入:finance/ai.py 提取共用 request_response / extract_output_text / validate_messages;财务助手与公式列设计共用同一份组织配置(数据库优先、显式禁用不回退、无数据库配置才用环境变量),移除硬编码 OpenAI URL/模型/Key。
  • 状态与权限:保留已有 custom_columns、筛选与期间;列设计仅允许全范围 admin/analyst,viewer、科室受限、跨组织均拒绝;消息边界、consent、表达式/可用指标校验在两条入口复用。
  • 界面:有界消息列表、来源标识(“模型回答 · 实际模型”或“规则摘要”)、新的同意文案、列预览与确认、“新对话/退出列设计”;范围/数据版本变化清空待确认状态并丢弃迟到响应。
  • 文档:README 补充动态回答、对话新增列、共用配置与同意范围。

验证(实际执行结果)

检查 结果
基线 origin/main 7be8854 后端 83 passed, 5 skipped
本分支后端(PostgreSQL 17) 112 passed, 5 skipped;finance 覆盖率 89.65%(门槛 85%)
ruff check / ruff format --check 通过(53 / 46 文件)
makemigrations --check --dry-run No changes detected
npm run build 通过(tsc + vite)
Playwright 全量 15 passed, 1 skipped(原附件用例按环境跳过)
npm audit --omit=dev 0 vulnerabilities
真实 DeepSeek 联调 见下

真实联调(合成数据,未记录/输出 Key):使用页面同源的 DeepSeek 官方端点 /responses、模型 deepseek-flash。

  • 动态回答:source=model,模型 deepseek-flash;追问“毛利怎么算”12.9s 成功。
  • 对话列设计:4.5s 返回 complete=true,表达式 revenue - cost。
  • 确认保存 201;查询本期 1000、基期 6000、差额 −5000;工作簿生成并包含“收入成本差”。
  • 独立 /formula-design 入口 3.4s 成功,证明两处共用页面配置。
  • 联调中发现 DeepSeek 推理模型的 reasoning token 会占满原 900 输出预算(incomplete/max_output_tokens),已将回答预算提高到 3000,并对截断返回明确错误(不伪装成功)。

已知问题与未完成项

  • 基线失败(非本 PR 引入):pip-audit 报告 filelock 4.0.1、certifi 2026.7.22、msgpack 1.2.2 共 17 个已知漏洞;uv.lock 未改动,main 上同样复现。需另开依赖升级 PR。
  • 安全提示(非本 PR 引入):仓库根目录 temp-key.txt 在 main 上已被跟踪,疑似包含真实密钥,建议立即轮换并从版本库移除。
  • 浏览器 E2E 连续重复运行会触发登录限流(30 次/15 分钟),需等待窗口或在隔离测试库清理 Throttle 后重跑;CI 单轮不受影响。
  • tests/e2e/formula-export.spec.ts 的金额断言由字符串 "1000" 改为按数值比较,因为 Decimal 以 "1000.000000000000000000000000" 保留精度;断言强度未降低。
  • Verify 结果以本 PR 的 CI 为准;尚未自动合并或部署。
## 背景 此前启用 AI 后只用模型解析查询意图,助手最终仍返回固定模板;公式工作簿的列设计则绕过页面配置,使用环境变量和硬编码 OpenAI 地址。本次按 `docs/ai-assistant-deepseek-execution-plan.html`(T0–T5)执行修复。 ## 本次修改 - **动态回答**:服务端先按权限计算聚合结果,再把白名单聚合交给同一份组织模型配置生成回答;显示实际模型名,支持最多 5 轮已完成的连续追问;普通问答不改变页面,只有显式的总览/异常/下钻/明细才导航。 - **对话新增分析列**:助手意图新增 `design_column`;信息不足先追问,完整后展示列名、含义、表达式、适用范围与缺失策略;用户确认后才保存到定义库并加入当前表格。同名替换保留原位置、最多 10 列、失败保留预览、保存中禁用重复提交;确认前不写定义/导出。 - **统一模型接入**:`finance/ai.py` 提取共用 `request_response` / `extract_output_text` / `validate_messages`;财务助手与公式列设计共用同一份组织配置(数据库优先、显式禁用不回退、无数据库配置才用环境变量),移除硬编码 OpenAI URL/模型/Key。 - **状态与权限**:保留已有 `custom_columns`、筛选与期间;列设计仅允许全范围 admin/analyst,viewer、科室受限、跨组织均拒绝;消息边界、consent、表达式/可用指标校验在两条入口复用。 - **界面**:有界消息列表、来源标识(“模型回答 · 实际模型”或“规则摘要”)、新的同意文案、列预览与确认、“新对话/退出列设计”;范围/数据版本变化清空待确认状态并丢弃迟到响应。 - **文档**:README 补充动态回答、对话新增列、共用配置与同意范围。 ## 验证(实际执行结果) | 检查 | 结果 | | --- | --- | | 基线 `origin/main` 7be8854 后端 | 83 passed, 5 skipped | | 本分支后端(PostgreSQL 17) | **112 passed, 5 skipped**;finance 覆盖率 **89.65%**(门槛 85%) | | `ruff check` / `ruff format --check` | 通过(53 / 46 文件) | | `makemigrations --check --dry-run` | No changes detected | | `npm run build` | 通过(tsc + vite) | | Playwright 全量 | **15 passed, 1 skipped**(原附件用例按环境跳过) | | `npm audit --omit=dev` | 0 vulnerabilities | | 真实 DeepSeek 联调 | 见下 | **真实联调(合成数据,未记录/输出 Key)**:使用页面同源的 DeepSeek 官方端点 `/responses`、模型 `deepseek-flash`。 - 动态回答:`source=model`,模型 `deepseek-flash`;追问“毛利怎么算”12.9s 成功。 - 对话列设计:4.5s 返回 `complete=true`,表达式 `revenue - cost`。 - 确认保存 201;查询本期 **1000**、基期 **6000**、差额 **−5000**;工作簿生成并包含“收入成本差”。 - 独立 `/formula-design` 入口 3.4s 成功,证明两处共用页面配置。 - 联调中发现 DeepSeek 推理模型的 reasoning token 会占满原 900 输出预算(`incomplete/max_output_tokens`),已将回答预算提高到 3000,并对截断返回明确错误(不伪装成功)。 ## 已知问题与未完成项 - **基线失败(非本 PR 引入)**:`pip-audit` 报告 `filelock 4.0.1`、`certifi 2026.7.22`、`msgpack 1.2.2` 共 17 个已知漏洞;`uv.lock` 未改动,main 上同样复现。需另开依赖升级 PR。 - **安全提示(非本 PR 引入)**:仓库根目录 `temp-key.txt` 在 main 上已被跟踪,疑似包含真实密钥,建议立即轮换并从版本库移除。 - 浏览器 E2E 连续重复运行会触发登录限流(30 次/15 分钟),需等待窗口或在隔离测试库清理 Throttle 后重跑;CI 单轮不受影响。 - `tests/e2e/formula-export.spec.ts` 的金额断言由字符串 `"1000"` 改为按数值比较,因为 Decimal 以 `"1000.000000000000000000000000"` 保留精度;断言强度未降低。 - Verify 结果以本 PR 的 CI 为准;尚未自动合并或部署。
jianwel added 4 commits 2026-11-01 02:55:28 +00:00
Author
Owner

Verify 实际结果(如实记录,不以本地通过代替 CI):

  • Verify / verify (push) — run 1962:失败,但仅失败于基线依赖审计。
    • ruff check / ruff format --check:通过。
    • pytest:112 passed, 5 skipped;finance 覆盖率 89.65%(门槛 85%)。
    • makemigrations --check、npm run build:通过。
    • pip-audit:连续 3 次均报告 filelock 4.0.1、certifi 2026.7.22、msgpack 1.2.2 共 17 个已知漏洞,job 在此步失败;uv.lock 本 PR 未改动,main 上同样复现。
  • Verify / verify (pull_request) — run 1964:失败于基础设施启动。 3 秒退出,日志为 Bind for 0.0.0.0:5432 failed: port is already allocated:与同一 push 触发的并行 run 争用宿主机 5432,尚未执行任何仓库步骤。
  • AI Review / review (pull_request) — run 1963:通过。
  • 因 pip-audit 提前中止,CI 内的 Playwright 未执行;本地全量 Playwright 为 15 passed, 1 skipped(原附件用例按环境跳过)。

上述两项基线问题正由已开启的 #12(fix(ci): 修复 Verify 数据库冲突和依赖审计失败) 处理;未在本 PR 内删除检查、降低覆盖率或夹带无关 CI 修复。待 #12 合并后可将 main 合入本分支重跑 Verify。本 PR 不自动合并、不部署。

Verify 实际结果(如实记录,不以本地通过代替 CI): - **Verify / verify (push) — run 1962:失败,但仅失败于基线依赖审计。** - `ruff check` / `ruff format --check`:通过。 - `pytest`:112 passed, 5 skipped;finance 覆盖率 89.65%(门槛 85%)。 - `makemigrations --check`、`npm run build`:通过。 - `pip-audit`:连续 3 次均报告 `filelock 4.0.1`、`certifi 2026.7.22`、`msgpack 1.2.2` 共 17 个已知漏洞,job 在此步失败;`uv.lock` 本 PR 未改动,main 上同样复现。 - **Verify / verify (pull_request) — run 1964:失败于基础设施启动。** 3 秒退出,日志为 `Bind for 0.0.0.0:5432 failed: port is already allocated`:与同一 push 触发的并行 run 争用宿主机 5432,尚未执行任何仓库步骤。 - **AI Review / review (pull_request) — run 1963:通过。** - 因 `pip-audit` 提前中止,CI 内的 Playwright 未执行;本地全量 Playwright 为 15 passed, 1 skipped(原附件用例按环境跳过)。 上述两项基线问题正由已开启的 **#12(fix(ci): 修复 Verify 数据库冲突和依赖审计失败)** 处理;未在本 PR 内删除检查、降低覆盖率或夹带无关 CI 修复。待 #12 合并后可将 main 合入本分支重跑 Verify。本 PR 不自动合并、不部署。
jianwel added 1 commit 2026-11-01 04:37:30 +00:00
Merge remote-tracking branch 'origin/main' into codex/deepseek-assistant-fix
AI Review / review (pull_request) Successful in 9s
Verify / verify (push) Successful in 3m49s
Verify / verify (pull_request) Successful in 4m0s
f9160ebcf2
Author
Owner

已合入最新 main(43d141e,含 #12 的 CI 修复与 amount_text),merge commit f9160eb,Verify 已转绿。

CI 实测(run 1971 push / 1973 pull_request,均 success)

  • ruff check / format --check:通过。
  • pytest:113 passed, 5 skipped;finance 覆盖率 89.64%(门槛 85%)。
  • npm run build:通过;pip-audit:No known vulnerabilities;npm audit:0 vulnerabilities。
  • CI 内 Playwright 实际执行:15 passed, 1 skipped,包含新增的 assistant.spec.ts(动态回答、对话新增列真实保存)与原 formula-export、workspace 回归。
  • AI Review:success。

合并后本地复核

  • 后端全量:113 passed, 5 skipped,89.64%。
  • Playwright 全量:15 passed, 1 skipped。
  • 真实 DeepSeek 复跑:回答 12.2s、追问 8.9s、列设计 4.8s、保存 201;查询本期 1000、基期 6000、差额 −5000(尾零已由 #12 的 amount_text 去除);工作簿含“收入成本差”;独立 /formula-design 2.4s。

按执行计划“不自动合并或部署”,本 PR 保持 open,等待你决定是否合入 main。

已合入最新 main(43d141e,含 #12 的 CI 修复与 `amount_text`),merge commit `f9160eb`,Verify 已转绿。 **CI 实测(run 1971 push / 1973 pull_request,均 success)** - `ruff check` / `format --check`:通过。 - `pytest`:113 passed, 5 skipped;finance 覆盖率 **89.64%**(门槛 85%)。 - `npm run build`:通过;`pip-audit`:**No known vulnerabilities**;`npm audit`:0 vulnerabilities。 - CI 内 Playwright 实际执行:**15 passed, 1 skipped**,包含新增的 `assistant.spec.ts`(动态回答、对话新增列真实保存)与原 `formula-export`、`workspace` 回归。 - AI Review:success。 **合并后本地复核** - 后端全量:113 passed, 5 skipped,89.64%。 - Playwright 全量:15 passed, 1 skipped。 - 真实 DeepSeek 复跑:回答 12.2s、追问 8.9s、列设计 4.8s、保存 201;查询本期 **1000**、基期 **6000**、差额 **−5000**(尾零已由 #12 的 `amount_text` 去除);工作簿含“收入成本差”;独立 `/formula-design` 2.4s。 按执行计划“不自动合并或部署”,本 PR 保持 open,等待你决定是否合入 main。
jianwel merged commit cfccd312db into main 2026-11-01 04:44:48 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jianwel/fa-agent#13