Guides
Streaming
使用 We0Agent.stream() 消费模型文本、工具调用、工具结果、step 状态和 session 事件。
stream() 是业务 UI 最常用的入口。它把模型增量、工具调用、工具结果、step、session 状态和错误统一成 We0Event,让调用方用一个异步迭代器消费。
何时使用 stream()
| 场景 | 为什么用 stream |
|---|---|
| 聊天 UI | 需要 text-delta 做打字机效果。 |
| 工具进度 | 需要展示工具开始、输入、结果和错误。 |
| 长任务 | 需要把 step、retry、compaction、status 发给前端。 |
| 调试 agent | 需要完整观察模型和工具之间的往返。 |
如果只关心最终状态,使用 We0Agent.invoke。
事件生命周期
不是每次运行都会出现所有事件。没有工具时不会有 tool-*;provider 不暴露 reasoning 时不会有 reasoning-*;没有重试时不会有 session.retried。
最小消费代码
async for event in agent.stream(
abort=abort,
session_id=session_id,
messages=[message],
):
if event["type"] == "text-delta":
print(event["text"], end="", flush=True)
elif event["type"] == "tool-call":
print(f"\n[tool] {event['name']} {event['input']}")
elif event["type"] == "tool-result":
print(f"\n[result] {event['name']} {event['result']}")
elif event["type"] == "finish":
print(f"\n[finish] {event.get('reason')}")事件是 TypedDict,字段要用键访问。可选字段要用 event.get(...)。
事件分类
| 类别 | 事件 | 典型用途 |
|---|---|---|
| 文本 | text-start、text-delta、text-end | 更新聊天正文。 |
| 推理 | reasoning-start、reasoning-delta、reasoning-end | 调试或展示 provider 暴露的 reasoning。 |
| 工具输入 | tool-input-start、tool-input-delta、tool-input-end | 展示模型正在构造工具参数。 |
| 工具执行 | tool-call、tool-result、tool-error | 展示工具状态和结果。 |
| Step | step-start、step-finish、finish | 管理一轮 agent loop 的阶段。 |
| Provider 错误 | provider-error | 展示模型供应商错误。 |
| Session | session.* | 更新运行状态、diff、retry、compaction。 |
| Question | question.* | 处理 agent 发起的交互式提问。 |
完整字段见 Events。
分发器模板
业务系统通常不会在一个 if 里写完所有事件,而是做一个分发器。
async def consume_events() -> None:
async for event in agent.stream(
abort=abort,
session_id=session_id,
messages=[message],
):
match event["type"]:
case "text-delta":
await ui.append_text(event["text"])
case "tool-call":
await ui.show_tool_call(event["id"], event["name"], event["input"])
case "tool-result":
await ui.show_tool_result(event["id"], event["result"])
case "tool-error":
await ui.show_tool_error(event["id"], event["message"])
case "session.status":
await ui.set_status(event["status"])
case "finish":
await ui.finish(event.get("reason"))控制台、UI、日志或 WebSocket 输出都可以按同样的 match event["type"] 方式分发。
UI 状态建议
| UI 状态 | 由哪些事件驱动 |
|---|---|
| assistant 正在输入 | text-start 到 text-end |
| 工具正在准备参数 | tool-input-start 到 tool-input-end |
| 工具正在执行 | tool-call 到 tool-result / tool-error |
| step 进行中 | step-start 到 step-finish |
| 会话忙碌/空闲 | session.status |
| 运行完成 | finish |
| 运行失败 | provider-error、tool-error、session.error |
易错点
tool-input-delta是参数字符串分片,不是完整 JSON。完整参数以tool-call["input"]为准。finish不代表一定有文本输出;工具任务也可能以 finish 收口。step-finish是单个 step 的结束,finish才是整轮请求结束。stream()配置结构化输出会抛错;结构化输出请用invoke()。abort事件不要跨轮复用。
下一步
- 精确事件字段:看 Events。
- 添加工具:看 AnyToolDefinition。
- 把事件发布给多个消费者:看 Built-ins: We0EventHub。