Skip to content

[BUG][P2] 独立 ReAct 的流式增量与完整消息应使用一致且分轮隔离的消息 ID #280

Open

Description

@Aias00

已确认问题

AgentEvent 约定同一消息的 delta 和完整快照共享 executor 分配的 ID。ReAct 将所有 TEXT_DELTA 固定标为 model-stream,完整模型消息却标为 model-<turn>。多轮时不同消息的增量共用一个 ID,且没有与其匹配的完整消息快照。

契约:https://github.com/agentic-ai-java/argi/blob/b34835354b27f1f320ea8438edf2e9d170e69c84/argi-agent/argi-agent-api/src/main/java/io/github/agentic/ai/agent/AgentEvent.java#L25;增量:https://github.com/agentic-ai-java/argi/blob/b34835354b27f1f320ea8438edf2e9d170e69c84/argi-agent/argi-agent-core/src/main/java/io/github/agentic/ai/agent/react/ReActAgent.java#L430;快照:https://github.com/agentic-ai-java/argi/blob/b34835354b27f1f320ea8438edf2e9d170e69c84/argi-agent/argi-agent-core/src/main/java/io/github/agentic/ai/agent/react/ReActAgent.java#L324。

最小复现场景与证据

配置 streamModel(true),假客户端第一轮发出文本增量和带工具调用的最终 RESPONSE,工具完成后第二轮发出另一条文本增量和终态 RESPONSE。记录 AgentEvent 中的消息 ID。

实测 delta IDs 为 [model-stream, model-stream],模型消息快照 IDs 为 [model-0, model-1]。按 messageId 拼接和替换的消费者会把两轮增量合到一条消息,且无法用快照完成原消息。

交付与验收

  • 为每条逻辑模型消息分配调用内稳定 ID,所有对应 delta 与完整 Message 快照共享该 ID。
  • 不同模型轮次、工具消息及单响应内多条消息按实际契约区分,不能依赖固定全局字符串。
  • 重复订阅与并发调用的投影互不串用;不要求跨独立调用全局唯一,除非公共契约另有明确需要。
  • 用按 ID 维护消息视图的消费者验证单轮、多轮工具循环、无文本工具轮次、多片段响应及失败/取消;不得通过忽略 delta 或重复展示快照绕过问题。
  • 若修复涉及当前 Schema 修复后的最终消息更新,保持最终快照与已显示消息的关联一致。

关联与范围

关联 #196、#236。本单修复现有 AgentEvent 的 messageId 一致性,不新建持久事件日志或游标体系。#275 是 Studio Graph 页面直接渲染结构化 content 引起的崩溃,位于不同消费者路径,不以修复该页面替代本单。

验证基线与变更约束

Core b34835354b27f1f320ea8438edf2e9d170e69c84;Extensions cb2635ab2fc338e8aade28a132a15f48b4e655fc。本轮 Core 19 模块 clean install 通过,2517 个测试中 173 个跳过;此处缺陷由额外的独立 Java 探针确认,说明已有测试尚未覆盖对应行为,不代表真实模型或生产环境验收。

优先修复现有契约的实现,不强制拆模块或重命名,不让独立 Agent/Workflow 反向依赖 Graph/Loop,不向 Core 引入供应商 SDK。若必须改变公开 API、事件、配置或持久格式,说明较小替代方案、消费者影响、收益、迁移成本与目标版本;不得通过删测试、吞错误或弱化取消保证获得通过。

配套缺陷

#278

Activity

  1. XianReallyHot-ZZH commented on Oct 28, 2026

    @XianReallyHot-ZZH
    Contributor

    你好,我想认领这个缺陷 @Aias00

    初步方案

    1. 移除固定 model-stream 标识:TEXT_DELTA 与该轮完整消息快照共用调用内稳定 ID(沿用现有 model-<turn> 形态),流式消费者按 messageId 拼接后可由同 ID 快照封口;不依赖任何全局固定字符串。
    2. ID 生成保持调用内局部(executor 分配),重复订阅与并发调用的投影互不串用;不引入跨调用全局唯一,不新建事件日志/游标(遵守非目标)。
    3. Schema 修复后的最终消息(现 model-repair,fix(agent): deliver repaired structured output message as final ReAct output #294 引入)与被替换的原始终态消息保持 ID 关联:倾向复用被替换消息的 ID,消费者按 ID 替换即得到一致终态,零事件契约变更。想确认您的偏好(另一种是保留独立 ID 并在事件中增加被替换 ID 的关联字段,需扩展契约)。
    4. 行为测试用一个按 ID 维护消息视图的消费者验证:单轮、多轮工具循环、无文本工具轮次、多片段响应、失败/取消路径,断言增量拼接与快照封口一致;不以忽略 delta 或重复展示快照绕过。
    5. 不改 AgentEvent 公开契约与事件 Schema;实现落点在 argi-agent-core 的 ReAct 路径,不涉及 Graph 反向依赖。

    一个衔接确认:验收第 5 条涉及 #294(尚在评审中)引入的修复消息路径,我计划在 #294 合并后基于 main 实现,避免同一段代码两个 PR 交叉;若您希望先行,我可基于 #294 分支堆叠实现。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions