- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
本指南完整讲解 Semantic Router 项目中
user_feedback信号的定义、决策规则编排与落地用法。user_feedback信号负责识别多轮对话中用户对上一轮回复的更正、澄清、重试与满意度表达,是构建「自适应路由」的关键信号之一。读完本文,你将掌握:如何在自己的config.yaml中声明反馈信号、如何将其组合进决策规则实现「不满自动升级到更强模型」、如何理解反馈检测器(FeedbackDetector)在源码层面的阈值、弃权与标签映射机制,以及客户支持升级、教育自适应学习等典型场景的完整配置。
为什么需要用户反馈信号
在传统单轮路由中,路由器只根据当前查询文本判断一次意图,之后便不再关注用户的态度变化。但在真实对话中,用户经常通过后续消息表达对上一轮回答的感受:
- 更正(Correction):"不对"、"不,我不是那个意思"
- 满意(Satisfaction):"谢谢"、"很有帮助"、"完美"
- 澄清(Clarification):"你能多解释一下吗?"、"我不明白"
- 重试(Retry):"再试一次"、"给我另一个答案"
这些消息本身往往很短,却携带了高价值的语义信号。Semantic Router 的user_feedback信号会自动识别上述模式,使路由层能够:
- 将更正请求路由到更强大的模型(能力升级);
- 检测满意度水平,供监控与运营分析使用;
- 适当地处理后续问题(澄清、换一种方法);
- 根据反馈动态提高响应质量。
其关键优势可以归纳为四点:自适应路由(检测到不满意即切换更强模型)、更正处理(自动识别 "错了"、"再试一次" 等消息)、满意度分析(区分正面与负面反馈)、改进的用户体验(用户表示不满意时获得更好的响应)。
从架构上看,user_feedback是 Semantic Router 信号驱动决策(Signal-Driven Decision)体系中的一员。关于 13 种信号类型与布尔组合规则的完整介绍,可参见 信号驱动决策架构,其中将用户反馈信号的定位描述为「用户反馈和更正的分类」,典型延迟 50-100ms,主要用例是客户支持与自适应学习。
信号如何工作:从对话上下文到反馈类型
与关键词、域名等信号不同,用户反馈信号依赖对话轮次上下文。在源码层面,这一约束由门控函数体现:
// src/semantic-router/pkg/classification/feedback_signal_gate.go func shouldEvaluateUserFeedbackSignal(hasPriorAssistantReply bool) bool { return hasPriorAssistantReply }也就是说,只有当请求中存在上一轮助手的回复(hasPriorAssistantReply 为 true)时,反馈信号才会被评估;否则直接跳过推理,避免在首轮无上下文的情况下凭空判定满意度。对应的测试 feedback_signal_gate_test.go 明确验证了「首轮不触发模型推理、有前序回复才触发」以及「空输入不返回任何反馈分类」的行为。
信号的调度发生在分类器的信号分发阶段,见 classifier_signal_dispatch.go:evaluateUserFeedbackSignal与 Keyword、Embedding、Domain、Fact-check 等信号一起构成主信号分发列表,传入input.HasPriorAssistantReply作为门控依据。
具体评估流程(实现于 classifier_signal_rule_evaluators.go):
- 若没有前序回复,直接跳过;
- 调用
ClassifyFeedback(ctx, text)让反馈检测器(FeedbackDetector)对当前用户消息做序列分类; - 将模型输出的反馈类型(FeedbackType)直接作为信号名;
- 记录信号提取指标(执行耗时、置信度、是否可用、策略默认值);
- 匹配配置中声明的
user_feedback_rules:只有模型预测的反馈类型与规则name一致时才记为命中(写入MatchedUserFeedbackRules并触发信号匹配); - 异常时分别登记错误码:评估失败记
user_feedback_evaluation_failed,模型弃权(Abstained)记user_feedback_uncertain。
反馈标签与标签映射
反馈检测器在初始化时从两个来源之一构建「标签 ↔ 类别索引」映射(feedback_detector.go):
- 显式指定
feedback_mapping_path,读取包含idx_to_label/label_to_idx(或id2label/label2id)的 JSON 映射文件; - 否则直接使用服务化模型自身的标签(
useServedLabels),并校验标签不与模型配置冲突。
映射读取后会经过normalizeFeedbackLabel归一化,将模型可能输出的SAT、SATISFIED、NEED_CLARIFICATION、WRONG_ANSWER、WANT_DIFFERENT等原始标签统一为标准小写形式。源码中定义的标准反馈标签常量为:
| 常量 | 标签值 | 含义 |
|---|---|---|
FeedbackLabelSatisfied | satisfied | 用户满意 |
FeedbackLabelNeedClarification | need_clarification | 用户需要澄清 |
FeedbackLabelWrongAnswer | wrong_answer | 用户表示答错了 |
FeedbackLabelWantDifferent | want_different | 用户想要不同答案 |
FeedbackLabelNoFeedback | no_feedback | 无反馈(Vela 的显式负类) |
阈值、置信度与弃权语义
FeedbackDetector.Classify使用模型输出的概率分布,取 argmax 类别与其置信度,然后与配置的threshold比较(默认阈值 0.5,见 feedback_detector.go):
- 若模型包含显式负类
no_feedback,则保留模型的真实标签与概率,即使置信度低于阈值也只标记Abstained: true——不确定性不等于满意(相关测试见 feedback_abstention_test.go); - 若模型是老的「四类模型」(无 no_feedback 类),低于阈值时执行
applyThreshold兜底策略:把低置信度预测改写为satisfied,并取 satisfied 类别的实际概率作为置信度,从而保持旧的阈值契约。
值得注意的默认配置:在 canonical_defaults.go 中,内置反馈检测器模块默认enabled: true、threshold: 0.37、use_cpu: true,模型引用名为feedback_detector;而默认系统模型将反馈检测器绑定到 Vela 2.0 0.3B 信号模型(Vela2SignalModel)。
配置:声明反馈信号与决策规则
基础配置:声明user_feedbacks
在config.yaml的routing.signals下通过user_feedbacks列表声明反馈信号。每条规则只包含两个字段(与源码结构体 UserFeedbackRule 一一对应:name必填、description可选):
signals: user_feedbacks: - name: "wrong_answer" description: "用户表示之前的回答不正确" - name: "satisfied" description: "用户对回答表示满意" - name: "need_clarification" description: "用户需要对回答进行更多澄清" - name: "want_different" description: "用户想要其他不同的答案"仓库内置的官方信号片段 escalation.yaml 给出了一个最小可用示例:
routing: signals: user_feedbacks: - name: wrong_answer description: User indicates the current answer is incorrect. - name: need_clarification description: User asks for a clearer or more detailed follow-up.在决策规则中使用
声明信号后,即可在decisions中通过type: "user_feedback"引用。以下配置展示两种典型决策:对「答错了」走重新思考 + 推理模式,对「想要不同答案」走替代方案模式:
decisions: - name: wrong_answer_route description: "处理表示错误答案的用户反馈 - 重新思考并提供正确的响应" priority: 150 rules: operator: "AND" conditions: - type: "user_feedback" name: "wrong_answer" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: true plugins: - type: "system_prompt" configuration: system_prompt: "用户已表示之前的回答不正确。请仔细重新考虑问题,找出之前响应中可能存在的错误,并提供经过更正且准确的答案。请逐步思考并在回答前验证你的推理。" - name: retry_with_different_approach description: "路由寻求不同方法的请求" priority: 100 rules: operator: "AND" conditions: - type: "user_feedback" name: "want_different" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: true plugins: - type: "system_prompt" configuration: system_prompt: "用户想要不同的方法或视角。请提供一个与之前响应不同的替代方案或解释。"要点解读:
priority用于多个决策同时匹配时决定优先级,更正类反馈建议给予更高优先级(如 150);rules.operator: "AND"表示所有条件必须同时成立;反馈条件还可以与 keyword、domain、projection 等其他条件组合成布尔树(参见上文引用的信号驱动决策文档);modelRefs[].use_reasoning: true让目标模型在纠正或换思路时启用推理模式,提升回答质量;plugins中的system_prompt根据反馈类型动态改写系统提示词,将路由策略「翻译」成对模型的明确指令。
反馈检测器模块配置
除了路由层信号规则,反馈检测器本身也可在global.model_catalog.modules.feedback_detector下配置(对应源码结构体 FeedbackDetectorConfig):
| 配置字段 | 说明 | 默认值 |
|---|---|---|
enabled | 是否启用反馈检测器 | true |
model_id | 反馈分类模型的 ID,必填 | feedback_detector(默认模型引用) |
threshold | 置信度阈值,低于阈值视为弃权/不确定 | 0.37(模块默认);Classify内部兜底0.5 |
use_cpu | 是否在 CPU 上推理 | true |
max_sequence_length | 单次推理的最大序列长度 | 未显式配置时由后端决定 |
feedback_mapping_path | 标签映射 JSON 文件路径;缺省时使用服务化模型标签 | 空 |
四种反馈类型的实战配置
1. 错误回答(Wrong Answer)
典型模式:"错了"、"不对"、"不正确"、"再试一次"
signals: user_feedbacks: - name: "wrong_answer" description: "用户表示之前的回答不正确" decisions: - name: wrong_answer_route description: "处理表示错误回答的用户反馈" priority: 150 rules: operator: "AND" conditions: - type: "user_feedback" name: "wrong_answer" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: true plugins: - type: "system_prompt" configuration: system_prompt: "用户已表示之前的回答不正确。请仔细重新考虑问题并提供更正后的答案。"示例查询:
- "错了,答案是 42" → ✅ 检测到更正
- "不,我不是那个意思" → ✅ 检测到更正
- "换个方法再试一次" → ✅ 检测到更正
2. 满意(Satisfied)
典型模式:"谢谢"、"完美"、"很有帮助"、"太棒了"
signals: user_feedbacks: - name: "satisfied" description: "用户对回答表示满意" decisions: - name: track_satisfaction description: "跟踪满意的用户" priority: 50 rules: operator: "AND" conditions: - type: "user_feedback" name: "satisfied" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: false plugins: - type: "system_prompt" configuration: system_prompt: "用户感到满意。请继续提供有用的协助。"示例查询:
- "谢谢,这正是我需要的" → ✅ 检测到满意
- "完美,这很有帮助" → ✅ 检测到满意
- "解释得太棒了" → ✅ 检测到满意
满意类反馈建议关闭推理(
use_reasoning: false)、保持低优先级(如 50),继续沿用当前模型即可,避免为正面反馈浪费高成本算力。
3. 需要澄清(Need Clarification)
典型模式:"你能多解释一下吗?"、"我不明白"、"你是什么意思?"
signals: user_feedbacks: - name: "need_clarification" description: "用户需要对回答进行更多澄清" decisions: - name: provide_clarification description: "提供更详细的解释" priority: 100 rules: operator: "AND" conditions: - type: "user_feedback" name: "need_clarification" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: true plugins: - type: "system_prompt" configuration: system_prompt: "用户需要更多澄清。请提供更详细的、带有示例的逐步解释。"示例查询:
- "你能用更简单的术语解释一下吗?" → ✅ 需要澄清
- "最后一部分我没听懂" → ✅ 需要澄清
- "你这话是什么意思?" → ✅ 需要澄清
4. 想要不同的方法(Want Different Approach)
典型模式:"换个答案"、"换种方式"、"给我看看其他选择"
signals: user_feedbacks: - name: "want_different" description: "用户想要其他不同的答案" decisions: - name: retry_with_different_approach description: "提供替代方案" priority: 100 rules: operator: "AND" conditions: - type: "user_feedback" name: "want_different" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: true plugins: - type: "system_prompt" configuration: system_prompt: "用户想要不同的方法或视角。请提供一个与之前响应不同的替代方案或解释。"示例查询:
- "再给我一个解决这个问题的方法" → ✅ 想要替代方案
- "给我展示一个不同的方法" → ✅ 想要替代方案
- "你能试试别的办法吗?" → ✅ 想要替代方案
典型用例
用例 1:客户支持 - 不满意自动升级
问题:不满意的客户需要更好的响应。检测到wrong_answer时,将请求升级到高级模型并给出更高质量的回复:
signals: user_feedbacks: - name: "wrong_answer" description: "客户表示之前的回答不正确" decisions: - name: escalate_to_premium description: "升级到高级模型" priority: 150 rules: operator: "AND" conditions: - type: "user_feedback" name: "wrong_answer" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: true plugins: - type: "system_prompt" configuration: system_prompt: "客户对之前的回答不满意。请提供一个更好、更准确的响应。"用例 2:教育 - 自适应学习
问题:学生在困惑时需要不同的解释。检测到need_clarification时切换到详细讲解模式:
signals: user_feedbacks: - name: "need_clarification" description: "学生需要对回答进行更多澄清" decisions: - name: detailed_explanation description: "提供详细解释" priority: 100 rules: operator: "AND" conditions: - type: "user_feedback" name: "need_clarification" modelRefs: - model: "openai/gpt-oss-120b" use_reasoning: true plugins: - type: "system_prompt" configuration: system_prompt: "学生需要更多澄清。请提供详细的、带有示例的逐步解释。"进阶:反馈信号与多信号组合(真实 Recipe 剖析)
user_feedback信号的价值在组合使用时最大。仓库内置的反馈路由 Recipe(config/recipes/feedback/config.yaml)展示了如何把反馈信号与 reask、keyword、fact_check、domain、context 等信号融合成「反馈恢复压力」(feedback_recovery_pressure)投影:
signals: user_feedbacks: - name: wrong_answer description: Explicit correction or dissatisfaction. - name: need_clarification description: Explicit request to restate the answer more clearly.该 Recipe 将wrong_answer反馈与reask(likely_dissatisfied/persistently_dissatisfied,即用户重复提问判定)、frustration_feedback_markers关键词("wrong"、"doesn't work"、"try again"、"不对"、"重新来" 等)、code_error_markers(traceback、exception、SyntaxError 等)、needs_fact_check以及health/law领域组合成加权求和投影,再映射到feedback_retry(0.24~0.55)、feedback_escalate(0.55~0.85)、feedback_verified_escalate(≥0.85)三个恢复档位,最终由多档位决策路由到不同能力的模型(见该文件中的模型卡:普通跟进走qwen/qwen3.5-rocm,重复不满意走google/gemini-3.1-pro,高风险不满意走openai/gpt5.4)。这展示了一种比单信号更稳健的实践:显式反馈、隐式情绪(关键词)与重复提问(reask)三者互相印证,避免仅凭一句反馈就误判。
最佳实践
1. 结合上下文改进检测
反馈检测依赖前序回复存在与否(见上文门控函数)。若希望更充分地利用对话状态,可在配置中显式跟踪对话信息:
# 跟踪对话状态 context: previous_response: true conversation_history: 3 # 最近 3 条消息结合源码可知,反馈信号的评估输入中携带HasPriorAssistantReply、PriorUserMessages等对话事实(见 classifier_signal_context.go),这为组合 reask(重复提问)等上下文敏感信号提供了基础。
2. 设置升级优先级
更正请求应具有高优先级,确保在多个决策匹配时优先触发纠错而非其他低优先级动作:
decisions: - name: handle_correction priority: 100 # 更正请求的高优先级3. 监控满意度
通过日志与指标跟踪反馈模式,观察不同反馈类型的命中频率与置信度:
logging: level: info user_feedback: true satisfaction_metrics: true从源码看,每次反馈评估都会记录执行耗时(Metrics.UserFeedback.ExecutionTimeMs)、置信度(Confidence/ConfidenceAvailable)、策略默认值(PolicyDefault)以及命中的规则列表(MatchedUserFeedbackRules),这些指标可直接接入监控面板。
4. 使用合适的模型
- 更正:路由到能力更强/更昂贵的模型(并开启
use_reasoning); - 澄清:路由到擅长解释的模型;
- 满意:继续使用当前模型(关闭推理以节省成本)。
排查与边界行为速查
- 首轮消息不会触发反馈评估:没有前序助手回复时,反馈推理被门控跳过,这是设计行为而非故障;
- 空输入/纯空白输入会被检测器拒绝,不会臆造出任何满意度标签;
- 低置信度 ≠ 满意:当模型带显式
no_feedback类时,低于阈值的结果保留真实标签并标记为弃权(Abstained),对应错误码user_feedback_uncertain; - 评估失败:模型不可用或推理报错时,所有已配置反馈规则会登记
user_feedback_evaluation_failed错误码,便于在信号结果中定位问题; - 标签未映射:模型输出了映射中不存在的类别索引时,检测器会返回 "feedback classifier returned unmapped class" 错误,配置
feedback_mapping_path时应确保映射文件与模型id2label一致。
参考
- 完整信号架构与 13 种信号类型、布尔组合规则:信号驱动决策架构
- 反馈检测器实现:feedback_detector.go
- 反馈信号评估与错误码:classifier_signal_rule_evaluators.go
- 反馈门控(首轮跳过逻辑):feedback_signal_gate.go
- 反馈信号配置结构:signal_config.go 与 model_config_types.go
- 官方反馈信号片段:escalation.yaml
- 反馈路由完整 Recipe:feedback/config.yaml
- 相关测试:feedback_signal_gate_test.go、feedback_abstention_test.go
- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
相关推荐
Semantic Router 用户反馈信号(user-feedback):让路由决策"听见"用户的纠正与不满
Semantic Router 用户反馈信号(user feedback):让路由决策"听见"用户的纠正与不满 user feedback 是 semantic
后端API网关模型推理服务AI AgentSemantic Router Feedback Recovery Recipe:基于用户反馈的多轮对话恢复路由实战指南
Semantic Router Feedback Recovery Recipe:基于用户反馈的多轮对话恢复路由实战指南 导读 本文深入讲解 semantic
后端API网关模型推理服务AI Agentsemantic-router 的 Elo 选择算法:基于反馈评分驱动的模型路由实践指南
semantic router 的 Elo 选择算法:基于反馈评分驱动的模型路由实践指南 导读 本文围绕 semantic router 提供的 elo 模型选
后端API网关模型推理服务AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考