一句话多意图与跨轮补答:子句拆分、单标签路由与补答取舍(MewHelp 实战·口播版)
面试高频问题:用户一句话里问了两个问题,路由只能出一个意图,怎么处理?/ 上一轮没答上的问题,下一轮 Agent 又答了一遍,怎么办? 一句话答案:检索层拆子句 —— 按标点拆、各查一遍、轮转合并,且必须配精排;路由层只出单标签 —— 选主意图走流程,次意图由主力 Agent 在回复里顺带调工具补上;跨轮补答不是缺陷而是取舍 —— 看业务,要收敛就在 system prompt 里限定「只回答用户最新一轮的问题」。 项目背景:mewhelp 电商智能客服(Workflow + 单主力 Agent,ch04 实现 split_clauses) 适用面次:二面深度(RAG 检索细节 / 意图路由) 本版定位:口语应答脚本 —— 先给「开口就能说」的话术,再给速记要点。
【30 秒极简版】(面试官随口一问时用)
一句话多个意图,我不靠意图分类拆 —— 分类只输出一个标签。ch04 做的是检索层拆分:
split_clauses按标点把整句拆成子句,每个子句各检索一遍,再轮转合并,让每个意图都能占到召回名额。 这招有个硬前提:必须配精排 —— 评估集实测,重排路径 +0.02,其余三条路反而掉 0.04 到 0.06;没精排拆完只是把噪声乘以三。 路由上分类只挑一个主意图走流程,另一个意图由主力 Agent 在回复里调工具补答。跨轮补答确实会出现:上一轮兜底没答的,下一轮看到历史就一起答了 —— 觉得体验好就留着,觉得容易答偏就加一句「只回答用户最新一轮的问题」。
【2 分钟完整口播】(正式被问到时的主干回答)
这题要分两层看:检索层怎么拆,和路由层怎么选。很多人一上来就说「意图分类改成多标签」—— 那是把两件事混成一件,反而说不清。
第一,拆是在检索层做的,不是意图分类。 ch04 里有个
split_clauses:按标点把一句话拆成子句,拆出来的碎片小于 4 个字就丢掉 —— 像「怎么办」这种单独去检索没有任何信息量,只会引噪声;拆不出两条就原样返回一条。拆完之后每个子句各检索一遍,再用轮转合并把结果拼起来:各子句轮流出一条、按 chunk id 去重,同一小节只留最靠前的那条。这样「物流到哪了 + 想退货」这种一句话两个意图,两个都能进召回名额,而不是整句向量化后被主语义带跑、只剩一个意图挤进前排。第二,这招有前提,不是加了就一定更好。 子句拆开后每一路的第一名都得够准,合并才有意义,所以必须配精排。评估集上的实测是:重排路径上 +0.02,其余三条路(纯向量、纯 BM25、混合不重排)反而掉 0.04 到 0.06 —— 没有精排把关,拆完只是把噪声乘以三。这个数字我在面试里会主动讲,因为它证明我知道每处优化的适用条件。
第三,路由层只出单标签,不做多标签。 意图分类给一个标签决定走哪条路:一句话问退货又问物流,分类会挑一个主意图 —— 假设判到退货,就走退款流程;另一个意图不靠第二个路由,而是靠主力 Agent 在回复里顺带处理:Agent 拿到历史消息,看到用户还问了物流,就调
query_order+query_logistics把物流也查一遍,一起回复。第四,跨轮补答要当成取舍,不是 bug。 上一轮因为依赖不够走了兜底、问题没答上;下一轮 Agent 看到历史里那条没回复的问题,会顺手补上 —— 结果这一轮既答了老问题、又答了新问题,看起来「答了两次」。这个现象确实会出,不一定要拉齐:如果补答让体验更连贯,就留着;如果容易答偏,就在 system prompt 里加一句「只回答用户最新一轮的问题」。判断依据是你的业务场景更怕「漏答」还是更怕「答偏」。
一、速记要点
1. 两层拆开看
| 层 | 做什么 | 不做什么 |
|---|---|---|
| 检索层 | 按标点拆子句,各查一遍再合并,保证每个意图都有召回名额 | 不改变路由结果 |
| 路由层 | 意图分类只出一个标签,选主意图走流程 | 不做多标签并行路由 |
面试时先讲这个分层,比直接说「多意图」有结构感。
2. split_clauses 的三条规则
- 按标点拆:整句拆成子句;
_MIN_CLAUSE = 4:太短的碎片丢弃(「怎么办」检索无信息量,只引噪声);- 拆不出两条就原样返回一条:不为拆而拆。
3. 合并策略:轮转 + 去重
- 各子句轮流出一条(round-robin),避免某一路霸占前排;
- 按 chunk id 去重;同一小节只留最靠前的那条,重复的挪到后面;
- 目的:每个意图都占到名额,而不是让主语义通吃。
4. 前提条件:必须配精排(有数据)
| 检索路径 | 拆子句后的效果 |
|---|---|
| 向量 + BM25 + 重排 | +0.02 |
| 纯向量 | −0.04 ~ −0.06 |
| 纯 BM25 | −0.04 ~ −0.06 |
| 混合不重排 | −0.04 ~ −0.06 |
一句话:子句的第一名必须够准,合并才有意义;没有精排的单路检索,拆完只是把噪声乘以三。
5. 单标签路由下,次意图怎么兜住
- 意图分类只给一个标签 → 主意图进对应流程(例:退货 → 走退款子流程);
- 次意图由主力 Agent 在回复里补:拿历史消息 + 工具(
query_order+query_logistics)现场查; - 效果:不新增路由分支,也不漏掉用户问的第二件事。
6. 跨轮补答:成因与处置
| 项 | 说明 |
|---|---|
| 成因 | 上一轮依赖不足走兜底、问题未答;下一轮 Agent 看到历史里那条未回复的问题,主动补上 |
| 现象 | 同一轮里既答了老问题、又答了新问题,看起来「答了两次」 |
| 处置 | 不强制拉齐:体验好就留;怕答偏就在 system prompt 限定「只回答用户最新一轮的问题」 |
| 判断依据 | 业务更怕漏答还是更怕答偏 |
二、露馅点 vs 加分点
- ❌ 说「我们意图分类支持多标签并行路由」→ ✅ 说清检索层拆、路由层单标签,两层分工
- ❌ 说「拆子句一定更好」→ ✅ 主动给适用条件:必须配精排,并说出 ±0.02 / −0.04 的实测差异
- ❌ 拆子句不设长度下限 → ✅ 讲
_MIN_CLAUSE=4挡碎片,避免引入噪声 - ❌ 主意图之外的第二问直接丢掉 → ✅ 讲主力 Agent 调工具补查(
query_order+query_logistics) - ❌ 把跨轮补答当成 bug 保证「已修复」→ ✅ 讲清是产品取舍,给出两种处置与判断依据
三、一句话收尾
一句话多意图的正解不是「让分类输出多个标签」,而是检索层拆子句保证召回名额、路由层单标签保证流程确定、回复层靠工具补答保证不漏 —— 每一层只做自己该做的事。
关联笔记:09多Agent架构取舍-客服场景为什么不用多Agent(为什么收敛到单主力 Agent)、12PDF文档RAG工程化-四环节流水线(检索链路)、21办公场景多轮对话管理-分层记忆与状态机语流编排(跨轮上下文)、18数据飞轮-智能体越用越聪明的底层逻辑(补答/漏答都可作为评测信号回流)