AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG

一、量化的本质是什么?

大模型量化的本质,不是简单地把 FP16、FP32 直接转换成 INT8 或 INT4,而是要在"模型压缩"和"能力保持"之间做工程平衡。

模型原本的权重和激活值通常使用高精度浮点数表示,比如 FP16 或 FP32。量化之后,部分数值会被映射成低精度整数,比如 INT8、INT4,甚至更低 bit 的表示。

这样做的直接好处是:

text 复制代码
模型参数更小;
显存占用更低;
内存带宽压力更小;
推理速度可能更快;
部署成本更低。

但它也会带来代价:

text 复制代码
数值精度下降;
量化误差增加;
模型输出可能变差;
极端情况下会出现精度崩塌。

所以量化真正要解决的问题不是"能不能压缩",而是:

text 复制代码
如何在压缩模型的同时,尽量不破坏模型原有能力。

1. 量化最底层的数学映射

量化的核心公式可以写成:

text 复制代码
Real = Scale × (Quantized - ZeroPoint)

也就是:

text 复制代码
真实浮点值 = 缩放因子 ×(量化整数值 - 零点)

这里有几个关键概念:

概念 含义
Real 原始浮点值,比如 FP16 / FP32
Quantized 量化后的整数值,比如 INT8 / INT4
Scale 缩放因子,用来控制整数和浮点数之间的比例
ZeroPoint 零点,用来表示浮点数里的 0 对应哪个整数值

可以简单理解为:

text 复制代码
浮点数范围更大、更细;
整数范围更小、更粗;
Scale 和 ZeroPoint 负责建立两者之间的映射关系。

比如 INT8 只有 256 个可能值,如果要用它表示一段连续的浮点数区间,就必须把浮点数压缩到这个整数范围里。压缩过程越粗,信息损失就越明显。

因此,量化不是简单的数据类型转换,而是一种带有误差的近似表示。


2. 对称量化和非对称量化

量化方式通常可以分成对称量化和非对称量化。

对称量化一般可以理解为:

text 复制代码
ZeroPoint = 0

它的整数范围围绕 0 对称,比如:

text 复制代码
[-127, 127]

这种方式计算简单,硬件执行效率也比较高。但如果原始数据分布本身不是对称的,就可能浪费一部分表示空间。

非对称量化允许:

text 复制代码
ZeroPoint ≠ 0

它更适合表示偏移明显的数据分布,比如某些激活值大部分都在正数区间。非对称量化对数据分布的适应性更强,但计算逻辑会更复杂一些。

可以简单理解为:

text 复制代码
对称量化:以 0 为中心,计算简单;
非对称量化:允许整体偏移,更适合非对称分布。

在实际工程中,到底选择哪一种方式,要看模型权重和激活值的分布,也要看推理框架和硬件是否支持。


3. 量化粒度:Per-Tensor、Per-Channel、Per-Group

量化不只是决定用 INT8 还是 INT4,还要决定 Scale 和 ZeroPoint 按什么粒度分配。

常见粒度有三类:

text 复制代码
Per-Tensor
Per-Channel
Per-Group

Per-Tensor 是整个张量共用一组 Scale 和 ZeroPoint。

它的优点是实现简单、计算高效、额外参数少。缺点是精度损失可能比较大,因为一个大矩阵里不同区域的数据分布可能差异很大,强行共用一套缩放参数,会导致某些区域表示得不够精细。

Per-Channel 是每一行或每一列单独分配一组 Scale 和 ZeroPoint。

它比 Per-Tensor 更细,能更好适应不同通道的数据分布。很多模型量化都会采用这种折中方式,因为它在精度和成本之间比较平衡。

Per-Group 是把一行或一列再切成多个小组,比如每 128 个元素一组、每 64 个元素一组,或者每 32 个元素一组,然后每一组单独使用一套量化参数。

它比 Per-Channel 更细,也比逐元素量化更高效,所以在大模型 INT4 量化里非常常见。

可以这样理解:

text 复制代码
Per-Tensor:整张表用一把尺子;
Per-Channel:每一行或每一列用一把尺子;
Per-Group:每一小段用一把尺子。

粒度越细,精度通常越好,但额外存储和计算管理成本也会更高。大模型量化里常见的 group size,比如 128、64、32,本质上就是在精度和成本之间做平衡。


4. 大模型量化最难处理的是离群值

大模型量化比普通神经网络量化更难,一个重要原因是权重和激活值里经常存在离群值。

