dsh-s2s 场景与最佳实践

September 1, 2026 · View on GitHub

定位:什么时候适合用 s2s、怎么把它用好。这不是使用手册(工具/挂载/配置见 USAGE.md),也不是设计方案(SOLUTION.md),而是围绕「选用」和「用得好」的实践指南。


一、它解决什么

同一台宿主上,让多个 DSH 会话按名字互相对话、接力,并能唤醒已结束(静止)的会话。 单进程、零端口,不引入网络层。

一句话判断是否适合:你的多个会话是否跑在同一台宿主、同一个 dsh 进程里,且你想让它们互相投递消息 / 交接任务 / 唤醒沉睡的专业会话。是 → 用 s2s;否 → 看下面的边界。

二、一个场景:同事协同

把每个会话想象成一位同事,各干各的专业活;s2s 就是「按名字喊一声」的协作方式。下面讲个具体的样子。

早晨,产品经理(协调会话)把手头活儿分给三位同事:前端、后端、部署。每位同事一个会话,各管一段,互不抢上下文。

部署这位干到一半——发布脚本刚起头,就被一通电话打断了。他的会话停在「部署中」,随后进入静止(done)。产品经理要接着从他这儿往下走,于是对着名字喊了一声:“部署,继续。”

s2s 找到了名为「部署」的会话,发现它已经静止,于是把它拉起来,并把交接消息投进去。部署会话醒来,看到上下文和接下来要做的步骤,继续把发布收尾——不用人再去重新开一遍、也不用重新交代背景。

过了一会儿,前端要改接口。产品经理见「前端」这位正闲着,就直接一条消息投进去,前端立刻响应。

整个过程:没人开第二个终端、没人跨机器——大家都在同一台宿主的各自会话里,产品经理按名字点名即可,要唤醒的唤醒、要直投的直投。

这个场景里,s2s 真正解决的是两件事:把「谁、在哪个会话、做什么」用名字表达出来,以及静止的同事也能被叫回来接着干

三、适用场景

  1. 多会话分工编排 — 一个总编排会话(产品/项目经理/总助)按名调度多个专业会话(开发、运维、设计),各自专注一个职责,由编排方点名投递。
  2. 任务交接 / 接力 — 会话 A 完成阶段产出后,把后续交给会话 B(例:分析完成 → 交给执行;设计完成 → 交给编码),避免一个会话上下文过载。
  3. 唤醒静止专业会话 — 一个会话说「做完了」进入静止后,后续需要它时按名拉起再投递(例:被中断的部署,结束后有需要时再拉回继续)。
  4. 跨会话状态同步 / 汇报 — 需要把某个会话的结果、进度、决策同步给另一个会话。
  5. 上下文隔离的专家协作 — 让每个会话保持自己的上下文边界,只通过 s2s 交换必要的消息,防止多职责上下文互相污染。

四、边界:什么时候不该用它

  • 跨主机 / 跨进程 — s2s 是单进程路径,无网络层;跨机请用 a2a(mesh)或外部网关。
  • 非 DSH 标准 A2A agent — 需要能讲标准 A2A 协议的 agent 时,s2s 不暴露这套 wire,需网关类插件。
  • 需要标准 A2A 协议互操作 — s2s 是宿主内部机制,不是可互操作的标准 A2A 端点。
  • 高并发 / 大规模 mesh — s2s 无 hub/WS/重连,不适合当成 mesh 用。
  • 需要 GUI 面板 / 命令面 — s2s 定位精简,无浏览器 UI/命令面。
  • 需要跨重启的历史查询s2s_history 是进程作用域,进程重启不保留;需要持久历史看信箱或会话日志本身。

五、最佳实践

5.1 命名与寻址

  • 给每个会话起唯一、稳定、可预测的标题(名)。主寻址按名;同名会 ambiguous,需用 session_id 消歧。
  • 改名即刻生效(每次现读最新标题),所以先改好名再投递,别在会话中途频繁改名。
  • session_id 兜底:当场景里名字太多或可能同名时,优先给工具传 session_id

5.2 autoResume 策略(要不要自动唤醒)

  • allow:有消息即拉起静止会话并投递。适合「高价值、需要及时响应」的专业会话(如部署、执行会话)。
  • deny:只入信箱,不自动拉起。适合「不该被随便唤醒」的会话,由人工 s2s_resume 按需拉起。
  • 别对低价值/易误扰的会话用 allow,否则消息一到就被拉起,造成反复唤醒。
  • 被拉起的会话会保持 live-idle(不自动归眠),后续消息走 live 直投。若希望它真正结束,需显式收束,而不是依赖它自动休眠。

5.3 防回环与预算

  • 两个会话来回复投递可能形成 ping-pong 死循环。务必配置 budget(maxHops + ratePerMinute),在发送侧做跳数/限速。
  • 会话内明确「什么时候该回、什么时候该停」,别让接收方无脑复读触发回环。

5.4 信箱语义与消息格式

  • 对静止会话,消息先入信箱,autoResume=allow 才拉起并 drain 投递。
  • 传递时用 from 标明来源、replyTo 标明上下文,接收方才清楚「谁发的、针对什么」,而不是只有一句裸文本。
  • 每条消息有 msgId,接收方可据此去重/幂等,避免重复投递造成误执行。

5.5 会话职责与上下文边界

  • 一个会话一个专业职责,s2s 做的是「交接」不是「合并」。让各会话上下文隔离,仅交换必要消息。
  • 目标会话可能带用户角色/persona;若 persona 是模板(内容含运行时变量),被拉起时 s2s 会按该会话上次运行的模型绑定这些变量,保证模板能正常装配。

5.6 错误处理与状态观测

  • 查无not-found 会给出候选;同名ambiguoussession_id 消歧;先看候选再投。
  • s2s_sessions / s2s_peers 观察目标三态(live-idle / live-busy / dormant),确认状态再决定直投还是拉起。
  • 目标 lives2s_message 直投(空闲 followup / 忙碌 inject);dormant 时走信箱/拉起路径。

5.7 信任与安全

  • s2s 是同宿主单进程机制:宿主机内任意进程/会话理论上都可向会话注入消息。只用于可信宿主、受信会话,不要把它暴露给不可信宿主或当作外部访问面。

六、反例(别这么干)

  • 同名会话频繁出现 → 命中 ambiguous,投递不确定;用 session_id
  • 对易扰会话开 allow → 消息一到就被拉起,反复唤醒、浪费轮次。
  • 不配 budget → 两会话互相 ping,形成回环。
  • 把 s2s 当跨机 mesh 用 → 它没网络层,必不满足。
  • 指望 s2s_history 跨重启 → 进程作用域,重启即丢。
  • 依赖目标会话自动休眠 → 被拉起的会话保持 live-idle;要结束需显式收束。