ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

DeepSeek低资源训练:政务政策问答的LoRA微调与部署全指南

DeepSeek低资源训练:政务政策问答的LoRA微调与部署全指南 简介这是一份面向政务信息化人员、数据工程师及大模型初学者的技术参考文档围绕“DeepSeek低资源训练实现政策智能问答”展开针对政务系统查询效率低、数据利用不足等痛点系统讲解从模型原理、低资源训练策略到智能问答系统搭建与评估的完整路径。资源为1个PDF文件压缩包共1.99MB包含31页完整内容涵盖数据增强、迁移学习、模型压缩、多轮对话、系统测试及政务场景案例适合用于快速建立技术框架并指导初步实践。文档目录清晰、内文与图表显示正常目前已有167人学习使用是了解DeepSeek在政务场景落地的实用入门资料尤其适合需要兼顾有限算力与政策问答需求的读者参考。1. 低资源训练让政策智能问答落地DeepSeek打通政务系统的最后一公里反复会看到一种尴尬场面政务系统想上政策问答采购单里写着“基于大模型”落实到机房却发现能批下来的算力最多是一两张消费级显卡甚至只有纯CPU节点数据又不能出内网线上API想都不用想。DeepSeek低资源训练正是为这类场景准备的——它不追求千亿参数而是把DeepSeek系列里几十亿参数的蒸馏模型拿来做LoRA微调再配合4bit量化让政策智能问答在政务内网这台“穷机器”上真正跑起来。这套方案适合两类人一类是要给政务系统做升级的开发和实施工程师另一类是负责选型、要评估“值不值得投入”的技术负责人。读完你至少能回答三个问题为什么能省钱、训练数据怎么造、上线后怎么验收。2. 为什么是DeepSeek加LoRA政务问答的三个硬约束与选型账2.1 政务场景的硬约束数据不出域、卡不多、答错要担责做政务系统的项目实施别先画功能大饼得先看机房里有什么。这是我在多个地市政务项目里见到的共性问题政务内网与互联网物理隔离政策原文、办件数据一律不许出域私有化部署是硬要求算力采购流程长多数项目起步阶段连一张A100都等不到能用的往往是一两张RTX 4090或国产加速卡最要命的是问责机制回答必须严谨、可溯源窗口人员照着答案念错了条款责任划分立刻出问题。这三个硬约束叠在一起排掉了两类方案。一类是直接调公有云大模型API不管效果多好数据出域这一条就把路堵死另一类是在内网部署千亿级开源模型且不说显存能不能放下单是推理时延和运维成本就够团队喝一壶。剩下的路就很清晰在本地部署一个参数量在7B到8B级别的模型用政策数据微调让它在“专有知识”上变专业。而DeepSeek恰好是这个级别里开源生态最完整的系列之一从基座模型到蒸馏版本都有社区工具链成熟低资源训练这件事才变得可操作。提示这里说的“低资源”有两层意思。一是训练阶段低资源用LoRA只微调少量参数不用全参微调二是推理阶段低资源把模型量化到4bit左右CPU或低显存卡也能跑。两层同时满足政务机房那台老服务器才有戏。2.2 基座选型用蒸馏小模型而不是千亿级大模型选基座模型第一步不是比谁的榜单分数高而是算“显存账”。把常见候选列出来看模型参数量4bit量化后推理显存QLoRA训练显存batch1适合场景DeepSeek-R1-Distill-Qwen-1.5B1.5B约1GB约4GB配置极低的边缘盒子只做关键词式问答DeepSeek-R1-Distill-Qwen-7B7B约4.5GB约10至12GB地市级政务问答主力DeepSeek-R1-Distill-Llama-8B8B约5.5GB约14GB需要更强推理能力的省级业务域DeepSeek-R1-Distill-Qwen-14B14B约9GB约20GB以上多业务域合并训练对硬件有要求为什么选蒸馏模型而不是原版DeepSeek-V3或R1原版是MoE架构推理时虽然只激活部分参数但全部专家权重都要驻留显存几百GB的权重文件在政务机房基本没有落地可能。蒸馏版本的做法是用R1这类强模型生成大量高质量思维链数据把推理能力“浓缩”进7B或8B的小模型里。对政策问答来说7B模型在本地化部署后回答质量和响应速度的平衡是目前最合适的。我自己踩过1.5B的坑它能把“哪类人员可以申请公租房”这类直白问题答对但一遇到“我父亲在老家交社保我在本市工作能否按家庭为单位申请”这种带条件的追问就开始胡编条款。所以除非设备实在不行否则建议直接上7B或8B档。2.3 低资源训练的账LoRA加4bit量化能把7B模型压进民用卡低资源训练的核心技术组合是LoRA加量化这笔账要算清楚。先看LoRA。全参微调7B模型光是把FP16权重加载进显存就需要约14GB再加优化器状态和梯度单卡24GB也紧张。LoRA的做法是冻结原始权重矩阵W只在旁边插入两个低秩矩阵A和B训练时只更新AB这部分新增参数量通常只有原模型的0.5%到1%。数学上权重更新量ΔW被分解成ΔW BAB是m×r矩阵A是r×n矩阵秩r取8到64。这样要存的梯度就小得多了。再看量化。模型权重默认是FP16每个数字占2字节4bit量化后每个数字只占0.5字节权重显存直接缩到四分之一。QLoRA就是在4bit基座上做LoRA训练时把量化权重反量化到BF16做前向计算梯度只传给LoRA参数反向传播不需要更新量化底模。这样7B模型的底模权重压缩到约3.5GB加上LoRA梯度和激活值10GB到12GB显存就能训练。我一般会建议刚接触的团队直接跑QLoRA别去折腾全参微调。全参在效果上限上确实更高但政务项目最怕的是“训到一半机器挂了没人会救”。QLoRA的训练体系成熟调参简单失败成本低对政策问答这类垂直任务和全参的差距并没有想象中大。3. 政策问答数据集怎么造从PDF原文到带出处的训练样本3.1 政策PDF抽取文字版、扫描版与表格版的分流处理训练模型之前你得先有数据。政务政策文件最常见的形态就是PDF但PDF和PDF之间的区别比人和狗还大。一上来就写通用抽取脚本大概率翻车。第一类是文字版PDF文本可以直接选中复制这种最省事。用pdfplumber逐页提取即可代码不复杂import pdfplumber with pdfplumber.open(policy_2024_001.pdf) as pdf: pages_text [] for page in pdf.pages: text page.extract_text() if text: pages_text.append(text) full_text \n.join(pages_text) # 基础清洗去掉页眉页脚和孤立页码 lines [ln.strip() for ln in full_text.splitlines() if ln.strip()] cleaned_lines [] for ln in lines: if ln.isdigit() and len(ln) 4: # 跳过纯页码 continue if len(ln) 8 and (部门 in ln or 印发 in ln): # 页眉特征 continue cleaned_lines.append(ln) policy_text \n.join(cleaned_lines)用pdfplumber而不是pypdf是因为它对文字版PDF的版面还原更好能保留换行和分段结构这对后续切分问答片段很重要。页眉页脚要去掉否则模型会把“XX市人力资源和社会保障局”当成政策正文的一部分生成答案时容易串味。第二类是扫描版PDF整页是图片extract_text抽出来是空的。这种必须先OCR常见做法是接PaddleOCR把每页图片转成文字。有一点要注意扫描件的识别结果往往夹杂“红头”“印章”等干扰词OCR后必须人工抽检一页确认文本顺序没有乱。第三类是表格版PDF很多政策附件是“申请条件一览表”“补贴标准表”直接用extract_text会把表格拆得七零八落。常见做法是用pdfplumber的extract_table按单元格提取再把表头和数据行拼成“字段:值”的文本结构。抽完文本后还有一道关键工序把长政策文档按“章-节-条”切块。切块不是简单按长度截断而是根据“第X条”“第X章”这类标题层级定位每个切块控制在500到1000字左右。这样后面做问答对生成时每一轮给模型的材料才足够聚焦不然把整份一万字的政策灌进去生成输出质量会明显下降。3.2 让大模型当“标注员”用DeepSeek API批量生成问答对有了切好的政策片段接下来要生成“问题-答案”对。人工写太慢一条条写几千条能写到崩溃。常见做法是用DeepSeek API当标注员让大模型读片段、出问答题再人工抽检。别觉得这是绕路这其实就是行业里说的“数据蒸馏”用强模型生成弱模型的训练语料。这里演示一个最直接的调用方式不需要额外装SDKrequests就够了import requests import json API_URL https://api.deepseek.com/chat/completions API_KEY sk-你的key def generate_qa(policy_chunk: str, n: int 3) - list: system_prompt ( 你是一名政务政策标注员。根据给定的政策原文片段生成若干个问答对。 要求1) 问题来自真实办事场景覆盖条件、材料、流程、时限 2) 答案只能使用原文信息不得推断 3) 答案末尾标注依据的政策条款编号 4) 问题不要出现‘根据原文’这类表述。 ) user_prompt f政策片段\n{policy_chunk}\n\n请生成{n}个问答对输出JSON数组每个元素包含question和answer两个字段。 resp requests.post( API_URL, headers{Authorization: fBearer {API_KEY}, Content-Type: application/json}, json{ model: deepseek-chat, messages: [ {role: system, content: system_prompt}, {role: user, content: user_prompt}, ], temperature: 0.3, max_tokens: 1024, response_format: {type: json_object}, }, timeout60, ) resp.raise_for_status() content resp.json()[choices][0][message][content] return json.loads(content)[qa_pairs]几个参数值得说清楚。temperature设为0.3是让模型在“稳定”和“多样”之间取平衡太高容易生成一些原文里没有的虚构政策max_tokens给1024一个问答对几百字足够了response_format指定json_object是为了后面解析方便少写一堆正则清理代码。至于DeepSeek API如何调用这类问题上面这个请求体就是标准形态唯一要确认的是你的账号有余额并且网络策略允许访问该API。生成完的问答对不能直接用先做两轮清洗。第一轮是规则去重用字符串相似度剔除重复问题比如“申请公租房需要什么材料”和“公租房申请材料有哪些”保留一个即可。第二轮是人工抽检我一般要求抽检比例不低于10%重点看两类错误答案是否纯粹来自原文、条款编号是否正确。宁可每天少生成一点也别让错误口径混进训练集。3.3 转成训练格式Alpaca JSONL与System提示词设计清洗完的问答对要转成微调框架认识的格式。目前最通用的是Alpaca格式的JSONL每条样本是system、instruction、input、output四个字段。但政策问答和通用指令微调不太一样我建议把“政策依据”放到output的末尾而不是单独开一个字段。直接上转换脚本import json def convert_to_alpaca(qa_pairs: list, policy_scope: str) - list: samples [] for item in qa_pairs: samples.append({ system: ( f你是{policy_scope}的政策智能问答助手。 回答必须基于提供的政策条款禁止编造。 如果问题超出政策范围回复‘该问题不在当前政策覆盖范围内’。 答案末尾必须标注依据条款编号。 ), instruction: item[question], input: , output: item[answer], }) return samples qa_data generate_qa(policy_chunk, n3) samples convert_to_alpaca(qa_data, 本市住房保障) with open(policy_qa_train.jsonl, w, encodingutf-8) as f: for s in samples: f.write(json.dumps(s, ensure_asciiFalse) \n)为什么system提示词要写成上面这样因为政务问答模型最容易犯的错就是“过度热情”用户问一句“房子漏水找谁”模型答出一大段保障房政策。把“禁止编造”和“超出范围要拒答”写进system就是在训练阶段给模型立规矩。另外不同的基座模型对system字段的处理能力不一样Qwen系列的ChatML模板对system的支持较稳用DeepSeek-R1-Distill-Qwen做底模时这个字段的设置会被保留到后续部署的提示词模板中所以值得认真写。3.4 把“出处”写进答案政策问答数据和其他语料的本质区别普通的大模型微调数据答案讲清楚就行。政策问答不行答案里必须带出处这是政务项目能验收通过的底线。我训练数据里的标准答案长这样用户问申请保障性租赁住房需要满足哪些条件 模型答申请保障性租赁住房需要满足以下条件1申请人及共同居住人在本市无自有住房2家庭人均收入低于上年度城镇居民人均可支配收入的1.3倍3在本市稳定就业且连续缴纳社保满12个月。依据《XX市保障性租赁住房管理办法》第八条、第九条。注意最后一句“依据第X条、第X条”。这句话不是装饰它承担两个作用一是训练阶段让模型学会把答案和条款编号绑定降低编造概率二是上线阶段让质检人员能一键核对答案有没有依据、依据对不对。如果训练数据里50%的答案不带出处模型生成时也会偷懒质检就会变成无头悬案。这里有个血的教训我见过一个项目只用问答对训练没在数据里约束出处结果模型答得头头是道一查条款全是自己编的整个验收被推翻重来。所以造数据时宁可每个片段只生成两三条高质量问答也别贪多求快把“出处”这个字段做成硬约束。4. DeepSeek低资源微调实操训练、合并、量化、部署一条龙4.1 选训练框架LLaMA-Factory还是unsloth数据和格式都备好了进入训练环节。低资源微调DeepSeek系列市面上常见做法有两个LLaMA-Factory和unsloth。两者都是开源工具选哪个取决于你的环境和习惯。LLaMA-Factory的优势是“全家桶”从数据处理、LoRA训练、合并导出到GGUF量化一条命令全部覆盖对新手极其友好。它支持DeepSeek-R1-Distill系列配置文件一改就能跑而且导出阶段能直接产出Ollama能用的GGUF文件。unsloth的优势是训练速度快、显存占用更低它把Attention和RoPE做了内核级优化在消费级显卡上训练7B模型速度能比标准实现快20%到30%而且支持在训练中动态调整LoRA权重。但从项目可维护性角度看我一般推荐LLaMA-Factory理由很简单政务项目交接时接手的团队大概率没跑过unsloth但LLaMA-Factory的文档路径清晰出了问题上搜索引擎一查就是一条龙。4.2 训练配置与启动一份可直接改的QLoRA参数表下面这份配置是我多次调过的基线显存12GB左右就能跑7B模型。先建一个YAML文件# lora_train.yaml model_name_or_path: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B dataset: policy_qa_train.jsonl template: qwen finetuning_type: lora lora_rank: 16 lora_alpha: 32 target_modules: all learning_rate: 2e-4 num_train_epochs: 3 per_device_train_batch_size: 1 gradient_accumulation_steps: 8 gradient_checkpointing: true optim: adamw_torch lr_scheduler_type: cosine warmup_ratio: 0.1 max_seq_length: 1024 quantization_bit: 4 output_dir: output/policy-lora logging_steps: 10 save_steps: 200逐项说参数。lora_rank设为16是LoRA低秩矩阵的秩政务问答数据集通常就几千条rank不用太大16足够太大反而容易过拟合lora_alpha设为32是缩放系数一般取rank的两倍这个比例在多数任务上表现稳。learning_rate用2e-4LoRA微调的学习率通常比全参微调高一到两个数量级太低学不动、太高震荡。num_train_epochs设3轮政策数据量小训练轮数过多会出现“背答案”现象。per_device_train_batch_size1配合gradient_accumulation_steps8等效批量大小为8显存压力却小很多。gradient_checkpointing必须开它是用计算换显存关掉的话12GB显存很可能直接OOM。max_seq_length设1024政策问答里问题和答案一般都在几百字内1024足够设太长会成倍放大显存占用——这是新手最容易忽略的一个坑。quantization_bit: 4就是QLoRA的4bit量化训练。启动训练只有一条命令llamafactory-cli train lora_train.yaml训练日志里重点看两个指标loss是否在下降、显存占用是否稳定。如果loss在第二个epoch后还明显下降说明数据没学完可以适当加轮数如果loss降得很低但验证集效果差就是过拟合了要回调rank或加大数据量。4.3 合并LoRA权重并导出GGUF训练完成后LoRA适配器是“附加”在原模型上的不能直接用。要合并回基座模型变成独立权重。LLaMA-Factory一条命令搞定llamafactory-cli export \ --model_name_or_path deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \ --adapter_name_or_path output/policy-lora \ --template qwen \ --export_dir output/policy-merged \ --export_size 4--export_size 4表示导出4bit的GGUF文件这是给llama.cpp/Ollama用的格式。如果服务器显存充足想把精度留高一点也可以去掉这个参数导出FP16的原始权重部署时再自己量化。建议第一次跑通流程时直接导出Q4文件小、部署快验证有效后再回去调精度。这一步有个常见误区有人直接在训练时留下的4bit量化底模上合并。不建议这么干LoRA最好在FP16基座上合并再统一量化否则精度损失叠加回答质量下降明显。换句话说训练用量化是为了省显存但合并时尽量用原始精度。4.4 用Ollama或vLLM部署并发不大用Ollama并发大用vLLM合并出的GGUF文件最省事的部署方式是用Ollama。先写一个ModelfileFROM ./policy-merged-Q4_K_M.gguf TEMPLATE {{- if .System }} |im_start|system {{ .System }}|im_end| {{- end }} |im_start|user {{ .Prompt }}|im_end| |im_start|assistant PARAMETER temperature 0.3 PARAMETER top_p 0.7 PARAMETER num_ctx 2048然后依次执行ollama create policy-qa -f Modelfile ollama run policy-qa 异地就医备案需要准备哪些材料TEMPLATE里那段|im_start|是Qwen基座的ChatML模板必须和训练时用的template保持一致否则模型会输出一串奇怪的“system token”而不是正常回答。这一步如果发现输出格式乱了先检查这里。用curl调HTTP接口也很简单curl http://localhost:11434/api/generate \ -H Content-Type: application/json \ -d {model:policy-qa,prompt:异地就医备案需要准备哪些材料,stream:false}Ollama的接口是OpenAI兼容的所以上位系统接入很方便。常见做法是在政务内网做一个API网关把Ollama封装成内部服务再对接政务APP、办事大厅自助终端或企业微信政务版。开发调试时VSCode里很多AI插件也能直接填这个本地地址等于日常办公也能复用这套模型。如果并发要求高比如省级平台同时几百个请求Ollama的调度能力会吃紧这时候用vLLM部署DeepSeek更合适。vLLM支持Continuous Batching能把多请求的推理过程合并吞吐量高出一个数量级。vLLM加载的是HF格式权重也就是--export_dir导出的未量化版本或FP16版本启动命令大致是vllm serve output/policy-merged \ --served-model-name policy-qa \ --tensor-parallel-size 1 \ --max-model-len 2048在政务场景我先说结论并发低于20的窗口端应用Ollama足够要支撑几十路并发直接上vLLM。别一上来就用vLLM它的部署运维比Ollama复杂是给有规模的系统准备的。5. 政务部署避坑五个让你返工的常见问题5.1 模型把废止政策当现行政策回答现象用户问“老旧小区加装电梯补贴标准是多少”模型答出的是已废止的旧办法里的金额与实际执行标准差了30%。原因训练数据只给了政策文本和问答对没有标注政策的“效力状态”。模型不具备时间概念它不知道某份文件已于去年废止只知道这段文字看起来和问题相关。政务政策更新频繁尤其是补贴标准、申请条件这类数字密集的内容旧政策残留是常态。解决在数据构建阶段给每个训练样本打上元数据“生效状态”和“生效起止时间”。训练时把这些信息拼进system提示词比如“当前时间2025年6月你的知识截止于训练数据如政策已更新请提示以官方最新文件为准”。同时在答案模板里强制模型输出“本回答依据《XX办法》2024年修订版”一旦政策废止至少用户能看出依据文件是什么不会把旧标准当成现行规定。更稳妥的做法是配合第6章的RAG在检索阶段就把失效文档过滤掉不把旧政策喂给模型。5.2 验证集分数好看真实工单全翻车现象训练时验证集准确率90%以上一上线接真实工单用户用大白话一问模型就答非所问甚至直接把问题复述一遍当答案。原因训练数据太“书面”了。生成问答对时大模型标注员出的题都是规范表达——“申请保障性租赁住房的条件是什么”但真实用户问的是“我这情况能申请么”“没房没车能住上那个便宜房不”。训练分布和推理分布不一致分数再高也是自欺欺人。解决建训练集时故意掺入口语化改写。常见做法是让标注员针对同一个条款分别生成“标准问法”和“口语问法”两个版本比例控制在7比3。测试集里一定要混入真实工单样本这些样本从历史办件记录或热线录音转写里来脱敏后使用。评价指标也要改别只盯着BLEU、ROUGE重点看“条款编号命中率”——答案里的依据条款是否和标准答案一致。5.3 显存不够直接OOM先别换卡改参数能救现象按教程配好参数启动训练跑不到200步就报CUDA out of memory进程被杀之前的进度全丢。原因大多数人第一反应是显存不够换卡但实际操作中80%的OOM是因为某个参数设置不合理。最常见的是max_seq_length设了2048甚至4096序列长度一上去激活值显存成倍增长其次是gradient_checkpointing没开这等于把省显存的开关关掉了还有的开了flash_attention但显卡太老不支持反而报错。解决按这个顺序排查。第一步把per_device_train_batch_size设为1第二步打开gradient_checkpointing第三步把max_seq_length从2048降到1024观察显存峰值第四步如果还是不够把quantization_bit从4换到8试试不现实应该反过来——确认是否真正启用了4bit而不是底模还以FP16加载。做完这四步一般都能跑起来。如果7B还是放不下就换DeepSeek-R1-Distill-Qwen-1.5B别硬扛。5.4 一量化回答质量就掉不是量化本身错是顺序错了现象训练完效果不错一转成GGUF部署回答明显变差依据条款经常张冠李戴。原因很多人在训练时就用了4bit基座训练完直接在4bit权重上合并LoRA再导出4bit。这一路都是低精度误差层层叠加模型生成的置信度自然下降。更隐蔽的原因是量化校准步数不足llama.cpp在量化大模型时校准数据不够极端值被截断影响输出质量。解决第一合并LoRA时用FP16底模合并完成后再统一量化第二量化级别不要一上来就Q4_K_M优先试Q5_K_M或Q6_K文件只大一点效果差异明显第三量化后的模型必须重新跑一遍测试集和量化前的条款命中率做对比如果下降超过5个百分点换更高精度的量化档。这条血泪经验建议直接写进项目规范里。5.5 国产化操作系统装不上依赖从工具链开始规划现象训练环境明明一切正常部署推到政务内网的国产化服务器麒麟、统信UOS这类后Python依赖装不上Ollama启动报GLIBC版本错误。原因国产化系统普遍基于较旧的Linux内核和GLIBC版本而很多Python轮子和深度学习工具链是在新版Ubuntu上编译的拿到旧系统上直接缺符号。这个坑不在模型在工具链兼容。解决三层应对。第一部署机优先用Ollama或llama.cpp的预编译静态版本这类程序对系统依赖少成功率最高第二如果内网允许容器把整个推理环境打成Docker镜像在开发机上构建好再导入内网规避编译问题第三训练在GPU服务器上完成部署环境尽量只放推理组件不在生产机上装训练依赖。这个“训练与部署分离”的原则在政务内网尤其重要。6. 让问答真正可验收RAG兜底、溯源检查与上线标准6.1 为什么政策问答不能只靠微调模型硬背微调模型把知识存在权重里存在一个绕不开的问题政策更新后模型不会自动忘掉旧政策。你不可能每出一个新文件就重新训练一次成本太高。更现实的做法是让模型学会“读材料回答问题”而不是“背材料”。这就是RAG检索增强生成在政策问答里的价值。架构上不复杂用户提问后先用向量模型把问句转成向量去政策知识库里检索最相关的若干条款片段把片段拼进上下文再让微调后的DeepSeek基于这些片段生成回答。这样政策变了只更新知识库模型不对了只调整提示词都不用重新训练。微调在这里的真正职责是让模型“学会规矩”——知道什么时候拒答、怎么标注出处而不是让它死记硬背政策原文。6.2 一个最小可用的RAG检索加生成接口用Python写一个FastAPI的最小实现把检索和生成串起来政务系统的第三方应用直接调这个接口就行。from fastapi import FastAPI, HTTPException from pydantic import BaseModel import requests app FastAPI() OLLAMA_URL http://127.0.0.1:11434/api/generate VECTOR_API http://127.0.0.1:8080/retrieve # 向量检索服务可用Elasticsearch或FAISS封装 class QARequest(BaseModel): question: str def retrieve_policies(question: str, top_k: int 3) - list: resp requests.post(VECTOR_API, json{query: question, top_k: top_k}, timeout5) return resp.json()[chunks] # 每个chunk包含text、doc_id、clause_no、effective_status app.post(/policy_qa) def policy_qa(req: QARequest): chunks retrieve_policies(req.question) active_chunks [c for c in chunks if c.get(effective_status) active] if not active_chunks: return {answer: 该问题不在当前政策知识库覆盖范围内建议转人工窗口。, citations: []} context \n\n.join([f[{c[doc_id]}-{c[clause_no]}]\n{c[text]} for c in active_chunks]) prompt f请仅根据下列政策条款回答问题。若条款不足以回答请明确说明。\n\n{context}\n\n问题{req.question} resp requests.post(OLLAMA_URL, json{ model: policy-qa, prompt: prompt, stream: False, options: {temperature: 0.2} }, timeout30) return {answer: resp.json()[response], citations: [c[clause_no] for c in active_chunks]}接口逻辑就三层先查知识库过滤掉已废止的资料再把命中的条款原文作为上下文最后让模型生成带出处的回答。注意temperature设到0.2比训练时还低因为RAG答案应该更收敛、更照本宣科。企业微信政务版、政务APP、自助终端这些入口统一对接这个接口就完成了智能问答的功能闭环。6.3 验收测试条款命中率与时效性是硬指标政务系统验收不能只看“答得像不像”要看“答得对不对”。我日常用的是一张验收对照表条目不复杂但每条都卡得住验收项测试方法通过标准知识覆盖率取100条历史真实工单提问能生成有效回答的比例不低于90%条款命中率检查答案中的依据条款是否在检索结果内命中率不低于95%溯源完整性随机抽50条回答所有回答均带“依据”且条款编号真实存在时效性用已废止政策相关问题提问返回现行政策或明确提示“此政策已更新”拒答率输入50条和政务无关的问题拒绝回答且不编造的比例不低于98%生成时延压测环境连续调用GPU部署p95低于3秒纯CPU部署p95低于10秒最后一栏的“时延”是按政务窗口的真实场景卡的办事人员不可能对着屏幕等30秒。如果达不到先检查检索环节是不是有慢查询再检查模型有没有无谓的输出长度。还有一个隐藏检查项把回答交给业务处室的人审他们说“行”才算行——模型层面的指标再好看也替代不了业务把关。我现在的习惯是在交付前至少留一周“影子期”让系统在人工坐席旁边悄悄跑坐席看到有问题的回答随时标记期间攒下来的坏案例全部补进测试集再做一轮针对性训练。这个阶段机器没有决策权只做辅助风险可控。做政务系统的智能化慢一点真没关系答错一条政策的后果比晚上线一个月严重得多。希望这篇拆解能让你在选型和落地时少一点犹豫多一点底气。本文还有配套的精品资源点击获取
返回列表