Initial travel knowledge graph release

This commit is contained in:
2026-06-09 09:56:26 +08:00
commit 5f061295d8
402 changed files with 103877 additions and 0 deletions

View File

@@ -0,0 +1,210 @@
# 客服图谱快速查询实现说明
更新时间2026-06-03
## 1. 目的
当前客服页 `http://localhost:8102/admin/plaza/user` 的原型目标不是生成完整复杂行程,而是让客服在对话中快速查到三类高频信息:
1. 固定线路有哪些。
2. 某个景区附近有哪些可选酒店、餐饮。
3. 某个景区有哪些门票、小交通、保险、二消、必付/可选费用。
因此这次没有把所有问题都交给 LLM 慢慢生成,而是先做“轻量 Agent 分流 + 图谱直查”的快速查询能力。
## 2. 当前采用的方法
### 方法一:高频问题先走规则意图识别
对客服常见问题先做规则判断:
- `路线有哪些 / 线路有哪些 / 产品有哪些`
- `黄果树附近有哪些酒店餐饮`
- `小七孔有哪些必付和可选费用`
- `酒店房型 / 旺季 / 淡季 / 房价`
- `加人 / 车型 / 用车`
命中这些问题后,直接进入专用图谱查询函数,不进入复杂推荐排序,也不等待 LLM。
代码位置:
- `/Users/xuexue/new2/app/api/travel_assistant.py:1944`
- `/Users/xuexue/new2/app/api/travel_assistant.py:3082`
### 方法二:线路清单使用轻量图谱查询
以前“有哪些线路”会加载完整图谱,包括酒店、餐饮、费用、车辆等关系,导致慢且容易只返回一个推荐方案。
现在改成只查询:
```text
TourProduct -> ProductDay -> RouteStop -> ScenicAttraction/SubAttraction
```
不查酒店、餐饮、费用细节。
这样“有哪些线路”只返回线路清单,默认最多显示 30 条。
代码位置:
- `/Users/xuexue/new2/app/api/travel_assistant.py:1679`
- `/Users/xuexue/new2/app/api/travel_assistant.py:2975`
### 方法三:景区附近资源使用 NEARBY 关系直查
酒店和餐饮已经拆成独立 POI 实体:
```text
ScenicAttraction -> ATTRACTION_NEARBY_RESOURCE -> Hotel
ScenicAttraction -> ATTRACTION_NEARBY_RESOURCE -> Restaurant
```
客服问“黄果树附近有哪些酒店餐饮”时,直接从景区节点查附近资源,不再绕到线路产品里查。
代码位置:
- `/Users/xuexue/new2/app/api/travel_assistant.py:2013`
### 方法四:费用资源兼容两条查询路径
费用、小交通、保险、二消可能来自两类关系:
```text
RouteStop -> STOP_USES_DEFAULT_RESOURCE -> TravelItem
ScenicAttraction -> ATTRACTION_HAS_ITEM -> TravelItem
```
因此费用查询同时查这两条路径。
如果关系里已有 `MANDATORY / OPTIONAL / INCLUDED`,就直接使用。
如果没有明确状态,就按证据文本轻量推断:
- 出现“必须、必付、需自理、不含、另付” -> `MANDATORY`
- 出现“自愿、可选、不必须、客人自愿” -> `OPTIONAL`
- 出现“已含、包含、赠送” -> `INCLUDED`
代码位置:
- `/Users/xuexue/new2/app/api/travel_assistant.py:2196`
### 方法五:推荐问题才走完整图谱排序
如果用户问的是复杂需求,例如:
```text
5个人想玩5天想去黄果树、小七孔、西江预算低帮我推荐线路
```
这时才加载完整固定线路图谱,做路线匹配、车辆建议、每日行程、费用提示。
完整图谱加载包含:
```text
TourProduct
ProductDay
RouteStop
TravelItem
Hotel
Restaurant
Vehicle
Fee
NEARBY
```
代码位置:
- `/Users/xuexue/new2/app/api/travel_assistant.py:1536`
- `/Users/xuexue/new2/app/api/travel_assistant.py:3082`
## 3. 当前已经验证的效果
本地直接调用后端函数验证:
| 测试问题 | 返回结果 | 响应时间 |
|---|---:|---:|
| `游路线有哪些` | 30 条线路,图谱候选 39 条 | 约 0.12 秒 |
| `黄果树附近有哪些酒店餐饮` | 8 个酒店、10 个餐饮 | 约 0.07 秒 |
| `小七孔有哪些必付和可选费用` | 90 条费用候选 | 约 0.09 秒 |
说明:这是后端图谱查询耗时,不包含浏览器渲染和网络开销。
## 4. 前端展示调整
客服页按不同结果类型做轻量展示:
- `route_catalog`:线路清单模式,只显示线路编号、名称、天数、路线概览。
- `nearby_resource`:附近资源模式,只显示酒店候选、餐饮候选、使用说明。
- 普通推荐:保留原来的行程方案卡片。
同时左侧增加常用问法:
- 有哪些线路
- 5天路线有哪些
- 黄果树附近有哪些酒店餐饮
- 小七孔有哪些必付和可选费用
代码位置:
- `/Users/xuexue/new2/admin-web/src/panels/plaza/TravelAgencyAssistantPanel.tsx:131`
- `/Users/xuexue/new2/admin-web/src/panels/plaza/TravelAgencyAssistantPanel.tsx:156`
- `/Users/xuexue/new2/admin-web/src/panels/plaza/TravelAgencyAssistantPanel.tsx:182`
- `/Users/xuexue/new2/admin-web/src/panels/plaza/TravelAgencyAssistantPanel.tsx:218`
## 5. 是否满足当前原型需求
当前已经满足原型阶段的核心需求:
1. 客服可以快速查询已有固定线路。
2. 客服可以按景区查附近酒店和餐饮候选。
3. 客服可以按景区查费用、二消、必付和可选项目。
4. 响应速度从原来的数秒级降到 0.1 秒级图谱查询。
5. 展示方式从复杂行程卡,调整为按问题类型展示足够信息。
## 6. 当前还不是完整 GraphRAG
当前实现是:
```text
用户问题
-> 规则/轻量 Agent 分流
-> 知识图谱快速查询
-> 结构化结果展示
```
还没有完整接入:
```text
图谱查询
-> 向量库补充原文话术/证据
-> LLM 生成客服自然语言回复
```
原因是当前原型优先解决“查得到、查得快、数据结构可控”。如果一开始所有问题都走向量和 LLM会更慢也更容易把线路、费用、可选资源说错。
## 7. 后续建议
下一步建议把 GraphRAG 分成三层:
1. 快速图谱层:线路、景区、费用、附近资源,必须秒级返回。
2. 向量证据层:客服话术、合同说明、退改规则、行程原文,用于补充解释。
3. LLM 话术层:只负责把图谱结果和证据整理成客服可复制的话,不负责凭空生成事实。
推荐的最终链路:
```text
用户自然语言
-> Agent 识别意图
-> KG 精确查询
-> Vector 补充原文证据
-> LLM 生成客服回复
-> 返回可复制话术 + 图谱依据
```
## 8. 当前风险
1. 酒店和餐饮的高德车程字段还有部分是 `pending_amap_driving`,附近推荐目前主要依赖业务区域匹配。
2. 部分费用状态来自文本推断,最终仍应以供应商/产品配置确认。
3. “路线有哪些”返回的是固定线路产品清单,不等于所有线路都支持小包团,需要看产品字段 `small_group_supported` 或后续供应商补充。
4. 如果后续图谱节点增加到几万级,需要给线路清单和 NEARBY 查询增加分页、索引或缓存。