想象你走进一家餐厅,开口说“我想吃点不辣的”。金牌管家没有转身就走,而是接着问:“您今天想吃面还是饭?如果偏辣我们也有免辣选项。”等你补了一句“随便来一份”,他端上菜时还能告诉你:“这是王师傅的拿手菜,用的今早到货的活鱼。”——一位好服务员做的事,远不只是递菜单:他听需求(意图理解)、补全信息(query改写)、记着前情(多轮上下文)、替你排好上菜顺序(结果排序)、标明每道菜的来历(引用溯源),拿不准时还会多问一句(澄清)。 现在把“服务员”换成“AI”——基于大模型的对话式搜索代理,正是这样一个数字管家。它不是把用户的每句话都当成一次全新搜索,而是在多轮对话中不断理解“你现在心里想要什么”,再去知识库里翻找,最后用带引用的方式把答案端到你面前。这篇文章,将带你拆解这位管家的整套工作流:从听懂需求、补全问法、管理记忆,到排序输出、注明来源,以及何时该停下来反问你一句。
学完本文,你将能画出对话式搜索代理从“意图”到“出餐”的完整流水线,并在真实产品中落地多轮问答、知识库召回与引用溯源,这是智能搜索、客服机器人和企业知识问答产品的核心竞争力。
目录
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
LLM对话搜索代理架构 意图理解与Query改写 Query改写策略 多轮上下文继承 LLM对话搜索代理可视化:展示意图理解、RAG知识库召回、多轮上下文管理及引用溯源机制。
意图理解——管家先听清“你到底要什么”
顾客说“我今晚想吃点清淡的”,金牌管家不会直接冲去后厨喊“清淡的!”,而是先在心里拆解:要轻食、不要重油、可能是素食。这就是意图理解——把一句口语翻译成后厨听得懂的动作指令。对话式搜索代理的第一步,同样是判断用户这句话属于什么类型的需求:查价格、查攻略、还是报故障?把意图认错了,后面检索和生成都会跑偏。
传统方案靠关键词规则和意图模板,遇到“我,嗯,那个,手机掉水里了怎么办”这种口语化表达就成了哑巴。LLM 的强项恰恰在于,它能结合上下文推测“掉水里”是“维修咨询”而不是“购买新机”。实际工程中,我们让 LLM 把用户输入映射到一组预定义意图上,同时提取“设备型号”“故障现象”这样的槽位,为后续的 query 改写提供素材。
形式化地说,意图分类可以建模为一个概率分布:
管家把“清淡”拆成轻食、不辣、素食,写到订单备注上,后厨才不会做错菜。同样,意图理解给整个搜索流程定了调:后续改写、检索、排序都在这个上下文里展开。
- 意图得分$h_z$ 是 LLM 对用户输入编码后,给每个候选意图 $z$ 打出的原始分数,可以理解为“这像不像这个类别”的证据强度。
- 指数映射$\exp(h_z)$ 把原始分数转成正数并放大差距,让高分明显高于低分,避免两个类别平分秋色。
- 归一化分母$\sum_{z'\in\mathcal{Z}}\exp(h_{z'})$ 把所有候选类别的指数得分加在一起,作为“总票数”,确保输出的概率之和为 1。
- 取最优解$\arg\max$ 从概率分布里选出最大的那一项,这就是最终认定的用户意图。
Query改写——把“再来一份”补全成完整订单
顾客一句“再来一份”,金牌管家绝不会让后厨猜,而是自动补全成“再来一份刚才的牛肉面,少辣”。这就是 Query 改写:把多轮对话里的碎片表达还原成一句能独立检索的完整话。用户与搜索代理对话时,很少会用书面语:“那续航呢?”——如果把这四个字直接丢给搜索引擎,召回质量可想而知。
Query 改写要处理三件事:指代消解,把“它”“那个”替换成上一轮提到的实体;省略补全,把缺失的主语宾语补齐;同义扩展,把口语词统一成知识库里的标准说法。现代做法是让 LLM 基于当前轮输入和会话历史直接生成改写句,然后用改写质量过滤(比如与原意一致性打分)决定是否采用。
改写过程可以看作一个条件生成任务:
管家确认一句“是刚才那份牛肉面对吗?”,你点个头,订单就清晰了。改写后的 query 多抓得住实体词,知识库召回才不至于答非所问。
- 候选改写集合$\mathcal{Q}$ 是所有候选改写句的集合,可能来自 LLM 采样,也可能来自模板组合。
- 条件背景$c$ 是当前轮用户输入,$h$ 是之前几轮的对话历史,两者共同构成“这个场景下这句话到底指什么”的依据。
- 生成概率$P_{\text{LLM}}(q'\mid c,h)$ 是 LLM 逐词生成 $q'$ 的概率连乘,句子的流畅度和贴合度越高,概率越大。
- 取最优$\arg\max$ 从候选集合中挑出概率最高、最贴近用户原意的句子,作为最终检索 query。
多轮上下文管理——好记性也要懂得取舍
金牌管家能记住老顾客上次点的菜,但绝不会把三个月前的账单也背下来。记性好不等于什么都记,多轮对话的上下文也是这样。LLM 的输入窗口有限,如果把十几轮对话原封不动全塞进去,既挤占了 token 预算,又让无关信息干扰检索。
对话式搜索代理需要一套上下文管理策略。工程上常见的做法有三类:一是窗口裁剪,只保留最近 N 轮;二是相关性过滤,按当前 query 与历史句子的语义相似度决定去留;三是摘要压缩,用 LLM 把旧历史浓缩成几句话,再与当前轮拼接。实际产品中,往往三者配合使用——既保证短期记忆完整,又维持长期记忆不丢主线。
递归摘要压缩可以写成:
管家在脑子里只留“这位客人口味偏淡、刚才点了面”,而不会复读整本菜单。好的上下文管理让代理既记得住“你刚才问过苹果手机”,又不会在第三轮回答时被第一轮的寒暄带偏。
- 旧笔记$c_{t-1}$ 是前一轮压缩后保留下来的上下文摘要,代表“到目前为止用户真正关心的事”。
- 新增消息$u_t$ 是用户这一轮刚说的话,它可能包含新的实体、新的偏好或修正信息。
- 预算控制$m$ 是上下文长度的硬上限,例如 2000 字,超出的部分必须被压缩掉,防止 token 溢出。
- 摘要函数$\text{Summarize}(\cdot)$ 是 LLM 执行的一次“信息蒸馏”,它把新旧内容融合重写,只保留对后续检索有用的实体、偏好和未决问题。
结果排序——把最合适的菜端在前面
后厨同时出了八道菜,金牌管家不会按出菜顺序端上桌,而是按“顾客口味偏淡”把白灼菜心放第一位,再上清蒸鱼,最后才上椒盐虾。检索阶段也一样:知识库召回的可能有几十条相关片段,但用户只需要一个答案。结果排序就是把最匹配的内容排到最前面。
排序链路分两步:先粗排,用耗时低的方法(BM25、向量相似度)快速筛出 Top-N;再精排,把 Top-N 交给 LLM 逐条打分,结合用户偏好和当前意图输出最终顺序。由于召回往往有“关键词一路 和 “向量一路”两条来源,我们还需要一个融合算法把多路排名合并。
常用的融合方法是 RRF(Reciprocal Rank Fusion,倒数排名融合):
管家把“最对口味”的菜放最前面,即使它在出餐单上排第五。排序不仅是相关度问题,还涉及多样性——前三条都讲同一个点,用户反而觉得信息单一。好的排序要在相关与覆盖之间找到平衡。
- 多路召回来源$\mathcal{R}$ 是所有召回路径的集合,比如 BM25 关键词召回一路,向量语义召回另一路。
- 单路名次$\text{rank}_r(d)$ 是文档 $d$ 在第 $r$ 路结果里的排名,排名从 1 开始,越小越好。
- 平滑常数$k$ 是一个固定常数(通常取 60),防止名次为 1 时分数爆炸,同时削弱头部名次的绝对优势。
- 累加融合$\sum_{r\in\mathcal{R}}$ 把文档在所有召回路径中的倒数名次相加,名次越靠前,融合分越高,最终按此分排序。
引用溯源——每道菜标明来路
管家递上一道招牌鱼,会说“这是王师傅今早从市场挑的活鲈鱼”——有来历,客人吃得放心。对话式搜索代理回答用户时,也不能只给结论不给出处。大模型有个臭名昭著的毛病:一本正经地胡说八道(幻觉)。如果没有引用溯源,用户拿到一个编造的答案,第一反应不是“AI 错了”,而是“这个产品不可信”。
引用溯源要做三件事:第一,生成答案时标记每句话对应的知识库片段编号;第二,对每个候选来源做可信度评估,优选权威、时效性高的资料;第三,构建证据链,让用户能从答案反查原始文档。工程上通常把检索结果和生成结果绑在一起——LLM 的每一句输出后面挂上来源索引,前端渲染成可点击的引用角标。
一个回答对证据集合的支持度可以建模为:
客人在引用列表里看到“王师傅、活鲈鱼、采购时间”,信任感自然就上来了。引用溯源不仅防幻觉,还能帮产品积累“哪些来源被高频引用”的数据,反过来优化知识库。
- 证据集合$E$ 是检索后保留的相关文档或片段,一个答案往往对应多条证据。
- 单条证据支持度$P(e\mid q)$ 是 LLM 判断“片段 $e$ 是否真正支撑问题 $q$”的打分,可以用模型的置信度近似。
- 连乘汇聚$\prod_{e\in E}$ 把所有证据的支持度相乘。任何一条证据严重不相关,都会拉低整体可信度,这要求答案必须“全部有据可依”。
- 阈值筛选生成回答前,丢弃支持度低于阈值的证据,只保留高置信片段,并在最终答案中标注对应编号。
追问澄清——拿不准时问一句比瞎猜强
客人说“随便”,金牌管家不会真的随便,而是问“主食想吃面还是饭?”——一次恰当的提问,把模糊变成确定。对话式搜索代理也会遇到信息不足的时刻:用户只说了半句话,或者意图分类器在“买手机”和“修手机”之间犹豫。这时候硬猜不如反问,让用户用一次点击或一句话把方向定下来。
什么时候该澄清?工程上靠两条信号:一是意图置信度低——最高概率还不够高,说明模型没把握;二是检索结果分散——召回的前几名来自完全不同的主题,说明 query 太含糊。有了澄清信号,代理再让 LLM 基于当前上下文生成候选问题,比如“您是遇到了手机进水,还是想咨询防水性能?”
澄清触发可以用不确定性来量化:
管家问“面还是饭”,你不会觉得啰嗦,反而觉得被照顾到了。澄清的本质是用一次低成本交互,换取后续检索和生成的高确定性——好的体验不是有问必答,而是在关键路口主动扶一把。
- 最高意图概率$\max_{z}P(z\mid x)$ 是意图分类器输出中概率最高的那个类别,它代表模型最倾向的判断。
- 不确定性度量$1-\max$ 得到不确定性,最高概率越接近 1,不确定性越低;越低说明越模糊。
- 阈值判断当 $\text{Unc}(x)>\tau$(例如 0.4),代理判定当前信息不足,进入澄清流程。
- 候选问题生成由 LLM 基于当前 query 与历史生成 2~3 条候选问题,请用户点选或自由回答,再将反馈融入上下文。
知识库召回增强——后厨的冷藏库够大才接得住
管家推荐的底气,来自后厨冷藏库里整整齐齐的食材。对话式搜索代理也一样——它的能力上限,取决于知识库召回的质量。哪怕 LLM 再聪明,如果知识库里根本没有相关信息,回答只能靠编。召回增强要解决的是“怎么把对的资料从冷库里翻出来”。
现代召回系统通常走混合检索路线:向量召回负责“语义相似”,把“怎么让手机撑一天”匹配到“手机省电技巧”;关键词召回负责“精确命中”,对型号、编号、价格这类词更敏感。两条路各自拉回 Top-K,再用上一节讲过的 RRF 融合,最后交给 LLM 重排和生成。这就是 RAG(检索增强生成)的经典骨架。
向量召回的核心运算是余弦相似度:
冷藏库够大、食材摆得够好,管家端上来的菜才有更多选择。召回增强不是堆数据量,而是让“对的内容”在需要时能被高效找到。混合检索加 RAG 生成,是当前对话式搜索从“能用”走向“好用”的关键一步。
- 语义向量$\vec{q}$ 和 $\vec{d}$ 是 LLM 将用户查询和知识库文档分别编码成的稠密向量,语义相近的句子在向量空间中距离更近。
- 点积计算$\vec{q}\cdot\vec{d}$ 逐维度相乘再求和,衡量两个向量“方向上的重合程度”。
- 模长归一化$\lVert\vec{q}\rVert_2$ 和 $\lVert\vec{d}\rVert_2$ 是各自的欧几里得长度,把结果压缩到 [-1,1],避免长文本天然占便宜。
- 相似度排序按余弦值降序取 Top-K,再与关键词召回结果做 RRF 融合,得到最终候选集。
AI 应用场景
企业智能客服——多轮故障排查
阶段:多轮上下文管理、追问澄清
解决的问题:用户报障时常说半句话,比如“我连不上网了”。传统脚本客服只能按预设菜单逐级提问,用户答非所问就卡死。AI 搜索代理结合对话历史动态追问:先澄清“有线还是无线”,再把“连不上 WiFi”改写为“Win11 WiFi 连接失败 排查”,从运维知识库召回排障文档,按相关度排序给出带引用编号的步骤。
具体案例:某企业 IT Helpdesk 接入对话式搜索代理后,用户说“我连不上公司 WiFi”,代理先澄清设备类型,再检索运维知识库中的 3 篇排障教程,把“重启路由器”排在第一位并标注文档出处。用户追问“那收不到验证码呢”,代理结合上文自动指代“验证码=WiFi 认证短信”,召回认证系统文档,整个处理时间从 10 分钟降到 2 分钟。
电商导购——跟着用户偏好迭代
阶段:意图理解、Query 改写、结果排序
解决的问题:用户第一轮说“想买通勤用的双肩包”,第二轮说“要轻一点的”。传统搜索把第二轮当成独立请求,返回一堆无关结果。对话式搜索代理把第二轮改写为“轻量 通勤 双肩包”,并结合用户画像里“预算六百以内”的槽位重排商品。
具体案例:某电商导购助手中,用户说“预算六百以内”,代理理解价格意图,向量召回候选商品,LLM 按“轻量、防水、通勤”打分排序,优先展示符合偏好的款式,并在回答中标注“符合预算”“通勤评测口碑好”等来源标签,点击可直接跳转商品详情。
学术文献问答——知识库召回与引用溯源
阶段:知识库召回、引用溯源
解决的问题:研究者问“对比特转换模型最近有什么改进”,要求每个结论都必须出自论文,不能凭 LLM 记忆编造。对话式搜索代理先从论文库做向量召回,再用 LLM 重排,生成时逐句标注引用编号,点击即可跳转原文 PDF。
具体案例:某企业知识平台接入 5 万篇内部论文,代理回答“对比特转换模型最近有什么改进”时,召回 20 篇相关论文,LLM 重排后选出 6 篇作为证据,回答中 [3]、[5] 等角标对应原文段落。上线后,该平台回答幻觉率下降 70%,研究员对 AI 回答的采纳率翻倍。
Python 演示
class ConversationSearchAgent: """基于规则的对话式搜索代理演示""" def __init__(self): self.history = [] self.documents = [ {"id": 1, "title": "苹果手机价格", "content": "苹果 iPhone 15 起售价 5999 元"}, {"id": 2, "title": "苹果手机续航", "content": "iPhone 15 续航约 20 小时"}, {"id": 3, "title": "安卓手机价格", "content": "某安卓旗舰机起售价 3999 元"}, ] self.candidates = [] def understand_intent(self, query): if any(k in query for k in ("价格", "多少钱")): return "price" if any(k in query for k in ("续航", "待机")): return "battery" return "general" def rewrite_query(self, query): if query.startswith("它") and self.history: last = self.history[-1]["query"] query = query.replace("它", last) return query def build_context(self): return " ".join(u["query"] for u in self.history[-2:]) def retrieve(self, query): scores = [] for doc in self.documents: s = 0 for kw in query.split(): if kw in doc["title"] or kw in doc["content"]: s += 1 scores.append(s) ranked = sorted( range(len(scores)), key=lambda i: -scores[i] ) self.candidates = [ self.documents[i] for i in ranked if scores[i] > 0 ] def answer(self, query): q = self.rewrite_query(query) self.retrieve(q) if not self.candidates: return "没找到相关信息,请换个问法。" best = self.candidates[0] self.history.append({"query": query}) return "引用来源[%d]: %s" % (best["id"], best["content"]) if __name__ == "__main__": agent = ConversationSearchAgent() print(agent.answer("苹果手机多少钱")) print(agent.answer("它的续航呢"))
self.documents = [定义一个模拟知识库,每条文档带 id、标题和正文。def understand_intent(self, query):用关键词规则识别用户意图,真实项目中这里换成 LLM 分类器。query = query.replace("它", last)指代消解:把“它”替换成上一轮的问题。self.history[-2:]只取最近两轮历史作为上下文,避免信息过载。ranked = sorted(...)按关键词命中数对文档排序,模拟“结果排序”环节。self.history.append(...)记录当前轮次,让后续对话能引用前文。
常见误区
误区我只要把用户和机器人的对话存下来,调一个搜索接口,再把搜索结果丢给大模型总结一下就完事了。
正解对话式搜索的核心是让每一轮检索都被“理解—改写—召回—排序—引用”这条流水线驱动,而不是简单拼接。就像管家不是“把菜单塞给顾客再让厨师随便炒”,他需要判断需求、补全信息、安排后厨顺序——每个环节缺一不可。只做拼接,第三轮之后就会开始答非所问。
为何常见:从产品形态上看,两者确实都是“对话框 + 结果列表”,容易让人忽略背后状态管理和意图流转的复杂度。
误区把十几轮对话全部拼进 prompt,大模型就一定能更懂我。
正解上下文越长,噪声越多,还容易超出窗口,导致关键信息反而被稀释。对话式搜索通常只需要最近 2~3 轮的关键信息,其余要靠摘要压缩和相关性裁剪。好管家的记性不是复读机,而是把要点提炼成一张小纸条。
为何常见:直觉上“信息越多越聪明”,忽略了 LLM 窗口和信噪比的边际效应。
误区大模型那么强,直接回答就行,标引用太麻烦,还可能暴露资料不全。
正解正因为 LLM 会一本正经地胡诌,引用溯源才必不可少。尤其在企业客服、医疗、法律场景,没有来源的回答会带来信任与合规风险。管家敢推荐菜,一定说得清“这是谁做的、用的什么料”。
为何常见:LLM 输出太流畅,流畅让人误以为可信,而幻觉恰恰藏在流畅里。
误区用户问一句“随便”,我就直接搜索,再问他可能就走了。
正解恰当的澄清反而降低沟通成本。一上来问三五个琐碎问题才会打扰;当意图不确定性高、候选结果跨主题分散时,一个高质量澄清能让后续结果准得多。好管家在你说“随便”时问“面还是饭”,你会觉得贴心而非啰嗦。
为何常见:把“提问次数”误当成体验负向指标,忽视了错误回答的更大代价。
误区上了 embedding 之后,关键词检索就没用了,只用向量召回就行。
正解向量召回擅长语义近似,但对精确的产品型号、编号、价格区间并不敏感;BM25 对精确词命中很稳。混合检索再融合,才是 RAG 产品的常态。后厨光有冰箱不行,贴着标签的货架同样重要。
为何常见:demo 里向量召回效果惊艳,让人忽略真实场景中长尾精确查询的检索难题。
面试题
Q1. 对话式搜索代理与传统“一次搜索”最本质的区别是?
- A.返回结果条数更多
- B.支持多轮交互和追问← 正确答案
- C.搜索结果加载更快
- D.无需任何索引结构
答案:B。对话式搜索的核心是多轮状态管理与追问澄清,像管家记着前几轮需求继续服务。A、C 只是工程指标优化,D 说法错误,任何搜索都离不开索引。
Q2. Query 改写中的“指代消解”主要指?
- A.处理用户口中的“它”字← 正确答案
- B.给图片生成文字描述
- C.将语音转换为文字
- D.压缩知识库文件大小
答案:A。指代消解把“它”“那个”等代词替换为上一轮提到的具体实体,是改写最典型的场景。B 是图像描述,C 是语音识别,D 是存储优化,都与 query 改写无关。
Q3. 多轮上下文管理的常用策略包括?
- A.裁剪最旧会话记录← 正确答案
- B.用摘要压缩历史← 正确答案
- C.每轮重放全量对话
- D.按相关性筛选保留← 正确答案
答案:ABD。A 是窗口裁剪,B 是摘要压缩,D 是按相关性保留,三者都是工程中常用的上下文管理手段。C 全量重放会超出窗口并引入噪声,不是合理策略。
Q4. 关于 LLM 重排序的作用,最准确的说法是?
- A.降低搜索后端内存占用
- B.提升召回结果相关度精排← 正确答案
- C.自动为页面生成广告位
- D.替代数据库的全部功能
答案:B。LLM 重排序是在粗排基础上对 Top-N 结果逐条精排,提升最终相关度。A、C、D 都与重排序无关——它计算更贵,不会降低内存占用,更不负责广告和数据库。
Q5. 引用溯源主要解决的问题是?
- A.缓解大模型幻觉← 正确答案
- B.减少服务器带宽
- C.加速模型推理
- D.美化前端界面
答案:A。引用溯源通过给答案绑定知识库来源,让每句话都有据可查,直接缓解“一本正经胡说八道”的幻觉问题。B、C、D 与来源验证无关。
Q6. 触发追问澄清的典型信号有哪些?
- A.意图分类置信度低← 正确答案
- B.用户请求内容过短← 正确答案
- C.检索结果主题分散← 正确答案
- D.用户网络连接超时
答案:ABC。意图置信度低说明模型没把握,请求过短说明信息不足,结果主题分散说明 query 太含糊——三者都适合触发澄清。网络超时是基础设施问题,与用户意图无关。
Q7. RAG 增强生成的核心流程是?
- A.召回知识库再生成← 正确答案
- B.直接微调生成模型
- C.使用传统协同过滤
- D.压缩全部训练样本
答案:A。RAG 先检索知识库得到候选片段,再交给 LLM 依据这些片段生成答案。B 是微调路线,C 是推荐算法,D 是模型压缩,都不属于 RAG 的检索—生成闭环。
Q8. 混合检索通常是指?
- A.向量检索叠加关键词检索← 正确答案
- B.多个模型并行推理
- C.多台服务器负载均衡
- D.多语言翻译交叉验证
答案:A。混合检索把向量召回的语义能力和关键词召回的精确匹配能力结合起来,再通过 RRF 等算法融合排名。B、C 是工程部署,D 是翻译评测,均与检索融合无关。
Q9. 构建对话式搜索代理通常包含哪些核心环节?
- A.意图理解与改写← 正确答案
- B.多轮上下文管理← 正确答案
- C.结果排序和溯源← 正确答案
- D.用户头像自动生成
答案:ABC。意图理解、query 改写、上下文管理、结果排序与引用溯源构成了对话式搜索的完整流水线。用户头像是 UI 定制功能,不属于搜索代理的核心能力。
Q10. 对不确定性建模,对澄清最有用的方式是?
- A.计算意图分布的信息熵← 正确答案
- B.统计服务器在线人数
- C.随机选取一个候选答案
- D.缩短上下文窗口长度
答案:A。信息熵能综合衡量意图分布有多“混乱”,熵越高说明模型越没把握,正好作为澄清触发信号。B 与对话无关,C 是放弃判断,D 只改变上下文长度,都无法量化不确定程度。