ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

中小项目AI原生落地实践:从合同审核助手看系统重构

中小项目AI原生落地实践:从合同审核助手看系统重构 上半年我帮一家做供应链 SaaS 的客户落地了一个合同审核助手需求倒不复杂销售上传合同后系统先自动抽关键条款再给出风险提示。但真正做完我才意识到这个项目最大的难点不在模型选型也不在提取准确率而在于整个系统的数据流、交互方式和评估逻辑是不是从一开始就按“AI 原生AI-native”的方式来设计的。如果还是按照老思路先建好数据库、画好表单、定好流程最后再想办法把 AI 塞进某个角落那这套系统做完大概率还是“老系统 一个 Chatbot”的缝合怪用不起来、迭代不动、也说不清楚到底值多少钱。这篇文章我想用这个真实项目作为主线把 AI-native 在中小型项目里怎么落地这件事讲透。我会先拆解 AI-native 的核心概念和判断标准然后给出一套适合中小团队的三级改造路径再用完整的实操案例演示关键模块怎么设计、代码怎么写、评估怎么做最后整理一份常见问题排查清单。适合谁看一句话你手头有真实业务场景想用 LLM 重构或新建一个系统但不想照搬大厂那套“AI 平台 中台 全链路观测”的重型玩法。中小型项目有自己的活法这篇文章就是讲活法的。1. AI-native 是什么不是标签而是数据流与架构假设的重构1.1 两个系统之间的本质差异很多人一听到“AI-native”第一反应是“用了大模型就是 AI-native”。这个理解差得很远。用大模型做一个“智能问答机器人”挂在网页右下角这叫 AI-added把大模型当作核心业务流程里不可替换的一环让系统从需求分析、数据建模到异常处理都围绕“模型推理 概率输出”这个前提来设计这才叫 AI-native。我习惯用一个判断标准来区分在系统运行过程中如果某一天模型服务挂了这个系统还剩下多少价值传统系统加上 AI 能力之后模型挂了系统退化成原来的样子照样能跑但 AI-native 系统如果模型不可用核心业务基本停摆因为它从一开始就没打算用“确定性规则”去实现那些能力而是把所有关键路径都建立在模型的判断之上。这个差异落到数据流上就非常具体。传统系统的数据流是“用户输入 - 结构化存储 - 规则处理 - 固定输出”整个链路是确定性的每一步都有明确的数据结构。AI-native 系统的数据流是“非结构化输入 - 模型推理 - 结构化中间结果 - 多步工具调用 - 生成式输出”中间充满了概率性判断和不确定分支所以它的关键命题变成了“怎么让不稳定的推理尽量稳定地服务于业务”。1.2 AI-native 系统的四个识别特征我给 AI-native 系统提炼了四个可操作的特征中小型项目可以直接拿来做体检维度传统系统AI-native 系统数据流入库优先先结构化再处理推理优先边理解边结构化交互范式表单驱动用户按系统设定路径操作对话/意图驱动系统理解用户后再引导架构假设输入完整、逻辑确定、输出可控输入模糊、上下文动态变化、输出需要校验评估方式单元测试 / 规则判定数据集评测 规则判定 用户反馈闭环大部分人误以为 AI-native 是交互层面的变化比如把表单换成聊天窗口。但本质上变化最大的是“架构假设”。传统系统假设“用户的输入总是完整的”所以表单会强制校验“合同编号必填”而 AI-native 系统假设“用户的输入往往是残缺的、模糊的”所以它需要模型主动判断“缺了合同编号我可以先从合同文本里抽抽不到再问用户”。这个假设差异决定了系统的容错设计、数据建模方式、甚至数据库表怎么建。1.3 一个“AI 增强”与“AI-native”的直观对比为了说清楚这个区别我拿“合同信息录入”这个场景举例。传统做法销售手工填写表单把合同名称、客户名、金额、付款条件一项项输入系统用校验规则检查格式通过后入库。如果要做“智能化”就在表单旁边加一个“AI 识别合同”按钮点击后 OCR 识别并自动填充。这个流程看起来很智能但它仍然是 AI-added——AI 只是个输入加速器系统的核心仍然是表单和数据库。AI-native 的做法销售直接把合同文件拖进对话框说一句“帮我登记这份合同重点看付款条件和违约金比例”。系统先把合同读进来抽取结构化字段再生成摘要让销售确认确认后直接入库同时自动触发后续的风险检查流程。如果模型抽到的字段置信度偏低系统会自动追问而不是默默接受或直接失败。整个体验的核心是“对话 自动判断”表单退居二线只作为确认界面存在。这两套方案用户感受到的差异是“我在填表”还是“系统在帮我干活”。但对开发者来说更关键的差异是前者只需要一个 OCR 接口而后者需要你重新设计输入接口、设计提示词链路、设计字段抽取的置信度阈值、设计追问策略——这些才是 AI-native 工程的核心工作量。2. 中小型项目的落地路径三级改造策略2.1 认清现实为什么大厂玩法在中小项目跑不通大厂做 AI-native 往往是从基础设施开始自建模型推理平台、建设向量数据库集群、搭建完整的 RAG 链路、做 prompt 全生命周期管理、搞模型网关和 fallback 机制。这套东西当然有价值但对一个几十人团队、两三个后端、一个前端的中小型项目来说这是灾难。等你把平台搭好业务需求早就变了老板也会失去耐心。中小型项目做 AI-native 落地核心策略是“识别度优先重做最核心的三件事”第一把容易用自然语言表达、又依赖规则判断的流程找出来用模型替换掉一部分原本用 if-else 写死的逻辑第二把每一轮“人机协作”的数据回流到评测集和提示词资产里让系统自己越用越聪明第三把交互入口从表单为主改成“对话 表单兜底”用最低成本实现体验代差。这三件事我分成三个改造层级中小团队可以从 Level 1 逐步往上走不必一次性全做到。2.2 Level 1流程级 AI 化改造把规则判定替换成模型判定第一个层级只做一件事找出系统里“看起来有规律、实际上极其依赖上下文”的环节把硬编码的规则替换成模型调用。举个例子一个工单系统里最常见的“工单分类”功能传统做法是写一个关键词匹配表匹配“登录”“密码”“闪退”“白屏”等关键词来打标签。这套规则看着简单实际上维护成本极高——关键词会不断膨胀两个关键词同时出现时还要定义优先级。用模型替换之后分类逻辑变成“把工单标题和内容一起丢给模型让它根据预设的分类体系输出一个类别”。这个改造看起来很浅但它触及了 AI-native 的第一个核心命题承认业务输入是模糊的规则无法穷尽用模型的语义理解能力去处理剩余不确定性。这一段的关键是不要贪心。不要想着一步到位替换所有模块而是先从两三个“明确产出可校验”的场景开始比如工单分类、客户意向分级、简历初筛、文章标签生成。这类场景的特点是输出结果有限、错误代价较低、人可以很快复核。改造完成后再把旧的规则代码留在旁边做 fallback模型识别不了的或置信度低的落回规则。2.3 Level 2数据回流与知识资产化让每一轮交互沉淀价值第二个层级是很多人会忽略、但恰恰是 AI-native 系统能否持续进化的分水岭建立数据回流机制。传统系统里用户每一次点击和提交都会进入数据库但这些数据大多只服务于统计报表。AI-native 系统要求你多做一个动作把每一次“人机协作”的原始输入、模型输出、用户修正结果记录下来并转换成可以用于下一次迭代的资产。这个资产有三个形态一是评测数据集把用户修正过的正确答案沉淀为标准样本让每次 prompt 调整都有据可依二是提示词模板变量把高频出现的业务词汇、条款模板、规范化表述提取成可复用的上下文片段三是工具调用的“成功案例”把一次顺畅的多步操作记录下来作为后续自动化的候选模板。举一个具体的例子。我在合同审核项目里初期让销售手动标注“这条违约金条款是否有问题”模型输出的审核结论经常和人工结论不一致。后来我把每一次人工修正结果存进一个 review_log 表每周导出一批修正样本再让大模型重新概括出那些“容易被误判的条款模式”把概括结果写回系统提示词里。两周后模型在“含重复违约金表述”这类条款上的判错率明显下降。这就是数据回流带来的复利效应——没有这一步AI 系统的效果就会一直卡在一个平台上不去。2.4 Level 3交互界面重构从表单驱动到对话驱动第三个层级是最有感知度的改造也是“AI-native”这个词最常被联想到的部分把核心业务入口从表单改成对话。但这一步在中小型项目里不应该盲目上马我的经验是“先选一条用户最痛的主路径做对话化保留表单作为高级模式”。什么叫主路径就是用户使用频率最高、操作步骤最冗余、信息填写最费劲的那条流程。拿报销系统举例传统流程是填报销单 - 选类型 - 填金额 - 上传发票 - 填事由 - 提交 - 审批。对话化之后变成用户把发票照片和一句“这周去上海出差的车费和住宿费总共2800”丢进来系统自动识别发票、自动填写字段、生成事由摘要用户确认后提交。这里的核心难点已经不在模型能力而在于你怎么设计“对话状态”。用户说一句话系统怎么知道当前需要向用户要什么信息这需要你给对话流程画一个状态机初始状态需要字段 A 和 B当模型从输入中抽到 A 但没抽到 B 时追问 B两个字段都齐全后进入确认状态。这个状态机不必复杂但对中小团队来说它是把 AI 从“玩具”变成“生产力工具”的关键一步。3. 核心实操一个合同审核 Assistant 的完整落地过程3.1 需求定义不要一上来就想做“全自动”我在开始做这个项目时客户一开始的需求是“全自动审合同有风险就拒绝”。这个需求非常危险。合同审核是高度依赖业务规则的场景十个法务有十一种判断标准指望一个模型全面替代人工几乎必然翻车。所以我们把目标重新定义为AI 在 30 秒内输出合同风险摘要和重点条款标注人工负责最终审核决策。这个目标看起来保守但实际使用时销售只需要在提交合同前花一分钟看 AI 摘要就能规避掉七八成明显风险客户价值已经很可观了。需求确定之后我们把整个系统拆成四个核心模块文件解析模块负责读 PDF/Word 并转成干净文本、信息抽取模块从文本里抽合同方、金额、付款条件、违约金、知识产权、保密义务等字段、风险判定模块根据预设的规则 模型推理产出风险点和严重级别、报告生成模块输出结构化审核意见和摘要。这里有一个经验模块的边界一定要按“输入输出是否清晰”来划分而不是按技术栈来划分。每个模块的输入都是明确的数据结构输出也是明确的数据结构这样即使某个环节的模型换掉其他模块也不受影响。3.2 文件解析与文本清洗的坑文件解析看起来简单实际是翻车高发地。PDF 里提取出来的文本往往有大量换行符、表格乱序、页眉页脚混入正文等问题。如果直接把这种文本丢给模型抽取结果大概率会跑偏。我当时的处理方案是三段式清洗第一段用 PyMuPDF 抽取文本块保留每个文本块在页面上的坐标信息这样至少能区分标题和正文第二段用正则做基础清洗把连续换行合并成段落去掉页眉页脚匹配页码附近的固定文本第三段用一个便宜的模型做“文本重构”把碎片化的段落按语义拼成完整的条款块并标记“第X条”这样的结构信息。第三段是我强烈推荐的做法。不要指望单纯的解析库能完美处理所有排版用一次轻量模型调用把“杂乱文本”处理成“结构化条款块”后续的抽取质量和稳定性都会大幅提升。实测下来这个步骤让后面信息抽取模块的准确率提升了 5 到 8 个百分点。3.3 信息抽取用 Pydantic 模型锁死输出格式信息抽取是整个 AI-native 系统最核心的一环。我的做法是定义好输出的 Pydantic 模型然后让大模型严格按照 JSON Schema 输出结构化结果。我定义的核心字段如下节选from pydantic import BaseModel, Field from typing import List, Optional class ContractField(BaseModel): field_name: str value: Optional[str] None confidence: float Field(..., ge0.0, le1.0) start_index: Optional[int] None end_index: Optional[int] None class ContractEntity(BaseModel): contract_party_a: Optional[str] None contract_party_b: Optional[str] None contract_amount: Optional[float] None currency: Optional[str] None payment_terms: Optional[str] None late_fee_rate: Optional[str] None ip_ownership: Optional[str] None confidentiality_period: Optional[str] None class ContractRisk(BaseModel): risk_type: str severity: str # low, medium, high clause_reference: str description: str suggestion: str class ContractExtractResult(BaseModel): entity: ContractEntity risks: List[ContractRisk] missing_required_fields: List[str]用 Pydantic 模型有两点好处一是给模型一个极其明确的“输出契约”模型知道你要什么字段、字段的类型是什么、可选还是必填输出稳定性明显好于“自由文本 正则提取”二是后续你可以在 Pydantic 模型上直接加校验逻辑比如金额字段必须大于零、日期必须是合法日期不符合就触发重试或人工复核。调用的时候我建议用函数调用function calling或者结构化输出接口而不是让模型返回一大段 JSON 字符串再自己解析。原因很简单字符串解析在“恰好少了一个大括号”的情况下会让整个链路崩掉。现在主流模型都支持结构化输出尽量用官方能力不要自己去写 JSON 修复逻辑。3.4 风险判定规则与模型组合的“双保险”风险判定模块我的设计思路是“规则打底 模型兜底”。纯规则的问题是误报率高纯模型的问题是漏报率高。组合起来的效果远好于任何单一方案。具体逻辑是这样的第一步用正则规则扫描全文本命中“违约金”“知识产权”“保密期限”“自动续约”等敏感关键词时生成一批“候选风险点”第二步把候选风险点连同上下文一起交给模型让模型判断这个风险是否成立、严重级别是多少、对应的合同条款原文是什么第三步如果模型给出的风险点里有规则没覆盖到的、但语义上确实是高风险的情况也一并补充进来。这里我踩过一个坑一开始把风险级别全交给模型判断结果模型把“违约金比例偏高”判成 high把“管辖法院约定在对方所在地”判成 low而业务方恰恰觉得后者风险更大。后来我改了一版在 prompt 里给了业务方提供的“风险分级指引表”明确列出什么情况算高、什么情况算中、什么情况算低并把之前人工审核的案例作为小样本附在 prompt 里。这样调整之后风险级别的判定结果才基本符合业务预期。3.5 提示词管理别再把提示词写在代码里做 AI-native 项目提示词就是核心代码。如果不做管理项目进行到第三周的时候你会发现自己根本不敢改提示词——改了不知道会影响到哪些场景测试也没有覆盖出了问题回滚都难。我的做法是把所有提示词按模块拆成独立的 markdown 文件放到项目里的 prompts 目录通过代码加载。每个提示词文件里包含 system 指令、业务背景、输出格式说明、示例few-shot。文件名带版本号或日期比如contract_risk_judge_v20240512.md。代码加载时读取当前目录下的最新文件这样每次修改都有记录可查。更重要的是变量管理。不要在主提示词里写死业务字段名所有动态内容通过模板变量注入。我的模板变量表大致是这样变量名内容来源典型更新频率{{business_rules}}业务方提供的审核规则每月{{example_cases}}人工审核修正后的样本每周{{clause_templates}}行业常见的条款模板不定期{{user_input}}当前待审核的合同文本每次调用{{extracted_entities}}上一轮抽取的结构化字段每次调用这样设计的好处是每次提示词迭代都有清晰的“改动面”可以针对变量单独做 A/B 测试而不是整段提示词盲调。4. 工具选型与最小可用架构4.1 中小型项目选型的三条原则我见过不少中小团队在 AI 工具选型上“用力过猛”买了三套向量数据库接了两家模型 API还自建了一个推理服务最后运维都成问题。选型的第一原则是能租不建能省则省。中小型项目没有海量并发没有极端安全合规要求大部分场景直接用模型厂商的 API 就足够了自建推理服务充分没必要。第二个原则是先跑通再扩展。不要因为向量检索很火就一上来就搭 RAG。如果你的场景里上下文基本都在一两页文档内那直接“把全文塞进 prompt 结构化抽取”就够用了。只有当你发现上下文长度不够、或者需要跨大量文档召回相关内容时才是有必要引入检索的时候。第三个原则是避免过度抽象。很多团队上来就做一个“AI Agent 框架”定义一堆抽象的 Tool、Memory、Plan 接口结果业务还没跑通框架倒写了一个月。我更推荐用轻量的编排代码直接写流程先跑通业务在代码里发现重复模式后再抽象。这个顺序反了项目很容易在架构的自我陶醉中流产。4.2 我当前推荐的中小型项目技术栈这套组合是我在几个项目里反复验证过、维护成本比较低的技术栈环节推荐方案理由模型 APIGPT-4o 或 Claude 按需选便宜模型处理清洗类任务推理能力集中在核心模块成本可控结构化输出模型自带 function calling / JSON Schema 模式避免自己写解析器稳定可靠文件解析PyMuPDF pdfplumber 轻量模型文本重构兼顾免费和准确率编排框架LangGraph 或直接 Python 代码流程根据团队熟悉度选不强求框架数据库PostgreSQL 存业务数据 JSONB 存抽取中间结果一个库解决日常需求别急着上向量库数据回流定时脚本从业务表汇总结论到评测集简单直接不引入额外组件Prompt 管理本地 markdown 文件 git 版本管理可追溯、易回滚适合小团队评测pytest LLM-as-judge 批量跑回归集自动化程度高不用人肉打分这套组合的优点是没有一个组件是“非它不可”的重型依赖任何一个环节都可以替换。而且整个系统的复杂度是可解释的——出了问题你知道去哪里看日志知道是哪个环节失败。4.3 自建模型推理平台先冷静一下接上一节我把“自建推理模型”单独拿出来说一句。很多中小团队看到“AI-native”就觉得自己得搞一套私有大模型数据不能出内网推理要自己部署。这个想法可以理解但大多数情况下是被供应商忽悠了。真正的需求往往是“数据隐私”和“可控性”。如果只是数据不出内网你可以用私有化部署的开源模型比如 Qwen 系列 72B 量化版跑相对简单的抽取任务核心判断任务仍然可以走云 API如果有更严格的合规要求那就用私有化模型 规则兜底做整套系统。但自建推理平台的运维成本GPU 监控、模型更新、并发调度绝不是中小型团队能轻松承担的。我的建议是除非你有明确的合规红线或者你的场景里模型调用量已经大到云 API 成本无法接受否则不要自建。中小型项目的第一要务是让业务跑起来而不是让基础设施看起来很酷。5. 常见问题与排查技巧实录5.1 模型输出跑偏这是第一个要解决的问题AI-native 系统最常见的崩溃方式就是模型给你输出了“看起来合理、实际完全不对”的内容。我总结了几类高频症状和对应的排查思路症状现象排查方向字段幻觉抽出了合同里根本没有的金额是否在 prompt 里要求“只能从原文中抽取”是否加了 start_index 回溯校验风险误判把常规条款判为高风险是否提供风险分级指引是否有足够多的人工修正样本做 few-shot格式不稳定同一次调用输出时而 JSON 时而文本切换成结构化输出接口不要用自由文本解析漏字段必填字段没被抽出检查抽取提示词里的字段清单是否忘了枚举全部必填字段针对字段幻觉我有一个屡试不爽的兜底方法要求模型对每个抽取字段同时返回原文位置索引 start_index 和 end_index然后在代码里用这个索引区间去合同原文里切出一段文字校验这段文字和抽取结果是否语义一致。如果 index 对不上或者原文切片里根本没有这个值就判定为幻觉触发重试或标记为“需人工确认”。这个方法对“金额”“日期”“公司名”这类可定位的字段非常有效。5.2 评测数据从哪来没有评测集的 AI 系统就是盲飞很多中小团队做 AI 应用靠的是开发过程中“随手试几条”。模型看起来效果不错就上线了结果线上翻车。原因很简单——你用手工测的几十条数据根本不具备代表性而且你也没有回归机制改了一个提示词可能旧功能就莫名变差了。我建议在项目启动的第一天就建一个评测集。当时我从客户那边要了 30 份历史合同覆盖销售合同、采购合同、保密协议、外包协议等不同场景每份合同都找业务方人工标注了“正确抽取结果 高风险条款”。这个评测集前期不要求精只要求覆盖尽量多的场景。每次改动提示词或模型参数就跑一遍评测集算字段抽取准确率和风险判定召回率。跑评测的方式不需要太复杂。早期可以用规则比较 LLM-as-judge 结合字段类的用精确匹配或者语义相似度风险点类的用“模型判断两个风险描述是否指同一问题”。测试框架直接用 pytest每个用例是一个独立测试函数失败用例会打印出“模型输出”和“期望结果”的对比这样一眼就能看出改了什么导致退化。5.3 上下文管理无节制地塞 prompt 会让效果适得其反有些人觉得 prompt 越长越好把合同全文、几十条业务规则、十几个示例全塞进去。模型能接受长上下文但注意力会被稀释反而在关键字段上表现变差。我的经验是当前场景真正需要的信息远比你想象得少。在合同审核这个项目里业务规则几十条但针对某一类型的合同可能只需要十几条。所以我在实现时做了规则预筛先根据合同类型通过文件名或首段识别从规则库里选出相关的规则子集只把子集放进 prompt。示例也是每个类型只给 2 到 3 个高相似度的示例。这么处理后prompt 从几千字降到一千字左右模型输出的稳定性和准确率都提升了。如果你确实需要处理超长文档不推荐一次性全文塞入。先做章节定位把最可能包含目标信息的段落挑出来再送进模型。这比盲目追求长上下文和 RAG 都更实用。5.4 数据回流做不好系统就永远停在及格线最后一个高频问题就是前文反复提到的数据回流。很多团队把 AI 功能上线之后就再也不碰了系统效果始终停留在上线的水平。等到业务方觉得“这 AI 不太聪明”又开始怀疑模型能力不行然后换模型、换平台问题依然在。我自己的体会是AI-native 系统的效果不是一锤子买卖而是持续迭代出来的。每次业务方修正一个错误判定就是一次免费的标注数据每次用户追问“为什么是高风险”就是一次 prompt 优化的方向每次模型输出被手动编辑就是一次评测集的扩展。如果你把这些东西都扔了那 AI 系统永远不会成长。所以我在合同审核项目里最后做的一件事是在后台加了一个“人工复核记录”模块。业务人员在审核报告里点“接受”或“修改”时所有修改会被记录到一张表里。每周跑一个脚本把这周的修改记录汇总成一份新评测集同时自动抽取几条“修改前后差异较大”的样本补充到提示词的 few-shot 里。坚持了一个月后模型的风险判定准确率从最初的 71% 提升到了 86%而且“高风险误报”的数量也明显减少。这才是 AI-native 系统“越用越聪明”的真正来源。回看这个项目我最大的感受是AI-native 对中小型项目来说并不意味着全面推翻重来也不意味着必须买最贵的模型、搭最重的基建。它真正改变的是你如何在设计系统的每个决策点上都把“不确定性”和“反馈闭环”考虑进去。这件事说起来抽象做起来也很细碎但只要把数据流、评测集、提示词资产这三件事从第一天就抓好中小团队完全可以用比想象中低得多的成本做出比“老系统加 AI 按钮”高一个维度的产品。我自己在下一个项目里也会更早一点把用户反馈回流机制放进核心路径而不是等上线后再补。
返回列表