AgentEvent 系统分层设计理念
AgentEvent 系统分层设计理念
pi-agent-core 和 pi-ai 的边界在哪里? AgentEvent 和 AssistantMessageEvent 的职责如何划分? 理解这个分层设计,是掌握整个系统的第一把钥匙。
应用开发者看到的是:用户说了什么、AI回复了什么、工具执行了什么。 API开发者看到的是:流式响应、token统计、错误重试。 这两层视角的差异,决定了事件系统的分离设计。
职责分离的本质
两个包的职责分离,本质上是”技术细节”和”业务语义”的分离。
pi-ai 只管 API 技术细节:与 Anthropic、OpenAI、Bedrock 等提供商通信, 处理它们之间的 API 响应格式差异,解析流式响应,处理错误重试,统计 token 用量。 它关心的是 HTTP 请求、SSE 流、JSON 解析——是”LLM 在说什么”的技术层。
pi-agent-core 只管 Agent 业务语义:管理多轮对话循环, 调度工具的串行或并行执行,维护消息历史,追踪 Agent 状态。 它关心的是”用户说了什么”、“AI 回复了什么”、“工具执行了什么”——是业务层。
事件流向
LLM Provider → pi-ai → pi-agent-core → 应用层 │ │ │ │ 解析API │ 封装转换 │ 业务处理 │ 响应流 │ 为高层事件 │ │ │ │ ↓ ↓ ↓ AssistantMessageEvent AgentEvent (13种技术事件) (7种业务事件)pi-agent-core 内部将底层事件转换为高层事件: 每个 message_update 都携带 assistantMessageEvent, 让应用层可以访问底层细节,但默认只暴露业务语义。
四个核心概念的关系
系统中有四个容易混淆的概念:
- AssistantMessageEvent:pi-ai层的13种技术事件
- AgentEvent:pi-agent-core层的7种业务事件
- AssistantMessage:pi-ai层的累积消息状态
- AgentMessage:pi-agent-core层的消息类型统称
关键区别:
- Event 是”正在发生什么”(流式增量)
- Message 是”累积成什么”(完整状态)
- pi-ai层只有 Assistant 视角
- pi-agent-core层有完整对话视角(User + Assistant + ToolResult)
时间线示例:四种概念如何协作
用一个实例说明:用户问”天气”,AI调用工具,返回结果。
时间轴 →
AssistantMessageEvent(pi-ai层,13种事件,字符级增量)││ text_delta "根据" → AssistantMessage.content[0].text += "根据"│ text_delta "查询" → AssistantMessage.content[0].text += "查询"│ toolcall_start → AssistantMessage.content[1] = ToolCall(空)│ toolcall_delta '{"query"' → ToolCall.arguments += '{"query"'│ toolcall_end → ToolCall.arguments完整││ 每次事件都更新 AssistantMessage(累积状态)│↓ done → AssistantMessage 完成,stopReason="toolUse"
────────────────── API响应完成,Agent开始处理 ──────────────────
AgentEvent(pi-agent-core层,7种事件,语义边界)││ message_start → AgentMessage(AssistantMessage)│ message_update → 携带 AssistantMessageEvent│ message_end → AgentMessage 完成│ tool_execution_start → 开始执行工具│ tool_execution_end → 工具完成│ turn_end → 本轮结束,携带 ToolResultMessage││ AgentMessage 是三种类型的统称:│ - UserMessage(用户输入)│ - AssistantMessage(AI回复)│ - ToolResultMessage(工具结果)│↓ agent_end → 所有 AgentMessage 汇总返回概念层级结构
pi-agent-core 层││ AgentEvent(7种业务事件)│ ├── message_start/update/end ← 携带 AgentMessage│ ├── tool_execution_start/end│ └── turn_start/end│ └── agent_start/end││ AgentMessage(消息类型统称)│ ├── UserMessage│ ├── AssistantMessage ────────┐│ └── ToolResultMessage │ 共享同一个类型│ │pi-ai 层 ││ ││ AssistantMessageEvent(13种)││ ├── text_delta ││ ├── toolcall_end ││ └── done/error ││ ││ AssistantMessage(累积状态)←─┘│ 每次事件都更新这个对象Event vs Message:
| Event | Message | |
|---|---|---|
| 性质 | 过程(增量) | 结果(累积) |
| 频率 | 高频触发 | 持续更新 |
| 用途 | 实时响应 | 状态查询 |
使用选择指南
| 需求 | 使用哪层 | 具体事件 |
|---|---|---|
| 显示”AI正在回复…” | 高层 | message_start |
| 实时显示文本流 | 底层 | message_update + text_delta |
| 显示”正在执行工具…” | 高层 | tool_execution_start |
| 显示参数生成过程 | 底层 | message_update + toolcall_delta |
| 获取 token 用量 | 高层 | message_end |
| 显示思考过程 | 底层 | message_update + thinking_delta |
| 判断一轮对话结束 | 高层 | turn_end |
| 处理 API 错误 | 底层 | message_update + error |
| 判断任务完成 | 高层 | agent_end |
使用原则:90% 的场景用高层事件就够了。 只有需要字符级实时性、或处理底层技术细节时,才深入底层。
分层设计的价值
这个分层设计带来六个核心价值:
- 单一职责:pi-ai 只管 API,pi-agent-core 只管 Agent,各司其职
- 可复用:pi-ai 可独立用于非 Agent 场景(直接调用 LLM)
- 抽象层级:默认用高层,需要时深入底层,按需访问
- 易于扩展:新增提供商只改 pi-ai,新增 Agent 功能只改 pi-agent-core
- 易于测试:两层独立测试,互不干扰
- 解耦演进:API 层和业务层独立演进,互不影响
一句话总结:AgentEvent 是”Agent 在做什么”,AssistantMessageEvent 是”LLM 在说什么”。两层分离,让应用默认关心业务,需要时深入技术。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!