背景
并发场景下(主 agent 并行扇出调用多个子 agent),当前 conversation_id 的拼装格式与此前约定的 {conv}-sub-{entity_id} 存在差异;同时 _remote_invocation 元数据仅支持 A→B 单层扁平投影,无法支撑真实的多层(多跳)并发场景在前端正确呈现。两者相互耦合,需一并解决。
延伸子项(单层投影"有条件发出"、单父单批次硬限制)另开 issue 单独跟踪,链接见文末。
问题一:conversation_id 拼装格式不一致
现状(并发远端调用路径)
serve 层并行远端调用的子会话 id 在 RemoteInvocationBatchCoordinator#remoteContextId 拼装:
private static String remoteContextId(RemoteInvocationBatch batch, Member member) {
String parentContextId = batch.request.getConversationId();
if (parentContextId == null || parentContextId.isBlank()) parentContextId = batch.parentTaskId;
if (batch.members.size() <= 1) return parentContextId; // 单成员:不拼接
return parentContextId + "_" + batch.batchId + "_" + member.toolCallId; // 多成员:父_batchId_toolCallId
}
抓包观察到的实际值为 {parentUuid}_{batchUuid}_{toolCallId},如 8211b1a4-…_635e1021-…_call_01_…(分隔符为下划线,非约定的 -sub-)。
与约定 {conv}-sub-{entity_id} 的差异
- 没有
sub 关键字:全仓搜索 "-sub-" 零命中;唯一带 sub 的是本地子 agent 路径 TaskTool#buildSubSessionId,且用的是下划线 _sub_,仍与约定的连字符 -sub- 不符。
- 中间段是随机
batchId(每次批次都变的 UUID),不是稳定的 entity_id:前端无法从 id 字符串识别"这是哪个子 agent"。
- 子 agent 身份(
target/agentName)不在 id 中:只存在于 _remote_invocation metadata(见问题二)。
根因:存在 3+ 套互不兼容的格式,无统一约定
| 路径 |
位置 |
格式 |
分隔符 |
| serve 层并发远端调用 |
RemoteInvocationBatchCoordinator.java:629 |
{parent}_{batchId}_{toolCallId} |
_ |
| 本地子 DeepAgent |
TaskTool.java:67 |
{parent}_sub_{type}_{uuid8} |
_sub_ |
| agent-as-tool 调用 |
AbilityManager.java:475 |
{parent}:{toolCallId} |
: |
| DeepAgent 请求级隔离 |
DeepAgent.java:597/641/671 |
{conv}_{seq} |
_ |
影响
前端拿到子会话 id 后,无法靠固定规则反向解析出"父会话 + 子实体身份",因为格式随调用路径变化、且不含实体名。约定的 {conv}-sub-{entity_id} 正是为前端可解析而设,当前任何路径都不满足。
问题二:_remote_invocation 仅 A→B 单层扁平投影
现状
唯一构造点 RemoteInvocationBatchCoordinator#forwardRemoteOutput(行 518-532),projection 永远只有 4 个字段:
projection.put("kind", "remote_agent_output");
projection.put("batchId", batch.batchId);
projection.put("toolCallId", member.toolCallId);
projection.put("target", …);
示例:
{"_remote_invocation":{"toolCallId":"call_00_…","kind":"remote_agent_output","batchId":"2445c385-…","target":"versatile-adapter"}}
多跳支持核查(全部为否)
- ❌ 无
depth/chain/hop/lineage/rootBatchId 字段(全仓零命中)
- ❌ 写入为覆盖式(每次 new LinkedHashMap,不合并父 projection);
ChunkMapper#toParts(行 44)同样直接覆盖
- ❌ 读取只判 key 存在性、不解析内部、不累积(
A2aPartContent#hasRemoteInvocationMetadata)
- ❌
parentTaskId 是单层向上指针:B→C 时 B 的 coordinator 用自己的 task id 做 parent,不形成链
- ❌ A→B 请求 metadata 经
outboundMetadata 过滤掉保留键,A 的 projection 根本不传给 B
影响
多跳并发(A→B→C)时,客户端无法还原调用链路(谁调了谁、第几跳、根会话是谁),无法在前端正确呈现多跳并发拓扑。
两个问题的耦合
前端要正确呈现多跳并发,需要同时具备:
- 稳定、可解析、按统一约定的每跳
conversation_id 命名(问题一)
- 携带链路信息的嵌套 metadata(问题二)
当前两者都不满足,且互不协同:id 是每跳向上拼接但不带链路语义;metadata 是扁平单跳投影。
建议修复方向
- 统一
conversation_id 命名约定:明确采用 {conv}-sub-{entity_id}(或定死分隔符),用稳定的子 agent 身份(target/agentName)作为 entity_id,不要用每次随机的 batchId。集中到单一工厂方法,消除 3+ 套格式分叉。
- 给
_remote_invocation 增加链路字段:如 depth/parentBatchId/rootConvId/chain[];forwardRemoteOutput 改为合并而非覆盖父 projection;放宽 outboundMetadata 过滤,允许链路信息跨跳传递。
关联
- 延伸子项(单层投影"有条件发出"、单父单批次硬限制)见姊妹 issue(链接将在评论中补充)。
- 详细代码追踪背景见
documents/zh/deepagent-a2a-delegate-dual-channel-leak-defect.cn.md。
背景
并发场景下(主 agent 并行扇出调用多个子 agent),当前
conversation_id的拼装格式与此前约定的{conv}-sub-{entity_id}存在差异;同时_remote_invocation元数据仅支持 A→B 单层扁平投影,无法支撑真实的多层(多跳)并发场景在前端正确呈现。两者相互耦合,需一并解决。问题一:
conversation_id拼装格式不一致现状(并发远端调用路径)
serve 层并行远端调用的子会话 id 在
RemoteInvocationBatchCoordinator#remoteContextId拼装:抓包观察到的实际值为
{parentUuid}_{batchUuid}_{toolCallId},如8211b1a4-…_635e1021-…_call_01_…(分隔符为下划线,非约定的-sub-)。与约定
{conv}-sub-{entity_id}的差异sub关键字:全仓搜索"-sub-"零命中;唯一带sub的是本地子 agent 路径TaskTool#buildSubSessionId,且用的是下划线_sub_,仍与约定的连字符-sub-不符。batchId(每次批次都变的 UUID),不是稳定的entity_id:前端无法从 id 字符串识别"这是哪个子 agent"。target/agentName)不在 id 中:只存在于_remote_invocationmetadata(见问题二)。根因:存在 3+ 套互不兼容的格式,无统一约定
RemoteInvocationBatchCoordinator.java:629{parent}_{batchId}_{toolCallId}_TaskTool.java:67{parent}_sub_{type}_{uuid8}_sub_AbilityManager.java:475{parent}:{toolCallId}:DeepAgent.java:597/641/671{conv}_{seq}_影响
前端拿到子会话 id 后,无法靠固定规则反向解析出"父会话 + 子实体身份",因为格式随调用路径变化、且不含实体名。约定的
{conv}-sub-{entity_id}正是为前端可解析而设,当前任何路径都不满足。问题二:
_remote_invocation仅 A→B 单层扁平投影现状
唯一构造点
RemoteInvocationBatchCoordinator#forwardRemoteOutput(行 518-532),projection 永远只有 4 个字段:示例:
{"_remote_invocation":{"toolCallId":"call_00_…","kind":"remote_agent_output","batchId":"2445c385-…","target":"versatile-adapter"}}多跳支持核查(全部为否)
depth/chain/hop/lineage/rootBatchId字段(全仓零命中)ChunkMapper#toParts(行 44)同样直接覆盖A2aPartContent#hasRemoteInvocationMetadata)parentTaskId是单层向上指针:B→C 时 B 的 coordinator 用自己的 task id 做 parent,不形成链outboundMetadata过滤掉保留键,A 的 projection 根本不传给 B影响
多跳并发(A→B→C)时,客户端无法还原调用链路(谁调了谁、第几跳、根会话是谁),无法在前端正确呈现多跳并发拓扑。
两个问题的耦合
前端要正确呈现多跳并发,需要同时具备:
conversation_id命名(问题一)当前两者都不满足,且互不协同:id 是每跳向上拼接但不带链路语义;metadata 是扁平单跳投影。
建议修复方向
conversation_id命名约定:明确采用{conv}-sub-{entity_id}(或定死分隔符),用稳定的子 agent 身份(target/agentName)作为entity_id,不要用每次随机的batchId。集中到单一工厂方法,消除 3+ 套格式分叉。_remote_invocation增加链路字段:如depth/parentBatchId/rootConvId/chain[];forwardRemoteOutput改为合并而非覆盖父 projection;放宽outboundMetadata过滤,允许链路信息跨跳传递。关联
documents/zh/deepagent-a2a-delegate-dual-channel-leak-defect.cn.md。