Skip to content

会议室匹配与平替推荐 · 优化方案(讨论稿) ​

状态:方案讨论稿(待评审,短期不排期) | 范围:对话端会议预定 · 指定会议室匹配与占用平替
关联:会议室推荐算法逻辑、SA_空间预约_物理执行逻辑、实体检索策略方案、SA_会议预定_设计实现偏差问题说明

定位:本文针对"用户指定会议室"链路的匹配不准、占用不可判、无平替三个问题给出优化方案,并记录讨论中形成的顾虑与替代路径。本文为设计讨论稿,短期内不实施(核心顾虑见 §5)。


0. 一句话 ​

现状用单一相似度分数 + 阈值去同时回答"是不是这一间 / 能不能订 / 换哪间"三个性质不同的问题,导致阈值怎么调都不对、占用判断做不出、平替缺失。本方案把三者拆开:目标识别交给 LLM 裁决节点,可用性交给带状态的后端接口,平替交给锚点父链的结构化查询。


1. 现状与根因 ​

1.1 现状链路(Dify 会议预定) ​

1.2 三个已核实的事实 ​

#事实出处
1"找到 / 没找到"由 resolve 的 score 判定(space_id_score_flag),不是由可用性结果判定会议预定.yml:847-849, 1007
2前端判定阈值 = 0.5(_DEFAULT_SPACE_ID_SCORE);Dify 发给后端的 scoreThreshold = 0.2会议预定.yml:805, 765
3Dify 解析 resolve 响应**只读 spaceId 与 score**,无路径 / 父节点 / 容量 / 占用会议预定.yml:843-849

阈值在 0.5 / 0.6 / 0.8 之间反复漂移,本身就是"调不准"的直接证据。

1.3 根因 ​

一个标量分数被要求回答三个不同的问题:

问题性质真正需要什么现状用什么
是不是用户要的那一间离散语义判断精确名录 / 结构化 key / 语义理解连续相似度分数 + 阈值
这一间能不能订时间相关查询目标已确定 + 忙闲接口空结果反推
换哪一间结构化检索锚点属性 + 邻居查询无(缺失)

由此派生三个直接后果:

  1. 阈值不可调:803 与 804 在向量空间近乎同分布;同一分数在"订 803"与"三楼那个大的"两种意图下含义相反;无 ground truth 可回归。
  2. 占用不可判:占用判断的前提是"目标已确定",而 score 只给排序列表、不给目标。top1 错,查的就是错房间的占用。
  3. 平替缺失(对应偏差文档 §3.3,P0):named path 用 locationIds 硬过滤到解析出的房间,被占 → 后端返回空 → 直接"未能匹配",不做同规格二次检索。

2. 设计目标与约束 ​

目标

  • G1 准确识别用户真实目标;识别不出时明确收敛或追问,不假装识别成功
  • G2 目标不可用时,给出就近、同规格的平替
  • G3 不显著增加端到端延迟

约束

  • C1 不能依赖 Exact 短路作为主干:room_name 经 LLM 槽位改写后,能精确命中名录是低概率事件
  • C2 空间树层级不固定:园区 / 楼栋 / 楼层 / 虚拟分区(行政区、工位区等)/ … 每项目配置不同,层数无统一规范,无法在 slot 阶段按固定 schema 类型化抽取
  • C3 空间是"控错 = 安全事故"的场景(检索方案 §二),不能瞎猜

3. 前置依赖:后端接口契约(共同前置) ​

⚠️ 本节不落地,主方案与降级方案都无法实施。 这是本方案的第一优先项,且与是否加 LLM 无关。

接口现状需要补充
/internal/spaces/resolve返回 spaceId + score① 可读渲染路径(如 园区A/3号楼/8楼/行政区/803) ② 父节点标识(parentId) ③ 结构化属性(capacity、capabilities) ④ 匹配类型(exact / fuzzy,可选)
list_available_meeting_rooms只返回空闲房间① 返回带 occupied 标记(或新增单点忙闲查询 spaceId → {exists, occupied}) ② locationIds 支持父节点级过滤(传楼层 / 分区 id,返回其下全部房间)

为什么路径是硬要求:LLM 裁决节点拿到 5 个裸 spaceId 是无法判断哪个是 803 的,它必须看到渲染后的路径串才能理解"这间在 8 楼行政区"。降级方案(字符串匹配)同样依赖路径。


4. 主方案:LLM 裁决节点 + 父链平替 ​

4.1 链路总览 ​

4.2 LLM 裁决节点 ​

输入:用户原话 + 候选集(每项含 spaceId / 渲染路径 / capacity / capabilities / score)+ 会议需求(人数、时间)

输出(结构化枚举,非自由文本):

字段取值说明
resolutionEXACT / AMBIGUOUS / NONE目标确定 / 多个近似需确认 / 无法定位
target_space_idstringEXACT 时给出
candidatesstring[]AMBIGUOUS 时给出待确认项
reasonstring便于回归与解释

