在处理复杂任务时,我们常常希望 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 task 和 Subagent [...] completed successfully。
由于子智能体是异步运行的,你会发现日志中主 Agent 的思考和子智能体的执行是交织在一起的,这正是异步并发的魅力所在。根据async异步性质,在主agent大模型思考的时候会切到subagent执行,subagent里面大模型思考的时候又会切回主agent执行。注意看debug控制台"Threads & Variables"中loop.py在执行还是subagent.py就能分清。但要一定要在subagent.py的while循环内打一个断点,这样就能看到子智能体的执行了。
总结
nanobot 的子智能体系统展示了如何利用 异步编程 + 消息总线 构建一个可扩展的协作模型。它不依赖复杂的编排框架,仅仅通过"工具调用"和"系统消息注入",就让 AI 拥有了并行处理复杂任务的能力。