也就是某些数值远远大于其他普通值。

量化需要确定一个表示范围。如果为了覆盖这些极大的离群值,就会导致大部分普通值被压缩到很小的整数区间里。

结果可能变成:

text 复制代码
少数极大值被保住了;
大量正常值被挤压到 0、1、-1 附近;
模型信息大量丢失。

这就是常说的 Activation Outliers,也就是激活值离群点问题。

它可能导致:

text 复制代码
量化误差变大;
模型输出不稳定;
模型能力下降;
严重时精度崩塌。

所以大模型量化的难点,不只是把参数变小,而是如何处理不同张量分布和激活离群点。

如果忽略离群值,直接用一个统一范围去量化,结果可能是少数异常大值决定了整个量化范围,而绝大多数正常值反而被压得很粗。模型中很多细微信息就会在这个过程中丢失。


5. 两条主流路线:Weight-Only 和 Weight + Activation

前沿量化方案大体可以分成两条路线。

第一条是 Weight-Only Quantization,也就是仅权重量化。

典型形式比如:

text 复制代码
W4A16

意思是:

text 复制代码
权重用 4 bit;
激活值仍然用 16 bit。

这种方式主要解决的是模型权重太大、显存占用太高、内存带宽压力太大的问题。

它的优点是精度更容易保持,实现相对更稳,也更适合大模型部署。缺点是激活值没有被量化,所以计算过程未必完全变成低精度整数计算,加速效果可能不如全量化彻底。

第二条是 Weight + Activation Quantization,也就是权重和激活都量化。

典型形式比如:

text 复制代码
W8A8

意思是:

text 复制代码
权重用 8 bit;
激活值也用 8 bit。

这种方式不仅压缩权重,还能让计算过程更适合低精度整数运算。它更容易获得真实推理加速,也更适合硬件上的 INT8 计算。

但它的难点也更明显:

text 复制代码
激活值更难量化;
离群点问题更严重;
精度保持更困难。

所以 W8A8 的关键不是简单地"把激活值转成 INT8",而是要先处理激活值分布,让它更适合低精度表示。

可以这样简单区分:

text 复制代码
W4A16:主要压缩模型权重,部署更稳;
W8A8:权重和激活都压缩,更利于硬件加速,但处理难度更高。

6. 常见解决思路:GPTQ、AWQ、SmoothQuant

大模型量化里有几类代表性思路。

GPTQ 这类方法可以理解为"二阶信息补偿"。它不是简单粗暴地四舍五入,而是会考虑某个权重量化错误一点,对最终损失影响大不大。它会利用损失函数的二阶信息来判断哪些权重更重要,并在量化过程中尽量补偿误差。

AWQ 这类方法可以理解为"激活感知权重保护"。它认为不是所有权重都一样重要,和高激活值相关的权重更值得保护。于是它会观察激活值分布,找出少量重要通道,在量化前对这些关键权重做缩放保护。

SmoothQuant 的思路是"平滑激活分布"。激活值往往比权重更难量化,所以它通过数学上的等价变换,把一部分激活量化难度转移到权重上。

直观理解就是:

text 复制代码
激活值太尖、太不平滑;
通过缩放把激活值变得更平滑;
同时对权重做反向补偿;
让整体计算结果尽量保持不变。

这样就能让激活值更适合 INT8 量化。

这些方法虽然具体实现不同,但目标是一致的:

text 复制代码
减少量化误差;
保护关键通道;
处理激活离群值;
尽量保持模型原有能力。

7. 量化问题可以怎么总结?

大模型量化的核心,是用低精度整数近似表示原来的高精度浮点权重或激活值。它通过 Scale 和 ZeroPoint 建立浮点数与整数之间的映射关系,从而减少模型存储、显存占用和内存带宽压力,并在合适硬件上提升推理速度。

但大模型量化的难点不只是数值映射,而是如何在压缩模型的同时保持精度。因为大模型的权重和激活值分布并不均匀,尤其是激活值中经常存在离群点。如果直接全局量化,少数极大值会拉大量化范围,导致大量正常值被压缩,最终造成精度损失。

所以工程上通常会从三个层面优化:

text 复制代码
选择合适的量化粒度,比如 Per-Tensor、Per-Channel、Per-Group;
选择合适的量化对象,比如 W4A16 或 W8A8;
通过 GPTQ、AWQ、SmoothQuant 等方法处理误差、关键通道和激活离群值。