分流:

  • EXACT → 锁定目标,进入可用性判断
  • AMBIGUOUS → 追问("你指的是 8 楼行政区那间 803,还是 9 楼的 803?")
  • NONE → 走容量推荐 + 追问,不做占用判断(目标未定,占用问题不存在)

设计要点:用枚举而非自由文本,是为了可测、可回归、可解释——正好治现状"没法调"的病。

4.3 占用冲突与平替(父链阶梯) ​

触发条件统一为"锚点不可用",不止"被占用":

触发现状行为
锚点房间不存在(短路未命中真实实体)空 → "未查询到"
锚点房间被占用空 → "未能匹配"
锚点容量 / 设施不满足空 → "未能匹配"

平替逻辑:沿父链逐级上跳(本方案核心思路)

空间树层数不固定(C2),因此不预设"楼层"这一层级类型,而是沿锚点的真实父链向上找兄弟节点:

锚点 = 803(parent = 8楼/行政区)
  ├─ 1. 同一 parent 下的兄弟房间,容量 ≥ 需求,按 |容量 − 需求| 升序,取 Top3
  ├─ 2. 同 parent 无合适 → 上跳到 grandparent(8楼)下的兄弟,重复
  ├─ 3. 继续上跳(3号楼 → 园区A),重复
  └─ 4. 到顶仍无 → 跨楼 / 跨园区按容量兜底;再无 → 如实告知

优点:不依赖"楼层"语义,天然适配任意层深与虚拟分区(行政区、工位区等)。"同一父节点下的兄弟"即等价于"同层 / 同区",无需知道那层叫什么。

排序:容量适配度 |RoomCap − UserCap| 升序(沿用推荐算法 §2.2 思想),保证"大小相近"。

4.4 状态与话术 ​

话术遵循智能体统一人设:不用「您好」、第一人称、去工程词。

场景状态示例话术
目标确定且空闲SUCCESS"803 这个时段空着,帮你订?"
目标确定但被占CONFLICT"803 被占了,同层还有 805、806 空着,你看要哪间?"
目标不明确AMBIGUOUS"你指的是 8 楼那间 803 吗?"
无法定位NONE"没找到你说的房间,能说下楼层或大概位置吗?"

5. 顾虑点与待决(重要) ​

本节是本方案短期不实施的主要原因,也是后续评审的重点。

#顾虑说明可能应对
1性能新增 LLM 节点 = +1 次模型往返,端到端延迟上升点名 + 短路命中时跳过 LLM,直接收敛 top1;LLM 仅在模糊 / 歧义时介入
2依赖运营数据质量路径可读性、父节点正确性取决于空间树与别名维护质量;检索方案 §四之二已警告空间树可能非标准结构路径渲染容错;缺失时降级
3占用状态的时间相关性"是否被占"取决于具体时间窗,属可用性层而非实体层,不应由 resolve 承担状态从可用性接口取,resolve 只做实体解析
4LLM 稳定性裁决节点输出是否稳定、歧义 margin 如何定枚举输出 + 评测集回归(复用 SA_会议预定_测试方法 L3)
5平替找不到时全父链走完仍无 → 需话术兜底如实告知 + 引导换时间
6是否值得加节点收益(准确率)vs 成本(延迟、维护)未量化建议先做 §3 后端契约 + 真实 query 分布统计

6. 附录:无 LLM 降级路径 ​

若性能约束优先,可在不加 LLM 节点的前提下覆盖大部分场景(代价:纯模糊语义场景降级为追问):

子问题无 LLM 解法依赖
目标识别① 匹配类型为 exact → 取 top1;② 分差 < margin → 追问;③ 路径含定位 key(楼层 / 区域字符串)→ 结构化过滤收敛resolve 返回路径 + 匹配类型
占用判断纯 if occupied → 平替可用性接口返回状态
平替同 §4.3 父链阶梯(本就是结构化查询,不需要 LLM)父节点标识 + 父级过滤

结论:无 LLM 版能覆盖点名、定位泛指、占用平替,零额外延迟、无阈值调参;不能覆盖纯模糊语义("那个靠窗的大房间")——这类只能追问,或由 LLM 猜。

决策依据建议:抽一批真实 query,统计"含结构化 key"与"纯模糊无 key"的占比。前者占大头 → 无 LLM 版够用;纯模糊占大头 → 需 LLM。


7. 待确认清单 ​

  1. /internal/spaces/resolve 响应完整字段是什么?是否已含路径 / 父节点 / 容量?
  2. 后端能否提供单点忙闲查询,或让 list_available 返回 occupied 标记?
  3. locationIds 是否支持父节点级过滤(传楼层 / 分区 id 返回其下房间)?
  4. 空间树的 parentId 链路是否稳定可得?
  5. 真实 query 中"有结构化 key / 纯模糊无 key"的分布?

Released under the Private License.