1. 这不是“选模型”而是“选解法”为什么问“中文大模型哪一个最好”本身就是一个危险问题“第一个问题中文大模型哪一个最好”——这句话我每天在技术群、面试现场、客户会议室里至少听到七次。它像一句口头禅也像一把没开刃的刀听着无害用起来却容易伤人。真正有经验的人不会这么问因为他们知道“最好”从来不是模型参数表上的一个排名而是你手头那个具体任务、那条业务流水线、那台部署服务器、那个预算周期和那个交付 deadline 共同签发的一张动态许可证。我们先拆开这个标题里的关键词“中文”、“大模型”、“最好”。这三个词组合在一起表面是技术选型实则是一场多维约束下的资源博弈。中文不是简单的 token 切分问题它牵扯到字词边界模糊比如“南京市长江大桥”有四种切法、语义依赖长距主语可能在三句前、文化语境强耦合“内卷”“躺平”“绝绝子”在不同场景下情感极性完全翻转大模型不是越大越好7B 模型在 24G 显存上能跑满推理吞吐而70B 模型在同样硬件上可能连 batch_size1 都卡顿至于“最好”如果你正在做政务热线工单分类那么一个在 CCKS 评测上排第三、但专为政务短文本微调过的 13B 模型会比全网刷榜的 Qwen2.5-72B 更“好”——因为它把“市民反映路灯不亮”准确归类为“市政设施”而不是泛泛标成“民生诉求”。我做过 23 个落地项目从银行智能投顾话术生成到中药厂 GMP 合规文档自动校验再到社区养老院老人语音日记的情感陪伴摘要。每一次选模型都不是打开 HuggingFace 页面点“star”最多那个而是先摊开一张纸写下四行字第一行写“我要它干啥”明确输入输出格式、延迟容忍度、错误成本第二行写“它能在哪干活”GPU 型号、显存、是否允许联网、能否加载 LoRA第三行写“谁来养它”团队有没有人能 debug flash attention 的 kernel panic有没有人敢动 deepspeed 的 zero-offload 配置第四行写“它干完活我怎么信它”有没有可解释性模块能不能输出 confidence scorebad case 能不能人工兜底。这四行字写完90% 的“哪个最好”问题就自动消失了。剩下的 10%才是真刀真枪比模型的时候——而那时你比谁都清楚你要比的不是“通义千问 vs 月之暗面”而是“Qwen2-7B-Instruct 在 4-bit AWQ vLLM 推理下对医保报销凭证 OCR 文本的实体抽取 F1 是否比 GLM-4-9B-Chat 在 llama.cpp 量化后高 0.8 个百分点且 P99 延迟是否压在 850ms 内”。所以这篇内容不给你列“2024 中文大模型排行榜”也不告诉你“闭眼入 Qwen 就对了”。我要带你走一遍真实世界里一个资深工程师/算法负责人/技术决策者在接到“我们需要一个中文大模型”这个需求后从需求翻译、能力测绘、工程适配到长期运维的完整决策链路。你会看到所谓“最好”其实是你在每个环节都做了足够克制、足够务实、足够带痛感的选择之后自然浮现的结果。2. 模型能力测绘不是跑 benchmark而是做“压力测试盲测坏案例反推”很多人一上来就去刷 CMMLU、C-Eval、CEval觉得分数高就是能力强。错。CMMLU 是个好工具但它测的是“模型知识库的广度与静态记忆”而真实业务要的是“在噪声输入下稳定输出结构化结果的能力”。举个例子某省电力公司要做故障报修单自动归因输入是用户语音转写的文字“昨天晚上十点多我家跳闸了空调开着呢冰箱也响着就突然黑了隔壁老王家也有电”。CMMLU 不会考这个但你的模型必须能从中精准抽取出【设备类型空调、冰箱】、【时间昨晚22:00左右】、【现象跳闸、全屋断电】、【对比信息邻居家有电】并推理出“大概率是户内线路过载而非电网故障”。所以我的能力测绘流程分三步缺一不可2.1 第一步构建“业务压力测试集”非公开、强场景这不是网上下载的通用数据集而是从你的真实业务中抠出来的“脏数据”。我通常要求产品/运营同事提供最近 30 天内被人工标注为“疑难工单”的 200 条原始记录脱敏后再额外加 50 条他们自己编的“最想难倒模型”的边界案例比如“我家WiFi连不上是不是你们基站坏了”——实际是路由器没插电。这 250 条构成你的黄金测试集。注意必须是原始输入不能是清洗后的标准句式。因为真实世界里90% 的输入都是“我家那个…呃…就是厨房那个嗡嗡响的东西不转了”而不是“请识别家电故障型号XXX现象电机停转”。提示测试集构建时一定要包含“低信息量输入”如“不行”“不好”“乱七八糟”、“高歧义输入”如“他昨天说今天来结果没来”——谁是“他”“昨天”是相对谁、“跨模态暗示”如OCR识别出的发票图片文字“金额8,500.00备注预付款”但用户提问“这笔钱付给谁了”——模型需理解“预付款”隐含收款方未明示。2.2 第二步盲测执行不看模型名只看输出把这 250 条输入喂给 5~8 个候选模型建议覆盖不同架构Qwen、GLM、DeepSeek、Yi、Phi-3、MiniCPM全部关闭 system prompt统一用空字符串作为 instruction只保留 raw input → raw output。让三位业务方同事非技术人员比如客服组长、一线审核员在不知道模型来源的情况下对每条输出打分1 分完全无法使用信息错乱或胡说2 分部分可用但关键字段缺失或错误3 分基本可用只需少量人工修正4 分高质量可直接进入下游系统5 分超出预期主动补全了业务需要但输入未提的信息如用户只说“空调不制冷”模型输出“建议检查滤网是否堵塞、冷媒是否泄漏并附本地售后电话”这个盲测不看模型名字只看结果。我见过太多次某个在 C-Eval 上 82 分的模型在盲测里平均得分只有 2.1而另一个 C-Eval 76 分、但专为工单场景微调过的模型平均得分 3.8。因为后者学会了“当用户描述模糊时优先输出可操作的排查步骤而不是纠结于‘制冷’的物理定义”。2.3 第三步坏案例反推定位能力短板而非模型优劣拿到盲测结果后重点不是看谁总分高而是拉出所有得 1 分和 2 分的 bad case做归因分析。我用一张三栏表格来管理原始输入脱敏模型A输出错误类型根本原因推测“快递还没到下单三天了单号SF123456789”“您的快递已签收”事实性错误模型将“下单三天”误读为“已发货三天”未结合物流API常识“这个合同第5条第2款和第7条冲突哪个有效”列出两条原文未判断效力缺乏法律条款效力层级知识或未激活 reasoning chain“帮我写个辞职信要显得专业但别太冷”输出一封语气生硬、充满套话的模板instruction tuning 偏向 formal style未学习“warm professionalism”语料这张表的价值远超任何 benchmark 分数。它告诉你如果错误集中在“事实核查”说明你需要 RAG 或 grounding 模块如果错误集中在“逻辑推理”说明你需要更强的 chain-of-thought prompt engineering 或换用推理优化模型如 DeepSeek-R1如果错误集中在“风格控制”说明你需要 SFT 微调或更好的 reward modeling。这才是“哪个最好”的答案起点不是模型本身而是它在哪种能力维度上最匹配你当前最痛的那个坏案例。3. 工程适配实战从“能跑起来”到“跑得稳、跑得省、跑得可维护”的全流程拆解模型选出来只是万里长征第一步。我在某市医保局项目里亲眼见过一个在 A100 上跑得飞起的 32B 模型部署到他们机房那台 2018 年采购的 T4 服务器上后P99 延迟从 1.2 秒飙升到 17 秒日均失败请求超 3000 次。最后不是换模型而是重构了整个推理栈。所以这一节我带你走一遍真实生产环境中的“模型落地七步法”每一步都带着血泪教训。3.1 步骤一硬件画像——不是查显卡型号而是测“真实可用显存带宽”很多人以为“T4 16G 显存”就能跑 7B 模型。错。T4 的显存带宽是 320 GB/s而 A100 是 2039 GB/s差 6.4 倍。这意味着在 A100 上7B 模型用 FP16 加载需约 14GB 显存剩余空间可塞 batch_size8在 T4 上同样的模型由于带宽瓶颈实际有效吞吐可能只有 A100 的 1/5batch_size1 时 latency 就已超标。我的做法是用nvidia-smi dmon -s u -d 1实时监控部署时的sm__inst_executedSM 指令执行数和dram__bytes_read显存读取字节数。如果dram__bytes_read长期接近 320 GB/s 上限而sm__inst_executed却很低说明模型在等数据——这是典型的带宽瓶颈不是算力瓶颈。此时与其换更大显存的卡不如做量化。实操心得T4 部署 7B 模型我强制要求必须用 AWQ 4-bit 量化不是 GGUF因为 AWQ 在 T4 上的 kernel 优化更好实测比 llama.cpp 的 Q4_K_M 快 22%且显存占用从 13.8GB 降到 5.2GB留出足够空间给 KV Cache。3.2 步骤二推理引擎选型——vLLM、TGI、llama.cpp不是看 star 数而是看“谁敢接你的烂输入”vLLM适合高并发、长上下文、需要 PagedAttention 的场景如客服对话历史回溯。但它对输入格式极其敏感如果用户输入里混入\x00或非法 UTF-8 字节vLLM 会直接 crash且错误日志晦涩。我在某电商项目里因此被半夜叫醒三次。TGIText Generation Inference由 HuggingFace 出品生态友好支持 FlashAttention-2但它的 batch 动态调度在流量突增时容易抖动P99 延迟波动可达 ±400ms。llama.cpp单线程性能极致内存占用低对烂输入鲁棒性强会自动过滤非法字符但不支持真正的 async inference高并发下需自己做 connection pool。我的选择逻辑很粗暴如果你的输入源可控如内部 API已做过严格清洗且需要极致吞吐 → 选 vLLM如果你的输入来自网页表单、微信小程序各种乱码、emoji、超长粘贴随时出现 → 选 llama.cpp如果你重度依赖 HuggingFace 生态如想无缝接入 PEFT、TRL且能接受中等稳定性 → 选 TGI。在最近一个社区健康档案项目中我们最终选了 llama.cpp因为基层医生录入的方言描述如“心口闷得慌像有块石头压着”经常包含生僻字和乱码llama.cpp 会静默丢弃无法 decode 的字节而 vLLM 会抛出UnicodeDecodeError导致整个 batch 失败。3.3 步骤三量化策略——4-bit 不是终点而是起点现在流行说“上 4-bit 就完事了”。但 4-bit 有至少五种实现AWQ、GPTQ、QLoRA、FP4、NF4。它们不是等价的。AWQ对权重做 channel-wise 量化保留重要通道精度适合推理但训练后量化post-training quantization效果一般GPTQ逐层量化精度损失小但量化过程慢且对某些 layer如 RMSNorm支持不好QLoRA不是纯量化是“量化 低秩适配”适合微调后部署但推理时需加载 adapter增加启动时间FP4/NF4HuggingFace 推出的新格式NF4 对大模型权重分布更友好但需要最新版 transformers≥4.41和 CUDA 12.1。我的量化实操清单先用auto_gptq对模型做 GPTQ 4-bit 量化bits4, group_size128, desc_actTrue再用awq工具对 GPTQ 模型做 AWQ 校准zero_pointFalse, q_group_size128进一步压缩最后用llama.cpp的quantize工具转成 GGUF 格式指定typeq4_k_m平衡速度与精度关键一步在 GGUF 文件头里手动注入metadata写入quantization_method: awq_gptq_q4_k_m和calibration_dataset_hash: sha256_xxx方便后续审计。为什么这么麻烦因为在某金融项目审计时监管要求提供“量化方法可复现、校准数据可追溯”的证明。没有 metadata你拿不出证据。3.4 步骤四Prompt 工程——不是写漂亮指令而是建“防错护栏”很多团队花两周设计一个华丽的 system prompt“你是一个专业的医疗助手知识截止于2024年3月回答需严谨、中立、不臆测…”。结果上线第一天用户输入“医生说我得了癌症怎么办”模型输出了一段长达 200 字的病理学解释完全没触发危机干预流程。Prompt 工程的本质是给模型装上“安全阀”。我的做法是三层防护L1 输入过滤在 API 网关层用正则匹配高危关键词“自杀”“跳楼”“绝食”“不活了”命中即返回预设应急话术“我理解您此刻非常痛苦请立即联系心理援助热线 XXX”不进模型L2 Prompt 注入在用户 query 前固定拼接一段“护栏 prompt”[SAFETY_GUARD] - 若用户表达自伤/自杀/伤害他人意图立即终止推理输出请立刻联系专业心理援助。 - 若用户询问医疗诊断仅可回答我无法替代医生诊断请尽快就医。 - 若用户问题涉及法律定性仅可回答我无法提供法律意见请咨询执业律师。 [/SAFETY_GUARD]L3 输出校验用一个轻量级分类器如 DistilBERT-finetuned实时扫描模型输出检测是否包含“绝对化表述”“肯定”“必然”“100%”、“医疗建议”“吃XX药”“每天按摩XX次”、“法律结论”“构成诈骗”“应负刑责”命中即替换为合规话术。这三层加起来增加了约 80ms 延迟但把高危响应率从 12.7% 降到了 0.3%。在生产环境里“多 80ms”和“少 12% 事故率”永远选后者。3.5 步骤五缓存与降级——当模型“思考”时系统不能“死等”大模型推理最怕什么不是慢而是“不确定多慢”。vLLM 的max_model_len设为 8192但用户输入一个 10 字问题模型却因 attention 计算复杂度高卡在第 3200 token 位置不动了。这时你的 API 不能一直 hang 着。我的降级方案是“三级熔断”一级500ms启动 fast tokenizer 预热若 500ms 内未返回首个 token切换至轻量 fallback 模型如 ChatGLM3-6B-int4二级2s若 fallback 模型也超时启用规则引擎基于关键词匹配的 if-else生成兜底回复如用户问“报销比例”直接返回医保局官网公布的通用比例表三级5s强制返回{status:timeout, suggestion:请稍后重试或拨打服务热线}并触发告警。这个方案在某政务热线项目中把“无响应”投诉率从 8.2% 降到了 0.17%。关键是所有降级路径的输出都带有source字段source:vllm_main/source:fallback_glm/source:rule_engine方便后续分析到底是模型真慢还是 fallback 模型也扛不住了3.6 步骤六可观测性埋点——不只看 GPU 利用率要看“模型在想什么”监控面板上显示 GPU 利用率 92%你以为一切正常错。可能模型正在反复重试同一个 bad token陷入死循环。我要求每个推理服务必须上报 7 个核心指标指标名计算方式告警阈值业务含义token_per_second(output_tokens - input_tokens) / duration_ms * 1000 15模型生成效率骤降可能卡在某个 layerkv_cache_hit_ratekv_cache_hits / (kv_cache_hits kv_cache_misses) 0.85上下文复用率低提示 prompt 设计不合理repetition_penalty_applied统计repetition_penalty 1.0时的触发频次 3 次/请求模型陷入重复需调整 penalty 参数eos_token_ratioeos_token_count / total_output_tokens 0.05模型不敢结束可能对任务理解偏差prompt_truncatedbool是否触发了max_prompt_length截断True输入超长需前端限制或服务端分片speculative_decoding_acceptance若启用 speculative decoding统计 draft model 接受率 0.6草稿模型质量差拖累整体性能logprob_variance输出 token 的 logprob 标准差 2.5模型信心不足输出随机性高这些指标不光看数字更要关联分析。比如某天token_per_second普遍下降同时logprob_variance升高基本可以断定上游数据管道混入了大量低质训练数据如网络爬虫抓取的乱码网页污染了模型的 token 分布。3.7 步骤七灰度发布与 AB 测试——不是“全量切流”而是“按用户特征分流”很多团队上线新模型就是改个配置kubectl rollout restart。结果第二天发现老年用户投诉率飙升——因为新模型把“血压计”识别成了“体温计”而旧模型虽然慢但对医疗设备名词更稳。我的灰度策略是“四维分流”按用户 ID 哈希保证同一用户始终走同一条路径便于问题复现按地域先在华东区 5% 用户放量观察方言处理效果按设备类型安卓用户走新模型iOS 用户走旧模型因 iOS 用户更习惯原生体验容忍度低按业务线先开放“查询类”接口如查余额、查进度再开放“生成类”接口如写通知、拟合同。AB 测试不只比“准确率”更要盯三个业务指标task_completion_rate用户发起请求后成功得到可用结果的比例human_intervention_rate下游系统需人工介入修正的比例session_duration_delta用户完成同一任务耗时相比基线的变化±5% 以内可接受。在某银行项目中新模型在 C-Eval 上高 3.2 分但human_intervention_rate却高了 1.8%原因是它过度优化了“专业术语准确性”把客户口语化的“我钱被扣了”强行转成“发生非授权资金划转”导致柜员看不懂。最后我们回滚了 prompt加了一条“请用客户原始表述风格复述关键事实”。4. 长期运维与演进模型不是“买来就完事”而是“养一个会成长的数字员工”把模型部署上线只完成了 30% 的工作。剩下 70%是让它在真实业务中持续进化。我见过太多项目上线时效果惊艳三个月后准确率掉 15 个点没人知道为什么。根源在于模型不是静态的 PDF 文档而是活在数据流里的动态器官——上游数据变了它就变下游反馈没闭环它就退化。4.1 数据漂移监测不是等准确率掉下去而是提前嗅到“味道变了”数据漂移Data Drift是模型退化的头号杀手。但传统做法是每月跑一次 PSIPopulation Stability Index等指标超标才行动——太晚了。我的做法是“实时气味监测”。我用一个轻量级模型TinyBERT做“输入表征提取器”对每天 1% 的线上请求输入计算其 embedding并与基线周数据做 MMDMaximum Mean Discrepancy距离。当 MMD 0.15 时触发预警。这个阈值怎么来的我拿历史数据回溯当 MMD 达到 0.15 时平均 3.2 天后task_completion_rate开始显著下降p0.01。预警后不是立刻 retrain而是启动“漂移根因分析”词频漂移用 TF-IDF 对比新旧数据看哪些词突然高频出现如某地突发疫情用户输入中“核酸”“抗原”“黄码”词频暴涨句法漂移用 spaCy 解析依存树统计“主谓宾”结构占比变化如政策宣传期“要”“必须”“严禁”引导的祈使句比例上升语义漂移用 Sentence-BERT 计算新旧样本 embedding 的余弦相似度分布若 90% 分位数下降超 0.1说明语义空间已偏移。去年某社保平台就靠这套机制在“电子社保卡申领”业务量暴增 300% 前一周就发现了输入中“手机收不到验证码”类问题占比从 12% 飙升至 47%提前协调运营商优化短信通道避免了大规模客诉。4.2 反馈闭环建设不是收集“好评差评”而是捕获“沉默的失败”用户不会主动告诉你模型哪里错了。他们只会放弃操作页面停留 5 秒就关闭点击“重新生成”按钮平均点击 2.3 次才满意把模型输出复制粘贴到微信再发给朋友问“这说得对吗”直接打电话给客服说“你们那个AI根本不懂我在说什么”。这些是“沉默的失败信号”。我的反馈闭环包含三层漏斗L1 行为信号埋点监控regenerate_click_count、copy_to_clipboard_event、page_bounce_rate_on_output。当某类问题如“医保报销流程”的regenerate_click_count7 日均值 1.8自动标记为 high-friction topicL2 人工抽检每天从 high-friction topic 中随机抽 50 条由业务专家标注“模型输出是否可用”并填写failure_reason选项事实错误、逻辑断裂、风格不符、信息冗余、无法理解输入L3 主动探针每周向 1000 名活跃用户推送一条“探针问题”如“请用一句话告诉我新生儿参保需要准备哪些材料”并强制要求用户对 AI 回复打分1~5 星 文字反馈。这个探针不追求覆盖率而追求“高质量噪声”——因为愿意认真填反馈的用户本身就是高价值样本。这套机制让我们在某教育项目中提前两周发现模型对“双减”新政后的课后服务政策理解滞后及时用政策原文微调避免了家长群体性投诉。4.3 模型迭代节奏不是“追新”而是“守旧渐进式升级”我坚决反对“一有新模型就立刻升级”。Qwen2.5 发布当天我团队没动一代码。为什么因为我们的 SLOService Level Objective是“99.95% 请求 P99 1.5s”而 Qwen2.5 在我们硬件上实测 P99 是 1.72s不达标。我的迭代节奏是“三不原则”不追版本号只关注模型在你业务压力测试集上的 delta提升 0.5 分且无新增 bad case不破兼容性新模型必须能用旧 prompt template输出 JSON schema 完全一致否则下游所有服务都要改不增复杂度如果升级需要加一台 GPU 或改 CI/CD 流程那就暂缓先用 prompt engineering 或 RAG 补足。真正的升级是“渐进式”的第一周在灰度流量中对 1% 的“查询类”请求启用新模型 旧 prompt监控指标第二周若指标达标扩大到 5%并加入 RAG用新模型重写 retrieval query第三周若 RAG 效果显著再微调新模型使其更适配你的 RAG 结果第四周全量但保留旧模型作为 fallback且 fallback 触发率需 0.1%。这个节奏让我们在三年内完成了 7 次模型主干升级每次升级后human_intervention_rate不升反降最低做到 0.37%。模型运维的终极目标不是“用上最新技术”而是“让业务感觉不到技术在变”。4.4 成本精细化治理不是“省 GPU”而是“算清每一 token 的生意账”很多人只算硬件成本T4 卡 2 万/年A100 卡 15 万/年。但真实成本远不止于此。我要求每个模型服务必须计算“Token 经济账”单次请求总成本 (GPU 卡成本 / 年运行小时) × 单次请求 GPU 占用秒数 (带宽成本 0.8元/GB × 输入输出总字节数 / 1024 / 1024) (存储成本 0.3元/GB/月 × 模型文件大小 / 1024) (人力成本 1500元/人天 × 每月运维工时 / 22)然后除以monthly_active_requests得到“单请求成本”。再除以business_value_per_request如医保查询单次节省柜员 3 分钟折合 15 元人力成本得出 ROI。在某政务项目中我们发现用 72B 模型做政策解读单请求成本 0.42 元ROI0.8而用 7B 模型 RAG召回 3 篇政策原文单请求成本 0.09 元ROI3.1。于是果断砍掉 72B把省下的钱投入 RAG 的 chunking 策略优化——把政策文件按“适用对象”“办理条件”“所需材料”“常见问题”四个维度切片召回准确率从 68% 提升到 92%。技术决策的最高境界是让财务总监看完成本报表主动给你批预算。5. 常见问题与避坑指南那些没人告诉你的“血色经验”以下是我踩过的、被客户骂过的、在凌晨三点 debug 过的、以及看着服务器冒烟后悔过的坑。没有理论全是带温度的教训。5.1 问题一“模型在测试集上 95 分上线后只有 65 分是不是数据泄露了”真相99% 的情况是测试集和线上数据分布不一致。但更隐蔽的坑是——你的测试集本身就在‘作弊’。我见过最典型的作弊把测试集的“标准答案”硬编码进 prompt。比如测试“医保报销比例”prompt 里写着“根据《XX市医保条例》第3.2条职工医保在职人员门诊报销比例为70%”。模型根本不用学照抄就行。排查技巧把测试集输入全部 anonymize替换所有人名、地名、数字为MASK再跑一遍。如果分数暴跌说明模型在 memorize不是 generalizing用transformers的Trainer加--do_predict但禁用--predict_with_generate改用model(**inputs).logits直接取 logits看 top-k 预测是否合理。如果 top-1 总是训练集里的高频答案说明过拟合。我的解决方案测试集必须满足“三不原则”——不出现训练集原文、不包含模型可查到的公开知识如维基百科、不依赖特定格式如必须带“请问”开头。我们用“对抗生成”方式构造测试集让另一个模型如 GLM-4针对业务场景生成 1000 条“人类可能问、但网上找不到标准答案”的问题再由业务专家人工校验。5.2 问题二“为什么模型对同一个问题每次输出都不一样是随机种子没设吗”真相temperature0.8是罪魁祸首但更深层的问题是——你没意识到‘确定性’和‘创造性’是同一枚硬币的两面。temperature0确实能让输出稳定但代价是模型变成“复读机”。用户问“怎么治感冒”它永远输出“多喝水、休息、必要时就医”哪怕用户补充“我已经喝了三天水还是发烧”它也不会调整。我的平衡方案对“事实查询类”如查政策、查流程强制temperature0.01top_p0.95确保稳定对“创意生成类”如写通知、拟文案用temperature0.7repetition_penalty1.2并开启best_of3生成 3 次选最优最关键在 API 响应里永远返回{response: ..., temperature_used: 0.01, seed_used: 42}让业务方知道这次输出的“确定性等级”。5.3 问题三“RAG 检索不到相关内容是不是向量模型太差赶紧换 bge-reranker”真相80% 的 RAG 失败不是检索模型问题而是chunking 策略和 query 重写双重失灵。比如用户问“新生儿参保需要准备哪些材料”原始 query 直接扔给向量库可能匹配到一篇讲“医保政策演变史”的长文而真正答案藏在文末的附件链接里。我的 RAG 三板斧Chunking不用固定长度切片。对政策类文档按“条款”切每个h2标题为一个 chunk对 FAQ 类按“QA 对”切对 PDF 扫描件用unstructured库先做 layout analysis再按视觉区块切Query Rewrite用一个小模型如 Phi-3-mini做 query expansion“新生儿参保” → “婴儿 医保登记 新生儿 社保卡 办理材料 所需证件”Hybrid Search向量检索 关键词 BM25 检索再用cross-encoder如 bge-reranker-base