RAG、Agent与模型优化:大模型落地应用的三条核心技术路线
2026/9/8 23:22:41 网站建设 项目流程

一个成熟的模型应用,往往不是靠一个动作成交的。大部分团队一开始都会被“模型什么都会”这句话带偏,等真上线才发现,同一个模型,放到不同场景里,表现可以千差万别。问内部文档,它可能答得像模像样却全是编的;让它在系统里自动查单、下单,它又经常“手滑”;真到了算成本的时候,调用量一大,按Token计费的账单能让你怀疑人生。

“查资料”“会做事”“省成本”这三件事,在大模型工程里其实是三条不同的技术线。“查资料”靠的是检索增强生成,也就是RAG,本质是给模型接上外部知识库;“会做事”靠的是函数调用和Agent编排,让模型把手伸进业务系统里操作;“省成本”靠的是量化、蒸馏和开源模型本地部署,把推理资源压到最低。这篇文章我会把三条线各自靠什么原理、怎么落地、选型时注意什么,一层层拆开讲,最后给出一套可以直接抄作业的组合方案。

1. 查资料:RAG给模型装上的“外部硬盘”

1.1 为什么模型自己“记不住”资料

很多人第一次看到大模型能对答如流,会下意识以为模型是一本百科全书。但模型记住的知识,本质上是“参数化记忆”——训练过程中把海量文本压缩成了几十亿甚至上千亿个参数。你问它常识、方法、公开知识,它确实能说得头头是道,因为这类内容在训练语料里反复出现,权重里已经刻进去了。

但一旦进入实际业务场景,问题就来了。第一,训练语料有截止日期,新政策、新产品、刚发布的制度它一概不知。第二,也是更致命的,公司内部的合同、规程、售后记录、项目复盘,这些私域文档根本不会出现在任何公开训练集里,模型自然连“见过”都谈不上。第三,参数的容量是有限的,它不可能把自己没见过的东西凭空记下来。

那模型遇到没见过的信息会怎样?它不会坦诚说“我不知道”,而是会用它最擅长的方式处理——把看起来合理的词串出来。一个语言模型最擅长的就是预测下一个词,所以它会一本正经地编一份看似合理的合同条款或者销售数据,这就是我们常说的幻觉。

所以,私域知识类问题,不能靠“问模型”,必须给模型接一条检索链路,让它先查资料、再回答。这正是RAG存在的理由:把外部知识做成可检索的数据库,在模型回答前先把相关资料捞出来,塞进上下文里让它参考。

1.2 RAG标准链路:从文档到答案的八步

我最早做RAG时,以为就是把文档切成小段喂进向量库,然后查一下拼进Prompt就行。真做起来才发现,链路里有八个环节,每一步出错都会让最终回答效果断崖式下跌。

第一步,文档解析。PDF、Word、HTML、扫描件都有各自的坑。PDF里如果带表格,直接按纯文本抽出来经常是乱的;扫描件需要OCR,这一步识别不准,后面全白搭。我现在的习惯是,先按文档类型走不同解析器,解析完做人工抽查,不要一股脑入库。

第二步,清洗与结构化。去掉页眉页脚、目录、重复章节,把标题层级保留下来。标题信息非常重要,因为后面分块和召回都要用到结构信息,比如“2024年第三季度销售数据”这个标题,本身就是一个很好的检索字段。

第三步,分块(Chunking)。这一步决定了后续召回的下限。分块太大会混入无关内容,向量表示会变得模糊;分块太小又可能把完整的知识切碎,导致语义断裂。我常用的策略是按标题层级切块,把每个小标题下的段落作为一个Chunk,长度控制在256到512个Token之间,块与块之间保留10%到20%的重叠,避免关键句被拦腰截断。

第四步,向量化。把每个文本块通过Embedding模型转成向量。中文场景我目前用得比较多的是bge-m3系列,对中文长文本的语义理解比较稳,也可以用来生成查询向量。如果对英文内容多,可以换多语言模型。

第五步,向量入库。把向量写入向量数据库。选项很多,从轻量的Chroma、pgvector,到生产级的Milvus、Qdrant。小项目或者原型阶段,pgvector就够用了,运维负担小;数据量上了几百万,再考虑独立向量库。

第六步,召回。用户提问后,把问题向量化,到向量库做相似度搜索,取回TopK个最相关的Chunk。这一步我用得比较多的是HNSW索引,检索速度很快,但也要记得设置合理的TopK范围,太少会漏,太多会噪声大。