因此,量化本质上是一个"低精度近似 + 误差控制 + 硬件友好"的综合工程问题,而不是简单地把 FP16 直接转换成 INT8 或 INT4。

二、在大模型应用里,Workflow 和 Agent 到底有什么区别?什么时候该用固定流程,什么时候该让大模型自主决策?

在大模型应用里,Workflow 和 Agent 的区别,本质上是控制流归属不同。

text 复制代码
Workflow:流程由开发者提前设计;
Agent:流程由大模型根据目标和环境动态决定。

更简单地说:

text 复制代码
Workflow 是人控制流程;
Agent 是模型控制流程。

Workflow 更像铁轨列车,路线提前铺好;Agent 更像自动驾驶,目标明确,但路线会根据环境动态调整。


1. Workflow 是什么?

Workflow 可以理解为开发者提前设计好的固定流程。

它的每一步怎么走、先做什么、后做什么、遇到什么情况走哪个分支,基本都由工程代码提前定义好。

比如:

text 复制代码
收到用户请求
  ↓
识别用户意图
  ↓
进入固定分支
  ↓
调用指定工具
  ↓
返回结果

在 Workflow 中,大模型通常只是其中一个执行节点。

它可能负责:

text 复制代码
意图识别;
文本分类;
信息抽取;
格式化输出;
简单判断。

但整个控制流不是大模型自己决定的,而是开发者写死或半写死的。

Workflow 最大的优点是确定性强。

它适合流程清楚、规则明确、容错率低的业务,比如:

text 复制代码
退款流程;
合同审核;
财务审批;
合规检查;
订单状态查询;
客服工单流转。

这些场景里,系统最重要的不是"聪明",而是:

text 复制代码
稳定;
可控;
可审计;
可回滚;
可测试。

所以 Workflow 的优势很明显:

特点 说明
确定性强 每一步都是提前设计好的
易于调试 出问题可以定位到具体节点
容易测试 每个节点输入输出都可以做测试
适合合规业务 关键流程不依赖模型临场发挥
可观测性好 日志、状态、异常都容易追踪

但 Workflow 也有明显缺点:灵活性不足。

只要用户的问题超出了预设分支,Workflow 就容易处理不了。

比如用户不是简单问"我要退款",而是问:

text 复制代码
我之前买了一个会员,但是后来又升级了套餐,现在想取消其中一个订单,
不过我不确定会不会影响另一个订阅,你帮我看一下怎么处理?

这种问题可能涉及订单、订阅、退款规则、用户历史、产品策略和客服话术。如果只靠固定 Workflow,就很容易出现分支爆炸。

所以 Workflow 适合稳定流程,但不适合处理所有开放式问题。


2. Agent 是什么?

Agent 可以理解为由大模型根据目标,自主决定下一步做什么。

开发者给 Agent 的不是完整流程,而是:

text 复制代码
目标;
工具;
约束;
环境信息;
可执行动作。

然后 Agent 自己决定:

text 复制代码
先查什么;
调用哪个工具;
是否需要继续检索;
是否需要写代码;
是否需要调用数据库;
是否需要重新规划;
什么时候结束。

一个典型 Agent 流程可能是:

text 复制代码
用户提出复杂任务
  ↓
LLM 理解目标
  ↓
拆解步骤
  ↓
选择工具
  ↓
执行工具
  ↓
观察结果
  ↓
重新判断下一步
  ↓
循环直到完成任务

这就是很多 ReAct Agent 的基本思路:

text 复制代码
Reasoning + Acting

也就是一边推理,一边行动。

Agent 最大的优点是灵活性强。

它适合路径不固定、任务模糊、需要探索的问题,比如:

text 复制代码
帮我分析这个项目为什么构建失败;
帮我查一下这个用户投诉背后的真实原因;
帮我根据日志定位线上问题;
帮我研究一下竞品的功能设计;
帮我写一个数据分析脚本并解释结果。

这些任务有一个共同特点:

text 复制代码
目标是明确的,但解决路径不一定提前知道。

Agent 的优势是:

特点 说明
灵活性强 可以根据中间结果调整下一步
适合复杂任务 可以拆解、检索、调用工具、反复修正
有探索能力 不局限于预设分支
能处理模糊需求 可以边做边观察,边观察边判断
更接近人类工作方式 像一个会使用工具的助手

但 Agent 的问题也很明显:可控性弱。

常见风险包括:

text 复制代码
死循环;
工具选错;
参数生成错误;
调用顺序错误;
目标跑偏;
幻觉;
Token 消耗过大;
高风险动作误执行;
调试困难。

