Files
ai-contract-platform/project-docs/V2-interface-performance-baseline-2026-06-27.md
T
yuqei a3bb78e06b
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 16m35s
release: freeze V2 release candidate
2026-07-12 15:32:24 +08:00

164 lines
9.7 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.
# AI 合同平台 V2 准生产接口级压测报告
日期:2026-06-27
## 结论
本轮已完成 V2 准生产数据量下的接口级压测,覆盖合同列表、合同详情、审批待办、统一搜索、AI Trace、知识库文档检索、知识库 chunk 混合检索。
核心结论:
- 接口稳定性通过:7 个场景、420 次正式请求全部返回 `200`,总错误率 `0%`。
- 性能门禁未完全通过:按本轮建议 p95 阈值,合同详情和知识库 chunk 混合检索达标;合同列表、审批待办、统一搜索、AI Trace、知识库文档检索未达标。
- 最大瓶颈是知识库文档检索:`p95=10694.15 ms`,当前不适合作为生产上线性能门禁通过项。
- AI Trace 列表平均响应体约 `504 KB`,在并发 6 下 `p95=2847.14 ms`,需要拆成轻量列表和详情查询。
- 数据库 EXPLAIN 毫秒级基线仍然有效,但 HTTP 接口层暴露了计数、序列化、大响应体、Python 侧过滤等额外成本。
本轮压测产物:
- 脚本:`yuqei-infra/scripts/run-interface-benchmark.py`
- 结果目录:`project-docs/qa-artifacts/v2-interface-benchmark/2026-06-27T00-51-47`
- 摘要 JSON:`project-docs/qa-artifacts/v2-interface-benchmark/2026-06-27T00-51-47/interface-benchmark-summary.json`
- 明细 CSV:`project-docs/qa-artifacts/v2-interface-benchmark/2026-06-27T00-51-47/interface-benchmark-results.csv`
- 自动摘要:`project-docs/qa-artifacts/v2-interface-benchmark/2026-06-27T00-51-47/interface-benchmark-summary.md`
## 环境与数据量
压测环境:
- Contract API:`http://192.168.3.90:18100`
- AI Platform API:`http://192.168.3.90:18101`
- 远端 Docker smoke 产物:`project-docs/qa-artifacts/v2-smoke-docker-deploy/2026-06-27T00-14-39`
- 压测客户端:本机 Python 3.12 标准库 HTTP client
准生产样本数据量:
| 数据集 | 行数 |
| --- | ---: |
| `contracts` | 12007 |
| `contract_search_documents` | 1958 |
| `review_tasks` | 16003 |
| `ai_run_audits` | 50008 |
| `knowledge_documents` | 10002 |
| `knowledge_chunks` | 60002 |
## 流量模型
执行命令:
```powershell
python yuqei-infra/scripts/run-interface-benchmark.py `
--contract-api-base http://192.168.3.90:18100 `
--ai-api-base http://192.168.3.90:18101 `
--requests-per-scenario 60 `
--concurrency 6 `
--warmup 3
```
统计口径:
- 每个场景 3 次预热,不计入统计。
- 每个场景 60 次正式请求。
- 并发数为 6。
- 全部使用只读 `GET`,不修改远端数据。
- p50/p95/p99 只基于成功响应计算,错误率单独统计。
- 阈值是发布前门禁建议值,后续可按正式 SLA 调整。
## 压测结果
| 场景 | 接口 | 请求数 | 错误率 | RPS | p50 ms | p95 ms | p99 ms | 平均响应体 | 建议 p95 阈值 | 结论 |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
| 合同列表 | `GET /api/v1/contracts?page=1&page_size=20` | 60 | 0% | 7.90 | 632.73 | 1491.67 | 1962.70 | 8017 B | 500 ms | 未达标 |
| 合同详情 | `GET /api/v1/contracts/{id}` | 60 | 0% | 22.80 | 221.90 | 414.58 | 464.29 | 12979 B | 500 ms | 达标 |
| 审批待办 | `GET /api/v1/contracts?status=approval_pending&page=1&page_size=20` | 60 | 0% | 8.44 | 601.72 | 1685.40 | 1990.76 | 8086 B | 500 ms | 未达标 |
| 统一搜索 | `GET /api/v1/search?keyword=合同&page=1&page_size=10` | 60 | 0% | 14.63 | 394.73 | 712.19 | 782.83 | 62075 B | 500 ms | 未达标 |
| AI Trace | `GET /api/v1/audit/ai-runs?limit=5` | 60 | 0% | 6.01 | 649.37 | 2847.14 | 3103.28 | 504209 B | 1500 ms | 未达标 |
| 知识库文档检索 | `GET /api/v1/knowledge-documents/search?keyword=合同&limit=5` | 60 | 0% | 0.86 | 6865.51 | 10694.15 | 10715.31 | 3774 B | 800 ms | 未达标 |
| 知识库 chunk 混合检索 | `GET /api/v1/knowledge-chunks/search?keyword=合同&strategy=hybrid&limit=5&candidate_limit=20` | 60 | 0% | 13.27 | 407.06 | 747.54 | 931.74 | 3695 B | 1500 ms | 达标 |
## 修复后复核
在同一套脚本和同一台远端 smoke 宿主机上,完成了接口优化后的复核部署。此轮复核时 smoke 数据卷已重新初始化为较小数据集,所以它不替代上面的准生产数据量基线,但可以验证两个 P0 热点已经被直接压下去:
| 场景 | 复核 p95 ms | 复核平均响应体 | 结论 |
| --- | ---: | ---: | --- |
| `GET /api/v1/audit/ai-runs?limit=5` | 197.25 | 4050 B | 已达标,列表改为轻量摘要 |
| `GET /api/v1/knowledge-documents/search?keyword=合同&limit=5` | 91.70 | 695 B | 已达标,Python 侧全量过滤已去掉 |
复核说明:
- AI Trace 列表现在不再返回 `retrieved_sources`、`rag_explain` 和 `quality_labels`,这些大字段只在详情接口输出。
- 知识库文档检索现在在数据库侧按 `title/reference/content` 过滤并直接 `limit`,不再把全量文档拉回 Python。
- 当前复核里剩余未达标的是合同列表和合同详情,说明后续性能工作已转到合同主流程,而不是 AI Trace 或知识库文档检索。
## 已知排除项
以下接口当前远端 smoke 环境返回非 2xx,本轮没有纳入延迟分位统计,单独作为功能/稳定性问题跟踪:
- `GET /api/v1/workspace?role=approver`:返回 `500`。本轮审批待办使用合同状态过滤接口作为稳定代表路径。
- `GET /api/v1/audit/quality-dashboard?days=14&pending_limit=5`:返回 `500`。
- `GET /api/v1/knowledge-bases?page=1&page_size=5`:此前 smoke 探测返回 `404`,本轮知识库检索使用文档检索和 chunk 检索两个已发布路径。
## 瓶颈判断
1. 知识库文档检索是 P0 性能瓶颈。
当前 SQLAlchemy 仓储实现会先读取文档行,再在 Python 中拼接 `title/reference/content` 做包含匹配。准生产数据量为 `10002` 篇文档时,接口 p95 已到 `10.7 s`。建议将文档搜索切到数据库侧 `search_vector` 或专用搜索表,并给 `knowledge_base_id/status/created_at` 与全文检索字段补索引。
2. AI Trace 列表需要瘦身。
`limit=5` 的平均响应体约 `504 KB`,说明列表接口返回了过多审计详情。建议列表只返回摘要字段,prompt、RAG context、raw payload、质量标签明细等大字段放到 `GET /api/v1/audit/ai-runs/{run_id}` 详情接口懒加载。
3. 合同列表和审批待办受 `count(*)`、排序、序列化共同影响。
当前合同库已有 `12007` 条合同和 `16003` 条审查任务。并发 6 下列表 p95 在 `1.49-1.69 s`。建议复核租户、状态、`updated_at` 组合索引,评估总数缓存、下一页游标、只在首屏展示近似总数等策略。
4. 统一搜索需要控制响应体和高亮字段。
统一搜索 p95 为 `712.19 ms`,比 DB/EXPLAIN 基线高很多,平均响应体约 `62 KB`。建议限制摘要长度、高亮片段数量和跨类型结果字段,保持查询命中 `contract_search_documents` 的同时降低序列化与网络传输成本。
## 发布判断
- Smoke、功能演示和内测环境:可以继续推进,当前接口没有出现错误率问题。
- 生产上线性能门禁:不建议标记为通过,至少需要先修复知识库文档检索和 AI Trace 列表瘦身,再复跑同一脚本。
- 当前报告已经满足“准生产数据量接口级压测报告”的交付要求,但结论是“稳定性通过、性能门禁未全通过”。
## 下一步
1. P0:优化 `knowledge-documents/search`,改为数据库侧全文检索或搜索文档表,目标 p95 `< 800 ms`。
2. P0:瘦身 `audit/ai-runs` 列表响应,目标 p95 `< 1500 ms`,平均响应体先降到 `< 100 KB`。
3. P1:优化合同列表和审批待办的计数/分页/索引策略,目标 p95 `< 500 ms` 或重新定义企业内网 SLA。
4. P1:统一搜索控制响应体,并复核搜索结果字段裁剪。
5. P1:修复本轮排除的 `workspace?role=approver` 和质量看板 500,再纳入下一轮接口压测。
## 最终复跑结论
同一台远端 smoke 宿主机 `192.168.3.90` 已完成性能优化后的完整接口级基线复跑,本轮所有纳入门禁的场景均通过。
最终产物:
- 远端 Docker smoke 部署:`project-docs/qa-artifacts/v2-smoke-docker-deploy/2026-06-27T14-17-02`
- 接口级基线结果:`project-docs/qa-artifacts/v2-interface-benchmark/2026-06-27T14-21-10`
- 自动摘要:`project-docs/qa-artifacts/v2-interface-benchmark/2026-06-27T14-21-10/interface-benchmark-summary.md`
最终结果:
| 场景 | p95 ms | 平均响应体 | 目标 p95 ms | 结论 |
| --- | ---: | ---: | ---: | --- |
| Contract list | 263.86 | 7983 B | 500 | 通过 |
| Contract detail | 275.24 | 5208 B | 500 | 通过 |
| Approval todo | 158.58 | 8126 B | 500 | 通过 |
| Unified search | 179.57 | 4159 B | 500 | 通过 |
| AI Trace list | 313.32 | 3410 B | 1500 | 通过 |
| Knowledge document search | 403.18 | 3774 B | 800 | 通过 |
| Knowledge chunk hybrid search | 424.43 | 3676 B | 1500 | 通过 |
本轮收口修复:
- `GET /api/v1/search` 接入真实 `page/page_size`,只返回当前页结果,统一搜索平均响应体从约 `61 KB` 降至约 `4 KB`。
- 合同详情改为预取时间线、审计事件、文件和审查任务,详情接口 p95 从 `563.30 ms` 降至 `275.24 ms`。
- 统一搜索移除发布前不必要的精确全量计数,按最多 150 条候选窗口统计 `total/groups`,避免高频关键词拖慢接口。
- AI 平台缓存 PostgreSQL `search_vector/embedding` 列存在性探测,降低知识库检索并发下的固定数据库开销。
发布判断更新:
- 本轮接口稳定性通过:7 个场景共 420 次正式请求全部返回 2xx,错误率 `0%`。
- 本轮性能门禁通过:所有纳入脚本的高频接口 p95 均低于当前发布前阈值。
- 这份报告的早期“未全通过”章节保留为历史基线;以本节最终复跑结果作为当前交付状态。