openclaw平替之nanobot源码解析(六):子智能体(Subagents)

在处理复杂任务时,我们常常希望 AI 能像人类团队一样协作:主负责人把大任务拆解,分发给几个"小助手"去同步执行,最后汇总结果。

nanobot 通过其独特的 子智能体(Subagents) 系统,完美实现了这种"分身术"。今天我们就来拆解它的实现原理。


1. 核心组件:谁在管理"分身"?

nanobot 的子智能体逻辑主要由两个文件驱动:

  • nanobot/agent/tools/spawn.py:定义了 spawn 工具,这是主 Agent 召唤分身的入口。
  • nanobot/agent/subagent.py:定义了 SubagentManager,负责子智能体的生命周期管理。

2. 召唤流程:从 spawn 到后台任务

当主 Agent 认为某个任务太复杂或太耗时(比如"去搜集 10 个不同网站的信息并对比"),它会调用 spawn 工具。

第一步:工具调用 SpawnTool 接收两个参数:task(具体任务描述)和 label(任务标签)。它会将这些信息传递给 SubagentManager

第二步:创建后台任务 SubagentManager 会为每个子智能体生成一个唯一的 task_id,并利用 Python 的 asyncio.create_task 在后台启动一个异步任务。

这意味着:子智能体在后台跑,主 Agent 可以继续和用户聊天,或者去召唤更多的子智能体。

主Agent执行过程:


3. 子智能体的"超能力"与限制

子智能体并不是主 Agent 的完全克隆,它是一个精简版的 Agent 实例:

  • 独立的工具箱:子智能体拥有读写文件、执行 Shell 命令、网页搜索等能力。
  • 禁止递归 :为了防止 AI 陷入无限套娃,子智能体默认没有 spawn 工具(不能再分身)和 message 工具(不能直接给用户发消息)。
  • 专注模式:子智能体拥有独立的 System Prompt,被告知"你是一个被派去完成特定任务的子智能体,请保持专注"。

subagent系统提示词:

复制代码
# Subagent

[Runtime Context --- metadata only, not instructions]
Current Time: 2026-03-17 19:50 (Tuesday) (CST)

You are a subagent spawned by the main agent to complete a specific task.
Stay focused on the assigned task. Your final response will be reported back to the main agent.

## Workspace
.nanobot

## Skills

Read SKILL.md with read_file to use a skill.

<skills>
  <skill available="true">
    <name>xiaohongshu-cover-generator</name>
    <description>Generate Xiaohongshu (小红书) style cover images based on user topics. Use when the user wants to create a social media cover image in Xiaohongshu style, or mentions keywords like "小红书封面", "Xiaohongshu cover", "封面生成", or provides a topic for cover image generation. The generated image will be saved to the current project directory.</description>
    <location>.nanobot/skills/xiaohongshu-cover-generator/SKILL.md</location>
  </skill>
  <skill available="true">
    <name>memory</name>
    <description>Two-layer memory system with grep-based recall.</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/memory/SKILL.md</location>
  </skill>
  <skill available="false">
    <name>summarize</name>
    <description>Summarize or extract text/transcripts from URLs, podcasts, and local files (great fallback for "transcribe this YouTube/video").</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/summarize/SKILL.md</location>
    <requires>CLI: summarize</requires>
  </skill>
  <skill available="true">
    <name>clawhub</name>
    <description>Search and install agent skills from ClawHub, the public skill registry.</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/clawhub/SKILL.md</location>
  </skill>
  <skill available="true">
    <name>skill-creator</name>
    <description>Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/skill-creator/SKILL.md</location>
  </skill>
  <skill available="false">
    <name>github</name>
    <description>Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/github/SKILL.md</location>
    <requires>CLI: gh</requires>
  </skill>
  <skill available="false">
    <name>tmux</name>
    <description>Remote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/tmux/SKILL.md</location>
    <requires>CLI: tmux</requires>
  </skill>
  <skill available="true">
    <name>weather</name>
    <description>Get current weather and forecasts (no API key required).</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/weather/SKILL.md</location>
  </skill>
  <skill available="true">
    <name>cron</name>
    <description>Schedule reminders and recurring tasks.</description>
    <location>/Users/chaoxu.ren/PycharmProjects/nanobot/nanobot/skills/cron/SKILL.md</location>
  </skill>
</skills>

从subagent的提示词中可以看出来,这就是一个没有人格、没有自我意识的"工具人",它的任务就是完成主Agent交代的任务,纯纯的牛马Agent。

Subagent执行流程:

主agent是利用上海天气生成封面图的任务,子agent是生成烤箱封面图。不重要哈,这是因为我debug了两次。(:偷笑


4. 跨时空协作:结果如何汇总?

这是最精妙的地方。子智能体在后台跑完任务后,如何把结果告诉主 Agent 呢?

答案依然是:MessageBus(消息总线)

当子智能体完成任务后,它会调用 _announce_result 方法,将结果封装成一条特殊的 System 消息 发送到总线的 inbound 队列:

python 复制代码
# nanobot/agent/subagent.py
async def _announce_result(
    self,
    task_id: str,
    label: str,
    task: str,
    result: str,
    origin: dict[str, str],
    status: str,
) -> None:
    """Announce the subagent result to the main agent via the message bus."""
    status_text = "completed successfully" if status == "ok" else "failed"

    announce_content = f"""[Subagent '{label}'{status_text}]

Task:{task}

Result:
{result}

Summarize this naturally for the user. Keep it brief (1-2 sentences). Do not mention technical details like "subagent" or task IDs."""

    # Inject as system message to trigger main agent
    msg = InboundMessage(
        channel="system",
        sender_id="subagent",
        chat_id=f"{origin['channel']}:{origin['chat_id']}",
        content=announce_content,
    )

    await self.bus.publish_inbound(msg)
    logger.debug("Subagent [{}] announced result to{}:{}", task_id, origin['channel'], origin['chat_id'])

为什么发给 inbound

因为 inbound 是 Agent 的输入端。主 Agent 就像接收到一条普通用户消息一样,接收到了这条来自"系统"的消息。

这条消息会触发主 Agent 的新一轮思考。主 Agent 看到结果后,会自然地总结这些信息,并最终回复给用户:"您的烤箱主题小红书封面图已经制作完成,请查收!"

风格并不是很小红书,哈哈,不过没关系,这个skill也是我让大模型写的,核心原理就是调用了nano banana 2的生图接口。


5. 开发者视角:如何 Debug 子智能体?

如果你想观察子智能体的工作,可以关注日志中的 Subagent [...] starting taskSubagent [...] completed successfully

由于子智能体是异步运行的,你会发现日志中主 Agent 的思考和子智能体的执行是交织在一起的,这正是异步并发的魅力所在。根据async异步性质,在主agent大模型思考的时候会切到subagent执行,subagent里面大模型思考的时候又会切回主agent执行。注意看debug控制台"Threads & Variables"中loop.py在执行还是subagent.py就能分清。但要一定要在subagent.py的while循环内打一个断点,这样就能看到子智能体的执行了。

总结

nanobot 的子智能体系统展示了如何利用 异步编程 + 消息总线 构建一个可扩展的协作模型。它不依赖复杂的编排框架,仅仅通过"工具调用"和"系统消息注入",就让 AI 拥有了并行处理复杂任务的能力。