一、本周工作概述

第七周已经完成 Prompt 模板版本化、本地 RAG 知识库和合同优化闭环。第八周的重点是在这些基础能力上继续扩展业务功能,让系统中更多 AI 模块真正使用模板、Prompt 和 RAG,而不是各自独立拼接提示词。本周主要围绕智能合同生成、模板管理、风险审查和摘要提取展开。

在第八周之前,智能合同生成功能虽然可以选择模板并调用 AI 生成合同,但模板数量较少,且生成结果会直接保存为合同,用户缺少确认和编辑机会。对于合同这种正式文本,AI 第一次生成的内容通常还需要人工检查,包括主体、金额、履行期限、交付标准、违约责任等关键事实是否正确。如果生成后立刻入库,会让合同台账中混入未经确认的草稿。

因此本周首先扩充模板管理,新增了 15 种以上默认合同模板,并将模板种子放入 template-seeds.json,保证队友拉取代码后也能共享模板数据。然后改造智能合同生成流程,把原来的“生成即保存”改成“生成预览、人工编辑、点击保存”。在后端实现上,新增 /api/contract/generate-preview 和 /api/contract/save-generated 两个接口,前者只负责调用 AI 生成草稿,后者才真正创建合同主数据、字段值和初始版本。

本周还把第七周建立的 Prompt 和 RAG 能力接入风险审查与摘要提取。风险审查页面和摘要提取页面新增选择已有合同、选择版本、载入正文功能,用户不再只能粘贴文本或上传文件。后端风险审查使用 risk_analyze-v2 Prompt 模板和知识库召回,摘要提取使用 summary_extract-v2 Prompt 模板和知识库召回。这样,合同生成、合同优化、风险审查、摘要提取四条主要 AI 链路都开始使用统一的 Prompt/RAG 技术路线。

二、模板管理扩充

模板是智能合同生成的主约束。如果没有模板,AI 只能根据用户自然语言需求自由发挥,生成结果结构不稳定,也容易遗漏关键条款。合同模板提供了标题、条款结构、占位符和动态字段,使 AI 生成结果更接近正式合同。

本周新增了 template-seeds.json,把默认模板从数据库手工维护改为代码资源共享。当前模板覆盖了买卖合同、房屋租赁合同、软件开发服务合同、保密协议、通用服务合同、技术服务合同、劳动合同、借款合同、委托代理合同、建设工程施工合同、采购合同、运输合同、设备租赁合同、股权转让协议、数据处理协议等类型。

每个模板不仅包含合同正文,还包含字段配置。例如软件开发服务合同模板中包含项目名称、开发范围、里程碑计划、交付物、验收标准、付款节点、知识产权归属等字段。前端根据字段配置动态渲染表单,用户填写后,后端会将基础字段和动态字段一起传给合同生成服务。

模板在智能生成中的定位类似知识库,但又不完全相同。模板是合同生成的结构主约束,决定合同应该有哪些章节和字段;RAG 知识库是补充参考,帮助模型完善条款表达、风险控制和行业习惯。生成时应优先遵守模板结构,再参考知识库片段。

三、智能合同生成预览与保存分离

本周对智能合同生成做了一个重要调整:生成结果不再直接保存,而是先生成预览。后端新增 generatePreview 方法,负责读取模板、校验字段、构造知识库查询、召回 RAG 片段、渲染 generate_contract-v2 Prompt,并调用模型生成合同正文。

核心流程如下:

public GenerateContractPreviewResponse generatePreview(GenerateContractRequest request) { GenerateContractPreview preview = buildPreview(request); return new GenerateContractPreviewResponse( request.contractName(), preview.generatedContent(), preview.promptVersion() ); }

真正保存时,前端会把原始生成请求和用户编辑后的正文一起提交:

@Transactional public GenerateContractResponse saveGenerated(SaveGeneratedContractRequest request) { GenerateContractRequest generateRequest = request.generateRequest(); ContractTemplate template = templateRepository.findById(generateRequest.templateId()) .orElseThrow(() -> new IllegalArgumentException("模板不存在")); validateRequiredFields(templateFields, generateRequest.fields()); ContractInfo contract = saveContractInfo(generateRequest, template); saveFieldValues(contract.getId(), templateFields, generateRequest.fields()); ContractVersion version = saveInitialVersion( contract.getId(), request.content(), request.changeSummary() ); contract.setLatestVersionId(version.getId()); contractInfoRepository.save(contract); return buildGenerateResponse(contract, version, request.content()); }

这段逻辑体现了一个重要设计:AI 生成内容和合同入库动作分离。generate-preview 只产生草稿,不改变业务数据;save-generated 才写入合同主表、字段值表和版本表。前端也配合增加了可编辑结果区域和保存按钮,用户可以在保存前修改 AI 生成的合同正文。

生成 Prompt 的构造也从简单拼接升级为模板渲染:

PromptRenderResult prompt = promptTemplateService.render("generate_contract", Map.of( "input", userPrompt, "templateName", template.getTemplateName(), "templateCategory", template.getCategory(), "retrievedKnowledge", knowledge ));

其中 knowledge 来自 KnowledgeContextService,内部会调用 RAG 召回服务。这样生成过程同时使用模板、字段、用户要求和知识库片段,比单纯交给 AI 自由生成更可控。