所以,纯 Prompt 驱动的 Agent 在真实工程里通常不够可靠。


3. Workflow 和 Agent 的核心区别

可以用一张表来区分:

对比项 Workflow Agent
控制流 开发者预先定义 大模型动态决定
任务路径 固定或半固定 不固定,可探索
适合场景 规则明确、流程稳定 目标明确、路径复杂
可靠性 相对较低
灵活性
可测试性 较弱
可观测性 需要额外设计
典型类比 铁轨列车 自动驾驶
工程重点 流程编排、节点校验 状态管理、工具治理、边界控制

最简单的判断方式是:

text 复制代码
能画成稳定流程图的,用 Workflow;
画不清楚流程,但目标明确的,用 Agent;
流程主干清楚,局部节点复杂的,用 Agentic Workflow。

也可以从风险角度判断:

text 复制代码
容错率低、规则明确、高风险动作多 → 优先 Workflow;
路径不确定、探索性强、多轮工具调用多 → 可以引入 Agent;
主流程稳定但局部复杂 → 使用 Agentic Workflow。

4. 为什么真实项目里不能只用 Agent?

很多人刚开始做大模型应用时,会觉得 Agent 更智能,所以所有任务都可以交给 Agent。实际并不是这样。

Agent 一旦进入生产环境,就会遇到很多问题。

第一类问题是死循环。

在 ReAct 模式下,Agent 会反复执行:

text 复制代码
思考 → 调工具 → 观察结果 → 再思考 → 再调工具

如果目标不清楚,或者工具返回结果不符合预期,Agent 可能会反复调用同一个工具,或者一直尝试无效路径。

最后可能导致:

text 复制代码
Token 爆炸;
接口反复调用;
任务超时;
成本飙升。

所以工程上必须加:

text 复制代码
最大迭代次数;
超时机制;
状态机;
失败退出条件;
人工确认节点。

第二类问题是工具调用失败。

Agent 一旦挂了很多工具,比如超过 5 到 10 个,模型就容易出现:

text 复制代码
选错工具;
漏填参数;
参数类型错误;
JSON 格式错误;
调用顺序错误;
把 A 工具的参数传给 B 工具。

所以工程上需要做:

text 复制代码
工具分层;
工具路由;
Schema 严格校验;
参数强制解析;
错误重试;
工具调用日志;
反例约束。

不要把所有工具都塞给一个"超级大脑"。

第三类问题是业务风险。

财务、合规、权限、订单、支付这类高风险场景,通常应该优先使用 Workflow。Agent 可以给建议,但不应该随意直接执行最终动作。

比如:

text 复制代码
退款;
删除数据;
发送邮件;
修改订单;
执行数据库写操作;
提交审批。

这些动作最好由固定 Workflow 执行,并在关键节点加入人工确认。


5. 什么是 Agentic Workflow?

真实项目里更稳的方案,通常不是 Workflow 和 Agent 二选一,而是 Agentic Workflow。

Agentic Workflow 可以理解为:

text 复制代码
外层用 Workflow 管住流程边界;
内层在复杂节点中引入 Agent 的自主能力。

也就是:

text 复制代码
Workflow 保证系统稳定下限;
Agent 提升复杂任务处理上限。

比如一个企业客服系统,可以这样设计:

text 复制代码
节点 1:解析用户邮件
  ↓
节点 2:Agent 查询知识库、判断问题类型、生成处理建议
  ↓
节点 3:合规审核
  ↓
节点 4:固定流程发送回复

这里面:

text 复制代码
节点 1、3、4 是 Workflow;
节点 2 是 Agent。

这样既保留了 Workflow 的稳定性,又利用了 Agent 的灵活性。

一个典型 Agentic Workflow 架构可以写成:

text 复制代码
用户请求
  ↓
入口分类器
  ↓
任务路由
  ↓
固定 Workflow 主流程
  ↓
复杂节点调用 Agent
  ↓
Agent 使用工具 / RAG / 数据库 / 代码执行
  ↓
结构化结果返回 Workflow
  ↓
业务校验
  ↓
人工确认 / 自动执行
  ↓
最终输出

核心原则是:

text 复制代码
Agent 不直接接管整个系统,只在需要智能判断的局部节点中工作。

这样可以避免纯 Agent 失控,也可以避免纯 Workflow 过于死板。


6. 工程落地时要加哪些控制机制?

