日程冲突检测与优化
适用场景
- 一天塞了七八个会,凭肉眼看不出哪两场撞了
- 会议邀请从微信/邮件/口头四面八方来,没有统一日历,全靠脑子记
- 明知道排满了,但不知道该砍哪一场、挪到几点
- 跨地点连场(公司→客户现场),忘了留通勤时间,次次迟到
- 想在排期里找一段完整的深度工作时间,但不知道还剩多少空档
核心能力
-
四类问题一次扫清
- 硬冲突:两场日程时间重叠,区分「部分重叠」与「完全覆盖」,精确到重叠了多少分钟
- 衔接过紧:相邻日程间隔不足缓冲时间;跨实体地点时自动叠加通勤时长(线上会议之间不计通勤)
- 连排疲劳:连续会议串超过阈值(默认 3 小时),提示插入休息或把低优先级项转异步
- 午休占用:会议吃掉饭点,单独列出并提示提前告知参会人 -
可执行的重排建议,不是"你自己看着办"
- 按「可改期性 > 优先级 > 时长」三级规则判定谁让路——绝不会建议你去挪一场不可改期的面试
- 让路方直接给出目标时间段(从真实空档里挑,且已排除午休),装不下就建议顺延次日或压缩时长
- 两场都钉死时不硬凑答案,输出取舍判断框架(谁缺席后果更不可逆、能否派代表、涉及外部方优先保留) -
可改期性自动推断:未标注
movable时,标题含「面试/客户/评审/签约/汇报/述职/培训/体检/考试」等关键词判为不可挪动,其余按优先级推断。 -
空档地图:列出工作时间内所有 ≥30 分钟的空档,≥90 分钟的标注「🧠 适合深度工作」,方便直接安排专注任务。
-
状态一目了然:时间轴表格逐条标 🔴 冲突 / 🟡 衔接紧 / 🟢 正常。
-
参会人视角,找出「自己看不见的撞车」:同一时刻被两场重叠会议同时占用的人会被单独列出(如你拉的两个会都约走了同一位技术负责人),避免会前十分钟才发现人抽不开身。
-
人均会议负载核算:统计每位参会人当天被会议吃掉的场数与时长,超过
person_overload_min(默认 240 分钟)触发 🔴 超载告警,便于砍低优先级会或减员。
输入规范(缺失主动引导)
脚本输入为 JSON(完整模板见 references/input_template.json):
{
"owner": "张三",
"date": "2026-08-04",
"events": [
{"title": "产品需求评审", "start": "09:30", "end": "11:00", "priority": "高", "location": "3楼会议室"},
{"title": "候选人面试", "start": "10:30", "duration_min": 60, "priority": "高", "location": "1楼洽谈室"},
{"title": "供应商电话", "start": "11:20", "end": "12:00", "priority": "低", "location": "线上"}
],
"settings": {"buffer_min": 10, "commute_min": 30, "lunch_break": ["12:00", "13:30"]}
}
- 必填:
events数组,每条至少有title与start;日期由顶层date提供或在单条内单独写(跨天排期必须逐条写) - 可选:
end/duration_min(都不给按 60 分钟)、priority(高/中/低,缺省=中)、location、movable、attendees、note attendees支持数组或顿号/逗号分隔的字符串(如"张三、李四"),脚本会自动去空去重并保持顺序;用于在参会人维度检测撞车与负载- settings 全部可缺省,默认:缓冲 10 分钟、通勤 30 分钟、连排阈值 180 分钟、工作时间 09:00-18:00、空档下限 30 分钟、午休 12:00-13:30、人均超载阈值
person_overload_min240 分钟
缺失引导:用户只说「帮我看下日程有没有冲突」时,先请其把日程贴成文本(每行一条:时间 + 事项即可),再由 AI 整理成上述 JSON。至少要问清:
- 是哪一天 / 哪几天的日程
- 每场的起止时间(只给开始时间也可以,会按 1 小时估算并在报告中体现)
- 哪几场是不能改期的(这个信息缺失会显著降低建议质量,务必追问)
- 有实体地点变化的场次(否则无法检测通勤缺口)
处理流程
- 收集日程文本,整理为输入 JSON,存为临时文件(如
schedule.json) - 运行脚本:
bash python scripts/detect_conflicts.py schedule.json # 或显式指定输入 / 输出 python scripts/detect_conflicts.py --input schedule.json --output 日程诊断.md # 也可从 stdin 读入 type schedule.json | python scripts/detect_conflicts.py - 将输出的诊断报告原样呈现给用户
- 若存在硬冲突,重点提示「必须处理」的那几条;若行动清单里有需要与他人协商的项,可顺带草拟一句沟通话术
脚本参数
| 参数 | 说明 |
|---|---|
schedule.json(位置参数)或 --input |
JSON 输入路径;二者二选一,都不给时读 stdin。编码自动兜底 utf-8 / 带 BOM / GBK |
--output / -o |
写入 markdown 文件(目录不存在会自动创建);缺省打印到 stdout |
--buffer N |
覆盖 settings.buffer_min:相邻日程最小缓冲(分钟),如 --buffer 15 |
--commute N |
覆盖 settings.commute_min:跨实体地点通勤预留(分钟),如 --commute 45 |
--selftest |
运行内置自检(10 组用例 + 边界断言),全过退出码 0,任一失败退出码 4 |
退出码:0 成功 | 2 输入内容非法(JSON 语法错、顶层不是对象、缺 events、时间格式错等)| 3 文件不存在 / 读写失败 / 编码无法识别 | 4 自检失败。
> 命令行 --buffer / --commute 优先级高于 settings 中的同名参数,便于在不改输入文件的前提下临时调整阈值(例如临时把通勤放宽到 45 分钟看排期是否还有救)。
输出格式
markdown 诊断报告,包含:
- 诊断结论:问题总数与分类计数;无问题时直接给 ✅ 放行结论
- 日程时间轴:时间 / 日程 / 时长 / 优先级 / 地点 / 状态(🔴🟡🟢)六列表格
- 硬冲突:逐条展开重叠类型、重叠时长、双方可改期性、通勤提示、💡 重排建议
- 衔接过紧:实际间隔 vs 建议间隔对照表,逐行给出「谁动、动几分钟」
- 连排疲劳段:连续会议串与休息插入建议
- 午休占用:占用时长与协商建议
- 人均会议负载:每位参会人场数 / 占用时长 / 状态(🔴 超载 🟡 偏满 🟢 正常),超过阈值单独告警
- 可用空档:已排除午休的空闲时段,标注是否适合深度工作
- 行动清单:可勾选的 checklist,最后一条固定为「调整后同步给相关参会人」
(完整示例见 examples/sample_input.json → examples/sample_output.md)
异常处理
events缺失或为空数组 → 报错并提示至少需要 1 条日程- 时间格式不合法 → 指名是哪条日程的哪个字段,提示应为
YYYY-MM-DD与HH:MM - 单条日程缺
date且顶层无默认date→ 报错并指名是哪一条 end早于或等于start→ 按跨零点处理,自动顺延一天end与duration_min均缺失 → 按 60 分钟估算priority值不在「高/中/低」内 → 静默降级为「中」- 当日无足够空档容纳让路方 → 不硬塞,改为建议顺延次日或压缩时长
- 输入为空 / 顶层不是 JSON 对象 / JSON 语法错 → 中文报错并退出码 2,不产生半截报告
- 输入文件不存在或是 GBK 编码 → 自动按 utf-8-sig → gbk 顺序兜底;均失败时退出码 3 并说明已尝试的编码
- 所有报错走 stderr,报告只走 stdout,便于
> 文件重定向或管道串联
边缘用例
settings数值字段脏数据(如"abc"、null、布尔)→ 自动回退默认值并告警,不中断- 标题含竖线
|或换行 → 渲染时转义为全角「|」并去换行、超长截断,避免破坏表格列结构 - 相邻日程首尾相接(前一场
10:00结束、后一场10:00开始)→ 不误判为重叠冲突 - 单条日程 → 无重叠 / 无衔接紧 / 无连排,仍正常输出时间轴与可用空档
attendees缺省或为空 → 跳过参会人维度分析,不报错- 同一个人被两场重叠会占用 → 在结论区与「人均会议负载」之外单独标出,提示「会前十分钟才发现就来不及」
自检
脚本内置 --selftest,覆盖 10 组用例 + 边界断言(完全重叠、衔接过紧、连排疲劳、午休占用、参会人撞车、人均负载排序与超载、duration_min 兜底、as_names 分隔符、脏 settings、单条日程,以及首尾相接不误判、超长标题不破表)。全部通过退出码 0,任一失败退出码 4。
python scripts/detect_conflicts.py --selftest
适用限制与免责声明
- 不连接任何日历系统(不读写企业微信/钉钉/飞书/Outlook/Google Calendar),仅基于用户提供的日程文本做离线分析;如需自动拉取日程,请配合相应平台的连接器技能先取数,再把结果喂给本技能
- 通勤时长为统一参数估算,不含实时路况、天气、跨城出行等因素,实体地点间的真实耗时请自行修正
commute_min - 可改期性在未显式标注时依赖关键词推断,可能误判(如标题为「和小王聊聊」的重要客户会)——建议对关键场次显式设置
movable - 重排建议是基于规则的排序结果,不理解业务上下文与人情关系;最终改期决策及与相关方的沟通仍需由用户完成
- 报告不构成任何工作安排承诺,误会/漏会造成的后果由使用者自行承担