四、风险审查接入Prompt模板和RAG

风险审查在第六周已经完成了低误报 Prompt 和人工复核闭环,但 Prompt 仍主要由 RiskPromptBuilder 构造。第八周将风险审查正式接入 Prompt 模板版本化和 RAG。

前端层面,风险审查页面新增了合同选择区域。用户可以选择已有合同,再选择版本,点击“载入正文”后,系统会调用合同详情或版本详情接口,把指定版本的正文填入文本输入区。这样用户可以直接对台账中的合同进行审查,不必复制粘贴。

后端层面,风险审查服务新增了 RagRetrievalService 和 AiPromptTemplateService 依赖。执行审查时,系统先根据合同正文构造查询词,召回付款、验收、违约、解除、争议解决等相关知识片段,再渲染 risk_analyze 模板。

关键代码如下:

String preparedContractText = prepareContractText(contractText); String ragContext = buildRagContext(contractText); PromptRenderResult prompt = promptTemplateService.render(PROMPT_CODE, Map.of( "contractText", preparedContractText, "ragContext", ragContext, "input", riskPromptBuilder.buildUserPrompt(preparedContractText, ragContext) )); String aiResult = aiChatService.chatWithPrompt( prompt.systemPrompt(), prompt.userPrompt(), "risk", prompt.promptVersion() );

risk_analyze-v2 的提示词重点约束三点:第一,只识别真实存在且能够引用合同原文的风险;第二,区分实质风险和一般优化建议,避免过度审查;第三,输出固定 JSON 结构,包括风险分类、风险等级、置信度、原文片段、风险描述和修改建议。

五、摘要提取接入Prompt模板和RAG

摘要提取也进行了类似升级。前端新增合同选择和版本选择功能,用户选择后可直接载入合同正文并生成摘要。提交摘要时,前端会把 contractId、versionId 和 contractText 一起传给后端。后端原有逻辑已经支持通过合同 ID 和版本 ID 读取正文,本周重点是补齐 Prompt 模板和 RAG。

摘要服务中新增了如下调用:

String preparedContractText = prepareContractText(contractText); String ragContext = buildRagContext(contractText); PromptRenderResult prompt = promptTemplateService.render(PROMPT_CODE, Map.of( "contractText", preparedContractText, "ragContext", ragContext, "input", summaryPromptBuilder.buildUserPrompt(preparedContractText, ragContext) )); String aiResult = aiChatService.chatWithPrompt( prompt.systemPrompt(), prompt.userPrompt(), "summary", prompt.promptVersion() );

摘要召回查询围绕主体、金额、日期、付款、违约责任、履行期限和证据等关键词展开。summary_extract-v2 要求模型返回合同主体、关键金额、关键日期、违约责任、一句话摘要、当事人数组、金额数组、日期数组、义务数组、责任数组、风险提示和证据字段。

摘要提取使用 RAG 的目的不是让模型从知识库中编造合同信息,而是帮助模型识别“应该抽取哪些要素”。所以 Prompt 中明确要求:原文没有的信息返回空字符串、空数组或 null,所有 sourceText 必须来自合同原文。这个约束对摘要质量很重要,因为摘要任务最怕模型为了完整而补写不存在的事实。

六、RAG和直接AI调用的差异

经过第七周和第八周的改造,合同生成、合同优化、风险审查和摘要提取已经与之前“直接交给 AI”有明显区别。

直接 AI 调用通常只有用户输入和简单任务说明,模型自由度很大,输出容易受上下文长度、措辞和模型状态影响。现在的实现增加了三类约束。

第一类是模板约束。智能生成以合同模板为主线,模板决定章节结构和必填字段。模型负责补全和润色,而不是凭空决定合同框架。

第二类是 Prompt 约束。每个任务有独立 Prompt 版本,明确角色、任务边界、输出格式、禁止编造、字段要求和 JSON Schema。这样输出更容易解析,也更方便比较版本效果。

第三类是 RAG 约束。知识库片段提供合同条款完整性、示范文本结构和风险控制要点。模型可以参考这些知识完善表达,但不能替代用户输入的事实。

在实际检验时,可以查看 ai_call_log。如果调用记录中的 prompt_version 是 generate_contract-v2、polish_contract-v2、risk_analyze-v2 或 summary_extract-v2,并且 user_prompt 中包含知识库参考片段,就说明当前功能已经走了 Prompt/RAG 链路,而不是旧的直接 AI 调用。

七、本周总结

第八周的工作让第七周建立的 AI 基础能力真正覆盖到主要业务流程中。模板管理不再依赖少量手工数据,而是通过 template-seeds.json 提供可共享的默认模板库;智能生成不再生成即落库,而是先预览再人工确认保存;风险审查和摘要提取不再只能粘贴文本,而是能够选择已有合同版本;这些功能都开始统一使用 Prompt 模板和 RAG。

从技术理解上看,本周最大的体会是:AI 合同系统的稳定性来自多层约束,而不是单次模型能力。模板保证结构,Prompt 保证任务边界,RAG 保证参考知识,版本管理保证历史可追溯,人工保存保证业务数据可信。只有这些机制组合起来,系统才更接近一个可维护的智能合同平台,而不是一个简单的大模型调用页面。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