如果要把 Agent 做成生产级系统,不能只靠 Prompt。

至少需要这些机制:

text 复制代码
状态管理;
最大迭代次数;
工具分层;
Schema 校验;
Human-in-the-loop;
全链路观测。

状态管理是为了让 Agent 每一步都有明确状态,比如:

text 复制代码
任务开始;
正在检索;
正在调用工具;
工具调用失败;
等待用户确认;
任务完成;
任务失败。

最大迭代次数是为了防止 Agent 无限循环,比如最多思考 5 次、最多调用工具 8 次、单个任务最多运行 60 秒。

工具分层是为了避免所有工具都暴露给模型。更合理的做法是:

text 复制代码
先判断任务类型;
再选择工具集合;
再让 Agent 在小范围工具里选择。

Schema 校验是为了保证工具输入输出结构化,避免自然语言传参导致格式漂移。

Human-in-the-loop 是为了控制高风险动作,比如退款、删除数据、发送邮件、修改订单、执行数据库写操作等。

全链路观测是为了让系统能够回答这些问题:

text 复制代码
为什么选这个工具?
传了什么参数?
工具返回了什么?
下一步为什么这么做?
最终结论来自哪些依据?

否则 Agent 出了问题很难排查。


7. Workflow 和 Agent 可以怎么总结?

Workflow 和 Agent 的核心区别在于控制流归属不同。

Workflow 的控制流由开发者提前定义,大模型只是流程中的一个执行节点;Agent 的控制流则由大模型根据目标、上下文和工具返回结果动态决定。

Workflow 更像铁轨列车,路径固定、确定性强、容易测试和审计,适合退款、审批、合规、财务、订单处理等规则明确、容错率低的场景。

Agent 更像自动驾驶,开发者给它目标、工具和边界,它自己拆解任务、选择工具、观察结果并调整下一步,因此更适合代码分析、日志排查、复杂问答、研究调研等路径不确定的场景。

但工程上不能简单认为 Agent 一定比 Workflow 高级。纯 Agent 容易出现死循环、工具误调用、参数错误、目标漂移和不可观测等问题;纯 Workflow 又缺少处理复杂模糊任务的灵活性。

所以真实的大模型架构通常会演进为 Agentic Workflow,也就是外层用 Workflow 控制主流程和安全边界,内层在复杂节点中引入 Agent 的推理、检索和工具调用能力。

三、在多轮对话中,用户经常不会把问题说完整,只说一句"那它还有什么优势?",系统应该如何准确检索?

在多轮对话 RAG 中,用户经常不会把问题说完整,而是会沿着前面的上下文继续追问。比如前面刚讨论完两个方案的差异,用户接着问一句:

text 复制代码
那它还有什么优势?

这句话对人来说很好理解,因为人可以结合前面的对话判断"它"指的是谁。但对检索系统来说,这句话本身信息非常少。如果直接拿它去做向量检索或关键词检索,很容易召回一堆泛化内容,最后导致回答偏离用户真正想问的问题。

所以,多轮对话 RAG 的关键不是直接搜索用户原话,而是先结合上下文补全用户真实意图,再生成一个可以独立检索的问题,最后进入检索、重排和生成流程。

简单来说,就是:

text 复制代码
上下文省略问题
  ↓
上下文补全
  ↓
Query Rewrite
  ↓
Standalone Query
  ↓
混合检索
  ↓
Rerank 重排
  ↓
基于证据生成回答

1. 为什么省略问题不能直接检索?

"那它还有什么优势?"这句话最大的问题是语义不完整。

它至少缺少两个核心信息:

text 复制代码
"它"指的是谁?
"优势"是相对于谁的优势?

假设前面的对话是在比较传统 RAG 和 GraphRAG:

text 复制代码
用户:传统 RAG 和 GraphRAG 有什么区别?
系统:传统 RAG 更偏向基于文本片段召回,GraphRAG 更强调实体、关系和全局结构。
用户:那它还有什么优势?

这里的"它"大概率指的是 GraphRAG,"优势"也不是泛泛而谈,而是指 GraphRAG 相比传统 RAG 的优势。

如果系统直接把下面这句话送进检索层:

text 复制代码
那它还有什么优势?

向量数据库并不知道"它"是谁,BM25 也只能看到"优势"这种非常宽泛的词。结果很可能召回一些和当前话题关系不大的内容,比如某个产品优势、某个方案优势,甚至完全不是 GraphRAG 相关的内容。

