feat(agent): 实现委派工具重构,支持子代理和代理团队模式

- 新增 spawn_subagent 和 spawn_agent_team 工具,替代原有的 spawn 工具
- 重构 DelegationManager 以支持单个子代理和代理团队两种委派模式
- 更新系统提示词中的委派策略说明,明确使用场景和区别
- 添加技能上下文传递功能,确保委派任务遵循指定技能
- 实现代理内部的受控下游委派机制,防止无限嵌套
- 更新工具注册和上下文设置逻辑以适配新架构
This commit is contained in:
2026-03-30 17:21:39 +08:00
parent 29dfd14aa6
commit fee9007da6
6 changed files with 490 additions and 90 deletions

View File

@ -32,7 +32,7 @@ from nanobot.agent.tools.filesystem import EditFileTool, ListDirTool, ReadFileTo
from nanobot.agent.tools.message import MessageTool
from nanobot.agent.tools.registry import ToolRegistry
from nanobot.agent.tools.shell import ExecTool
from nanobot.agent.tools.spawn import SpawnTool
from nanobot.agent.tools.spawn import DelegationTool, SpawnAgentTeamTool, SpawnSubagentTool
from nanobot.agent.tools.web import WebFetchTool, WebSearchTool
from nanobot.bus.events import InboundMessage, OutboundMessage
from nanobot.bus.queue import MessageBus
@ -145,6 +145,7 @@ class AgentLoop:
workspace=workspace,
bus=bus,
registry=self.agent_registry,
skills_loader=self.skills,
local_executor=self.subagents,
timeout_seconds=self.a2a_config.timeout_seconds,
poll_interval_seconds=self.a2a_config.poll_interval_seconds,
@ -157,6 +158,7 @@ class AgentLoop:
allow_plugin_delegation=self.allow_plugin_delegation,
allow_local_fallback=self.include_local_fallback,
)
self.subagents.set_nested_delegate(self.delegation)
# 运行时状态位。
self._running = False
@ -209,13 +211,14 @@ class AgentLoop:
protected_paths=protected_skill_paths,
))
# 网络、消息、子代理工具按职责注册。
# 网络、消息、委派工具按职责注册。
self.tools.register(WebSearchTool(api_key=self.brave_api_key))
self.tools.register(WebFetchTool())
if self.allow_message:
self.tools.register(MessageTool(send_callback=self.bus.publish_outbound))
if self.allow_spawn:
self.tools.register(SpawnTool(manager=self.delegation))
self.tools.register(SpawnSubagentTool(manager=self.delegation))
self.tools.register(SpawnAgentTeamTool(manager=self.delegation))
# 只有注入 cron_service 时才暴露 cron 工具,避免空引用。
if self.cron_service and self.allow_cron:
@ -347,11 +350,12 @@ class AgentLoop:
if isinstance(message_tool, MessageTool):
message_tool.set_context(channel, chat_id, message_id)
# spawn 工具:子代理完成后需要把结果回投到原会话,
# 委派工具:后台任务完成后需要把结果回投到原会话,
# 因此只需记住来源 channel/chat_id。
if spawn_tool := self.tools.get("spawn"):
if isinstance(spawn_tool, SpawnTool):
spawn_tool.set_context(channel, chat_id, announce_via_bus=self._running)
for tool_name in ("spawn_subagent", "spawn_agent_team"):
if delegation_tool := self.tools.get(tool_name):
if isinstance(delegation_tool, DelegationTool):
delegation_tool.set_context(channel, chat_id, announce_via_bus=self._running)
# cron 工具:创建任务时会把 deliver 目标写入任务 payload
# 后续定时触发时才能把结果送回同一会话。