当前general-purpose子智能体的继承规则是不是有缺陷?
当主智能体开启memory(长期记忆)的工具时,子智能体会集成开启的状态,但是长期记忆的配置不会同步给子智能体,使用的是默认的配置。
而且子智能体长期记忆的刷新耗时严重,同步阻塞,因为长期记忆,主智能体无法及时感知和获取子智能体的结论。
禁用状态同步。 开启状态同步, 配置应该也自动同步,或者可以定制配置子智能体的配置。
【问题描述】
general-purpose 子智能体在构建时会继承父 Agent 的部分状态和配置,包括:
- disableMemoryTools
- disableMemoryHooks
- CompactionConfig
- disableCompaction
- model、toolkit、middleware、hooks 等
但不会继承父 Agent 的 MemoryConfig。因此父 Agent 即使配置了定制的 memory
flush、长期记忆合并周期、memory model 和 prompt,general-purpose 仍会回退使用
MemoryConfig.defaults()。
这导致 Memory 相关状态和配置只同步了一部分,行为不一致且不符合“general-purpose 与主 Agent
具备相同能力和配置”的预期。
【当前行为】
父 Agent 配置:
builder.memory(
MemoryConfig.builder()
.flushTrigger(MemoryConfig.FlushTrigger.throttled(Duration.ofHours(2)))
.consolidationMinGap(Duration.ofHours(24))
.flushPrompt(customFlushPrompt)
.consolidationPrompt(customConsolidationPrompt)
.build()
);
创建 general-purpose 后,其实际配置为框架默认值:
flushTrigger = ALWAYS
consolidationMinGap = 30 minutes
consolidationMaxTokens = 4000
flushPrompt = default
consolidationPrompt = default
memory model = child primary model
daily retention = 90 days
session retention = 180 days
只有父 Agent 的以下禁用标志会传播:
disableMemoryTools
disableMemoryHooks
【预期行为】
general-purpose 应完整继承父 Agent 的 Memory 配置,包括:
- MemoryConfig
- memory model override
- flush trigger
- flush prompt
- consolidation prompt
- consolidation interval
- consolidation token limit
- retention 配置
- memory tools/hooks 禁用状态
继承逻辑应保持一致:
父 Agent 使用定制 MemoryConfig
→ general-purpose 使用相同 MemoryConfig
父 Agent 显式禁用 memory hooks/tools
→ general-purpose 同步禁用
【影响】
- 产生非预期的额外模型调用
父 Agent 将 flush 设置为节流模式,但 general-purpose 默认每次调用结束都会执行 memory flush。
- 非预期触发长期记忆合并
父 Agent 将 consolidation 周期设置为 24 小时,但 general-purpose 使用默认 30 分钟周期。
- 阻塞子智能体结果返回
Memory 后处理通过 concatWith 串联在 Agent Flux 末尾,且 consolidation 内部执行:
consolidator.consolidate(rc).block();
因此可能出现:
子智能体已输出 AgentResultEvent / AgentEndEvent
→ Memory consolidation 仍在执行
→ 子 Agent Flux 未完成
→ child call() 未返回
→ 主 Agent 无法获得 agent_spawn 结果
实际观察日志:
(MemoryConsolidator.java:191) MEMORY.md consolidated (27642 chars), watermark advanced to ...
表现为子智能体流式输出已经结束,但主智能体长时间收不到结果。
- 定制 Prompt 和 Memory Model 失效
父 Agent 为长期记忆设计的过滤规则、业务约束和低成本 memory model,在 general-purpose 中均不会生效。
- enableMemory=false 语义容易失效
如果上层仅通过“不调用 .memory(customConfig)”表达关闭 memory,Builder 会回退到
MemoryConfig.defaults(),并不会真正关闭 memory hooks。
这会进一步放大配置继承不完整的问题。
【根因分析】
问题位于:
agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgentBuilderSupport.java
buildGeneralPurposeFactory(...) 捕获并传播了:
final boolean capturedDisableMemoryTools = b.disableMemoryTools;
final boolean capturedDisableMemoryHooks = b.disableMemoryHooks;
final CompactionConfig capturedCompactionConfig = b.compactionConfig;
final boolean capturedDisableCompaction = b.disableCompaction;
但没有捕获:
final MemoryConfig capturedMemoryConfig = b.memoryConfig;
构建子 Agent 时也没有调用:
sub.memory(capturedMemoryConfig);
因此子 Builder 使用自身默认值:
MemoryConfig memoryConfig = MemoryConfig.defaults();
建议修复
在 buildGeneralPurposeFactory(...) 中完整传播 MemoryConfig:
final MemoryConfig capturedMemoryConfig = b.memoryConfig;
构建子 Agent 时:
if (capturedMemoryConfig != null) {
sub.memory(capturedMemoryConfig);
}
同时继续保留禁用标志传播:
if (capturedDisableMemoryTools) {
sub.disableMemoryTools();
}
if (capturedDisableMemoryHooks) {
sub.disableMemoryHooks();
}
建议同样检查 buildDeclaredFactory(...),确保所有由父 Agent 派生的子智能体遵循一致的配置继承规则。
建议补充测试
- 父 Agent 定制 flushTrigger,general-purpose 应继承。
- 父 Agent 定制 consolidationMinGap,general-purpose 应继承。
- 父 Agent定制 memory model 和 prompts,general-purpose 应继承。
- 父 Agent 禁用 memory hooks/tools,general-purpose 应保持禁用。
- 父 Agent 定制 retention 和 token limit,general-purpose 应继承。
- declared subagent 与 general-purpose 的继承行为应保持一致。
- 子智能体结束时不应因为意外使用默认 MemoryConfig 而产生额外 flush/consolidation
当前general-purpose子智能体的继承规则是不是有缺陷?
当主智能体开启memory(长期记忆)的工具时,子智能体会集成开启的状态,但是长期记忆的配置不会同步给子智能体,使用的是默认的配置。
而且子智能体长期记忆的刷新耗时严重,同步阻塞,因为长期记忆,主智能体无法及时感知和获取子智能体的结论。
禁用状态同步。 开启状态同步, 配置应该也自动同步,或者可以定制配置子智能体的配置。
【问题描述】
general-purpose 子智能体在构建时会继承父 Agent 的部分状态和配置,包括:
但不会继承父 Agent 的 MemoryConfig。因此父 Agent 即使配置了定制的 memory
flush、长期记忆合并周期、memory model 和 prompt,general-purpose 仍会回退使用
MemoryConfig.defaults()。
这导致 Memory 相关状态和配置只同步了一部分,行为不一致且不符合“general-purpose 与主 Agent
具备相同能力和配置”的预期。
【当前行为】
父 Agent 配置:
builder.memory(
MemoryConfig.builder()
.flushTrigger(MemoryConfig.FlushTrigger.throttled(Duration.ofHours(2)))
.consolidationMinGap(Duration.ofHours(24))
.flushPrompt(customFlushPrompt)
.consolidationPrompt(customConsolidationPrompt)
.build()
);
创建 general-purpose 后,其实际配置为框架默认值:
flushTrigger = ALWAYS
consolidationMinGap = 30 minutes
consolidationMaxTokens = 4000
flushPrompt = default
consolidationPrompt = default
memory model = child primary model
daily retention = 90 days
session retention = 180 days
只有父 Agent 的以下禁用标志会传播:
disableMemoryTools
disableMemoryHooks
【预期行为】
general-purpose 应完整继承父 Agent 的 Memory 配置,包括:
继承逻辑应保持一致:
父 Agent 使用定制 MemoryConfig
→ general-purpose 使用相同 MemoryConfig
父 Agent 显式禁用 memory hooks/tools
→ general-purpose 同步禁用
【影响】
父 Agent 将 flush 设置为节流模式,但 general-purpose 默认每次调用结束都会执行 memory flush。
父 Agent 将 consolidation 周期设置为 24 小时,但 general-purpose 使用默认 30 分钟周期。
Memory 后处理通过 concatWith 串联在 Agent Flux 末尾,且 consolidation 内部执行:
consolidator.consolidate(rc).block();
因此可能出现:
子智能体已输出 AgentResultEvent / AgentEndEvent
→ Memory consolidation 仍在执行
→ 子 Agent Flux 未完成
→ child call() 未返回
→ 主 Agent 无法获得 agent_spawn 结果
实际观察日志:
(MemoryConsolidator.java:191) MEMORY.md consolidated (27642 chars), watermark advanced to ...
表现为子智能体流式输出已经结束,但主智能体长时间收不到结果。
父 Agent 为长期记忆设计的过滤规则、业务约束和低成本 memory model,在 general-purpose 中均不会生效。
如果上层仅通过“不调用 .memory(customConfig)”表达关闭 memory,Builder 会回退到
MemoryConfig.defaults(),并不会真正关闭 memory hooks。
这会进一步放大配置继承不完整的问题。
【根因分析】
问题位于:
agentscope-harness/src/main/java/io/agentscope/harness/agent/HarnessAgentBuilderSupport.java
buildGeneralPurposeFactory(...) 捕获并传播了:
final boolean capturedDisableMemoryTools = b.disableMemoryTools;
final boolean capturedDisableMemoryHooks = b.disableMemoryHooks;
final CompactionConfig capturedCompactionConfig = b.compactionConfig;
final boolean capturedDisableCompaction = b.disableCompaction;
但没有捕获:
final MemoryConfig capturedMemoryConfig = b.memoryConfig;
构建子 Agent 时也没有调用:
sub.memory(capturedMemoryConfig);
因此子 Builder 使用自身默认值:
MemoryConfig memoryConfig = MemoryConfig.defaults();
建议修复
在 buildGeneralPurposeFactory(...) 中完整传播 MemoryConfig:
final MemoryConfig capturedMemoryConfig = b.memoryConfig;
构建子 Agent 时:
if (capturedMemoryConfig != null) {
sub.memory(capturedMemoryConfig);
}
同时继续保留禁用标志传播:
if (capturedDisableMemoryTools) {
sub.disableMemoryTools();
}
if (capturedDisableMemoryHooks) {
sub.disableMemoryHooks();
}
建议同样检查 buildDeclaredFactory(...),确保所有由父 Agent 派生的子智能体遵循一致的配置继承规则。
建议补充测试