b76a2baad2
- Split landing page into public landing page and authenticated workspace - Extract contract generation logic into use-contract-generation hook - Extract contract generation service into sub-services - Add AI quality scoring for contract generation - Expand risk rules library with employment-specific rules - Add custom exception classes (NotFoundError, ValidationError, etc.) - Add prompt asset seeding script from LexForge documentation - Add format utility library - Fix SSR hydration mismatch on Ant Design inputs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
285 lines
13 KiB
Markdown
285 lines
13 KiB
Markdown
# AI 合同平台深度优化分析报告
|
||
|
||
**日期**:2026-05-29
|
||
**分析范围**:全栈代码审查(Backend FastAPI + Frontend Next.js + AI 服务集成)
|
||
**目标**:简化用户流程、优化不合理功能、提高合同生成质量与审查专业性
|
||
|
||
---
|
||
|
||
## 一、用户体验与流程简化(最高优先级)
|
||
|
||
### 1.1 合同生成页面过载 —— 一屏做完一切反而不好用
|
||
|
||
**问题**:`frontend/src/app/contracts/page.tsx`(~1358 行)在一个页面里塞了:模板选择 + 变量填写 + 预览 + 生成 + 下载 + 历史列表 + 生命周期 Modal + 自动审查展示。用户同时面对太多信息,认知负担大。
|
||
|
||
**建议**:
|
||
- 将"合同生成"拆为 **轻量引导式流程**:Step 1 选模板 → Step 2 填必填变量(隐藏高级选项)→ Step 3 预览 → Step 4 结果
|
||
- 历史记录从生成页移到独立的 `/contracts/history` 页面,或改为可折叠面板
|
||
- 生命周期更新操作从列表页撤掉,只留在详情页
|
||
|
||
### 1.2 审查详情页信息过载 —— 把运维信息暴露给了用户
|
||
|
||
**问题**:`frontend/src/app/reviews/[id]/page.tsx`(~1880 行)展示了大量用户不需要看到的技术细节:
|
||
- OCR 门禁状态、文本抽取模式、PDF 类型判定
|
||
- AI 运行证据(workflow_run_id, task_run_id, conversation_id)
|
||
- confidence_summary、structured_analysis 等内部评分结构
|
||
|
||
**建议**:
|
||
- **普通用户角色**只看:风险总览、条款摘要、审查意见、报告下载
|
||
- **管理员/开发者角色**可展开查看技术细节(通过角色判断或折叠面板)
|
||
- 将 OCR/AI Trace/Workflow State 归入"技术详情"折叠区域
|
||
|
||
### 1.3 入口分散且命名不一致
|
||
|
||
**问题**:
|
||
- 审查入口:`/review`(提交)、`/reviews`(列表)、`/reviews/[id]`(详情)
|
||
- 合同入口:`/contracts`(生成+历史)、`/contracts/[id]`(详情)
|
||
- 文档编辑:`/documents/new`、`/documents/[id]/edit`
|
||
- 首页 `/page.tsx` 同时展示公共页面和工作台,逻辑分支复杂
|
||
|
||
**建议**:
|
||
- 统一命名规范:审查类用 `/reviews/*`,合同类用 `/contracts/*`,文档类用 `/documents/*`
|
||
- 首页只做**角色感知的工作台**,去掉公共展示逻辑(Landing Page 和 Workspace 应该分开)
|
||
- 把 `documents/edit` 合并进 `contracts/[id]/edit`,减少路由碎片
|
||
|
||
### 1.4 前端状态映射大量重复
|
||
|
||
**问题**:`contracts/page.tsx`、`contracts/[id]/page.tsx`、`reviews/page.tsx`、`reviews/[id]/page.tsx` 四个文件中存在大量**完全重复**的 status → label/color 映射代码:
|
||
- `statusLabelMap`、`statusColorMap`、`riskLabelMap`、`riskColorMap`
|
||
- `lifecycleStatusMeta`、`dueStatusMeta`
|
||
- `formatDateTime`、`formatStatus`、`formatRisk` 等格式化函数
|
||
|
||
每种映射至少在 2-3 个文件中重复定义,维护时极易遗漏。
|
||
|
||
**建议**:
|
||
- 抽取共享模块 `frontend/src/lib/format.ts`
|
||
- 统一 label、color、formatter 函数,减少 ~300 行重复代码
|
||
|
||
### 1.5 生命周期状态更新体验差
|
||
|
||
**问题**:`contracts/page.tsx` 中通过 Modal 让用户逐个填写 `lifecycle_status`、`counterparty_name`、`owner_name`、`effective_at`、`expires_at`、`lifecycle_note`,全部是自由文本,没有业务规则引导。
|
||
|
||
**建议**:
|
||
- 改为**快捷状态流转**:把"已签署→履约中→即将到期→已到期→已终止→已归档"做成状态机,用户只需点选下一步
|
||
- 自动计算 `due_status` 和 `days_to_expiry`(后端已有),在界面上可视化提示
|
||
- 将相对方/负责人改为从已有数据下拉选择
|
||
|
||
---
|
||
|
||
## 二、合同生成质量优化
|
||
|
||
### 2.1 模板变量替换过于机械
|
||
|
||
**问题**:`backend/app/services/contract_generation_service.py` 中 `_replace_variables`(具体行号在 1800+)只做字符串替换。当变量值包含 HTML 特殊字符时,通过 `escape()` 转义但缺乏语义感知。
|
||
|
||
**建议**:
|
||
- 在 AI 增强生成时,把"模板草稿 + 变量值"整体交给 AI 做**自然语言融合**,而不是直接替换
|
||
- 引入占位检测后的**智能补全**:对 `请补充` 占位,自动根据上下文推断合理值(参考 missing_fields + legal_articles)
|
||
|
||
### 2.2 Generation Quality 评分标准可优化
|
||
|
||
**问题**:`_build_generation_quality_summary`(约 1104 行)的评分标准基于简单关键词正则匹配:
|
||
- `has_payment` = 检测"付款|价款|费用|服务费|租金|发票|结算|金额"
|
||
- `has_breach` = 检测"违约|赔偿|责任承担|违约金"
|
||
- 分数 = 100 - unresolved_variable_count × 20 - missing_field_count × 6 - ...
|
||
|
||
这种评分无法反映实际的合同法律质量。
|
||
|
||
**建议**:
|
||
- 增加 AI 评分维度:让 AI 对生成结果进行专业法律质量评分(条款完整性、措辞严谨度、风险覆盖度)
|
||
- 将质量评分结果与 auto_review 结果交叉验证
|
||
- 质量报告应输出**具体哪个条款质量不足**,而非笼统的"缺少付款条款"
|
||
|
||
### 2.3 AI 增强回退不够透明
|
||
|
||
**问题**:`generate_contract`(约 142 行)中 AI 增强失败时静默回退到模板渲染,仅在内嵌的 `enhancement_trace` 中记录。用户在界面上只能看到一个灰色的"AI回退"标签,看不到具体问题和影响范围。
|
||
|
||
**建议**:
|
||
- 当 AI 增强回退时,在界面上给出明确 Alert:
|
||
- 回退原因(模型超时?平台不可达?)
|
||
- 影响范围(哪些内容没有被优化)
|
||
- 建议动作(手动复核特定条款)
|
||
- 在合同详情页增加"建议 AI 重新增强"按钮
|
||
|
||
### 2.4 Auto Review 同步执行影响体验
|
||
|
||
**问题**:`generate_contract`(约 376 行)在合同生成后**同步**触发 auto_review,前端设置了 15 秒超时(`GENERATE_RECOVERY_TIMEOUT_MS`)。如果 auto_review 耗时长,用户可能以为生成失败。
|
||
|
||
**建议**:
|
||
- 合同生成成功后立即返回,auto_review 改为**异步后台任务**
|
||
- 前端轮询或 WebSocket 推送审查状态更新
|
||
- 用户看到合同生成成功后,可以继续操作,不会被审查阻塞
|
||
|
||
---
|
||
|
||
## 三、审查结果专业性优化
|
||
|
||
### 3.1 风险规则库过于基础
|
||
|
||
**问题**:`review_service.py` 中 `DEFAULT_RISK_RULES`(约 46 行)只定义了 5 条硬编码的关键词规则(违约金、自动续约、免责、保密、付款)。这些规则缺乏法律深度和场景区分。
|
||
|
||
**建议**:
|
||
- 按合同类型扩展规则库(服务合同 vs 采购合同 vs 劳动合同 vs 投资协议各有不同的风险点)
|
||
- 增加**风险联动分析**:如"付款条款没有验收前置条件"应该是一个跨条款风险
|
||
- 引入动态规则加载(从 review_rule 表读取),而非硬编码
|
||
|
||
### 3.2 条款分类仅靠关键词匹配
|
||
|
||
**问题**:`_classify_clause_type`(约 1137 行)基于 `keyword in title/content` 做简单打分。例如:
|
||
- "付款" 在标题中出现 +5 分,在内容中出现 +1 分
|
||
- 无法处理"本合同项下的服务费..."这种间接表述
|
||
|
||
**建议**:
|
||
- 结合 AI 做条款类型识别(少样本分类)
|
||
- 对"general"类型(无法分类的条款)做**二次扫描**,用语义相似度匹配已知条款类型
|
||
|
||
### 3.3 审查报告 PDF 格式简陋
|
||
|
||
**问题**:`build_report_pdf`(约 829 行)使用 ReportLab 的 `drawString` 逐行绘制纯文本 PDF。字体使用 `STSong-Light`,不支持富文本、表格、高亮、页眉页脚。生成的 PDF 更像一个文本转储,不适合对外交付。
|
||
|
||
**建议**:
|
||
- 使用 HTML→PDF 渲染引擎(WeasyPrint 或 wkhtmltopdf)
|
||
- 模板化报告:
|
||
- 封面页(合同名称、审查视角、总体风险)
|
||
- 风险汇总(带颜色标识的仪表盘)
|
||
- 每条风险项带原文引用+修改建议+法条依据
|
||
- 条款结构化摘要
|
||
- 支持中文字体嵌入,确保跨平台一致性
|
||
|
||
### 3.4 结构化审查报告未被充分利用
|
||
|
||
**问题**:`review_service.py` 中 `_enrich_review_result`(约 918 行)同时处理"远程 AI 返回的结构化报告"和"本地 Python 兜底"。当远程报告不可用时,本地生成的结构化数据(contract_structure, payment_milestones, clause_relationships)内容丰富但不展示给用户,造成浪费。
|
||
|
||
**建议**:
|
||
- 将 `contract_structure` 中的 `payment_milestones`、`clause_relationships`、`liability_carve_outs` 直接嵌入审查报告
|
||
- 在审查详情页增加**条款关系可视化**(谁依赖谁,谁可能冲突)
|
||
- 法条引用自动关联知识库中的全文链接
|
||
|
||
### 3.5 法条引用回溯链路不完整
|
||
|
||
**问题**:`_attach_legal_article_refs`(约 1717 行)通过关键词触发规则匹配法条,但 `LEGAL_ARTICLE_REFERENCE_RULES`(约 378 行)覆盖范围有限。对于新合同类型或非常见风险项,法条关联会缺失。
|
||
|
||
**建议**:
|
||
- 当规则匹配不到法条时,使用语义搜索(向量检索)从 knowledge_base 或 legal_article 表中查找最相关法条
|
||
- 审查结果中展示法条引用的**置信度**和**匹配原因**
|
||
- 法条全文应可一键查看(已有 `detail_path` 字段,但前端展示不突出)
|
||
|
||
---
|
||
|
||
## 四、后端代码架构优化
|
||
|
||
### 4.1 服务类过于庞大
|
||
|
||
**问题**:
|
||
- `ContractGenerationService`:3058 行
|
||
- `ReviewService`:3282 行
|
||
|
||
两个类承担了过多职责:
|
||
- ContractGenerationService = 模板管理 + 变量替换 + AI 增强 + 导出 + 生命周期 + 版本管理 + 任务管理 + 自动审查
|
||
- ReviewService = 任务创建 + 文件解析 + OCR + 规则审查 + 报告生成 + PDF 生成 + 法条匹配
|
||
|
||
**建议**:
|
||
- 拆分 ContractGenerationService:
|
||
- `ContractTemplateService`(模板查询、变量解析)
|
||
- `ContractAIGenerationService`(AI 增强调用)
|
||
- `ContractExportService`(导出/下载/格式转换)
|
||
- `ContractLifecycleService`(生命周期+版本+任务)
|
||
- 拆分 ReviewService:
|
||
- `ReviewTaskService`(任务创建、重试、状态管理)
|
||
- `ReviewDocumentService`(文件解析、OCR、文本抽取)
|
||
- `ReviewRuleEngine`(规则匹配、风险分析、条款分类)
|
||
- `ReviewReportService`(报告生成、PDF 渲染)
|
||
|
||
### 4.2 管理端和用户端混合
|
||
|
||
**问题**:
|
||
- `contracts.py` API(约 636 行)同时暴露用户接口和管理接口(如 lifecycle management、version management、audit logging 耦合在一起)
|
||
- 前端 same page 同时渲染用户和管理员功能
|
||
|
||
**建议**:
|
||
- API 层保持薄,把管理操作和用户操作在 service 层分开
|
||
- 前端通过角色判断分离渲染逻辑
|
||
|
||
### 4.3 硬编码常量分散
|
||
|
||
**问题**:前端 4 个页面重复定义 `lifecycleStatusOptions`、`riskColorMap` 等。后端的 `CONTRACT_TYPE_HINTS`、`CLAUSE_TYPE_DEFINITIONS`、`PAYMENT_TRIGGER_HINTS` 等常量在 `review_service.py` 顶部占约 400 行。
|
||
|
||
**建议**:
|
||
- 后端将领域常量移到 `legal_domain_registry.py`(已有部分,还不够)
|
||
- 后端新增 `/api/v1/meta/constants` 接口,前端首次加载时拉取
|
||
- 前端统一使用 `frontend/src/lib/constants.ts`
|
||
|
||
### 4.4 错误处理不一致
|
||
|
||
**问题**:
|
||
- 部分方法抛出 `HTTPException`(同步)
|
||
- 部分返回 `None` / `{}`(如 `get_review_detail`)
|
||
- 部分在异常时返回空列表/默认值
|
||
|
||
**建议**:
|
||
- Service 层统一使用自定义异常类(如 `ContractNotFoundError`),API 层统一捕获并转 HTTPException
|
||
- 避免混合使用 `None` 返回和异常抛出
|
||
|
||
---
|
||
|
||
## 五、前端性能与代码质量
|
||
|
||
### 5.1 页面组件过大
|
||
|
||
**问题**:
|
||
- `contracts/page.tsx`:1357 行
|
||
- `contracts/[id]/page.tsx`:1282 行
|
||
- `reviews/[id]/page.tsx`:1879 行
|
||
- `reviews/page.tsx`:507 行
|
||
- `page.tsx`(首页):554 行
|
||
|
||
**建议**:
|
||
- 将页面拆分为 5-6 个逻辑组件(如 `TemplateSelector`、`VariableForm`、`PreviewPanel`、`AutoReviewSummary`)
|
||
- 提取业务逻辑到自定义 hooks(`useContractGeneration`、`useReviewDetail`)
|
||
|
||
### 5.2 API 调用模式可优化
|
||
|
||
**问题**:当前使用 `messageApi` 处理所有成功/失败反馈,缺少统一的请求状态管理。多个页面各自实现 loading/error/empty 状态。
|
||
|
||
**建议**:
|
||
- 封装通用 `useApi` hook:`const { data, loading, error, execute } = useApi(apiFunction)`
|
||
- 统一错误处理:自动兜底 message、默认空状态、重试逻辑
|
||
|
||
### 5.3 路由跳转参数编码复杂
|
||
|
||
**问题**:`buildReviewChatHref`(约 459 行)手动构造复杂的 JSON payload 并 encodeURIComponent,容易出错且难以调试。
|
||
|
||
**建议**:
|
||
- 使用 Next.js searchParams 构建器
|
||
- 或使用共享状态(zustand store)传递上下文,而非 URL
|
||
|
||
---
|
||
|
||
## 六、优先级建议
|
||
|
||
### P0 — 立即修复(用户体验阻塞项)
|
||
1. 拆分合同生成页面,减少信息密度
|
||
2. 审查详情页默认隐藏技术细节
|
||
3. 前端常量和格式化函数去重
|
||
4. 生命周期状态改为状态机快捷操作
|
||
|
||
### P1 — 重要改进(质量与专业性)
|
||
1. 审查报告改用 HTML→PDF 模板引擎
|
||
2. 扩展风险规则库,覆盖更多合同类型
|
||
3. 合同生成质量引入 AI 专业评分
|
||
4. auto_review 改为异步,不阻塞生成流程
|
||
|
||
### P2 — 深度优化(架构与可维护性)
|
||
1. 拆分超大 Service 类
|
||
2. 统一错误处理模式
|
||
3. 后端领域常量集中管理和 API 化
|
||
4. 前端组件化和 hooks 抽取
|
||
|
||
---
|
||
|
||
## 七、总结
|
||
|
||
当前系统的功能完整度非常高,覆盖了合同审查、生成、生命周期管理、法条知识库、治理流程等全链路。核心瓶颈已经从"功能缺失"转向了"信息密度过高"和"交互体验不细腻"。
|
||
|
||
**核心优化方针**:减少用户每次需要处理的信息量,把专业能力藏在背后,让界面只呈现用户当前步骤需要的、可行动的内容。
|