值班排班助手
帮护士长、科室管理者、门店/网点负责人生成月度/周期值班表:按人员资质和约束条件自动分配班次,校验公平性与冲突,输出可打印的排班表。只做排班计算与表格产出,不做人员能力评价,不替代管理者的用人决策。
目录
- 触发方式|2. 何时用我|3. 不做
- 五步流程(需求判定 → 卡点A → 生成 → 卡点B → 交付)
- 能力边界(量化)|6. 国内适配|7. 异常话术|8. FAQ
触发方式(怎么开口)
对话触发——对助手说一句即可,识别到意图自动进入五步流程:
- 「帮我排 11 月的科室值班表」
- 「下个月排班表,夜班要 1 个二线,6 个人」(顺带说明班次需求更快)
- 「把这张人员名单排成值班表」(可同时把名单表格发过来)
- 只说「排班」也算触发,助手会追问周期/班次/每班人数/人员名单四件事
命令行直跑——规则确认后想自己复现或调整重排:
python scripts/roster.py --rules 规则.json --out 值班表.xlsx
python scripts/roster.py --rules 规则.json --staff 名单.xlsx --out 值班表.xlsx # xlsx/csv 名单导入
python scripts/roster.py --rules 规则.json --swap 调班.json --out 新表.xlsx # 换班计算:两人互换当天班次
使用前提(依赖):Python 3.8+ 与 openpyxl(pip install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple)——读取名单与输出排班表 xlsx 离不开它;缺依赖时脚本会直接提示本安装命令(退出码 21),装完重跑同一条命令即可。
规则 JSON 结构见 scripts/roster.py 文件头注释;完整可复制示例见 assets/examples/(三班制自然月/周排区间/节假日专班/换班 4 个,零改动可直接跑通)。名单列头:姓名(必填)/资质/不可排日/连续夜班上限/夜班后休息天数,日期支持「11-05」「11月5日」等写法(JSON 的 off_days 同样支持),与规则 JSON 的 staff 自动合并(同名以 JSON 为准)。
回读口径:本技能的全局设置全部存放在规则 JSON(scope/needs/rules 阈值/holidays/staff 偏好),--rules 每次运行都从该文件回读——改过阈值或节假日后重跑即生效,无需重复传参;--staff 名单与 JSON staff 合并时同名以 JSON 为准(JSON 优先级更高)。
输出预览(节选自示例1实际生成的 xlsx 关键单元格):
【排班表 sheet】
2026年11月值班表
姓名 1日(日) 2日(一) 3日(二) 4日(三) 5日(四)…
护士1 白/大 大 大 (休) 小/大… ← 休=灰底;周末节假日标色
【公平性统计 sheet】
姓名 资质 总班数 夜班数 周末数 节假日数 工时(h) 最长连班 偏好满足
护士1 二线 32 25 10 0 256 3 -
【冲突清单 sheet】(示例名单小于需求时)
日期 班次 类型 说明
… 夜班 缺口 仅排到 1/2 人(休假/资质/间隔/连工上限过滤后候选不足)
换班怎么算:调班 JSON 写 {"date":"2026-11-05","a":"张三","b":"李四"}——两人在该日期互换班次(一方休班=代班)。引擎用与排班同一套硬约束逐条校验(夜班后休息期/连续夜班上限/连续工作上限/资质名额),可行 → 输出调班后完整表并在冲突清单写「调班」记录行;不可行 → 退出码 13 逐条说明谁违反哪条,绝不硬换。
何时用我
- 每月要做科室值班/排班表(护士、门急诊、行政值班)
- 需要保证资质要求(如夜班必须有二线资格人员)、公平性(天数/节假日均衡)
- 手排总出差错:有人漏班、连班超限、节假日总落到同一批人
- 临时调班后要快速核验整月不冲突
不做(边界声明)
- ❌ 不做医疗/资质判断:资质分组完全按用户提供的名单执行,不自行认定「谁能上夜班」
- ❌ 不替管理者做用人决策:约束冲突时列出选项请拍板,不硬填
- ❌ 不涉及薪酬计算:排班表不产出加班费/绩效数据
- ❌ 人员敏感信息(身份证、联系方式)不进排班表,用户给了也只保留姓名
五步流程
第 1 步:排班需求判定
先确认四个基本盘(有缺项就问,不猜):
| 判定项 | 取值 | 说明 |
|---|---|---|
| 周期 | 回字母选路:A 月度(默认)/ B 周排 / C 节假日专班 / D 自定义起止 | A=自然月含节假日标注;B=近 7 天或用户指定某周;C=只排指定节假日(如国庆 3 天专班);D=任意区间(单次 ≤62 天) |
| 班次 | 白班/夜班/两头班/自定义(1–4 个) | 护士常用 APN 三班制;每个班次可给 time 时间段(如「08:00-17:00」)与 hours 工时(缺省 8,用于工时统计口径),time 会写进打印版表尾的班次时间说明 |
| 岗位需求 | 每班次需要几人、什么资质 | 如「夜班 1 人且有二线资格」 |
| 人员 | 名单 + 资质分组 + 不可排日 + 长期偏好 | 资质分组(一线/二线/可带教等)以用户口径为准;prefer_shift(尽量排某班)/avoid_weekend(尽量避开周末)为软约束——硬约束与公平前提下尽量满足,满足度写进公平性统计「偏好」列如实呈现 |
> 周期选路落 JSON:A→scope:"month";B→scope:"range", days:7;C→scope:"holidays"+holidays 列表;D→scope:"range", start_date+days。用户只回字母,助手代填。
第 2 步:约束清单整理 → 🛑 卡点 A
把收集到的约束整理成一张「排班规则确认表」,必须经用户确认后才计算:
- 硬约束(违反即重排):每班人数、资质要求(带
min_qualified时引擎优先填满资质名额,如「夜班至少 1 名二线」;不带则整班硬过滤)、不可排日(休假/进修/孕期照顾)、夜班后休息天数(默认 ≥1 天)、连续夜班上限(默认 ≤3 个)、连续工作上限(默认 ≤6 天,rules.max_work_streak可调)。夜班识别默认取名称含「夜」的班次(夜班/小夜/大夜均计入连班与休息约束,v1.5.0),可用rules.night_shifts显式指定 - 软偏好(尽量满足,不满足只预警):个人意愿班次、老带新搭配、公平性历史(上月谁节假日多)
- 公平性规则(先和用户确认口径):全月总班数差 ≤1(超阈值引擎自动白班对调再平衡,v1.3.0 硬执行)、夜班数差 ≤1 / 周末班数差 ≤2 / 节假日班数差 ≤1(受资质与连班规则约束时如实呈现差异由管理者决策,不硬凑)、节假日班跨月季度轮换找平为人工流程(脚本只做单表内均衡并提示「记录到下月轮换依据」,不读历史排班自动轮换——见 fairness-rules.md 第 2 节)
🛑 卡点 A:规则确认。输出规则确认表,用户回复「确认」或修正后才进入第 3 步。约束互相矛盾(如要求 3 人夜班但只有 2 人有资质)当场指出,给出可行调整选项。
第 3 步:排班生成(v1.1.0 起脚本自动执行)
把确认后的规则写成 JSON,交给 scripts/roster.py 一键生成:
- 硬约束先行:不可排日不分配、同日不双岗、连续工作 ≤6 天(可调)
- 资质名额硬执行:带 min_qualified 的班次优先填满资质合格者(如夜班先排二线再补一线),凑不够才如实报缺口
- 连班规则正确区分两种情形:连续夜班允许(最多 max_nights 个)与夜班序列结束后强制休息 min_gap_days 天——两者不矛盾,引擎分开处理
- 白夜班间隔 ≥16h 检查(v1.7.2):相邻两天的夜→白/白→夜组合按班次 time 字段估算间隔,<16h 计入冲突清单(连续夜班为允许情形不参与;「昨夜班今日不接白班」仍为硬约束)
- 连工豁免预警(v1.7.2):rules.max_work_streak 调到 6 天以上时,冲突清单记「连工豁免」行提示书面豁免留痕
- 稀缺班次优先分配:受限人员(如仅有的二线)不会被宽松班次抢占
- 公平再平衡:总班数差超阈值时引擎自动做白班对调(避开夜班序列连锁);夜班/周末/节假日差异如实呈现在冲突清单由管理者决策,不偷偷抹平
- 算不出可行解 → 报缺口继续排其余日期,不硬塞
脚本退出码:0 成功|10 规则文件问题|11 规则结构/字段值错误(非法日期会指明是谁的哪条,如「人员「张三」的不可排日不是合法日期:2026-11-32」)|12 名单/需求为空|13 调班不可行(逐条说明谁违反哪条硬约束,绝不硬换)|14 输出被占用(已自动重试 2 次仍失败才报,提示关闭表格重试)|15 运行超时(300 秒看门狗,重跑同一条命令)|20 未预期|21 缺依赖(提示安装 openpyxl 后重跑)。对照 references/error-playbook.md 话术转述,不念退出码。
第 4 步:冲突与公平性检查 → 🛑 卡点 B
脚本产出 xlsx 四个 sheet,逐个过一遍:
- 冲突清单:缺口 / 资质不足 / 公平性(总班差/夜班差/周末差/节假日差)——有冲突必须处理后才算完成
- 公平性统计:每人总班数、夜班数、周末数、节假日数、最长连班(强度保护可视化,一张表横向对比)
- 排班表(打印版):人×日期,工作日无班灰底、周末节假日标色,表尾签名区
- 个人一览:按人汇总的班次日历 + 每人合计与最长连续工作,方便各自截图保存
🛑 卡点 B:预览确认。用户核对调整(如换班、豁免某规则)后,改规则 JSON 重跑或由助手微调,再次过检查。
第 5 步:输出交付
打印版 sheet 内置完整交付件(v1.2.0 起全部由脚本产出):
- 标题行:按周期自动生成(如「2026年11月值班表」/「2026年11月23日起 7 天值班表」/「节假日专班值班表」)
- 打印版排班表:人×日期矩阵 + 节假日周末标色 + 表尾班次时间说明(含每个班次时间段;缺
time的班次如实标「时间待确认」)+ 调班记录页头(空表供归档后手工登记)+ 签名区(护士长/主管、科主任/上级、日期) - 个人一览版:按人汇总,方便截图各自保存
交付时附一句提醒:排班表签名归档后如有临时调班,改动要同步更新台账并重跑本脚本复核冲突(改 JSON 重跑 10 秒出新表)。
能力边界(量化)
| 项目 | 范围 |
|---|---|
| 周期 | 自然月(28–31 天)/ 任意起止区间(单次 ≤62 天,周排=7 天区间)/ 节假日专班(只排指定节假日);更长周期分月出表 |
| 人数 | 建议 3–50 人;>50 人提醒分科室多表 |
| 班次 | 每日 1–4 个班次;APN 三班制需给时间段(time 字段,缺失时表尾标「时间待确认」);hours 工时(缺省 8)用于工时统计口径 |
| 资质 | 按用户口径分组(一线/二线等);min_qualified 为名额要求(引擎优先填满),未给 min_qualified 的 require_grade 为整班硬过滤;公平再平衡不会降低资质名额(v1.4.0 硬保证) |
| 输入格式 | 对话直接说需求;xlsx/csv 人员名单(--staff,列头与合并规则见「触发方式」节);规则 JSON(完整可复制示例见 assets/examples/ 4 个) |
| 换班 | --swap 调班.json 两人互换指定日期班次(硬约束校验、退出码语义见「触发方式·换班怎么算」) |
| 不支持 | 薪酬/绩效计算;et 老格式直读(请另存 xlsx);加密文件;自动识别法定节假日调休(holidays 需用户提供);跨月季度轮换自动找平(单表内均衡,跨月按 fairness-rules 第 2 节人工流程);半天班按 1 班计(按 0.5 计的口径需交付时人工注明);跨表多人连环换班(一次只算一对,多对分次跑);周末按周六/周日分别计数均衡(周六+周日合并计,分日均衡需交付时人工核对) |
国内环境适配要点
- 表格默认 xlsx;用户要 et(WPS 文件)时按 WPS 兼容方式生成,节假日标色用填充色而非条件格式(跨软件显示更稳)
- 日期一律「10月27日(周一)」双标注,避免纯数字日期被误读
- 班次符号用「白/夜/休」汉字,不用字母缩写(打印黑白件仍可读)
- 身份证号、电话不进表;姓名用全名即可,避免生僻字生成时提示用户确认字体
详细规则见 references/fairness-rules.md 与 references/conflict-checklist.md。
异常与拒绝话术
见 references/error-playbook.md。核心三条:
- 人手不足算不出可行解 → 报缺口数(「夜班 30 天 ×2 人 =60 班次,现有 5 人均摊 12 个/人,已超出合理强度」),请管理者决策,不硬排
- 约束互相矛盾 → 列出矛盾点 + 2–3 个调整方案供选择
- 用户要求「让某些人节假日全免」这类破坏公平的定制 → 说明会导致公平性失衡,仍可执行但要在统计表中如实呈现差异,由管理者签字担责
常见问题汇总(FAQ)
见 assets/faq.md——16 条高频问题(连上夜班怎么算、二线不够怎么办、周排/专班怎么排、名单怎么导入、换班怎么算、偏好没被满足怎么办、工时口径怎么用、表被占用怎么办等),先查这里再翻剧本;反模式集中清单见 assets/anti-patterns.md。
模板
输出格式参考 assets/schedule-template.md(打印版 + 个人版 + 签名区)。
出厂自检(发布前必过)
- [x] 名称 ≤15 字、描述 40–50 字
- [x] 引用文件双向一致(剧本引用 = 磁盘文件)
- [x] 内测场景通过(公平性断言 + 硬约束断言 + 冲突检出),记录见 beta-test/
- [x] 异常剧本覆盖五类:数据缺失 / 人数不足 / 约束矛盾 / 中途调班 / 用户要求改数据口径
- [x] v1.2.0 评测整改:三周期落地(周排 24 项断言内含)、非法日期精确报错、占用自动重试、打印版完整交付件(标题/时间说明/调班记录/签名区)——beta-test/run_test3.py 24/24 通过