第七步,重排(Rerank)。向量召回是初筛,它只看语义相似度,不够精确。我会先召回Top50,再用一个Rerank模型精排,筛出Top5到Top8作为最终上下文。这一步对效果提升非常明显,千万别省。

第八步,注入与生成。把精排后的内容按固定模板拼进Prompt,并明确告诉模型“只能依据参考内容回答,不能凭空发挥”。生成模型再基于这些材料组织答案,必要时要求它给出引用来源。

1.3 决定效果上限的是“检索质量”,不是回答问题那个模型

许多团队会陷入一个误区:回答得不好,第一反应是换更大的模型。但RAG场景里,回答质量的上限在检索端,不在生成端。我做过一次对照实验:同样用7B小模型做问答,检索质量优化前后,回答的准确率从大概六成直接提到九成以上。模型没换,效果却天差地别,问题就出在“该召回的内容没召回来”。

检索质量主要取决于三件事。

第一件,分块是否合理。如果一份合同被按固定500字机械切块,一条完整条款可能被切进两个Chunk,召回了上半段丢了下半段,模型自然答不完整。这时候把分块策略改成按条款边界切,效果立竿见影。

第二件,元数据过滤有没有做。给每个Chunk打上来源、部门、时间、文档类型这些标签。比如用户问“2024年Q3销售报表”,如果不过滤时间,向量库很可能把2023年、2022年的相似内容一起召回,干扰模型判断。加了时间过滤后,召回准确率会非常明显地提升。

第三件,混合检索要不要上。向量检索擅长语义匹配,但缺点是专有名词、产品编号、合同号这类关键词一旦出现,向量召回很容易被带偏。比较稳的做法是“向量召回加BM25关键词召回,再做结果融合”,最后统一交给Rerank精排。这样既能命中同义表达,又能精确匹配编号和术语。

检索方式擅长场景弱点
纯向量召回同义改写、语义相近专有名词/编号可能失准
BM25关键词召回精确术语、编号匹配对同义表达无感知
向量+BM25融合+重排两种场景都覆盖链路复杂,耗时略高

2. 会做事:从聊天到调用工具的Agent链路

2.1 Function Calling是怎么工作的

RAG解决的是“模型知道什么”的问题,但很多业务需求是“模型做点什么”。比如用户说“帮我查一下订单状态,如果已发货就推送物流消息”,这时候模型不能只输出一句“好的”,它得真的去调订单查询接口、逐条判断、再调消息推送接口。

模型自己当然不会直接调接口。它做的是“输出工具调用意图”——通过训练学会了在特定情况下生成一个结构化的JSON片段,描述它想调用哪个函数、传什么参数。应用层拿到这个JSON后,再真正执行对应的函数代码,把执行结果返回给模型,模型再基于结果继续生成回复。

实际开发时,函数定义的格式在应用侧写好,作为工具描述传给模型。比如要做一个天气查询工具,定义大致是:

{ "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的当前天气和未来三天预报", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,如北京、上海" } }, "required": ["city"] } } }

模型读完工具描述后,如果判断当前问题需要查天气,就会在回复中输出类似这样的内容,而不是直接去执行:

{"name": "get_weather", "arguments": "{\"city\":\"北京\"}"}

应用层解析这个输出,调用真正的天气API,再把“北京今天晴,最高温度12度”这样的结果回填给模型。模型据此组织成最终的自然语言回答。

为什么不干脆让模型自己写代码执行?因为模型生成的代码不稳定,直接执行等于把一个不可控程序放进生产环境,安全和正确性都没法保证。而函数调用把“决策”和“执行”分离,模型只负责判断调用哪个工具、传什么参数,真正执行的是你在代码里反复测试过的函数。这个设计非常重要,我建议所有做Agent应用的人都把这个边界守住。

2.2 多步任务靠Agent循环

一次函数调用只能完成一个动作,但真实业务很少只有一步。用户说“帮我整理一下本周所有待办,把今天该做的标出来,并且给相关负责人发一封催办邮件”,这就涉及查待办、分类、查人员、发邮件四个动作,而且还有依赖关系。

这种多步任务,需要的是Agent循环。目前工业界最常用的是ReAct模式:模型先思考,然后决定执行什么动作,执行完看到观察结果,再继续思考,循环往复,直到任务完成。流程可以概括为:思考(Thought)→ 动作(Action)→ 观察(Observation)→ 再思考。

我举个例子。用户要求“查一下最近一周的主机CPU使用率,如果超过80%,请生成一份关注清单”。Agent会先调用“查询监控数据”工具,拿到一堆指标数据,发现有三台机器超过阈值,于是调用“生成清单”工具,把三台主机的信息整理成文档,最后再调用“发送通知”工具推送给指定负责人。整个过程,模型需要根据每一步的结果动态调整下一步动作,而不是脚本提前写死的。

但工程上绝对不能把Agent循环做成“无限循环”。我在实际项目里会强制做几层约束:最大迭代轮数要设上限,比如20轮;每个工具调用要有超时时间;工具白名单严格限定,不允许模型调用业务之外的接口;涉及发送消息、修改数据这类敏感操作,要加人工确认节点。这些约束在演示时看着多余,但生产环境里能避免90%的“Agent发疯”事故。

2.3 本地模型做Agent,选型和量化都要注意

做Agent不一定要用云端大模型,很多场景因为数据合规或成本原因,需要本地模型来承担工具调用。但这里有个现实问题:开源模型的工具调用能力参差不齐,选型不对,整个链路就崩了。

我踩过的坑是,拿一个早期版本的聊天模型硬套Function Calling,结果它经常不按格式输出,要么把参数名改了,要么把JSON输出成Markdown代码块。应用层解析直接报错,Agent循环里全是异常重试。

后来我把开源模型筛了一遍,稳定能跑工具调用的主要看几个系列:Qwen2.5系列、GLM-4系列、Llama 3.1系列都对函数调用做了专门对齐,格式规范。中文场景,Qwen2.5-7B和GLM-4-9B都是性价比比较高的选择;如果要求更强推理能力,可以把Qwen2.5-14B甚至更大的模型拿来做本地推理。

另一个坑是量化等级。做纯问答时,Q4量化可能还能接受,但做工具调用时,量化等级过低会导致输出的JSON格式漂移。我的建议是,凡是涉及工具调用和Agent链路的模型,量化等级至少从Q5_K_M起步,条件允许直接用Q8_0。别为了省那一点显存,牺牲格式稳定性。后面章节我会详细讲量化和成本的关系。

3. 省成本:量化、蒸馏、本地部署三条路线

3.1 成本花在哪:推理端的账要会算

模型应用的账,大头在推理端,不是训练端。很多团队一说降本,就打算去重新训练一个模型,这是误区。训练是一次性投入,推理是每次调用都要付钱,随着业务量上涨,推理成本的滚雪球速度非常恐怖。

推理成本到底高在哪?三个方面。第一,模型参数占用的存储和带宽,参数越大,每次前向传播的计算量越大。第二,上下文越长,KV Cache占的显存和带宽越多。第三,并发请求越多,需要的GPU资源就越多,服务端的排队和延迟也会抬升成本。

我经常用JVM内存模型来给团队做类比。JVM运行时不是只有堆内存,还要区分栈、方法区、直接内存;大模型推理时也不只是“把模型权重加载进显存”就完事,还要算上KV Cache、临时激活值、调度缓冲。很多人想省钱,只盯着模型权重大小,结果上下文从4K调到32K以后,显存莫名其妙就爆了,就是因为KV Cache部分被忽略了。上下文越长,KV Cache占据的显存几乎线性增长,这个账必须提前算。

3.2 量化:把模型“压扁”再塞进小显存

量化是目前最直接的省成本手段。它的原理很简单:模型参数原本用FP16(16位浮点数)存储,每个参数占2字节;量化后改成INT8甚至INT4,每个参数只占1字节或0.5字节。参数变小,模型占用显存变小,推理速度变快,成本自然降下来。

本地部署大模型,目前最常用的是GGUF格式,配合llama.cpp系列推理框架。GGUF支持多种量化等级,不同等级在体积、速度、效果之间做取舍。以7B模型为例,各量化等级的大致情况如下:

量化等级7B模型权重体积建议显存质量损失
FP16约13GB16GB以上基线
Q8_0约7.2GB10GB以上非常小
Q5_K_M约5.2GB8GB以上可接受
Q4_K_M约4.1GB6GB以上有一定损失
Q2_K约2.8GB4GB以上明显

我的经验是,通用对话和内容生成场景,Q5_K_M和Q4_K_M是比较划算的选择,肉眼感受不到太大差别;但涉及工具调用、代码生成、数学推理这类对格式和逻辑要求高的场景,最好用Q8_0甚至原版FP16。量化省下来的成本,可能最后要花在更多次重试和调试上。

实际操作非常简单。本地装好Ollama之后,拉取一个已经量化好的模型就行:

ollama pull qwen2.5:7b-instruct-q4_K_M

模型下载完成之后直接通过兼容OpenAI的接口调用即可。这套流程把本地模型部署的门槛降到很低,也是很多中小团队选它的原因。

3.3 蒸馏:小模型继承大模型的“作业”

量化的思路是把大模型“压缩”,蒸馏的思路则是“再造一个小模型,并让它学大模型的本事”。知识蒸馏的做法是:用大模型(比如能力很强的商用闭源模型)生成大量高质量的输入输出对,然后拿这些数据去微调一个小尺寸开源模型。

举个例子,我想做一个客服意图分类模型。与其让我手写几百条规则,不如让大模型按照我的分类体系生成一万条示例对话,再把这些数据拿去微调一个7B模型。最终效果是,这个7B模型在“客服意图分类”这个垂直任务上的准确率,可能超过同等尺寸的通用模型,而推理成本只有大模型的零头。

但别神化蒸馏。小模型的结构决定了它的上限,复杂推理、长链条规划、抽象归纳这些能力,小模型再怎么学也追不上大模型。蒸馏更适合“把某个窄领域任务做到够用”,不适合指望它全面替代超大模型。我通常会把蒸馏用在意图识别、信息抽取、格式改写这类单一、重复、规则相对稳定的任务上。

3.4 本地部署:免费模型不是零成本

开源模型加本地部署,看起来API费用直接归零,很多老板一听就觉得“省钱了”。但真正算总账,本地部署的成本结构完全不一样。

硬件采购或租赁费用跑不掉。一个7B量化模型,配合长上下文运行,建议准备16GB以上显存,或者直接上64GB内存靠CPU推理也行,但性能会差很多;14B级别,32GB显存是相对宽裕的配置;再往上跑70B级别,就得组多卡或上大显存服务器了。其次是运维成本,环境部署、模型升级、监控告警、故障恢复,都得有人盯。最后是模型升级成本,开源模型版本迭代很快,每半年到一年可能就要重新评估、重新适配。

那本地部署到底省在哪?边际成本。API模式是按Token付费,调用量越大,费用越高。本地部署是一次性投入加电力成本,上线后推理次数再高,边际成本也几乎是零。所以我的判断是:并发量高、调用频繁、数据敏感的项目,适合本地部署;调用量不稳定、需要快速实验的场景,反而用API更灵活。

4. 三件事合体:一套可复用的落地架构

4.1 分层架构参考

只谈单项技术没有意义,实际应用里,RAG、Agent、模型优化三个能力要组合成一个完整系统。我在项目里通常分成四层来设计。

数据层负责接入各种数据源,包括企业内部文档、数据库、业务系统API、日志流。这一层要做大量脏活累活,比如文档格式转换、接口鉴权、数据清洗,但它是上层能力的基础。

能力层封装各类模型能力,包括Embedding模型、Rerank模型、主对话模型、工具执行器。RAG的检索链路和Agent的函数调用都挂在这一层,对外提供统一接口,上层不需要关心底层是本地模型还是API模型。

调度层负责意图判断和任务编排。用户的请求进来,先判断是走RAG问答,还是需要调用工具,或者两者结合。Agent循环、路由策略、安全校验也都在这层做。

应用层是面对用户的入口,可能是问答机器人、运维助手、客服工作台。这层只跟调度层交互,保持轻量,方便快速迭代。

这个分层的好处是,每一层都可以独立替换。想换一个更好的Embedding模型,只改能力层;想从API模型切到本地模型,只改调度层配置。我在实际项目中经常只改一层就能明显提升整体效果。

4.2 不同预算下的组合方案

为了节约试错时间,我把不同预算下的推荐组合整理成了一个表格,方便直接对照参考。

预算级别主模型选择检索方案工具能力适用场景
低预算本地7B-14B量化模型bge-m3向量检索 + BM25混合 + Rerank仅限2-3个简单工具,人工确认内部知识库问答,数据不出内网
中预算本地14B模型 + 按量调用云端大模型同上,增加自动路由中等复杂度Agent,需超时和重试客服辅助,流程自动化初阶
高预算私有化部署大参数模型集群大规模向量库,全链路监控多工具并行、复杂任务规划金融、医疗等对安全和效果要求都很高的场景

低预算方案是我最推荐的起步方式。先用本地小模型把整个链路跑通,数据库、工具接口、前端交互都验证了,再根据瓶颈决定要不要加预算。很多项目一上来就上云大模型,花了大钱,最后发现数据采集和工具对接才是真正卡住的地方。

4.3 我建议的分工原则

做组合方案时,我有一条核心原则:把三种能力拆开分配,不要指望一个模型全干。

“查资料”会更倾向于本地化。私域数据通常有合规要求,不能随便出内网,本地Embedding加本地量化模型,既能保证数据安全,又能保证检索质量。“会做事”会更重视稳定性,工具调用链路一旦崩了,会给业务造成实际损失,所以宁可选用格式稳定、经过充分验证的模型,也不要为了省钱选一个输出容易漂移的小模型。“省成本”则优先压推理端,从量化、蒸馏、路由三个方向同时下手,而不是动不动就重训模型。

另外,我强烈建议在系统里加一个简单的路由层。问题简单时用小模型处理,问题是高难度推理时再调度大模型。我做过一个线上系统,大概有60%到70%的请求是小模型能搞定的,路由机制直接让总成本降了一半以上。这个优化点,很多人一开始都意识不到。

5. 常见问题与排查技巧实录

5.1 回答被截断:输出Token上限的坑

实际运行里最常遇到的故障就是回答写到一半停住了,或者接口直接报“已达到输出Token上限”。很多新手的第一个反应是加大模型参数,但其实问题往往出在请求侧的max_tokens设置上。

我处理过的一个案例:一个长文档总结任务,模型已经把内容组织好了,但max_tokens只设了512,结果输出到一半被切断,而且切得很不是地方,看起来就像模型“不会回答”。把max_tokens调到1024甚至2048之后,问题立刻解决。

但这里有个隐藏问题:模型是会把“已有输出保留在对话中”的,被截断后如果直接让模型“继续”,它可能会重新组织语言,而不是接着后半段写,导致内容重叠。更稳的做法是,把长文生成任务拆解成多段,分段生成再拼接;或者让模型先输出一个结构化大纲,再逐段扩写。不要依赖“继续”这种补救手段。

5.2 RAG召不回、召回不准怎么办

RAG最常见的故障是“用户问题明明在文档里有,模型却回答不知道”。我排查这个问题的顺序很固定:先单独测试向量召回,把TopK结果直接打印出来看相关度。

如果TopK结果相关度就很低,那问题大概率出在Embedding或者分块上。检查分块是不是把完整信息切碎了,或者查询语句里的专业术语没有在向量语义层面和文档匹配上。这时候上混合检索,加上BM25关键词召回,通常能救回来。

如果召回结果相关度很高,但最终回答还是不对,那问题在生成端。检查注入Prompt的模板,是不是没有明确告诉模型“只能依据参考内容回答”,或者召回的内容太多,把关键信息淹没在噪声里。精排时把TopK从50缩到5到8,往往有奇效。

5.3 Agent死循环、工具调用格式错乱

Agent应用跑一段时间,最让人头疼的问题就是模型的循环退化。现象是,同一个工具被反复调用,参数也不变,每一次观察结果都一样,但模型就是停不下来。

这种情况,先在工程层做兜底:最大迭代轮数、工具调用超时、结果去重判断。如果工具返回的结果跟上一次完全相同,就直接打断循环,让模型换策略。另一个常见原因是量化等级太低,导致工具输出JSON格式漂移,应用层解析失败后反复重试。遇到这种情况,先用量化等级高一点的模型做对比测试,如果马上恢复正常,那就不是模型智商问题,是量化把格式稳定性压坏了。

5.4 量化后的模型“变笨”了

量化确实会在某些能力上打折。我实测过,同样一个14B模型,Q4量化后在做简单问答时几乎感觉不到差别,但在做代码生成和复杂推理时,错误率会明显上升。

因此不要一刀切选择最低量化等级。生产环境建议给不同任务配置不同量化等级,路由层根据任务类型把请求分发到不同等级的模型实例上。低难度意图识别用Q4,中等难度的问答和抽取用Q5,涉及代码和工具调用的请求用Q8或原版。这套组合比单一量化等级更省成本,也更稳。

另一个建议是,在本地建立一份20到50条的业务回归问题集,每次切换模型、升级版本或者调整量化等级后,都跑一遍这份回归集。很多模型综合评测榜单上的高分,放到你的业务场景里未必好用。跑完自己业务集,比看什么榜单都靠谱。

回到开头那个问题:模型查资料、会做事、还省成本,分别靠什么?一句话回答就是:查资料靠RAG把外部知识接进来,会做事靠Function Calling和Agent把工具交到模型手里,省成本靠量化、蒸馏和本地部署把推理开销压下来。这三条线可以独立使用,也可以组合成一个完整系统。我个人经历里最深的经验是,别把模型当成什么都懂、什么都会、还便宜的全能选手,把它当成一个需要给资料、给工具、控制成本的“聪明新员工”,反而能把它的价值发挥到最大。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询