合同智能审批实战:LangGraph+HITL人机协同方案(附源码)
合同审核全流程:上传PDF或DOCX格式合同文件 → 系统自动完成文档解析,提取签约主体、合同金额、生效日期等核心字段 → AI引擎扫描潜在风险,按高、中、低三个等级自动分级 → 法务人员介入确认关键条款(高风险需逐条复核,中风险支持批量处理) → 最终生成完整的审核报告。
要解决什么业务痛点?
企业法务在合同审核中面临一个典型的结构性矛盾:业务量激增,人力配置捉襟见肘;审核深度要求高,项目积压如山。一份中等复杂度的合同,资深法务也需要投入 2至4小时;若强行压缩审核时间,条款遗漏风险便会急剧攀升。
完全依赖自动化路径同样行不通——合同条款包含大量模糊地带与商业意图,需要回溯业务部门确认,责任追溯要求明确“谁在何时基于何种判断作出了决策”。最终签字权绝不能交给AI模型,但让法务逐页手动搜索违约金条款,无疑是对专业资源的巨大浪费。
这套系统的核心目标可以概括为:将重复性、规律性任务交由机器处理,将需要专业判断与最终决策的关键节点留给人类。
| 业务痛点 | 传统应对方式 | 系统解决方案 |
|---|---|---|
| 手动抄录主体信息、查找金额 | 逐页人工翻阅 | 自动抽取关键字段,低置信度结果标黄人工核对 |
| 逐条排查风险条款 | 通读全文 | AI初筛后按高/中/低排序,支持双向定位原文 |
| 审核精力分散 | 所有条款无差别处理 | 三档路由分流,高风险强制人工逐条介入 |
| 审核中途被中断 | 进度难以接续 | 基于LangGraph中断/恢复机制,隔天可无缝续审 |
| 结论缺乏可追溯性 | 口头沟通或零散记录 | 每条决策完整落库并生成审计日志 |
| 对AI判断缺乏信任 | 不清楚AI依据 | 提供置信度评分与来源标签(规则引擎或AI推理) |
MVP阶段不涉及的应用场景:跨境多法域合同、强监管特大项目、律所对外法律服务——当前Agent能力范围尚无法覆盖这些复杂需求。
谁是核心用户?
| 角色 | 核心职责 | 使用频率 |
|---|---|---|
| 法务审核员(Reviewer) | 查看AI初筛结果,对高风险条款逐一执行批准、编辑或驳回操作,导出审核报告 | 每日高频使用 |
| 业务提交人(Submitter) | 上传合同文件、追踪审核进度,不参与审核决策 | 不定期使用 |
| 系统管理员(Admin) | 维护风险规则库、配置用户权限 | 低频维护 |
权限体系采用双层设计:前端路由守卫实现“防君子”的界面层控制,后端接口独立权限校验确保“防小人”——业务提交人无法访问审核页面,决策记录仅限授权角色查看。
具体需求是什么?
端到端流程清晰明确:上传PDF/DOCX文件 → 解析并提取字段 → AI扫描风险 → 分级路由 → 人工确认 → 生成报告。
拆解为四个MVP核心场景:
场景 1:结构化信息提取
上传后自动解析文本,通过LLM抽取签约主体、合同金额、生效日期、适用法律等字段;低置信度结果标黄,供人工快速核对。目标是将手动抄录主体信息的时间从20-40分钟压缩至分钟级。
场景 2:风险初筛与分级路由
对全文进行风险扫描,覆盖单边条款、违约金不对等、弹性表述等常见风险点;每条风险附带等级、置信度及原文锚点。路由规则如下:
- 低风险 → 自动放行,不进入人工审核流程
- 中风险 → 批量复核页面,支持勾选确认
- 高风险 → 强制中断流程,需逐条处理完毕方可继续
场景 3:人机协同(HITL)人工决策
双栏对照界面:左侧卡片展示风险描述与操作按钮,右侧原文区域高亮定位。提供三个选项:批准(认同AI判断)、编辑(调整风险等级或描述)、驳回(标记为误报)。高风险条款必须填写备注(不少于10个字符),严禁提供“全部同意”的批量操作按钮。
场景 4:审核报告生成
汇总AI初步判断与人工最终决策,包含覆盖范围声明(明确审核了哪些内容、未审核哪些内容)以及免责声明,支持导出PDF或JSON格式。
设计红线
基于业务调研与竞品分析提炼出的核心原则,已固化到Prompt与交互逻辑中,不容妥协:
- 高风险条款必须逐条人工处理,界面层不渲染任何批量操作按钮
- AI结论不得绝对化——使用“可能存在…风险”等表述,严禁出现“违法”或“审核通过”
- 报告必须包含覆盖范围声明,明确说明已审和未审的内容
- 规则触发与AI推理必须清晰区分(使用蓝标/紫标加以标识)
- 每步操作均可追溯——依赖审计日志(AuditLog)与检查点(Checkpointer)
- 不做完整CLM系统——聚焦“上传→审核→报告”核心链路,不涉及电子签章、模板库等模块
- 合同原文必须私有化部署,生产环境中不得以明文形式调用公网API
系统架构设计
总体设计思路
数据流:合同文件 → 持久化存储 → 解析/字段抽取 → 分段风险扫描 → 风险条目入库 → 人工决策(落库并记录审计日志)→ 校验 → 生成报告
控制流:采用LangGraph进行流程编排;在需要人工介入的节点调用 interrupt() 暂停流程;决策数据以数据库为准,Checkpointer仅负责流程状态续跑;当人工确认全部完成后,调用 Command(resume=...),经 resume_check 校验后再生成报告;前端通过SSE推送实时进度。
后端三大模块
上传模块:文件校验 → 持久化存储 → 创建 Contract / ReviewSession → 触发解析流程
↓
状态模块:LangGraph + interrupt/resume + SSE(决策落库,Checkpointer 辅助流程续跑)
↓
查询模块:ReviewItem / ExtractedField / ReviewReport / AudLog 提供前端数据读取
上传模块执行Magic Bytes校验、大小限制(50MB)、加密PDF拦截、扫描件标记等;解析与扫描解耦——解析过程在LangGraph图外部执行,避免解析失败干扰工作流状态。
技术栈选型
前端采用React + Vite;后端使用FastAPI;工作流引擎为LangGraph;模型调用DeepSeek(兼容OpenAI接口);数据存储采用SQLite;合同原件存储于服务器本地磁盘。
上传模块
校验 → 持久化存储 → 创建 Contract / ReviewSession → 触发解析
↓
状态模块
LangGraph + interrupt/resume + SSE(决策落库,Checkpointer 辅助续跑)
↓
查询模块
ReviewItem / ExtractedField / ReviewReport / AuditLog → 供前端读取
数据流(6个关键步骤)
- 上传文件,服务端校验格式与大小,合同原件持久化存储
- 解析过程提取文本,LLM抽取字段——在LangGraph图外部执行
- 解析完成后启动工作流:扫描节点逐段调用模型,生成ReviewItem
- 路由节点根据高、中、低风险等级决定分支路径(低风险直接跳过人工节点)
- 需要人工介入时调用
interrupt暂停流程——每条决策先落库、记录审计日志 - 高风险条款全部处理完毕后执行
resume,经resume_check校验,最终生成报告
① 上传 → ② 解析+字段抽取(图外执行,标记为黄色)→ ③ 启动工作流 scanning
→ ④ 路由节点(菱形判断)
├─ 高/中风险 → ⑤ interrupt 暂停等待人工(红色)
└─ 低风险 auto_pass ─────────────┐
⑤ ────────────────────────→ ⑥ resume + 报告生成(绿色)
核心业务逻辑解析
合同审核并非“一次模型调用即可完成”的同步任务,而是会暂停、会续跑、会分支的长流程——因此引入了LangGraph。竞品调研中,10家产品均采用“AI先行、人工确认”的模式,但跨天中断/恢复(interrupt/resume) 几乎无对标案例,这正是本项目最值得深入探讨的技术亮点。
人机协作机制
如果仅依赖 POST /review 同步等待至流程结束,法务下午审核到一半关闭页面,所有状态便会丢失。
LangGraph 的 interrupt() 能够将流程图冻结在指定节点,Checkpointer保存快照;下次通过 Command(resume=payload) 即可接着执行。每个审核会话拥有唯一的 thread_id,确保多合同实例不会混淆。
前端每一条决策写入数据库,同时记录审计日志——业务数据以数据库为准,Checkpointer仅解决流程状态续跑问题。待高风险条款全部处理完毕,服务层才会触发 resume。
人类兜底保障
模型仅负责识别并列出风险点,无权替代法务做出最终判断。Prompt严格限定:输出格式为JSON;风险描述使用“可能存在…”,禁止出现“违法”“审核通过”等绝对化表述。
界面呈现的是“待您确认的风险点”,而非“AI已做出的判决”。source_type 字段预置了规则引擎与AI推理两种来源标签——MVP阶段以模型推断为主,后续规则引擎接入后,来源将真正基于Playbook规则匹配。
自动化偏差(Automation Bias)防御
人机协同中最忌惮的是人类变成“橡皮图章”——界面上一键全过,底层全部同意。文档与代码中设置了多层拦截:
- 高风险页面不渲染批量操作按钮(DOM中根本不存在)
- 批准前备注必须不少于10个字符,原文高亮段落需进入视野
- 连续快速批准会触发警示弹窗
- 后端决策接口具备幂等校验,重复提交将被拦截
技术手段能够拦截一部分风险,但组织层面的培训仍需配套跟进。
三档路由规则
if high_count > 0:
route = "interrupt" # 双栏逐条审核
elif medium_count > 0:
route = "batch_review" # 批量勾选页面
else:
route = "auto_pass" # 直接生成报告
核心代码实现思路
工作流图设计
START → scanning → routing → human_review → resume_check → report → END
↘ auto_pass 跳过 human_review,直接进入 resume_check
builder.add_conditional_edges(
"routing_node",
route_after_routing,
{
"auto_pass": "resume_check_node",
"batch_review": "human_review_node",
"interrupt": "human_review_node",
},
)
开发阶段Checkpointer使用内存实现,服务重启会丢失状态;上线后需切换为数据库持久化方案。
人工介入节点
if route_result == "interrupt":
human_decisions = interrupt({
"review_type": "high_risk_review",
"session_id": state["session_id"],
"pending_item_ids": state.get("pending_item_ids", []),
"message": f"发现 {state.get('high_risk_count', 0)} 个高风险条款,请逐条审核",
})
return {"human_decisions": human_decisions}
前端每条决策写入数据库;服务层检查高风险条款是否仍有 pending 状态——全部处理完毕后才执行 resume:
def resume_workflow(thread_id: str, decisions_payload: list) -> dict:
graph = get_compiled_graph()
config = {"configurable": {"thread_id": thread_id}}
return graph.invoke(Command(resume=decisions_payload), config)
扫描执行逻辑
全文按段落切割(单段约800字符以内),MVP阶段逐段调用DeepSeek模型,解析返回的JSON结果并写入ReviewItem。API密钥通过 .env 管理,扫描与字段抽取共用 app/config.py 中的 get_llm():
def get_llm():
return ChatOpenAI(
model=settings.deepseek_model,
api_key=settings.deepseek_api_key,
base_url=settings.deepseek_base_url,
temperature=0.1,
)
前后端职责边界(概要)
| 层级 | 核心职责 |
|---|---|
| 前端 | 界面渲染、路由守卫、SSE事件订阅、防橡皮图章行为的UI约束 |
| 后端 | 业务规则执行、状态机管理、LangGraph编排、LLM调用、数据落库、审计日志记录 |
前端不直接调用模型;合同文件通过后端API上传,禁止经由浏览器直接传输至第三方服务。
界面效果展示
上传与字段抽取 — 低置信度字段标黄,供人工快速修正。
风险扫描进度 — 进度条通过SSE实时更新,后台逐段分析。
人工审核界面 — 高风险进入双栏逐条审核模式;仅含中风险时进入批量勾选页面。
报告输出 — 包含执行摘要、逐条清单、覆盖声明与免责声明,支持PDF/JSON格式下载。
合同列表 — 多份合同当前所处状态,一目了然。
从构思到可操作DEMO
- 先确立红线:人机协同、人类兜底——高风险逐条审核,模型仅提供提示、不下定论
- 梳理链路:上传与解析放在LangGraph图外执行;扫描、路由、人工、报告封装进工作流
- 构建规则库:将法务日常使用的Playbook整理进
RuleLibrary,关键词/正则优先匹配,模型仅扫描规则未覆盖的段落 - 打通interrupt/resume:参照LangGraph文档实现Checkpointer,确保跨天续审功能可用
- 确定交互设计:双栏对照、三档路由、来源标签(规则蓝标/AI紫标),参考市面产品但摒弃“一键全过”
- 连通后端:上传 → 解析 → 规则库 + 模型扫描 → interrupt → resume → 报告
- 联调前端:将页面假数据替换为真实接口,SSE推送扫描进度,状态栏与审核会话保持一致
- 用真实合同验证:分别评估规则命中率与模型误报率,将驳回数据回流用于规则优化
后期迭代规划
- 规则库引擎集成:基于Playbook的关键词/正则匹配,使
source_type真正区分规则与AI来源 - Checkpointer切换为数据库持久化方案
- 规则库引入Embedding语义匹配
- 加强扫描件OCR能力,识别错误时主动提醒
- 误报数据半自动回流,驳回数据进入规则优化队列
- 跨条款组合风险单独开辟知识图谱线,不与主流程绑定
- 生产环境模型私有化部署
特别说明
合同Agent不应急于替人做出判断,首先应当将“该停必须停”的流程机制固化到位。
合同审核与知识库问答存在本质差异。问答追求答案全面;而审批追求责任清晰、关键节点由人拍板、全程可追溯。首要任务是确保LangGraph闭环稳定运行,再将Playbook规则库逐步叠加。







