You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
[RFC] useXChat AgentProvider:模型无关的 Agent 事件接入
@ant-design/x-sdkSummary
本 RFC 提议在
@ant-design/x-sdk中增加模型、Agent Runtime 和传输协议无关的AgentProvider,将 AG-UI、OpenAI Compatible、Anthropic 风格事件、私有 SSE、WebSocket、本地 Runtime 和录制 Fixture 等不同输入统一转换为AgentEvent。React 侧继续使用现有入口:
不新增
useAgUIChat或useAgent,也不向useXChat增加agentUrl、mode、transport、store等配置。Provider 是唯一接入入口,并在内部绑定 Transport;useXChat负责 React 生命周期与状态订阅;Headless Agent Core 负责事件校验、归约与重放。Motivation
Discussion #1005 提出了将 AG-UI 与 Ant Design X 对话能力集成的需求,主要解决两个问题:
该方向成立,但直接增加
useAgUIChat({ agentUrl, transport, tools })会把 Hook 与单一协议、网络地址、工具执行策略绑定,并形成与useXChat平行的消息状态体系。随着第二种 Agent 协议进入,调用方仍需要切换 Hook 和 UI 状态逻辑。本 RFC 将问题拆成三个稳定边界:
useXChat保持唯一 React 接入入口。AG-UI 因此是可实现的
AgentProvider之一,而不是 Agent Core 的唯一协议。Goals
AgentState。useXChat({ provider })同时获得兼容消息和完整结构化状态。useXChat调用和消息组件兼容。Non-goals
meta中。Terminology
AsyncIterable<Chunk>的传输层onRequest对应的完整 Agent 执行Detailed Design
1. 模块归属
依赖方向为:
约束如下:
agent不引用 Provider、Transport、React 或具体模型 SDK。chat-providers依赖 Agent Protocol,负责 Runtime 适配与执行。x-chat组合 Provider 和 Store,处理 React 生命周期。agent/providers,因为 Provider 属于外部数据接入,不属于状态核心。2. AgentProvider
Provider 负责:
onRequest输入转换为 Runtime 请求。Provider 不负责:
protocol是useXChat识别 AgentProvider 的显式判别字段。id仅用于日志和元数据,不能参与能力判断。3. Transport
Transport 只负责执行请求并产生 Chunk,不理解消息、工具或 Run 语义。它保持独立接口以便组合和测试,但在 Provider 构造时绑定,不作为
useXChat的第二个配置项。自定义 Transport 使用命名空间标识,例如
company.websocket,避免与后续内置类型冲突。4. Provider 能力声明
Runner 在运行时验证:
5. Agent Event Protocol
每个事件使用统一信封:
字段约束:
eventId在 Run 内唯一,并与runId组成幂等键。sequence在同一 Run 内严格递增。sessionId和runId必须与当前执行一致。payload按type进行运行时校验。meta,不改变核心状态机。标准事件族:
run.started->run.completed/failed/cancelledmessage.started->message.delta->message.completed/failed/cancelledreasoning.started->reasoning.delta->reasoning.completed/failed/cancelledtool.requested->tool.arguments_delta->tool.running->tool.completed/failed/cancelledapproval.requested->approval.resolvedtask.created->task.updated->task.completed/failed/cancelledartifact.created->artifact.updated->artifact.completed/failed每个 Run 必须恰好包含一个
run.started和一个 Run 终态事件。实体增量和终态事件必须位于对应开始事件之后,Run 终止后不得继续更新实体。消息内容允许纯文本或结构化 Part:
核心层不得为了兼容纯文本 UI 而丢失结构化内容。
6. AG-UI 适配方式
AG-UI Provider 读取 AG-UI 事件,并按语义转换为标准 Agent Event。以下为非规范性示意:
run.started/completed/failedmessage.started/delta/completedtool.requested/arguments_delta/completedtask.*或命名空间扩展meta,不得伪造标准事件语义AG-UI 的连接地址、请求头和 Transport 配置由
AgUIAgentProvider的构造参数管理,不进入useXChat:这使同一 UI 可以在 AG-UI、其他标准协议和私有 Runtime 之间切换,而不更换 Hook。
7. useXChat API
AgentProvider 使用独立的 TypeScript 重载,但运行时入口保持不变:
使用方式:
返回值语义:
messagesAgentMessageState到MessageInfo[]的兼容投影parsedMessagesparser转换的组件展示模型agentStateisRequestingrunningRunabortonReloadrequestPlaceholder和requestFallback仅属于存量 ChatProvider。AgentProvider 的 loading、失败和取消状态必须由事件表达。setMessages、setMessage和removeMessage只修改兼容消息层,不伪造 Agent Event,也不直接修改agentState。8. useXChat 内部流程
AgentProvider 判别依赖
protocol.name,不使用instanceof、类名、模型名或方法形状,避免跨包实例和自定义实现失效。9. AgentState 与 Headless Store
AgentState包含:sessionsrunsmessagesreasoningtoolCallsapprovalstasksartifactsissuesReducer 与 Store 遵循以下不变量:
runId + eventId必须幂等。runId + entityId。record模式记录协议问题并继续处理。strict模式在第一个协议问题处抛出。batch先在临时快照归约,失败时不提交状态且不通知订阅者。10. 错误与取消
错误来源分为三类:
provider.transformError,转换为实体失败事件和run.failed。AbortSignal覆盖用户取消和组件卸载,转换为实体取消事件和run.cancelled。Provider 输出 Run 终态前必须关闭所有仍活动的消息、推理、工具或任务实体。
11. Provider 契约测试
校验器覆盖:
run.started和一个 Run 终态。AG-UI、OpenAI Compatible、Anthropic 风格和私有 Runtime Provider 应运行同一套 Fixture 契约测试。语义等价的 Fixture 应归约为等价的
AgentState。Example Usage
以下示例使用本地
AsyncIterable模拟 Runtime,不依赖 API Key、Mock Server 或网络:完整可运行示例位于
packages/x/docs/x-sdk/demos/x-chat/agent-provider.tsx,覆盖消息、推理、工具、成功、失败和取消流程。Backward Compatibility
现有调用不变:
兼容策略:
AbstractChatProvider,避免将多实体事件压缩为单条消息 Chunk。useXChat通过 TypeScript 重载保留普通 ChatProvider 的类型推导。agentState为undefined。messages,现有 Bubble 等消息组件无需理解完整事件协议。defaultMessages仅初始化兼容消息层;完整 Agent 会话恢复另立持久化 RFC。experimentalAgent和实验性文档标签提示不稳定性。Alternatives Considered
A. 新增
useAgUIChat优点是与 #1005 草案和 AG-UI 概念直接对应。缺点是产生第二套 Hook、消息状态和错误处理 API,并将 Ant Design X 的 Agent 能力绑定到单一协议。
结论:不采用。AG-UI 通过
AgUIAgentProvider接入现有useXChat。B. 新增通用
useAgent优点是 Agent API 与普通聊天完全隔离。缺点是前端切换 Provider 时必须更换 Hook,消息组件和会话管理也需要重复装配。
结论:第一阶段不采用。只有当 Agent 交互出现无法由
useXChat表达的稳定能力时再重新评估。C. 在
useXChat增加mode、agent、transport或store优点是底层对象显式。缺点是 Provider 与 Hook 同时承担能力判断,形成多种等价配置,并把 Runtime 细节泄漏到 UI。
结论:不采用。Hook 顶层仅保留
provider作为执行入口。D. 让 AgentProvider 继承 AbstractChatProvider
优点是复用现有类层级。缺点是 ChatProvider 的核心抽象是单消息转换,无法无损表达推理、工具、审批、任务和 Artifact 的独立生命周期。
结论:不采用。两类 Provider 共享
useXChat入口,不共享错误的继承关系。E. 将 Provider 放入
agent/目录优点是名称集中。缺点是纯事件 Core 将开始依赖网络和 Runtime 接入概念,且与现有
chat-providers形成重复归属。结论:不采用。Provider、runner 和契约测试归入
chat-providers;协议、Reducer 和 Store 归入agent。Security and Privacy
meta、错误详情、工具参数和 Artifact 可能包含敏感数据,日志与持久化实现不得默认上传这些字段。AbortSignal,避免用户停止后 Runtime 仍持续产生前端副作用。Performance
Testing Strategy
Rollout Plan
Phase 1: Experimental Core
experimentalAgent暴露 Protocol、Reducer 和 Store。chat-providers顶层导出 AgentProvider、Transport、runner 和契约校验器。useXChat中增加 AgentProvider 重载与内部桥接。Phase 2: Reference Providers
AgentState。Phase 3: Stabilization
稳定 API 必须同时满足:
useXChat测试无回归。Open Questions
abort()应取消当前 Run 还是全部活动 Run?Decision Summary
useXChat({ provider })。chat-providers。experimentalAgent只暴露不稳定的事件与状态核心。References
packages/x/docs/x-sdk/agent-provider.zh-CN.mdpackages/x/docs/x-sdk/use-x-chat.zh-CN.mddocs/roadmap/phase-1-breakdown.zh-CN.mdAll reactions