三台本地小模型协同架构:LoRA微调+RAG+全链路本地化实战

三台本地小模型协同架构:LoRA微调+RAG+全链路本地化实战 1. 项目概述当“GPT-6 Astra”刷屏时我关掉了云API把三台旧笔记本搬进了书房最近朋友圈、技术群、甚至咖啡馆角落的程序员都在聊GPT-6 Astra——那个被传得神乎其神、号称“首次实现真正多模态推理闭环”“原生支持硬件级Agent调度”的下一代模型。OpenAI没官宣但跑分截图满天飞社区里有人贴出Astra在MMLU-Pro上92.3%的分数旁边标注“未启用任何RAG或外部工具”底下立刻跟帖“桌面端没有Astra”“MacBook M2跑不动”“等官方API等得头发发白”。可就在这股集体亢奋里我做了件反直觉的事卸载了所有大模型API调用SDK清空了Cloudflare Workers里的转发规则把三台积灰的旧设备——一台i7-8750HRTX 2060的二手游戏本、一台AMD Ryzen 5 3500UVega 8核显的轻薄本、还有一台连独显都没有、只靠Intel UHD 620硬扛的办公本——全搬进书房插上电源装上Ollama和LM Studio开始用它们搭一个不依赖任何云端服务的本地智能体系统。这不是对抗也不是情怀而是基于过去三年亲手部署过47个RAG知识库、微调过19个LoRA适配器、踩过包括显存溢出、embedding错位、chunk语义断裂、query重写失效在内的全部典型坑之后得出的一个实操结论对绝大多数真实业务场景而言“单一大模型强能力”远不如“多个小模型分工协作精准知识注入轻量决策路由”来得稳定、可控、可解释、可审计。这个项目不追求榜单分数它解决的是你明天就要交的客户方案PPT怎么自动从内部Wiki生成、是你刚拍的产线故障照片如何秒级匹配维修手册图文、是你上周会议录音里提到的三个待办事项怎样拆解成Jira子任务并分配给对应工程师——这些事GPT-6 Astra或许能做但它不会告诉你为什么选了那条路径也不会在你内网断网时突然罢工。而我的三台小模型会。1.1 核心需求解析为什么是“三台”为什么是“本地”为什么不是“一个更大模型”这个问题我被问了至少23次每次我都先反问对方“你上一次因为API限流/账单超支/模型突然下线导致关键流程中断是什么时候”答案惊人一致就在过去30天内。这揭示了一个被光环掩盖的现实——当前所有所谓“最强模型”的可用性Availability与可控性Controllability仍严重依赖外部基础设施。而“三台本地小模型”的设计本质是一套面向生产环境的冗余架构第一台推理主力运行Qwen2.5-7B-Instruct量化版AWQ 4-bit承担90%的自然语言理解与生成任务。选它不是因为参数最多而是因为它在中文长文本理解、结构化输出JSON/YAML、指令遵循稳定性上经我们团队在金融合同解析、医疗报告摘要等12个垂直场景实测错误率比同尺寸Llama3-8B低37%且对prompt中“请严格按以下格式输出”这类约束响应更鲁棒。第二台知识引擎运行Phi-3-mini-4K-InstructGGUF Q5_K_M专责RAG检索增强。它不生成答案只做两件事① 将用户query实时编码为768维向量② 在本地Milvus向量库中执行近似最近邻搜索ANN返回Top-3最相关知识片段。选Phi-3-mini而非更大模型是因为它的embedding模型all-MiniLM-L6-v2精调版在我们的法律条款相似度测试集上召回率比bge-m3高5.2%且单次编码耗时仅127msRTX 2060比Qwen2.5内置embedding快2.8倍——这对需要毫秒级响应的客服场景至关重要。第三台决策中枢运行TinyLlama-1.1BGGUF Q4_K_S作为轻量级Agent Router。它接收前两台的输出Qwen的初步回答 Phi-3的检索片段判断是否需触发外部动作如查数据库、调用Python脚本、生成图表。例如当用户问“上季度华东区销售额环比变化”它不直接计算而是解析出“华东区”“上季度”“销售额”“环比”四个实体调用预置的SQL模板生成查询语句再将结果喂给Qwen做最终润色。TinyLlama虽小但经过LoRA微调后在我们的2000条Agent意图分类测试集上准确率达94.6%远超用Qwen2.5做同样任务时因上下文过长导致的82.1%准确率。提示这里“三台”不是固定数字而是功能解耦的最小可行单元。你可以把三台合并到一台机器我们实际部署就是如此但逻辑上必须保持这三层分离——就像微服务架构中绝不把订单、支付、物流写进同一个函数。1.2 技术选型背后的硬逻辑LoRA、RAG、本地化为何缺一不可标题里“三台本地小模型”只是表象真正支撑起整个系统的是三个技术锚点LoRA微调、RAG知识注入、全链路本地化。它们不是流行词堆砌而是针对具体痛点的精准手术刀LoRALow-Rank Adaptation为什么不用全参数微调因为全参数微调7B模型需24GB显存FP16而我们的主力机只有6GB显存RTX 2060。LoRA通过在原始权重旁插入低秩矩阵rank8将可训练参数压缩到0.1%实测在QLoRA配置下Qwen2.5-7B仅需3.2GB显存即可完成微调且在客服话术风格迁移任务上收敛速度比全参数快3.5倍。关键在于LoRA不是“让模型学新知识”而是“教会模型用新方式表达已有知识”——比如把通用问答口吻切换成某银行内部合规话术“根据《XX管理办法》第X条您需提供…”。RAGRetrieval-Augmented Generation为什么不用模型内置知识因为大模型的“知识”是静态快照而企业知识库是活的。上周法务部更新了《供应商保密协议》模板云端模型不会自动同步。RAG则像给模型装了个实时搜索引擎用户提问时系统先从本地向量库已索引全部PDF/Word/Confluence页面捞出最新条款再让Qwen基于此生成回答。我们实测RAG使Qwen2.5在合同审查类问题上的事实准确率从68%提升至91%且所有引用均可追溯到具体文档页码——这点对审计至关重要。全链路本地化为什么坚持不用API除了前述的可用性问题更深层的是数据主权与调试效率。“本地”意味着① 所有token处理在内存中完成无网络传输风险② 每次推理的完整trace输入、检索片段、中间推理步骤、最终输出可100%记录方便回溯错误③ 当用户说“这个回答不对”你能立刻打开日志看到是Phi-3检索错了片段还是Qwen误解了指令抑或TinyLlama路由失误——这种颗粒度的可观测性是任何黑盒API无法提供的。这三者构成铁三角LoRA确保模型“懂规矩”RAG确保模型“知现状”本地化确保一切“可掌控”。少一个系统就从生产级退化为演示级。2. 核心细节解析与实操要点从硬件准备到模型选型的硬核取舍很多人看到“三台本地小模型”第一反应是“我的MacBook Air能跑吗”答案是肯定的但必须明确这不是拼硬件参数的游戏而是做工程权衡的艺术。下面拆解每个环节的真实考量与避坑经验。2.1 硬件准备旧设备不是妥协而是经过验证的最优解我们用的三台设备最老的是2018年的Ryzen 5 3500U轻薄本16GB内存无独显最新的是2021年i7-8750H游戏本32GB内存RTX 2060 6GB。它们共同特点是CPU多核性能尚可、内存足够、有M.2 NVMe插槽。为什么不用更新的M系列芯片因为截至2024年中Ollama对Apple Silicon的GPU加速支持仍不稳定纯CPU推理Qwen2.5-7B需42秒/请求而RTX 2060AWQ量化后仅1.8秒。关键参数对比如下设备型号CPUGPU内存存储实测Qwen2.5-7B推理延迟AWQ 4-bit适用角色i7-8750H RTX 20606核12线程6GB GDDR632GB DDR41TB NVMe1.8秒推理主力高负载Ryzen 5 3500U Vega 84核8线程512核心核显16GB DDR4512GB NVMe4.3秒知识引擎中负载i5-8250U UHD 6204核8线程24EU核显16GB DDR4256GB NVMe12.7秒决策中枢低负载注意核显机型必须开启Linux内核的amdgpu或i915驱动并在Ollama中指定--gpu-layers 20Vega 8或--gpu-layers 10UHD 620才能启用GPU加速。Windows用户请直接放弃核显加速改用CPU模式——我们实测Win11下UHD 620的OpenCL加速反而比纯CPU慢17%。旧设备的优势在于① 散热设计成熟长时间满载不降频② BIOS解锁充分可关闭Secure Boot以兼容自定义内核模块③ 驱动生态稳定不像新款笔记本常有WiFi/蓝牙驱动冲突。我们曾试过一台2023年i9-13900H笔记本结果因Intel Arc核显驱动bug导致Ollama启动后GPU占用率恒为0%折腾三天无解最终换回Ryzen 3500U。2.2 模型选型参数不是越大越好场景才是唯一标尺网上充斥着“必须用72B模型才够强”的声音但我们用数据说话。在真实客服对话场景含127个复杂多轮问题中各模型表现如下模型参数量量化方式平均响应时间事实准确率指令遵循率适用角色Qwen2.5-7B-Instruct7BAWQ 4-bit1.8s89.2%93.7%推理主力Phi-3-mini-4K-Instruct3.8BGGUF Q5_K_M0.3s91.5%96.2%知识引擎TinyLlama-1.1B1.1BGGUF Q4_K_S0.1s94.6%98.1%决策中枢Llama3-8B-Instruct8BAWQ 4-bit2.1s85.3%88.4%——Gemma-2-9B9BGGUF Q4_K_S3.4s82.1%84.9%——关键发现TinyLlama-1.1B在Agent路由任务上准确率最高。原因在于其架构更“专注”——1.1B参数全部用于学习意图分类没有被通用语言建模任务稀释。而Llama3-8B虽大但在我们的2000条路由指令测试集上因上下文窗口被无关token占据导致关键实体识别失败率高达15.6%。这印证了一个朴素真理给专用任务配专用模型永远比给通用模型塞专用指令更高效。选型时我们坚持三个原则推理延迟必须≤5秒超过此阈值用户会感知“卡顿”影响体验显存占用必须≤设备GPU显存的70%预留空间给RAG向量检索与系统缓存必须有活跃社区维护的量化版本避免自己编译GGUF时陷入CUDA版本地狱。2.3 LoRA微调实战不是调参而是教模型“说人话”LoRA微调常被神化其实质是“用少量数据教会模型在特定场景下切换表达模式”。我们为Qwen2.5-7B做的LoRA目标很明确让它把通用回答转成符合某制造企业《客户服务SOP》的话术。数据集仅327条每条包含输入用户原始提问 “机器报错E102屏幕黑了”输出SOP标准回复 “您好E102错误表示主控板通信异常。请您先断电30秒后重启若仍存在请提供设备序列号及错误出现时的操作步骤我们将为您安排工程师远程诊断。”微调过程踩过三个深坑坑1学习率爆炸。初始用1e-4学习率3个epoch后loss突增至inf。排查发现是Qwen2.5的RMSNorm层对LoRA梯度敏感将学习率降至3e-5loss曲线才稳定。坑2LoRA rank选择。试过rank4/8/16rank4时收敛快但泛化差对未见过的错误码回复生硬rank16时拟合好但推理变慢最终rank8在速度与质量间取得最佳平衡。坑3权重合并陷阱。微调后直接用lora-adapter加载响应延迟飙升至8秒。正确做法是用llama.cpp的convert_lora_to_gguf.py脚本将LoRA权重合并进基础模型GGUF文件生成全新模型——合并后延迟回归1.8秒且无需额外加载LoRA参数。实操心得LoRA不是万能膏药。它擅长风格迁移、领域术语对齐、输出格式固化但无法赋予模型它原本不具备的知识。想让模型知道“E102错误”的含义必须靠RAG注入设备手册PDFLoRA只负责把检索到的知识包装成SOP要求的语气。3. 实操过程与核心环节实现从零搭建可运行的三模型协同系统现在进入最硬核部分如何把上述设计变成可一键启动的本地系统。我们摒弃复杂K8s编排采用极简方案——所有服务由systemd管理通过curl和jq完成跨模型通信全程无需Python后端。以下是完整步骤。3.1 环境初始化统一基座规避版本战争所有三台设备均安装Ubuntu 22.04 LTS非24.04因后者内核对某些旧GPU驱动支持不佳执行以下命令构建纯净环境# 升级系统并安装基础依赖 sudo apt update sudo apt upgrade -y sudo apt install -y build-essential curl git python3-pip python3-venv libgl1 libglib2.0-0 # 安装Ollama官方二进制非snap curl -fsSL https://ollama.com/install.sh | sh # 创建模型存储目录挂载到SSD避免系统盘IO瓶颈 sudo mkdir -p /mnt/models sudo chown $USER:$USER /mnt/models关键点禁用Snap安装Ollama。我们曾因Snap沙盒限制导致Ollama无法访问GPU设备节点/dev/nvidia*折腾两天才发现问题根源。官方二进制安装可完全控制权限。3.2 模型部署三步走每台设备只跑一个角色第一台推理主力Qwen2.5-7B-Instruct LoRA# 拉取基础模型自动选择AWQ量化版 ollama pull qwen2.5:7b-instruct-q4_k_m # 创建自定义Modelfile/home/user/ollama-modelfiles/qwen25-lora.Modelfile FROM qwen2.5:7b-instruct-q4_k_m ADAPTER /mnt/models/qwen25-customer-sop-lora.gguf PARAMETER num_ctx 4096 PARAMETER temperature 0.3 PARAMETER top_p 0.9 TEMPLATE {{ if .System }}|im_start|system {{ .System }}|im_end| {{ end }}{{ if .Prompt }}|im_start|user {{ .Prompt }}|im_end| |im_start|assistant {{ .Response }}|im_end| {{ else }}|im_start|assistant {{ end }} # 构建并运行 ollama create qwen25-customer -f /home/user/ollama-modelfiles/qwen25-lora.Modelfile ollama run qwen25-customer第二台知识引擎Phi-3-mini-4K-Instruct Milvus RAG# 拉取模型 ollama pull phi3:mini-4k-instruct-q5_k_m # 启动Milvus单机版Docker docker run -d --name milvus-standalone \ -p 19530:19530 \ -p 9091:9091 \ -v /mnt/milvus:/var/lib/milvus \ --shm-size2g \ --ulimit nofile65536:65536 \ milvusdb/milvus:v2.4.7 # 使用Python脚本见后文将企业知识库PDF批量转为向量并导入Milvus python3 ingest_knowledge.py --pdf-dir /mnt/knowledge --milvus-host 127.0.0.1第三台决策中枢TinyLlama-1.1B Agent Router# 拉取模型 ollama pull tinyllama:1.1b-q4_k_s # 创建Router Modelfile/home/user/ollama-modelfiles/tiny-router.Modelfile FROM tinyllama:1.1b-q4_k_s ADAPTER /mnt/models/tiny-router-lora.gguf PARAMETER num_ctx 2048 PARAMETER temperature 0.1 # 低温度确保决策确定性 TEMPLATE You are an agent router. Classify user query into one of these intents: - knowledge_query: asks for facts, definitions, procedures from knowledge base - data_query: asks for numbers, statistics, status from database - action_request: asks to perform a task (send email, generate report) - chat: casual conversation, no action needed Output ONLY the intent name, nothing else. User query: {{ .Prompt }} Intent: # 构建并运行 ollama create tiny-router -f /home/user/ollama-modelfiles/tiny-router.Modelfile ollama run tiny-router3.3 RAG知识库构建从PDF到可检索向量的全流程RAG效果好坏80%取决于知识库质量。我们不用现成的Unstructured.io而是手写Python脚本确保每个环节可控# ingest_knowledge.py import fitz # PyMuPDF from sentence_transformers import SentenceTransformer from pymilvus import connections, Collection, FieldSchema, DataType, CollectionSchema import os import json # 1. PDF解析保留标题层级与表格结构 def parse_pdf(pdf_path): doc fitz.open(pdf_path) chunks [] for page_num in range(len(doc)): page doc[page_num] # 提取文本块非整页OCR避免乱序 blocks page.get_text(blocks) for b in blocks: if b[4].strip(): # b[4]是文本内容 # 过滤页眉页脚基于Y坐标 if b[1] 50 and b[3] page.rect.height - 30: chunks.append({ text: b[4].strip(), page: page_num 1, source: os.path.basename(pdf_path), section: unknown }) return chunks # 2. 智能分块不按固定长度切而按语义边界 def semantic_chunk(chunks): model SentenceTransformer(all-MiniLM-L6-v2) chunk_embeddings model.encode([c[text] for c in chunks]) # 计算相邻chunk余弦相似度相似度0.65处切分 final_chunks [] current_chunk for i, chunk in enumerate(chunks): if i 0: current_chunk chunk[text] else: sim cosine_similarity([chunk_embeddings[i-1]], [chunk_embeddings[i]])[0][0] if sim 0.65 and len(current_chunk) 100: final_chunks.append({ text: current_chunk, metadata: {k: v for k, v in chunk.items() if k ! text} }) current_chunk chunk[text] else: current_chunk chunk[text] return final_chunks # 3. 写入Milvus简化版 connections.connect(host127.0.0.1, port19530) collection Collection( nameknowledge_base, schemaCollectionSchema([ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue, auto_idTrue), FieldSchema(nametext, dtypeDataType.VARCHAR, max_length65535), FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim384), FieldSchema(namesource, dtypeDataType.VARCHAR, max_length255), FieldSchema(namepage, dtypeDataType.INT32) ]) ) collection.create_index(embedding, {index_type: IVF_FLAT, metric_type: COSINE, params: {nlist: 100}})关键技巧PDF解析不用OCR除非扫描件用PyMuPDF直接提取原生文本保留字体加粗/标题样式分块不用固定512字符而用embedding相似度动态判断语义断裂点——实测使RAG检索相关性提升22%。3.4 三模型协同工作流curl驱动的极简Agent系统没有后端服务器所有逻辑由Shell脚本串联。用户提问时执行./ask.sh 机器报错E102脚本内部流程如下#!/bin/bash QUERY$1 # 步骤1TinyLlama路由决策 ROUTER_RESULT$(curl -s http://localhost:11434/api/generate -d { model: tiny-router, prompt: $QUERY } | jq -r .response) # 步骤2根据路由结果调用不同服务 case $ROUTER_RESULT in knowledge_query) # 调用Phi-3编码query并检索Milvus EMBEDDING$(curl -s http://localhost:11434/api/embeddings -d { model: phi3:mini-4k-instruct-q5_k_m, prompt: $QUERY } | jq -r .embedding) # Python脚本执行Milvus ANN搜索此处省略具体代码 KNOWLEDGE$(python3 search_milvus.py $EMBEDDING) # 将检索结果喂给Qwen2.5生成最终回答 FINAL_ANSWER$(curl -s http://localhost:11434/api/generate -d { model: qwen25-customer, prompt: 基于以下知识回答问题$KNOWLEDGE 问题$QUERY } | jq -r .response) ;; data_query) # 调用预置SQL脚本查数据库结果喂Qwen DB_RESULT$(python3 query_db.py $QUERY) FINAL_ANSWER$(curl -s http://localhost:11434/api/generate -d { model: qwen25-customer, prompt: 将以下数据库结果转化为自然语言回答$DB_RESULT 问题$QUERY } | jq -r .response) ;; esac echo $FINAL_ANSWER整个流程耗时约2.3秒RTX 2060主力机所有组件独立运行任意一台宕机系统自动降级如Phi-3宕机则Qwen2.5用自身知识回答标注“此回答未检索知识库”。4. 常见问题与排查技巧实录那些文档里不会写的血泪教训部署过程中我们记录了37个典型问题。以下是高频、致命、且网上几乎找不到解决方案的5个附真实排查路径与修复命令。4.1 问题1Ollama启动后GPU占用为0模型纯CPU推理延迟暴涨300%现象nvidia-smi显示GPU显存未被Ollama进程占用htop显示CPU满载。排查路径ollama serve启动时加-v参数发现日志中有WARN llama.cpp: failed to initialize CUDA执行nvidia-smi -L确认GPU被识别ls -l /dev/nvidia*发现/dev/nvidia-uvm权限为crw-------非Ollama用户组可读查/etc/group确认ollama组存在但当前用户未加入。终极修复# 将当前用户加入ollama组 sudo usermod -a -G ollama $USER # 重启udev规则 sudo udevadm control --reload-rules sudo udevadm trigger --subsystem-matchnvidia # 重启Ollama sudo systemctl restart ollama注意必须重启udev仅加组不生效。这是NVIDIA驱动与Ollama权限模型的经典冲突90%的教程都漏掉这一步。4.2 问题2Milvus向量检索返回空结果但手动查数据确认存在现象search_milvus.py返回[]但pymilvus.Collection(knowledge_base).num_entities显示有12万条。排查路径检查Milvus日志docker logs milvus-standalone | grep -i search发现WARN SearchTask: invalid vector dimension对比all-MiniLM-L6-v2的embedding维度384与Milvus collection schema默认512确认ingest_knowledge.py中创建collection时未指定dim384。修复命令# 删除旧collection数据会丢失需重跑ingest from pymilvus import utility utility.drop_collection(knowledge_base) # 重建时指定正确维度 collection Collection( nameknowledge_base, schemaCollectionSchema([ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue, auto_idTrue), FieldSchema(nametext, dtypeDataType.VARCHAR, max_length65535), FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim384), # 关键 FieldSchema(namesource, dtypeDataType.VARCHAR, max_length255), FieldSchema(namepage, dtypeDataType.INT32) ]) )4.3 问题3Qwen2.5-7B在长文档总结时输出突然截断末尾缺失现象输入3000字PDF摘要请求输出只到第2800字处戛然而止无报错。根本原因Ollama默认num_ctx2048但Qwen2.5-7B的原生上下文是32768AWQ量化版因精度损失实际有效上下文仅约2400。当输入输出token数超限时llama.cpp底层静默截断。解决方案在Modelfile中显式增大num_ctx并接受轻微性能下降FROM qwen2.5:7b-instruct-q4_k_m PARAMETER num_ctx 4096 # 必须设为40962048不够 PARAMETER num_gpu 1 # 强制使用GPU避免CPU fallback4.4 问题4LoRA微调后模型响应变慢且出现重复token现象微调前1.8秒/请求微调后4.2秒/请求且输出中“的的的”“是是是”高频出现。排查发现LoRA适配器的rrank参数过大设为16导致低秩矩阵乘法引入额外计算开销同时alpha缩放因子未按alpha r * 2设置造成梯度更新幅度过大引发输出震荡。修复参数# 微调时使用 --lora-r 8 \ --lora-alpha 16 \ # alpha r * 2 --lora-dropout 0.1 \ --learning-rate 3e-54.5 问题5三台设备间网络通信不稳定curl偶尔超时现象./ask.sh执行时5次中有1次curl: (7) Failed to connect。根因分析Ubuntu默认net.ipv4.tcp_fin_timeout60而Ollama API短连接频繁TIME_WAIT状态socket堆积耗尽端口。永久修复所有三台设备执行# 编辑sysctl配置 echo net.ipv4.tcp_fin_timeout 30 | sudo tee -a /etc/sysctl.conf echo net.ipv4.ip_local_port_range 1024 65535 | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 重启Ollama使新参数生效 sudo systemctl restart ollama实操心得本地化不是“不用网络”而是“把网络当作可管理的组件”。我们最终在./ask.sh中加入重试逻辑curl --retry 3 --retry-delay 0.5配合上述内核调优超时率降至0.02%。5. 系统扩展与场景深化从Demo到生产级的必经之路这个三模型系统不是终点而是起点。基于当前架构我们已在三个方向深度扩展验证其工业级潜力。5.1 多模态增强让小模型“看见”世界标题中“GPT-6 Astra”被热议的多模态能力其实可拆解为“视觉理解语言生成”两个模块。我们用现有三模型框架无缝接入视觉理解层在第三台设备TinyLlama主机上额外部署SigLIP-So400m视觉模型GGUF Q4_K_S仅1.2GB。当用户上传图片先由SigLIP编码为图像向量再与Phi-3的文本向量拼接输入Milvus进行跨模态检索如拍一张电路板检索匹配的维修手册图文。语言生成层Qwen2.5-7B的LoRA微调数据集新增200条“图文描述”样本如“图中显示一个红色按钮位于面板右下角标签为‘紧急停止’”使其能将视觉检索结果转化为符合SOP的指导语句。实测在产线故障诊断场景图文联合检索使问题定位准确率从76%提升至93%且响应时间仍控制在3.1秒内。5.2 动态知识更新告别“月更知识库”传统RAG知识库更新需停服、重索引、耗时数小时。我们实现“热更新”新增PDF放入/mnt/knowledge/incoming目录inotifywait监听该目录触发ingest_knowledge.py增量处理Milvus支持insert()单条插入无需重建collection同时更新Qwen2.5的LoRA微调数据集加入新文档中的典型问答对每周自动微调一次。整个过程全自动知识从上传到可检索平均耗时47秒。5.3 混合推理当小模型遇到超纲问题系统设计了优雅降级机制当TinyLlama判定为knowledge_query但Phi-3检索返回的相关度均0.3余弦相似度则自动触发“混合推理”将原始query发送至Qwen2.5提示“你未检索到相关知识请基于通用