问题分类器(QuestionClassifier
)是Citu智能数据问答平台的核心组件,负责将用户问题分类为DATABASE
(数据库查询)或CHAT
(聊天对话)类型。本文档详细解释其基于规则的分类逻辑和评分机制。
graph TD
A[用户问题输入] --> B[提取当前问题]
B --> C[检查非业务实体词]
C --> D{包含非业务词?}
D -->|是| E[直接分类为CHAT<br/>置信度0.85]
D -->|否| F[计算各类评分]
F --> G[业务实体评分]
F --> H[系统指示词评分]
F --> I[查询意图评分]
F --> J[SQL模式评分]
F --> K[聊天关键词评分]
G --> L[组合评分逻辑]
H --> L
I --> L
J --> L
K --> L
L --> M[分类决策]
M --> N[返回分类结果]
问题分类器定义了 8种关键词类型,用于不同的分类判断:
序号 | 关键词类型 | 数据结构 | 权重/作用 | 数量 | 定义位置 |
---|---|---|---|---|---|
1 | 强业务关键词 | 字典(6个子类别) | 混合权重 | 65个 | classifier.py:49-79 |
2 | 查询意图关键词 | 列表 | +1分/词 | 25个 | classifier.py:81-87 |
3 | 非业务实体词 | 列表 | 立即CHAT(0.85) | ~80个 | classifier.py:91-122 |
4 | SQL模式 | 正则表达式列表 | +3分/匹配 | 2个 | classifier.py:126-129 |
5 | 聊天关键词 | 列表 | +1分/词 | 17个 | classifier.py:132-136 |
6 | 追问关键词 | 列表 | 上下文判断 | 16个 | classifier.py:139-143 |
7 | 话题切换关键词 | 列表 | 上下文判断 | 12个 | classifier.py:146-150 |
8 | 业务上下文文件 | 外部文本 | LLM分类辅助 | 1个文件 | tools/db_query_decision_prompt.txt |
关键概念区分:
graph TD
A[强业务关键词<br/>strong_business_keywords] --> B[业务实体词<br/>+2分/词<br/>5个子类别]
A --> C[系统查询指示词<br/>+1分/词<br/>特殊处理]
B --> D[核心业务实体]
B --> E[支付业务]
B --> F[经营品类]
B --> G[车流业务]
B --> H[地理路线]
C --> I[系统指示<br/>数据指示<br/>平台指示]
style B fill:#e1f5fe
style C fill:#fff3e0
包含关系说明:
代码实现逻辑:
# 在 _rule_based_classify 方法中
for category, keywords in self.strong_business_keywords.items():
if category == "系统查询指示词": # 系统指示词单独处理
continue
for keyword in keywords:
if keyword in question_lower:
business_score += 2 # 业务实体词权重更高
这是分类器的核心词库,分为6个业务类别:
用于识别数据查询意图,权重: +1分/词
使用正则表达式匹配SQL语句特征,权重: +3分/匹配
select|from|where|group by|order by|having|join|update
数据库|表名|表|字段名|SQL|sql|database|table
定义位置: agent/classifier.py
第91-122行
处理机制: 一旦匹配,直接分类为CHAT,置信度0.85(最高优先级判断)
具体分类:
定义位置: agent/classifier.py
第132-136行
处理机制: 倾向于聊天分类,权重: +1分/词
具体分类:
定义位置: agent/classifier.py
第139-143行
处理机制: 用于检测追问型问题,在渐进式分类中起上下文判断作用
具体分类:
定义位置: agent/classifier.py
第146-150行
处理机制: 检测明显的话题转换,避免错误继承上下文类型
具体分类:
定义位置: agent/tools/db_query_decision_prompt.txt
处理机制: 为LLM分类提供详细的业务范围描述
内容概要:
# 1. 业务实体评分 (business_score)
for 每个业务类别:
if 类别 != "系统查询指示词":
for 每个关键词:
if 关键词 in 问题:
business_score += 2
# 2. 系统指示词评分 (system_indicator_score)
for 每个系统查询指示词:
if 关键词 in 问题:
system_indicator_score += 1
# 3. 查询意图评分 (intent_score)
for 每个查询意图词:
if 关键词 in 问题:
intent_score += 1
# 4. SQL模式评分
for 每个SQL正则模式:
if 模式匹配:
business_score += 3
# 5. 聊天关键词评分 (chat_score)
for 每个聊天关键词:
if 关键词 in 问题:
chat_score += 1
系统指示词具有特殊的组合效应:
if system_indicator_score > 0 and business_score > 0:
# 系统指示词 + 业务实体 = 强组合效应
business_score += 3 # 组合加分
elif system_indicator_score > 0:
# 仅有系统指示词 = 中等业务倾向
business_score += 1
设计理念:
非业务实体词检查 (最高优先级)
CHAT
, 置信度=0.85强业务特征 (次高优先级)
business_score ≥ 2
AND intent_score ≥ 1
DATABASE
min(max_confidence, 0.8 + (total_business_score * 0.05))
中等业务特征
business_score ≥ 4
DATABASE
min(max_confidence, 0.7 + (business_score * 0.03))
聊天特征
chat_score ≥ 1
AND business_score = 0
CHAT
min(max_confidence, base_confidence + (chat_score * confidence_increment))
不确定情况 (最低优先级)
UNCERTAIN
uncertain_confidence
(默认0.2)confidence = min(max_confidence, 0.8 + (total_business_score * 0.05))
其中: total_business_score = business_score + intent_score
confidence = min(max_confidence, 0.7 + (business_score * 0.03))
confidence = min(max_confidence, base_confidence + (chat_score * confidence_increment))
默认: base_confidence=0.4, confidence_increment=0.08
graph TD
A[规则分类完成] --> B{非业务词匹配?}
B -->|是| C[直接CHAT<br/>置信度=0.85<br/>🔴王炸优先级]
B -->|否| D{置信度 ≥ 0.7?}
D -->|是| E[🟢毫不犹豫<br/>直接使用规则结果<br/>不调用LLM]
D -->|否| F[🟡调用LLM分类<br/>进行二次判断]
F --> G[比较两个置信度]
G --> H[选择置信度更高的结果]
置信度范围 | 决策行为 | 代码位置 | 说明 |
---|---|---|---|
非业务词匹配 | 🔴 直接CHAT,置信度=0.85 | classifier.py:354-361 |
最高优先级,立即决策 |
≥ 0.7 | 🟢 毫不犹豫使用规则结果 | classifier.py:291-292 |
高置信度,不调用LLM |
0.4 - 0.69 | 🟡 规则+LLM双重判断 | classifier.py:294-301 |
取置信度更高者 |
< 0.4 | 🟡 规则+LLM双重判断 | classifier.py:294-301 |
取置信度更高者 |
问题: "统计服务区的微信支付金额"
规则分类: DATABASE, 置信度=0.9
决策: 直接使用规则结果,不调用LLM ✓
问题: "服务区情况"
规则分类: DATABASE, 置信度=0.6
LLM分类: DATABASE, 置信度=0.8
决策: 选择LLM结果 (0.8 > 0.6) ✓
问题: "苹果什么时候成熟"
非业务词: 苹果 ✓
决策: 直接CHAT,置信度=0.85,跳过所有其他判断 ✓
代码位置: agent/classifier.py:283-301
(_hybrid_classify
方法)
def _hybrid_classify(self, question: str) -> ClassificationResult:
# 第一步:规则预筛选
rule_result = self._rule_based_classify(question)
# 如果规则分类有高置信度,直接使用
if rule_result.confidence >= self.high_confidence_threshold: # 0.7
return rule_result # 毫不犹豫使用规则结果
# 第二步:使用增强的LLM分类
llm_result = self._enhanced_llm_classify(question)
# 选择置信度更高的结果
if llm_result.confidence > rule_result.confidence:
return llm_result
else:
return rule_result
关键特点:
参数名 | 默认值 | 范围 | 说明 |
---|---|---|---|
high_confidence_threshold |
0.7 | 0.7-0.9 | 高置信度阈值,超过则直接使用规则结果 |
low_confidence_threshold |
0.4 | 0.2-0.5 | 低置信度阈值,低于则启用LLM辅助 |
max_confidence |
0.9 | 0.8-1.0 | 最大置信度上限,防止过度自信 |
base_confidence |
0.4 | 0.3-0.6 | 基础置信度,聊天分类的起始值 |
confidence_increment |
0.08 | 0.05-0.2 | 置信度增量步长 |
uncertain_confidence |
0.2 | 0.1-0.3 | 不确定分类的置信度 |
关键词类型 | 权重 | 用途 | 说明 |
---|---|---|---|
业务实体词 | +2分/词 | 规则评分 | 核心业务概念,强业务关键词的主要部分 |
系统指示词 | +1分/词 | 规则评分 | 系统查询指示,权重低于业务实体词 |
查询意图词 | +1分/词 | 规则评分 | 数据查询意图,辅助判断 |
SQL模式 | +3分/匹配 | 规则评分 | 技术查询特征,权重最高 |
聊天关键词 | +1分/词 | 规则评分 | 聊天交互意图 |
非业务实体词 | 立即CHAT(0.85) | 直接分类 | 最高优先级,跳过所有评分 |
追问关键词 | 无直接权重 | 上下文判断 | 检测追问型问题 |
话题切换关键词 | 无直接权重 | 上下文判断 | 检测话题转换 |
组合加分 | +3分 | 特殊逻辑 | 系统词+业务词组合效应 |
问题: "统计服务区的微信支付金额"
匹配:
- 业务实体: 服务区(+2), 微信支付(+2) → business_score=4
- 查询意图: 统计(+1) → intent_score=1
- 总分: 4+1=5
结果: DATABASE, 置信度=min(0.9, 0.8+5*0.05)=0.9
问题: "驿美运营公司档口数量"
匹配:
- 业务实体: 驿美运营公司(+2), 档口(+2) → business_score=4
- 查询意图: 无 → intent_score=0
结果: DATABASE, 置信度=min(0.9, 0.7+4*0.03)=0.82
问题: "苹果什么时候成熟"
匹配: 苹果(非业务词)
结果: CHAT, 置信度=0.85
问题: "怎么使用这个平台"
匹配:
- 聊天关键词: 怎么(+1), 使用方法(+1) → chat_score=2
- 业务实体: 无 → business_score=0
结果: CHAT, 置信度=min(0.9, 0.4+2*0.08)=0.56
问题: "请问一下"
匹配: 无关键词匹配
结果: UNCERTAIN, 置信度=0.2
def _extract_current_question_for_rule_classification(self, question: str) -> str:
"""提取当前问题用于规则分类,避免上下文干扰"""
if "\n[CURRENT]\n" in question:
current_start = question.find("\n[CURRENT]\n")
current_question = question[current_start + len("\n[CURRENT]\n"):].strip()
return current_question
return question.strip()
所有关键词匹配都转换为小写进行,确保大小写不敏感。
SQL模式使用正则表达式匹配,支持单词边界检查,避免子字符串误匹配。
本文档基于 agent/classifier.py 代码分析生成,版本日期: 2024年