# Summary
1. 意图分类之间不能有交叉和模糊地带
2. 路由到的意图如果有 tool 能穷尽该空间,则 workflow;如果不能穷尽则 Function Call 的 Agent
3. 至于微调训练集的数据量,四分类任务没有绝对标准,但有个模糊的参考范围:如果是基于通用大模型(比如7B以下参数)微调,每个类别至少要有100-200条高质量标注样本,总共400-800 条是基础门槛;如果想把准确率提到90%以上, 每个类别300-500条会更稳妥,总数据量1200-2 000条左右~
4. 对了调整prompt时可以用逐步优化法:先写一个基础版prompt测试,统计每个类别的准确率,比如发现类别4”其他”的误判率最高,就针对性补充更多类别4的示例;如果有某些特定表述总被错分,也可以直接在prompt里加“排除提示“、
5. 另外也可以做针对性的数据增强,不是盲目加量,而是看模型哪类错得最多,就重点扩哪类: 比如模型在“预约服务“类上错率高,就用同义词替换(“预约“改成“想预定“)、句式改写(“预约周五”改成“请问能帮我预定周五吗”)、补充边缘场景示例(“约下周一下午3点的餐厅“这种带具体时间和服务类型的),让这类样本更丰富,也能平衡各类别数据分布,避免某类样本太少导致模型偏向性
6. 特别理解意图识别准确率卡在85%的瓶颈期~首先,关于意图识别的prompt编写和调整,其实可以先从“明确任务边界+给足参考示例”入手,比如不要只简单说”做四分类”,可以写得更具体:“请完成意图识别四分类任务,四个类别分别是【类别n:用途/场景,样例:•。】这样模型能更清晰把握每个类别的边界,尤其对易混淆的类别,可以把它们的示例放在一起对比。如果之前没加判断理由,也可以试着在prompt里加一句“输出类别后简要说明判断依据”,倒逼模型更严谨,后续也能通过理由快速定位它错在哪~
7. 不过也要看数据质量—如果样本语义清晰、
## 数据需要多少?
1. 样本本身是模糊的还是清晰的
1. 类别区分度高,哪怕每个类别150条也能出效果;
2. 但如果样本本身模糊(比如短文本、多意图混杂),或者类别边界近,就得加到每个类别500条以上,甚至更多。
2. 另外模型大小也影响数据量, 小尺寸模型(比如7B以内)几百条够了,大些的模型(13B及以上)需要更多数据才能”喂饱”,不然容易过拟合,反而掉准确率
## 操作笔记
### 数据处理
- 输出: data_level1_pair_outputl1.json(3122 条)
- 字段: user_text, ai_text, label;内部用 [SEP] 拼接最近轮次
-
```
# 方案C: [SEP] + segment embedding
# F1: 0.85 ✅ 最好,但收益有限
user_text = "去三亚[SEP]飞机[SEP]海边"
ai_text = "请补充信息[SEP]推荐方案"
# 只保留最近N轮
user_text = " ".join(user_utterances[-3:]) # 最近3轮用户输入
ai_text = " ".join(ai_utterances[-2:]) # 最近2轮AI回复
# 使用 segment embedding 区分
return tokenizer(
text=user_text, # segment 0: 用户
text_pair=ai_text, # segment 1: AI
max_length=256,
truncation=True,
padding=True
)
```
## 特征工程增强(备选)
python
```python
# 除了文本,还可以提取结构化特征:
features = {
'has_location': True, # 是否提到地点
'has_date': True, # 是否提到日期
'has_duration': True, # 是否提到时长
'has_budget': False, # 是否提到预算
'has_companion': True, # 是否提到同行人
'query_length': 32, # 查询长度
'question_words': ['怎么', '如何'] # 疑问词
}
```
[[Focal Loss]]
## 选 LLM 还是人打标
```
- 新增
- prepare_level1_pair_data.py:把 adjusted.json 转成成对输入数据,输出 data_level1_pair.json,字段为:
- user_text: 最近 N 条 user 话术拼接(默认 3)
- ai_text: 最近 M 条 agent 话术拼接(默认 2)
- label: expected_output_level1
- 已生成:data_level1_pair.json(3122 条,标签分布与 adjusted 一致)
- 修改
- train_model.py:兼容成对输入
- Example 新增 ai_text 字段
- python3 prepare_level1_pair_data.py --src adjusted.json --dst data_level1_pair.json --user-last-n 3 --ai-last-m 2
- 启用 MPS:
- export PYTORCH_ENABLE_MPS_FALLBACK=1
- 用 BERT 微调(建议 BERT 系列,以利用 segment embeddings;RoBERTa 会忽略 token_type_ids):
- 文件位置
- 预处理脚本: prepare_level1_pair_data.py:1
- 训练脚本(已更新): train_model.py:1
```
## 微调训练
```
> 已完成 3 个 epoch 微调,并导出混淆矩阵 CSV。
- 训练
- 数据: data_level1_pair_outputl1.json
- 模型输出: outputs/bert_level1_pair_outputl1_mps
- 配置: 3 epochs, MPS 加速, max_length=256, batch_size=16/32
- 评估(Holdout 集 469 条)
- 命令: python eval_pair_confmat.py --data data_level1_pair_outputl1.json --model outputs/bert_level1_pair_outputl1_mps
--split holdout --csv-out outputs/confusion_matrix_outputl1_holdout.csv
- Accuracy: 0.8635
- Macro F1: 0.8945
- 分类报告
- 交通单意图: P=0.8980, R=0.8800, F1=0.8889, support=50
- 其他意图: P=0.9796, R=1.0000, F1=0.9897, support=48
- 多意图组合: P=0.7681, R=0.8281, F1=0.7970, support=128
- 模糊意图: P=0.8958, R=0.9773, F1=0.9348, support=44
- 路线单意图: P=0.8851, R=0.7988, F1=0.8397, support=164
- 酒店单意图: P=0.8919, R=0.9429, F1=0.9167, support=35
- 混淆矩阵 CSV
- 路径: outputs/confusion_matrix_outputl1_holdout.csv
- 形式: 宽表(首行列头为预测标签,首列为真实标签)
要不要同时导出验证集的混淆矩阵,或生成 PNG 热力图版本?
▌ 好了吗,混淆矩阵给我
> 好了。以下为 Holdout 集的混淆矩阵(行=真实,列=预测):
- 列顺序: [交通单意图, 其他意图, 多意图组合, 模糊意图, 路线单意图, 酒店单意图]
- 交通单意图: [44, 0, 4, 1, 1, 0]
- 其他意图: [0, 48, 0, 0, 0, 0]
- 多意图组合: [2, 0, 106, 1, 15, 4]
- 模糊意图: [0, 0, 0, 43, 1, 0]
- 路线单意图: [3, 1, 26, 3, 131, 0]
- 酒店单意图: [0, 0, 2, 0, 0, 33]
CSV 文件已保存到: outputs/confusion_matrix_outputl1_holdout.csv
```
## 混淆矩阵分析
3. [[意图识别]]和 [[对话状态跟踪 DST]] 必须同时存在
todo:咱们不是每句话,有个 DST,就是那个偏好识别 那个是走 IIm 的 让那个同时出一个意图识别,然后和 bert 的 double check,不一样再把 agent 动作回退,不就可以了
2. 意图识别是已经做到的地方,归到chatbot的里面的进一步意图分类本质是在找到我们潜在的能比gpt做的好的地方。
3. 忙猜一个一级节点,直接进入该节点的 context 下匹配意图
4. **对于用户的问题** **其实有两个衡量维度一个是高频重要** **还有一个是容易实现**
___
## 已超越
1. 高分酒店按钮、酒店咨询
2. 低价交通按钮、交通咨询
3. 景点咨询
4. 自然语言行程规划、小红书导入按钮、小红书导入路线、行程调整、旅游咨询
5. 热门景点卡片、Al开启行程规划
6. Chatbot
1. tool1 拿行程内容
2. tool2 查 POI 详情页接口
3. tool3 查天气
___
chatbot
1. 优惠券
2. 发票
3. 客服电话
4. 转人工
5. 哪儿网app的字体太小,在哪里设置
交通咨询 8331 (20.4%) 低价交通按钮 841 (2.1%)
自然语言行程规划 6721 (16.5%) 热门景点卡片 5606 (13.7%) AI开启行程规划 3858 (9.4%) 行程调整 108 (0.3%)
闲聊 6676 (16.3%)
酒店咨询 3028 (7.4%) 高分酒店按钮 487 (1.2%)
小红书导入按钮 594 (1.5%) 小红书导入路线 184 (0.5%)
大模型错误 3491 (8.5%)
旅游咨询 701 (1.7%)
chatbot_vl 92 (0.2%)
chatbot_vl 92 (0.2%)
drawer_chat 87 (0.2%)
景点咨询 42 (0.1%)
# Cues
[四渡赤水-偏好更新](四渡赤水-偏好更新.md)
# Notes
## 问题一:单轮意图 vs 多轮意图
### 如何选择
- **如果你的对话语料中,单句用户发言大多数都能独立判断意图** → 直接用 **单轮输入**,训练简单,泛化好。
- **如果你发现很多样本离开上下文就完全没法判断** → 用 **多轮拼接**,但要注意设计格式,不要让 `<agent>` 的提示语变成“答案泄露”。
1. 上下文场景(多轮对话意图识别)
但有些情况下,确实需要上下文,比如:
- 用户说:**“好的”**——单独看没法判断意图,但结合上一轮 “要帮我订机票吗?” 就是确认意图。
- 用户说:**“那帮我也查一下酒店”**——需要上一轮有“机票”才能推断这是“酒店查询”意图。
做法:
- 拼接上下文(前几轮用户 + agent),通常格式:
- `[prev_user]我想去北京` `[prev_agent]好的,要订机票吗?` `[curr_user]嗯,帮我看看机票`
- 再交给 BERT/LLM 训练。
- 注意:上下文长度要控制,一般拼接前 1–3 轮就够。