feat(agent): 支持子代理最大嵌套深度控制
- 在配置结构体中新增 max_nesting_depth 字段,设置子代理最大嵌套深度 - 在 AgentFactory、todo_read、todo_write 等处初始化 nesting_depth 字段为 0 - 允许 Task 工具注册,使用 max_nesting_depth 控制子代理嵌套层数 - SubAgentRuntimeConfig 新增 max_nesting_depth 配置项,默认值为 1 - TaskTool 新增 max_nesting_depth 字段和带深度限制的构造函数 - 任务执行时增加嵌套深度校验,超过最大深度返回错误提示,防止无限递归创建子代理
This commit is contained in:
parent
e842ae0608
commit
631c61fea2
@ -221,6 +221,8 @@ pub struct TaskConfig {
|
||||
pub ttl_hours: u64,
|
||||
#[serde(default = "default_task_allowed_tools")]
|
||||
pub allowed_tools: Vec<String>,
|
||||
#[serde(default = "default_task_max_nesting_depth")]
|
||||
pub max_nesting_depth: u32,
|
||||
}
|
||||
|
||||
fn default_task_enabled() -> bool {
|
||||
@ -239,6 +241,10 @@ fn default_task_ttl_hours() -> u64 {
|
||||
24
|
||||
}
|
||||
|
||||
fn default_task_max_nesting_depth() -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
fn default_task_allowed_tools() -> Vec<String> {
|
||||
vec![
|
||||
"read".to_string(),
|
||||
@ -264,6 +270,7 @@ impl Default for TaskConfig {
|
||||
explore_max_execution_secs: default_task_explore_max_execution_secs(),
|
||||
ttl_hours: default_task_ttl_hours(),
|
||||
allowed_tools: default_task_allowed_tools(),
|
||||
max_nesting_depth: default_task_max_nesting_depth(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,6 +79,7 @@ impl AgentFactory {
|
||||
message_id: request.message_id.map(str::to_string),
|
||||
message_seq: None,
|
||||
subagent_description: None,
|
||||
nesting_depth: 0,
|
||||
});
|
||||
// 如果有取消信号接收端,注入 Agent
|
||||
if let Some(token) = request.cancel_token {
|
||||
|
||||
@ -193,6 +193,7 @@ pub(crate) fn build_session_manager_with_sender(
|
||||
explore_max_execution_secs: task_config.explore_max_execution_secs,
|
||||
ttl_hours: task_config.ttl_hours,
|
||||
skills_index: skills.system_index_prompt(),
|
||||
max_nesting_depth: task_config.max_nesting_depth,
|
||||
};
|
||||
|
||||
let subagent_runtime = Arc::new(DefaultSubAgentRuntime::new(
|
||||
|
||||
@ -243,7 +243,15 @@ impl ToolRegistryFactory {
|
||||
}
|
||||
}
|
||||
|
||||
// 注意:不注册 task 工具,防止递归创建子代理
|
||||
// 注册 task 工具,允许子代理创建孙代理(深度由 TaskTool 运行时控制)
|
||||
if self.is_enabled("task") && self.task_config.enabled {
|
||||
if let Some(runtime) = &self.subagent_runtime {
|
||||
registry.register(TaskTool::new_with_depth(
|
||||
runtime.clone(),
|
||||
self.task_config.max_nesting_depth,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
registry
|
||||
}
|
||||
|
||||
@ -34,6 +34,8 @@ pub struct SubAgentRuntimeConfig {
|
||||
pub ttl_hours: u64,
|
||||
/// 技能索引(可选,预生成的技能列表字符串)
|
||||
pub skills_index: Option<String>,
|
||||
/// 子代理最大嵌套深度(0 = 禁止嵌套,1 = 允许 1 层孙代理)
|
||||
pub max_nesting_depth: u32,
|
||||
}
|
||||
|
||||
impl Default for SubAgentRuntimeConfig {
|
||||
@ -57,6 +59,7 @@ impl Default for SubAgentRuntimeConfig {
|
||||
explore_max_execution_secs: 3600, // 60分钟
|
||||
ttl_hours: 24,
|
||||
skills_index: None,
|
||||
max_nesting_depth: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -323,6 +326,7 @@ impl DefaultSubAgentRuntime {
|
||||
&self,
|
||||
session: &TaskSession,
|
||||
system_prompt: String,
|
||||
parent_nesting_depth: u32,
|
||||
) -> Result<AgentLoop, TaskError> {
|
||||
let prompt_provider = Arc::new(StaticSystemPromptProvider::new(system_prompt));
|
||||
|
||||
@ -342,6 +346,7 @@ impl DefaultSubAgentRuntime {
|
||||
message_id: None,
|
||||
message_seq: None,
|
||||
subagent_description: Some(session.description.clone()),
|
||||
nesting_depth: parent_nesting_depth + 1,
|
||||
});
|
||||
|
||||
// 如果有 MessageBus,附加实时广播 emitter
|
||||
@ -561,7 +566,7 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
||||
);
|
||||
|
||||
// 7. 创建子代理
|
||||
let agent = self.create_subagent(&session, system_prompt)?;
|
||||
let agent = self.create_subagent(&session, system_prompt, parent_context.nesting_depth)?;
|
||||
|
||||
// 8. 执行任务
|
||||
let result = self
|
||||
@ -642,7 +647,7 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
||||
);
|
||||
|
||||
// 5. 创建子代理
|
||||
let agent = self.create_subagent(&session, system_prompt)?;
|
||||
let agent = self.create_subagent(&session, system_prompt, parent_context.nesting_depth)?;
|
||||
|
||||
// 6. 使用历史继续执行
|
||||
let result = self
|
||||
|
||||
@ -10,11 +10,24 @@ use super::types::{TaskDefinition, TaskToolArgs};
|
||||
/// Task 工具 - 创建和管理子代理
|
||||
pub struct TaskTool {
|
||||
runtime: Arc<dyn SubAgentRuntime>,
|
||||
/// 最大嵌套深度(0 = 主 agent 不允许创建子代理,1 = 子 agent 可创建 1 层孙 agent)
|
||||
max_nesting_depth: u32,
|
||||
}
|
||||
|
||||
impl TaskTool {
|
||||
pub fn new(runtime: Arc<dyn SubAgentRuntime>) -> Self {
|
||||
Self { runtime }
|
||||
Self {
|
||||
runtime,
|
||||
max_nesting_depth: 0, // 主 agent 无深度限制
|
||||
}
|
||||
}
|
||||
|
||||
/// 创建带嵌套深度限制的 TaskTool(用于子代理)
|
||||
pub fn new_with_depth(runtime: Arc<dyn SubAgentRuntime>, max_nesting_depth: u32) -> Self {
|
||||
Self {
|
||||
runtime,
|
||||
max_nesting_depth,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +139,19 @@ impl Tool for TaskTool {
|
||||
});
|
||||
}
|
||||
|
||||
// 4. 执行任务
|
||||
// 4. 深度校验(仅对嵌套场景生效,主 agent 的 max_nesting_depth = 0 不限制)
|
||||
if self.max_nesting_depth > 0 && context.nesting_depth >= self.max_nesting_depth {
|
||||
return Ok(ToolResult {
|
||||
success: false,
|
||||
output: String::new(),
|
||||
error: Some(format!(
|
||||
"Cannot create nested subagent: max nesting depth ({}) reached",
|
||||
self.max_nesting_depth
|
||||
)),
|
||||
});
|
||||
}
|
||||
|
||||
// 5. 执行任务
|
||||
let result = if let Some(task_id) = task_args.task_id {
|
||||
// 恢复现有任务
|
||||
self.runtime
|
||||
|
||||
@ -182,6 +182,7 @@ mod tests {
|
||||
message_id: Some("msg-1".to_string()),
|
||||
message_seq: Some(1),
|
||||
subagent_description: None,
|
||||
nesting_depth: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -402,6 +402,7 @@ mod tests {
|
||||
message_id: Some("msg-1".to_string()),
|
||||
message_seq: Some(1),
|
||||
subagent_description: None,
|
||||
nesting_depth: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,8 @@ pub struct ToolContext {
|
||||
pub message_seq: Option<i64>,
|
||||
/// 子代理标识,用于标注消息来源
|
||||
pub subagent_description: Option<String>,
|
||||
/// 当前嵌套深度(0 = 主 agent,1 = 子 agent,2 = 孙 agent...)
|
||||
pub nesting_depth: u32,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user