# dsh-s2s 场景与最佳实践 > 定位:什么时候适合用 s2s、怎么把它用好。这不是使用手册(工具/挂载/配置见 [USAGE.md](USAGE.md)),也不是设计方案([SOLUTION.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` 会给出候选;**同名** → `ambiguous` 用 `session_id` 消歧;先看候选再投。 - 用 `s2s_sessions` / `s2s_peers` 观察目标三态(`live-idle` / `live-busy` / `dormant`),确认状态再决定直投还是拉起。 - 目标 **live** 时 `s2s_message` 直投(空闲 `followup` / 忙碌 `inject`);**dormant** 时走信箱/拉起路径。 ### 5.7 信任与安全 - s2s 是**同宿主单进程**机制:宿主机内任意进程/会话理论上都可向会话注入消息。**只用于可信宿主、受信会话**,不要把它暴露给不可信宿主或当作外部访问面。 ## 六、反例(别这么干) - **同名会话频繁出现** → 命中 `ambiguous`,投递不确定;用 `session_id`。 - **对易扰会话开 `allow`** → 消息一到就被拉起,反复唤醒、浪费轮次。 - **不配 `budget`** → 两会话互相 ping,形成回环。 - **把 s2s 当跨机 mesh 用** → 它没网络层,必不满足。 - **指望 `s2s_history` 跨重启** → 进程作用域,重启即丢。 - **依赖目标会话自动休眠** → 被拉起的会话保持 live-idle;要结束需显式收束。