Files
bot_dev1 5bc7ff957e feat(#53): 移动端交接班摘要生成(NL,PRD 场景C ⑤ 移动端交接班摘要)
对应 PRD 场景C(辅助):交接班 → LLM 汇总本班关键事件/能耗/待办 → 生成交接班
报告 → 推送下一班(line 84/350-351)。把本班原始数据 → 移动端交接班摘要这条
链路模板化、可配置、可测试。

新增 core/shift-handover 内核模块:
- handover.py:班次数据归一化(ShiftRecord) + 摘要配置(HandoverBriefConfig) +
  validate/load 校验对 + build_llm_input(填 shift_handover v1.0.1 提示词占位符) +
  generate_handover_brief(LLM 注入生成, 离线/故障自动降级为确定性摘要) +
  render_handover_brief(编译移动端只读卡片 props)
- 零运行时依赖(仅标准库); LLM 以依赖注入传入, 内核不绑定云端 SDK
- 离线/LLM故障降级保证可用性≥99.8%(PRD 模型服务故障自动降级)
- 含 P0/安全事件时强制 requireConfirm=true(PRD 高利害人工确认)

新增资产/测试/验收:
- templates/ti-cl4/dashboard/handover_brief.ti.yaml(Ti 模板配置资产)
- tests/test_handover.py(32 用例全通过) + tests/_bootstrap.py(连字符目录挂载)
- scripts/verify_handover_brief.py(4 能力点全通过: 配置合法/LLM+降级/
  配置点驱动展示/≤2分钟验收线)
- README.md

验证: python -m unittest discover -s tests (32 OK) +
      python scripts/verify_handover_brief.py (全部通过)
2026-08-05 03:38:07 +08:00
..

移动端交接班摘要模块(iAOP-Core / shift-handover)

对齐 PRD 场景C(辅助) 与 5.4「④ LLM 网关」:

交接班 → LLM 汇总本班关键事件/能耗/待办 → 生成交接班报告 → 推送下一班。

以及 PRD 验收口径:交接班报告生成 ≤ 2 分钟(line 350)、移动端交接班摘要可用(line 284/351)。

模块状态

能力 Issue 状态
移动端交接班摘要生成(NL) #53 本分支 feature/issue-53

#53 把"本班原始数据 → 移动端交接班摘要"这条链路模板化、可配置、可测试: 班次数据归一化(ShiftRecord)→ 按 HandoverBriefConfig 经 LLM(或离线确定性降级) 生成摘要 → 编译成移动端只读卡片可直接消费的 props。

设计要点

  • 零运行时依赖:与 cockpit / data-bus / llm-gateway 一致,只用标准库;LLM 调用以 依赖注入形式传入(llm_generate: Callable[[str], str]),内核不绑定云端 SDK, 便于本地闭环与离线降级。
  • 离线/故障自动降级:未注入 LLM 或调用失败时回落到 render_deterministic_brief (PRD「模型服务故障自动降级」「可用性 ≥ 99.8%」),保证交接班链路不中断。
  • 声明式 + 强校验:validate_handover_config 收集全部字段级错误(沿用 #50/#52 风格),load_handover_config 校验失败抛 HandoverConfigError 并携带错误清单。
  • 与未合并分支解耦:不 import llm-gateway 的 PromptRegistry;仅按约定的 prompt_template 名字产出 LLM 输入文本,待 llm-gateway 合入后由调用方注入真正的 LLM 生成函数。

配置点(外置为模板资产,切换模板零改码)

配置点 字段 说明
提示词模板 promptTemplate / promptVersion 绑定 shift_handover v1.0.1(current)
章节 sections overview/abnormal/safety/energy/todos
展示策略 maxEvents / maxTodos / collapseThreshold 移动端折叠与截断
字号 fontSize sm/md/lg
高利害确认 requireConfirm 默认 false;含 P0/安全事件时内核强制 true

用法

import sys, types, os
# 含连字符目录挂载为 shift_handover 包(同 core/data-bus 的做法)
_d = os.path.join("core", "shift-handover")
if "shift_handover" not in sys.modules:
    _p = types.ModuleType("shift_handover"); _p.__path__ = [_d]; sys.modules["shift_handover"] = _p

from shift_handover.handover import (
    normalize_shift_record, render_handover_brief, generate_handover_brief,
)

# 1) 班次数据(来自驾驶舱/总线/告警面板聚合)
record = normalize_shift_record({
    "shift": "夜班 2026-08-05 00:00~08:00", "operator": "张工",
    "overview": "TiCl4 产量 36.2t。",
    "events": [{"time": "01:20", "title": "炉层温度越上限", "severity": "P1"}],
    "todos": [{"title": "白班复测 3 层温度", "priority": "high"}],
    "safety": "注意 3 层高温区巡检。",
})

# 2) 生成摘要(llm_generate=None 时离线降级;注入则用 LLM 输出)
summary = generate_handover_brief(record, llm_generate=my_llm_fn)

# 3) 编译移动端只读卡片 props
props = render_handover_brief(record, summary=summary)

测试与验收

# 单元测试(在 core/shift-handover 目录下)
python -m unittest discover -s tests -v          # 32 用例全通过

# 验收脚本(4 能力点:配置合法 / LLM+降级 / 配置点驱动展示 / ≤2 分钟)
python scripts/verify_handover_brief.py