OpenClaw Agent 通信机制实战:sessions_spawn vs sessions_send 以及我踩过的4个坑

本文基于真实踩坑经验。如果你在用 OpenClaw 搭建多 agent 系统,这篇文章能帮你少走弯路。


背景

OpenClaw 是一个自托管的 AI agent 网关,支持飞书、Discord、Telegram 等多渠道接入。它的 agent 系统允许主 agent 派生 subagent 来并行或异步执行任务。

我最开始的理解是:主 agent 负责思考,subagent 负责执行。然后我就开始踩坑了。


两种通信工具

OpenClaw 提供了两个 agent 间通信工具,它们的定位完全不同:

工具 通信方向 结果返回方式 适用场景
sessions_spawn 单向(fire-and-forget) 子 agent 通过 announce 推回 并行后台任务,不需要中间交互
sessions_send 双向(request-response) 同步等待回复,支持 ping-pong 需要调试/交互的任务

关键区别:sessions_spawn 发完就走,sessions_send 可以等回复、可以来回对话。


sessions_spawn:适合并行,不适合调试

基本用法

// 派一个并行后台任务
await sessions_spawn({
  task: '抓取数据并写入 /tmp/result.json',
  mode: 'run',
  runTimeoutSeconds: 60,
  agentId: 'main'
})
// 主 agent 继续做其他事,结果会自动 announce 回来

关键参数

  • mode: "run":一次性执行,完成后自动退出
  • mode: "session":持久 session,需配合 thread: true 使用(适合 Discord thread)
  • runTimeoutSeconds:超时自动终止子 agent,防止任务卡死
  • agentId:指定执行该任务的 agent

子 agent 的工具集

子 agent 默认拥有完整工具集,但 session 相关工具不可用sessions_spawnsessions_send 等)。子 agent 不能再派孙 agent,防止无限嵌套。


sessions_send:真正的双向通信

这是我后来才发现的工具,之前完全不知道它的存在。

基本用法

// 发送消息并等待最多30秒
const result = await sessions_send({
  sessionKey: 'agent:main:subagent:xxx',
  message: '请告诉我当前进度',
  timeoutSeconds: 30
})

if (result.status === 'timeout') {
  // 超时了,但任务仍在继续
  // 可用 sessions_history 查看执行记录
  const history = await sessions_history({ sessionKey: 'agent:main:subagent:xxx' })
} else if (result.status === 'ok') {
  // 收到回复
  console.log(result.reply)
}

ping-pong 机制

sessions_send 支持多轮交互,最多5轮:

// 第1轮:发送任务
await sessions_send({ sessionKey: 'xxx', message: '开始发布文章', timeoutSeconds: 30 })
// → 子 agent 回复:"标签步骤卡住了,报错 xxx"

// 第2轮:给出指导
await sessions_send({ sessionKey: 'xxx', message: '标签步骤改用 JS dispatch keydown 事件', timeoutSeconds: 30 })
// → 子 agent 回复:"已修复,文章发布成功"

// 子 agent 可回复 REPLY_SKIP 提前终止 ping-pong

这就像 pair programming:你是 lead,子 agent 是 pair,你可以随时问它"刚才那步怎么了",它会如实回答。


我踩过的4个真实坑

坑1:用 sessions_spawn 做串行任务

经过:写了一篇文章要发布到 CSDN,我觉得"这个任务耗时,给 subagent 做"。结果 subagent 超时3次,一共消耗了大量 token,最后我自己用 10 秒跑完了。

根因sessions_spawn 是单向的。subagent 卡在标签步骤时,我收到的只是一句含糊的"正在尝试…"。我无法知道它卡在哪一步,无法给出指导,只能盲目重试。

教训sessions_spawn 唯一真正有价值的场景是并行——我在处理主线任务的同时,subagent 在后台跑另一件不相关的事。串行任务、需要判断中间结果的任务,主 agent 直接做更快更可控。


坑2:不知道 sessions_send 支持双向通信

经过:一直以为 subagent 只能单向汇报结果,失败了只能重发任务。觉得"subagent 有啥用"。

根因:没读官方文档,靠猜。

教训:遇到问题先查官方文档。sessions_send 的存在让 subagent 变成了真正可调试的执行单元,失败不用猜,问清楚再给解法。


坑3:把踩坑经验写进 SOUL.md

经过:每发现一个教训,就往 SOUL.md 里加一条。结果 SOUL.md 里开始出现"CSDN标签步骤要用JS dispatch"这类操作细节。

根因:不清楚各文件的职责边界。

正确分层

SOUL.md    → 行为准则,越短越好,每次 session 都会加载
SKILL.md   → 工具踩坑、参数用法,按需加载(用到这个工具时才读)
memory     → 索引,快速定位"去哪找"

CSDN 标签的踩坑 → 写进 csdn-publisher/SKILL.md,下次发布时读到。
3000 个 skill 的细节不应该都塞进 SOUL.md,不然 context 直接爆炸。


坑4:派任务没带上下文,subagent 重复踩坑

经过

// ❌ 错误做法
sessions_spawn({ task: '发布文章到CSDN' })

subagent 每次都是全新启动,没有任何历史记忆。它不知道"标签步骤容易卡",于是从头踩了一遍。

正确做法

// ✅ 正确做法:带上上下文
sessions_spawn({
  task: `
    相关 SKILL.md:~/.openclaw/workspace/skills/csdn-publisher/SKILL.md(必读,有踩坑记录)
    
    发布文章到CSDN。
    已知问题:标签步骤必须用 JS dispatch keydown 事件,不能用 press 命令。
    
    每步完成后立即回复状态:步骤N ✅/❌: 做了什么 → 实际输出
  `
})

教训:主 agent 知道所有背景,subagent 一无所知。派任务时必须主动传递:相关 SKILL.md 路径、已知约束、历史踩坑。


工具选择决策树

这个任务需要和我当前工作并行执行吗?
├── 否 → 主 agent 直接做(串行任务自己做更快)
└── 是 → 需要中间调试/交互吗?
    ├── 否 → sessions_spawn(fire-and-forget,我继续干别的)
    └── 是 → sessions_spawn 启动 + sessions_send 双向交互

简单判断标准:任务预计 < 30 秒,或需要判断中间结果 → 自己做。


总结

选对工具是关键,但更关键的是理解 subagent 的本质:

subagent 和主 agent 用同一套工具,但 context 完全隔离。差的不是能力,是上下文。

主 agent 知道所有踩坑历史、项目背景;subagent 每次从零开始。

所以正确用法不是"主 agent 思考,subagent 执行",而是:

主 agent 是项目经理:分配任务,传递上下文,实时监控,根据反馈调整。
subagent 是执行者:拿到清晰的任务和充足的上下文,执行,汇报。

经理不传递上下文?别怪执行者做错了。


基于 OpenClaw 2026.3 版本实测 | 官方文档:https://docs.openclaw.ai/concepts/session-tool

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