发布日期:2026-11-06 | 适用对象:中大型项目 / 需要多任务并发、review、返工与合并的无人值守场景 | 结论先行:night-shift-team 是 night-shift 的团队协作版——13 项无人值守机制一项不少,只把派工层从一次性子代理换成全持久队友。
1. 它是干什么的
一句话:人离开设备之后,它把一份任务清单自动跑完,而且是「多任务并发 + 互相 review + 返工 + 合并」地跑完。
名字叫 night-shift-team,但触发条件不是"晚上",是"人不在设备前"——出门、开会、通勤、吃饭、睡觉都算。人还在的时候一切照常,该问就问,夜班的默认处置不生效。
它本质仍是一堆纯文本 markdown 文件:不是插件、不编译、不 fork 运行时、不改 the agent harness 的 app.asar / config.json / profiles。下游用户只要「启用两个内置实验性插件 + 装这份 skill」就能用。
完整保留的无人值守机制
B 仓不是"精简改造版"。原仓 night-shift 的基础设施一项不少:
| 类别 | 保留的机制 |
|---|---|
| 开工 | 项目初始化、开工预检单、每对话插件轨道自检、挂机门禁(卡片 + 文件 + 正文三信号) |
| 续跑 | every_seconds 周期心跳、主机级运行登记表、外部看门狗(崩溃后自动拉起) |
| 决策 | 习惯决策树(自由区 / 禁区 / 拿不准)、决策日志、升级标记 |
| 质量 | 验证证据制、按任务类型的最低证据要求、证据时间戳防伪 |
| 收尾 | 任务总结、晨间简报、commit 豁免、熔断 |
一句话:只换派工层,其余全部继承。所以原仓已经解决过的问题(心跳到点丢失、积压空转、崩溃后没人叫醒会话)在 B 仓里不用重新解决一遍。
2. 和原来的非 team 版比,优点在哪
先看全貌:
| 维度 | A 仓 night-shift(原仓) | B 仓 night-shift-team(本仓) |
|---|---|---|
| 定位 | 个人 / 小项目 / 全栈单人 | 中大型项目、多任务并发、需要 review / 返工 / 合并 |
| 插件前提 | agent-team 未启用(subagent 可用) | 已启用内置 Agent Teams(+ git 工作树,按场景) |
| 派工 | subagent / subagent_fork,一次性 | spawn_teammate + send_message + team_task_*,全持久 |
| 队友 | 无 | 开发 4(新增/修复/界面/审阅)、非开发 2(通用/审阅);Lead = 主会话,不 spawn |
| 模型 | 可配 tool-subagent.agentOptions(worker 便宜 / 主循环贵) | 全角色继承会话模型,不可单独配 |
| 看板 | 任务文件 / 清单 | team_task_* 共享任务板(Web GUI 可见) |
| 隔离 | 无 | 编码 + git:worktree 分支;其余:write_scopes 输出路径前缀 |
| 审阅 | 子代理自验 + 验证证据 | 持久只读「审阅」队友,出 RESULT: PASS/FAIL |
| 返工 | 重新派一个新子代理 | 打回同一 doer、送回同一审阅,review_notes 累积 |
| 交付 | 任务总结 / 晨间简报 | 仅 PASS 后 Lead 在 main 顺序 git merge;非 git 项目交付目录汇总 |
| 跨会话上下文 | 决策日志 | context-pack(新会话装载一次)+ 队友会话内记忆 |
| 项目类型 | 任意 | 编码 / 非编码均可,project-profile 声明式分流 |
| push / PR | 白天人工 | 白天人工(永久闸门) |
下面把最值得换的几点展开。
优点一:任务真的能并发,进度看得见
B 仓用 team_task_create 建共享任务卡,字段包含 owner / blocked_by / status / round / review_notes / write_scopes。任务依赖只走 blocked_by,不靠口头约定;team_task_update 是 CAS 语义(先 team_task_get 取最新 revision 再写),多个队友并发改同一张板不会互相覆盖。
状态机很直白:
pending → in_progress(claim) → review(自验完成) → done(RESULT: PASS)
│
└─ RESULT: FAIL → 返工闭环 → review(同一审阅)
任意状态 → blocked(round>=3 / 空转 / 冲突 / 二进制 / 会话级熔断)共享任务板在 Web GUI 里能看到,卡从 pending 流转到 done 的全过程是可观察的,不用翻日志猜进度。
优点二:持久审阅,返工不丢上下文(最核心)
原仓用一次性子代理,返工时要重新派一个——新代理不知道上一轮被判 FAIL 的原因,得重扫项目结构。B 仓的「审阅」是全持久只读队友,它记得上一轮提了什么意见,能验证 doer 是不是真的改了。
返工闭环是双方都带上下文的:
审阅 FAIL → review_notes 累积追加(不覆盖)+ round += 1
→ round >= 3 ? 或 本轮改动与上一轮实质相同(空转)? → blocked 交白天
→ 否 → send_message 带累积意见打回【同一个 doer】
→ doer 带上下文改(同分支增量 commit / 同交付路径)
→ 送回【同一个「审阅」】队友
→ PASS → done;FAIL → 回到闭环开头「审阅」只读、共享 cwd、不改代码,只写任务卡和结构化结论:
RESULT: PASS
task: <task id>
evidence: <evidence 路径 / diff 范围>RESULT: FAIL
task: <task id>
round: <当前轮>
issues:
- <具体问题:文件:行号 / 与任务卡哪条不符>
suggestion: <可执行的修改方向,不做审美评审>优点三:返工有闸门,不会整晚空转
| 熔断项 | 值 |
|---|---|
单卡 maxRounds | 3 |
| 会话级熔断 | 累计 blocked >= 3 或时长触顶 → 停止派新卡、只收尾 |
| 空转检测 | 本轮 diff / 产物与上一轮实质相同 → 立即 blocked |
| 队友并发 | 开发 4 / 非开发 2(= roster 预设) |
write_scopes 是第二道防震荡措施:它是 advisory 非锁,靠任务卡把输出路径划清,避免「A 改完 B 又改回去」。
优点四:合并只在审阅通过之后
仅 done + RESULT: PASS 后,由 Lead 在本地 main 顺序 git merge,产生 merge commit 记录。冲突 / 二进制一律 blocked 交白天,不 rebase / amend / force。git push、开 PR、清理已合并 worktree 分支、非编码产物最终发布、所有 blocked 卡裁定,全部留白天。
优点五:非编码项目也覆盖
project-profile 用声明式字段分流,加预设只加文件、不改编排逻辑:
projectType: code | content # 编码 / 内容产出
vcs: git | none # 是否 git 仓库
isolation: worktree | write-scopes
reviewTarget: diff | content-checklist
delivery: merge | collect # 合并 / 交付目录汇总
evidence: test-output | validation-checklist内容类项目(绘图、剪辑、文档、设计稿)走 references/validation-checklist.md 的 L0–L4 验收:存在性、完整性、规格、内容合规、证据。审阅队友按 L3 清单核对,不做审美评审。
3. 诚实的对照:原仓仍然更强的地方
B 仓不是"替代" A 仓,是按项目规模分发:
- 模型路由:A 仓能配
tool-subagent.agentOptions,让 worker 跑便宜模型、主循环跑贵模型;B 仓的SpawnTeammateRequest没有model字段,全角色继承会话模型。想省钱,A 仓更合适。 - 小项目:一晚 1–3 个基本独立的任务,任务清单文件 + 决策日志 + 晨间简报就够,不需要共享看板和持久队友。
- 不想启用插件:A 仓用
subagent,不依赖 Agent Teams。
两个仓库可以同时装在磁盘上,但同一实例同一时刻只有一轨生效:Agent Teams 由 profile 的 dsh.profile.bundles 决定,是实例级全局开关,新对话只能选 preset、选不了 profile。切换轨道 = 改 bundle 并重启 DSH。
4. 用之前要准备什么
| # | 前置条件 | 说明 |
|---|---|---|
| 1 | 启用两个实验性插件 | UI:插件 → 实验性插件 → 「启动智能体团队插件」+「git 工作树」,然后重启 DSH(实例级,热更新不生效) |
| 2 | 装 skill | Copy-Item -Recurse night-shift-team ~\.dsh\skills\ -Force |
| 3 | 独立可写的工作区 | 两个 skill 的状态目录都叫 night-shift/,别用含 A 仓运行时状态目录的父目录当 cwd |
| 4 | git 仓库 + 本地 main 分支 | 仅 isolation: worktree 或 delivery: merge 需要;非 git / collect 项目不需要 |
| 5 | 本机全局 AGENTS.md 豁免条款 | commit 豁免与功能类依赖豁免是本机配置,不是 skill 自带能力 |
插件分工别记混:
| 插件 | 提供的工具 | 什么时候必需 |
|---|---|---|
| 智能体团队 | spawn_teammate / list_agents / send_message / interrupt_agent / team_task_* | 所有场景 |
| git 工作树 | create_worktree | 仅编码 + git 的 isolation: worktree |
花名册两套,由 projectType 决定加载哪份:开发项目 4 个队友(新增/修复/界面/审阅),非开发项目 2 个(通用/审阅)。Lead 是主会话、常驻、不 spawn 自己。
配套插件 dsh-plugin-schedule-sweep(收尾清空积压心跳)两种装法:
npm i dsh-plugin-schedule-sweep
dsh plugin --profile desktop add https://github.com/firstsaofan/dsh-plugin-schedule-sweepnpm 页面:<https://www.npmjs.com/package/dsh-plugin-schedule-sweep?activeTab=readme>
5. 红线速查
- 不改 A 仓:原仓是基准,也是模型路由能力的唯一载体。
- 不改运行时:不 fork 插件、不改
app.asar、不改config.json、不装包。 git push永远人工闸门:夜班 commit 豁免不等于 push 豁免。- 两个同名
night-shift别混:firstsaofanskills/night-shift是源码,上层那个是运行时状态目录(含真实决策记录)。 - A/B 不可混用:同一实例同一时刻只跑一轨。
6. 一句话总结
原仓解决的是「人不在时能不能自己跑完」,B 仓解决的是「人不在时,多个任务能不能并发跑完、互相审阅、返工不丢上下文、还只把通过审阅的结果合并进去」。基础设施一样,派工层不同,按项目规模选一个就行。
- A 仓(原仓):<https://github.com/firstsaofan/dsh-night-shift>
- B 仓(Agent Teams 版):<https://github.com/firstsaofan/dsh-night-shift-team>
- 配套插件 npm:<https://www.npmjs.com/package/dsh-plugin-schedule-sweep?activeTab=readme>
- 配套插件源码:<https://github.com/firstsaofan/dsh-plugin-schedule-sweep>
- 许可:MIT(
Copyright (c) 2026 firstsaofan);作者 credit:firstsaofan
一套 markdown 能做的事,取决于它把多少条规则写成了别人不用重新踩一遍的默认值。
原文首发:www.firstsaofan.top
本文首发于我的个人博客,其他平台为同步发布。若样式丢失或图片不显示,请到站内阅读完整版。
night-shift-team:让无人值守流水线用上持久队友
https://www.firstsaofan.top/archives/night-shift-team
评论