Skip to content

SA 空间预约:Agent 设计方案 (Semantic/AI Layer)

NOTE

模块文档导航

  1. [入口] Agent 调度逻辑 (当前文档):负责 Slot Filling 与全链路编排。
  2. [逻辑] 时间处理流水线:负责 P1-P4 时间归一化与贪婪策略。
  3. [逻辑] 资源处理流水线:负责 Task B 空间检索与忙闲校验。
  4. [算法] 会议室推荐算法逻辑:定义排序权重与冲突处理算法。

文档目的:描述会议预约专家(Meeting Specialist)如何通过多轮对话完成时间、人数及偏好提取,并结合后端实时忙闲数据实现预约建议与确认。


整体流程

20260117121649

1. 槽位定义与验证逻辑 (Slot Filling & Validation)

1.1 槽位定义与提取规则 (Slots & Extraction)

Agent 需严格遵循以下 JSON 结构从用户输入中提取槽位(详见 提示词模板):

槽位名称类型说明示例
start_dateString"yyyyMMdd",未指定则为 null (由逻辑层补全)20260121
start_timeString用户数字时间 "hh:mm" 或语义标签 "NOW" / "ASAP"05:00 / NOW
periodString明确词时为 "AM" 或 "PM",无则为 nullPM
capacityInteger精确人数, 未指定则为 null (由逻辑层补全)20
duration_hoursFloat时长(小时)或 null1.5
room_nameString用户指定的会议室精确名称或 null火星厅
facilitiesString[]用户要求的设施名称列表,未指定则为 []["投影仪", "电视机"]
topic_nameString会议主题。默认 "临时会议"研发周会

针对 start_time 举例:

  • 用户输入 "下午5点" start_time: "05:00", period: "PM"
  • 用户输入 "现在/马上" start_time: "NOW" (由逻辑层根据系统时间执行即时预订策略)。
  • 用户输入 "越快越好/尽快" start_time: "ASAP"。逻辑层返回 Status: OK (Strategy: ASAP),Agent 随即跳转至 ASAP 专用查询接口
  • 用户未输入时间(如“订个明天的会议室”) start_time: null。逻辑层返回 Status: AMBI (Reason: 缺少具体时间)。

1.2 设施字典动态注入 (Facility Dictionary Injection)

设施列表由后端会议系统 API 动态获取并注入至 Slot 提取提示词中。注入内容为设施名称列表,供 LLM 从用户自然语言中匹配提取。

注入时机:每次预约对话均注入(字典规模小,token 成本可忽略)。

当前字典示例

名称标识符
投影仪Projector
电视机TV
音频设备Audio
视频设备Video

标识符用于下游系统对接,Slot 输出使用名称,与 equipment 字段值直接匹配。

1.3 提示词模板 (Prompt Template)

markdown
# 角色:Slot提取器
严格从用户输入提取会议室预订slot。仅输出JSON,无额外文本。

# Slot规则
1. [参照 1.1 槽位表数据结构]
2. **特殊时间处理**
   - 若用户表达“现在/马上/立刻”,请填充 `start_time: "NOW"`
   - 若用户表达“尽快/越快越好/看最早什么时候有”,请填充 `start_time: "ASAP"`
   - 不要尝试自行计算具体分钟数,保留语义标签交给逻辑层处理。