这类问题可以称为 Contextual Query,也就是依赖上下文才能理解的问题。

像下面这些表达,都属于典型的 Contextual Query:

text 复制代码
那它呢?
这个还有什么问题?
上面那个方案适合什么场景?
还有别的吗?
为什么会这样?

这些表达在真实对话里非常自然,但对检索系统不友好。检索系统需要的是语义完整、实体清楚、范围明确的查询语句,而不是一句依赖上下文的省略表达。

所以,多轮 RAG 的第一步不应该是直接检索,而是先判断用户这句话是否可以独立表达完整语义。

如果省略问题不做补全,RAG 后面的流程都会被影响:

text 复制代码
Query 表达不完整
  ↓
检索召回不稳定
  ↓
Rerank 排序依据偏移
  ↓
上下文组装质量下降
  ↓
最终回答容易答非所问

也就是说,多轮对话 RAG 的召回质量,很多时候不是从向量数据库开始决定的,而是从用户问题是否被正确改写开始决定的。


2. 如何把省略问题改写成独立检索语句?

解决这类问题的核心思路是:

text 复制代码
先补全意图,再做检索。

也就是把用户的原始问题:

text 复制代码
那它还有什么优势?

改写成一个可以脱离上下文独立理解的问题,例如:

text 复制代码
GraphRAG 相比传统 RAG 还有哪些优势?

这个改写后的问题通常叫 Standalone Query,也就是独立查询语句。

Standalone Query 的判断标准很简单:

text 复制代码
把这句话单独拿出来看,也能知道用户到底想查什么。

一个好的 Standalone Query 通常要包含四类信息:

text 复制代码
核心实体;
比较对象;
问题意图;
必要限定条件。

比如:

text 复制代码
GraphRAG 相比传统 RAG,在复杂知识关联和多跳推理方面有哪些优势?

这句话就比"那它还有什么优势?"更适合检索,因为它明确了:

text 复制代码
要查的对象:GraphRAG
比较对象:传统 RAG
关注方向:复杂知识关联、多跳推理
问题类型:优势分析

在系统设计上,可以把这一步拆成两个模块:Query Router 和 Standalone Engine。

Query Router 的作用,是判断当前问题是否需要改写。它主要判断三件事:

text 复制代码
当前问题语义是否完整;
当前问题是否依赖历史上下文;
当前问题是否需要进入检索流程。

如果问题语义完整,就直接进入检索。

如果问题语义缺失,就进入 Query Rewrite。

整体流程可以写成:

text 复制代码
用户原始问题
  ↓
读取最近几轮对话上下文
  ↓
Query Router 判断语义是否完整
  ↓
语义完整:直接检索
  ↓
语义缺失:进入 Query Rewrite
  ↓
生成 Standalone Query
  ↓
进入检索流程

Standalone Engine 的作用,是真正把上下文依赖问题改写成独立问题。

它一般会读取这些信息:

text 复制代码
用户当前问题;
最近几轮对话;
当前话题中的核心实体;
业务领域信息;
历史摘要;
Prompt 约束。

例如上下文是:

text 复制代码
用户:方案 A 和方案 B 有什么区别?
系统:方案 A 成本更低,方案 B 在计算效率方面更好。
用户:那它还有什么优势?

系统应该识别出:

text 复制代码
它 = 方案 B
优势 = 相对于方案 A 的优势
关注点 = 计算效率以及其他可能优势

然后改写成:

text 复制代码
方案 B 相比方案 A 还有哪些优势?

这里有一个关键原则:Query Rewrite 不是回答问题,而是改写问题。

改写模块只能补全上下文中已经存在的信息,不能凭空扩展新事实。

为了让改写稳定,Prompt 需要做明确约束:

text 复制代码
只负责改写查询,不负责回答问题;
只能使用当前问题和历史上下文中的信息;
不能引入上下文中不存在的实体;
不能扩展用户没有表达的需求;
输出必须是一个可以独立检索的问题;
必要时返回结构化 JSON。

在实际工程中,最好让模型输出结构化结果,例如:

json 复制代码
{
  "need_rewrite": true,
  "standalone_query": "GraphRAG 相比传统 RAG 还有哪些优势?",
  "core_entities": ["GraphRAG", "传统 RAG"],
  "reason": "用户问题中的"它"依赖上一轮上下文"
}

这样后续系统可以继续做校验,比如:

text 复制代码
need_rewrite 是否为 true;
standalone_query 是否为空;
core_entities 是否能在上下文中找到;
confidence 是否低于阈值;
是否需要追问用户。

