SA 空间预约:Agent 设计方案 (Semantic/AI Layer)
NOTE
模块文档导航
文档目的:描述会议预约专家(Meeting Specialist)如何通过多轮对话完成时间、人数及偏好提取,并结合后端实时忙闲数据实现预约建议与确认。
整体流程

1. 槽位定义与验证逻辑 (Slot Filling & Validation)
1.1 槽位定义与提取规则 (Slots & Extraction)
Agent 需严格遵循以下 JSON 结构从用户输入中提取槽位(详见 提示词模板):
| 槽位名称 | 类型 | 说明 | 示例 |
|---|---|---|---|
start_date | String | "yyyyMMdd",未指定则为 null (由逻辑层补全) | 20260121 |
start_time | String | 用户数字时间 "hh:mm" 或语义标签 "NOW" / "ASAP" | 05:00 / NOW |
period | String | 明确词时为 "AM" 或 "PM",无则为 null | PM |
capacity | Integer | 精确人数, 未指定则为 null (由逻辑层补全) | 20 |
duration_hours | Float | 时长(小时)或 null | 1.5 |
room_name | String | 用户指定的会议室精确名称或 null | 火星厅 |
facilities | String[] | 用户要求的设施名称列表,未指定则为 [] | ["投影仪", "电视机"] |
topic_name | String | 会议主题。默认 "临时会议" | 研发周会 |
针对 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 遵循以下核心编排逻辑完成预约闭环:
- 意图解析 (Slot Filling):从用户输入中提取槽位信息。若必填项缺失,直接追问。
- 时间流水线启动 (Time Pipeline):槽位初步完成后,直接调用
time pipeline处理逻辑。- 注:流水线内部负责日期补全(如缺失则默认为当前下个整点)等兜底逻辑。
- 时间结果处理:
- 4.1 错误拦截:若返回非法日期(昨天)、语义逻辑矛盾(如:明天现在、下午预订上午尽快)、或数字时间矛盾(上午 15 点),则 Agent 进一步追问引导用户修正。
- 4.2 多候选确认:若返回多个可选时间(歧义),Agent 展示选项供用户进一步确认。
- 4.3 锁定成功:若返回唯一合法时间,则锁定时间并进入 Step 3a: 调用 Resource Pipeline。
- 4.4 ASAP 策略:若返回 ASAP 标记,跳过常规资源检索,直接进入 Step 3b: 调用 ASAP 专用接口。
- 资源流水线启动 (Resource Pipeline):时间锁定后,调用物理资源检索逻辑。传递
capacity+facilities参数,由后端接口一并筛选。 - 资源结果处理:
- 5.1 有效推荐:返回可用会议室列表,Agent 直接发送前端展示组件。
- 5.2 冲突后推荐:原会议室全忙但有建议方案,Agent 回复话术引导后发送前端展示组件。
- 5.3 无房可用:返回全忙且无推荐(含设施不满足),Agent 回复无法预订的话术。
- 用户最终决策:用户在前端组件(卡片)中完成最终的点击预约操作。
2.1 编排架构流程图
2.2 物理归一化逻辑 (Normalization)
Time Pipeline 仅处理基础的时间归一化与校验:
- Time Parsing: 结合
start_time与period进行 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 需组织前端组件完成闭环:
- 候选列表组件 (Meeting Room Card):
- 内容:展示 Top 3 推荐会议室。
- 元素:房间名、楼层、容纳人数、IoT 实时状态(如:“24℃ 舒适”)。
- 交互:点击“立即预定”按钮。
- 最终预定触发 (Execution):
- 用户点击组件后,Agent 调用后台执行逻辑(Task C)。
- 接口分流:根据企业配置调用
飞书/钉钉/自有系统的Create Event接口。
- 执行反馈:
- 成功:展示“预定成功”状态卡片,并提供“查看详情”或“邀请参会人”的 AppLink (飞书客户端等) 跳转。
- 失败:提示具体原因(如:“登录状态失效,请重新登录”或“该时段刚刚被其他同事抢占”),引导重新选择。
4. 相关设计参考
- 路由分发层:意图识别与分发技术方案
- Time Pipeline:SA_空间预约_时间处理逻辑
- Resource Pipeline:SA_空间预约_物理执行逻辑