3. **设施提取**
   - 可用设施列表:${facility_list}(由系统动态注入,当前为 ["投影仪", "电视机", "音频设备", "视频设备"])
   - 用户提及设施需求时,提取为 `facilities` 数组(如"带投影仪的会议室"→`["投影仪"]`
   - 用户未提及设施,`facilities` 填空数组 `[]`

# 输出示例
用户:"我想订个下午5点会议室"
输出:{"start_date":null,"start_time":"05:00","period":"PM",...,"facilities":[]}

用户:"现在就要开会,要个10人房"
输出:{"start_date":null,"start_time":"NOW","capacity":10,...,"facilities":[]}

用户:"明天下午2点,订一间带投影仪和电视机的会议室"
输出:{"start_date":"${tomorrow_date}","start_time":"02:00","period":"PM","facilities":["投影仪","电视机"]}

1.4 当前 Dify 编排提示词(参考, 含设施扩展)

以下为 Dify 平台实际部署的 Slot 提取提示词,已集成设施过滤能力。 最终版本以 AI 应用工程师编排为准,本文档仅作设计对齐参考。

markdown
# 角色:会议信息Slot提取器
严格从用户输入提取会议室预订slot。仅输出JSON,无额外文本。

# 【强制日期计算铁律 必须严格遵守】
1. 基准日期 {{#1776758708660.date_hint#}}
2. 星期定义:周一=1,周二=2,周三=3,周四=4,周五=5,周六=6,周日=7。
3. 语义严格定义:
   - 今天:基准当日
   - 明天:基准日+1天,后天:+2天

# Slot规则
- start_date: "yyyyMMdd" ,如用户未指定日期则为 null
- start_time: 用户数字时间"hh:mm" (5点→05:00,17点→17:00,3点半→03:30,保持原hh数字无转换) 或 null
- period: **最高优先级:严格按用户文字,绝不按时间数字自动修正**
  - 明确说出:上午、早上、凌晨、清早 → 输出 "AM"
  - 明确说出:下午、晚上、中午、傍晚 → 输出 "PM"
  - 用户未明确指定上下午 → 必须给 null,禁止根据时间数字自动推测
  - **用户只说数字时间(如9点、10点、15点)→ 必须输出 null,绝对禁止自动推测**
- capacity_at_least: 参与会议的人数,只有用户明确指定会议人数有值,否则给 null
- duration_hours: 会议时长小数。只有用户明确指定会议时长有值,否则给 null
- room_name: 会议室名称或者是会议室描述,精确名称。如8楼的会议室,802会议室等,没有提取到给 null
- topic_name: 精确会议主题,如研发周会,财务会议等,没有提取到给 null
- facilities: **设施过滤(新增)**
  - 可用设施列表由系统动态注入,当前:["投影仪", "电视机", "音频设备", "视频设备"]
  - 用户提及设施需求时提取为字符串数组(如"带投影仪"→["投影仪"])
  - 用户提及多个设施时全部提取(如"要有电视机和音频设备"→["电视机","音频设备"])
  - 用户未提及任何设施 → 输出空数组 []

# 输出强制要求
1. 仅输出纯净JSON,无解释、无多余文字、无markdown
2. start_time 必须两位小时格式:05:00 / 09:30 / 17:00
3. 未填写字段统一为 null,禁止写"null"字符串;facilities 未指定时输出空数组 []
4. 无论语义推断、星期换算,只要用户**没有口头明确说出日期/今天/明天/周几**,start_date 一律强制设为 null,禁止自动填充任何日期。

# 输出JSON结构
{
  "start_date": "yyyyMMdd 或 null",
  "start_time": "hh:mm 或 null",
  "period": "AM" 或 "PM" 或 null,
  "capacity_at_least": 整数 或 null,
  "duration_hours": 浮点数 或 null,
  "room_name": "字符串 或 null",
  "topic_name": "字符串 或 null",
  "facilities": ["字符串"] 或 []
}

2. Dify 流程编排逻辑 (Dify Workflow Logic)

Agent 遵循以下核心编排逻辑完成预约闭环:

  1. 意图解析 (Slot Filling):从用户输入中提取槽位信息。若必填项缺失,直接追问。
  2. 时间流水线启动 (Time Pipeline):槽位初步完成后,直接调用 time pipeline 处理逻辑。
    • 注:流水线内部负责日期补全(如缺失则默认为当前下个整点)等兜底逻辑。
  3. 时间结果处理
    • 4.1 错误拦截:若返回非法日期(昨天)、语义逻辑矛盾(如:明天现在、下午预订上午尽快)、或数字时间矛盾(上午 15 点),则 Agent 进一步追问引导用户修正。
    • 4.2 多候选确认:若返回多个可选时间(歧义),Agent 展示选项供用户进一步确认。
    • 4.3 锁定成功:若返回唯一合法时间,则锁定时间并进入 Step 3a: 调用 Resource Pipeline
    • 4.4 ASAP 策略:若返回 ASAP 标记,跳过常规资源检索,直接进入 Step 3b: 调用 ASAP 专用接口
  4. 资源流水线启动 (Resource Pipeline):时间锁定后,调用物理资源检索逻辑。传递 capacity + facilities 参数,由后端接口一并筛选。
  5. 资源结果处理
    • 5.1 有效推荐:返回可用会议室列表,Agent 直接发送前端展示组件。
    • 5.2 冲突后推荐:原会议室全忙但有建议方案,Agent 回复话术引导后发送前端展示组件。
    • 5.3 无房可用:返回全忙且无推荐(含设施不满足),Agent 回复无法预订的话术。
  6. 用户最终决策:用户在前端组件(卡片)中完成最终的点击预约操作。

2.1 编排架构流程图


2.2 物理归一化逻辑 (Normalization)

Time Pipeline 仅处理基础的时间归一化与校验:

  • Time Parsing: 结合 start_timeperiod 进行 24 小时制转换。
  • Time Validation: 校验时间是否合法(是否过期、是否在工作时间、是否具有上下午歧义)。
  • No Guessing: 若 start_time 为空,流水线不执行任何默认补全,直接返回 Status: AMBI 要求追问。

2.3 澄清追问与边缘处理 (Clarification & Edge Cases)

为了提升对话的“智能体感”,Agent 需具备以下场景的针对性回复逻辑:

异常类型判定条件Agent 预期话术 (示例)
时间缺失返回 Reason: 缺少时间"没问题,请问您想订 几点 的会议室呢?"
时间模糊返回 Status: AMBI"好的,请问您是想订 上午 {X} 点 还是 下午 {X} 点?"
时间过期返回 Status: ERROR (已过去)"抱歉,您选择的时间点已经过去了,麻烦重新说个时间?"
完全冲突available_list 为空且无平替"哎呀,这个时段的会议室都满了。建议您看看 其他时间 或者 切换到其他楼层?"
容量严重不足用户需求 > 空间 Max"305 只能坐 20 人,装不下 50 位哦。我为您推荐了 隔壁大礼堂,您看可以吗?"
设施不满足指定房间有会议但缺少用户要求的设施"抱歉,{房间名}没有{设施名},暂不支持预订"
设施全量无房满足设施要求的房间在该时段全部被占用"当前时段满足{设施名}的会议室暂无可约,建议换个时间或减少设施要求"
任务中断多轮对话中途用户话题转移(保持上下文 5 分钟) 若用户问别的,回复完后主动兜底:"刚才的会议室还要订吗?"

2.4 终端交互与执行 (UI & Action)

当 Resource Pipeline 返回 SUCCESS 状态时,Agent 需组织前端组件完成闭环:

  1. 候选列表组件 (Meeting Room Card)
    • 内容:展示 Top 3 推荐会议室。
    • 元素:房间名、楼层、容纳人数、IoT 实时状态(如:“24℃ 舒适”)。
    • 交互:点击“立即预定”按钮。
  2. 最终预定触发 (Execution)
    • 用户点击组件后,Agent 调用后台执行逻辑(Task C)。
    • 接口分流:根据企业配置调用 飞书/钉钉/自有系统Create Event 接口。
  3. 执行反馈
    • 成功:展示“预定成功”状态卡片,并提供“查看详情”或“邀请参会人”的 AppLink (飞书客户端等) 跳转。
    • 失败:提示具体原因(如:“登录状态失效,请重新登录”或“该时段刚刚被其他同事抢占”),引导重新选择。

4. 相关设计参考

Released under the Private License.