为了进一步提升改写稳定性,还可以给模型提供 Few-shot 示例,让模型知道什么样的改写才是正确的。

例如:

text 复制代码
上下文:A 方案成本低,B 方案速度快。
用户:那它适合什么场景?
改写:B 方案适合什么场景?
text 复制代码
上下文:GraphRAG 更擅长处理实体关系和全局结构。
用户:那它还有什么优势?
改写:GraphRAG 相比传统 RAG 还有哪些优势?
text 复制代码
上下文:W4A16 主要压缩权重,W8A8 同时量化权重和激活值。
用户:这个有什么缺点?
改写:W8A8 量化方案有哪些缺点?

同时,负向约束也很重要。因为模型很容易把"改写问题"误解成"回答问题",所以要明确禁止这些行为:

text 复制代码
不要回答用户问题;
不要总结知识库内容;
不要生成最终结论;
不要引入上下文中没有的实体;
不要把一个简单问题扩展成多个无关问题;
不要改变用户原始意图;
不要丢失核心比较对象。

如果上下文中同时出现多个对象,比如方案 A、方案 B 和方案 C,用户又问:

text 复制代码
那它有什么问题?

这时"它"可能指任意一个方案。如果系统无法高置信度判断,就不应该强行改写,而应该追问:

text 复制代码
你这里说的"它"是指方案 A、方案 B,还是方案 C?

多轮 RAG 不应该为了保持对话流畅而胡乱补全上下文。低置信度时主动追问,反而能提升系统整体可靠性。


3. 如何在工程上保证检索准确和系统稳定?

生成 Standalone Query 之后,才真正进入检索流程。

但这里也不能只依赖一种检索方式。更稳的方案是混合检索:

text 复制代码
Vector Search + BM25 / Keyword Search

向量检索适合处理语义相似问题,比如:

text 复制代码
优势;
好处;
价值;
收益;
改进点。

这些表达字面不同,但语义接近,向量检索更容易召回相关内容。

关键词检索适合精确命中实体和术语,比如:

text 复制代码
GraphRAG;
BM25;
Query Rewrite;
Standalone Query;
HyDE。

这些专有名词如果只靠向量相似度,有时不如关键词命中稳定。

所以,混合检索可以同时兼顾:

text 复制代码
语义召回能力;
关键词精确命中;
专有名词稳定匹配;
复杂问题覆盖率。

召回之后,还需要 Rerank 对候选结果重新排序。因为初次召回追求的是"尽量别漏",而 Rerank 追求的是"把最相关的内容排到前面"。这一步可以明显降低无关内容进入上下文的概率。

完整链路可以写成:

text 复制代码
Standalone Query
  ↓
向量检索召回语义相关内容
  ↓
关键词检索命中核心实体和术语
  ↓
合并候选结果
  ↓
Rerank 重排
  ↓
Context Packing 组装上下文
  ↓
大模型基于检索结果生成回答

除了检索层本身,多轮对话 RAG 还要做好上下文窗口管理。

不能把所有历史对话都塞给改写模型,因为上下文越长,延迟越高,噪声越多,旧话题也越容易干扰当前问题。

更合理的做法是只取最近几轮对话,比如:

text 复制代码
最近 3 轮对话;
最近 5 轮对话;
最近 N 条与当前问题相关的历史。

如果对话很长,可以先做历史摘要,把核心话题和实体压缩出来:

json 复制代码
{
  "current_topic": "GraphRAG 与传统 RAG 对比",
  "entities": ["GraphRAG", "传统 RAG", "多跳推理", "实体关系"],
  "last_focus": "GraphRAG 的优势"
}

这样改写模型不需要阅读全部历史,也能知道当前问题处在哪个上下文里。

系统还需要判断用户是否切换了话题。

比如前面一直在聊 GraphRAG,用户突然问:

text 复制代码
那北京明天天气怎么样?

这时候不能强行把"那"理解成 GraphRAG 的上下文延续。系统应该识别出这是一个新话题,不要继续沿用旧上下文。

可以通过这些信号判断是否发生了话题切换:

text 复制代码
当前问题是否出现新的实体;
当前问题是否和历史主题语义距离很远;
当前问题是否属于新的业务分类;
当前问题是否不需要历史上下文也能理解;
当前问题是否包含明显的新场景词。

在高并发场景下,Query Rewrite 也不一定要交给最强的大模型。它本质上更像上下文理解和格式化任务,主要能力包括:

