- 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>
13 KiB
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、riskColorMaplifecycleStatusMeta、dueStatusMetaformatDateTime、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.pyAPI(约 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 状态。
建议:
- 封装通用
useApihook:const { data, loading, error, execute } = useApi(apiFunction) - 统一错误处理:自动兜底 message、默认空状态、重试逻辑
5.3 路由跳转参数编码复杂
问题:buildReviewChatHref(约 459 行)手动构造复杂的 JSON payload 并 encodeURIComponent,容易出错且难以调试。
建议:
- 使用 Next.js searchParams 构建器
- 或使用共享状态(zustand store)传递上下文,而非 URL
六、优先级建议
P0 — 立即修复(用户体验阻塞项)
- 拆分合同生成页面,减少信息密度
- 审查详情页默认隐藏技术细节
- 前端常量和格式化函数去重
- 生命周期状态改为状态机快捷操作
P1 — 重要改进(质量与专业性)
- 审查报告改用 HTML→PDF 模板引擎
- 扩展风险规则库,覆盖更多合同类型
- 合同生成质量引入 AI 专业评分
- auto_review 改为异步,不阻塞生成流程
P2 — 深度优化(架构与可维护性)
- 拆分超大 Service 类
- 统一错误处理模式
- 后端领域常量集中管理和 API 化
- 前端组件化和 hooks 抽取
七、总结
当前系统的功能完整度非常高,覆盖了合同审查、生成、生命周期管理、法条知识库、治理流程等全链路。核心瓶颈已经从"功能缺失"转向了"信息密度过高"和"交互体验不细腻"。
核心优化方针:减少用户每次需要处理的信息量,把专业能力藏在背后,让界面只呈现用户当前步骤需要的、可行动的内容。