text 复制代码
指代消解;
实体提取;
意图补全;
问题改写;
结构化输出。

这些任务可以交给 7B 级别的小模型,甚至可以用量化后的小模型本地部署。

这样做的好处是:

text 复制代码
延迟更低;
成本更低;
吞吐量更高;
更适合高并发场景;
可以减少对主大模型的调用压力。

一种比较合理的企业级分工是:

text 复制代码
小模型:负责意图分类、Query Rewrite、路由判断;
Embedding 模型:负责向量化;
Rerank 模型:负责结果重排;
大模型:负责复杂推理和最终回答。

如果用户问题太短、关键词不充分,还可以用 HyDE 辅助召回。

HyDE 的全称是 Hypothetical Document Embeddings,可以理解为"假设性文档嵌入"。它的思路是:

text 复制代码
先根据用户问题生成一个假想答案或假想文档;
再用这个假想内容去做向量检索。

例如用户问:

text 复制代码
GraphRAG 相比传统 RAG 还有哪些优势?

系统可以先生成一段假想内容:

text 复制代码
GraphRAG 的优势可能包括实体关系建模、全局知识组织、多跳推理、社区结构分析和复杂问题理解能力。

然后用这段假想内容去做向量检索,从而增强召回。

但 HyDE 也有风险:

text 复制代码
可能生成错误假设;
可能引入上下文中不存在的信息;
可能导致检索方向偏移。

所以 HyDE 更适合作为召回增强手段,不能直接当作最终答案依据。最终答案仍然应该基于真实检索到的知识库内容生成。

综合来看,一个稳定的多轮对话 RAG 系统,不只是"用户问一句,系统搜一下"。它应该具备完整的上下文理解、指代消解、查询改写、混合召回、结果重排、低置信度追问和话题切换识别能力。

可以把整个系统理解成下面这条链路:

text 复制代码
用户省略问题
  ↓
判断是否依赖上下文
  ↓
提取最近几轮核心实体
  ↓
生成 Standalone Query
  ↓
低置信度时追问用户
  ↓
高置信度时进入混合检索
  ↓
Rerank 重排
  ↓
组装可靠上下文
  ↓
大模型基于证据生成回答

最后总结一下:

text 复制代码
多轮 RAG 的关键不是直接搜索用户原话,
而是先结合上下文补全用户真实意图,
再生成一个可以独立检索的问题,
最后通过混合检索和重排找到可靠依据。

也就是说,多轮对话 RAG 的本质不是"更复杂的搜索",而是让系统先理解用户在上下文里真正想问什么,再把这个问题转换成检索系统能够准确处理的表达。

总结:三个问题背后的共同工程思想

这三个问题表面上分别属于模型部署、应用架构和检索系统,但它们背后的工程逻辑是一致的:

text 复制代码
量化解决的是如何让模型更轻、更快,同时控制精度损失;
Workflow 与 Agent 解决的是如何让大模型应用既灵活又可控;
多轮 RAG 解决的是如何把用户不完整的自然表达转成可检索、可验证的问题。

最终可以归纳成一句话:

text 复制代码
大模型应用真正难的地方,不只是让模型"会回答",
而是让模型能力在工程系统中稳定、可控、可观测、可优化地发挥作用。
相关推荐
梦想的颜色1 小时前
TypeScript 完全指南(上):从零开始掌握类型系统
前端·typescript
陆业聪1 小时前
WebView代理方案实现:拦截请求、注入资源与离线包架构
人工智能·ai编程
之歆1 小时前
Day01_ES6+ 专业指南:从基础到实战的现代JavaScript开发(下)
前端·javascript·es6
薛定谔的猫-菜鸟程序员2 小时前
2小时智能体开发一个智能体?我用CodeArts Agent 和 AtomCode 开发了一个适老化智能体。
人工智能·python·agent
lichenyang4532 小时前
鸿蒙 MVVM 实战:从 Demo 到工程化,聊聊登录、状态管理与埋点系统设计
前端
HIT_Weston2 小时前
101、【Agent】【OpenCode】task 工具提示词(Usage Notes)
人工智能·agent·opencode
qcx232 小时前
【系统学AI】09 Multi-Agent架构(2026版):从学术理论到工业级实践
java·人工智能·架构·multi-agent·claude agent
洛宇2 小时前
一个口语 skill,灵感居然来自2021年的那个夏天
人工智能·程序员·github