不流式的 agent 是个黑盒:用户发一个请求,盯着转圈等一分钟,分不清它在干活还是卡死。An unstreamed agent is a black box: the user sends a request and stares at a spinner, unable to tell working from hung.
8 分钟 · 初稿 2026.058 Min · Drafted 2026.05
你的研究助手现在能跑、能上生产了,但它对用户还是个黑盒:发一个问题,盯着转圈等一分钟,不知道它在搜、在算,还是卡死了。这一章讲流式 —— 让用户看着它干活。对多步 agent,流式不是锦上添花,是它能不能真给人用的分界。Your research assistant runs and is production-ready, but to a user it's still a black box: send a question, stare at a spinner for a minute, unsure if it's searching, computing, or hung. This chapter is about streaming — letting users watch it work. For a multi-step agent, streaming isn't a nice-to-have; it's the line between actually usable by people and not.
— I
不流式的 agent 是个黑盒An Unstreamed Agent Is a Black Box.
多步 agent 不流式,用户体验就是「发一个请求,盯着转圈等」—— 而且分不清它在干活还是卡死。A multi-step agent without streaming gives one experience: 'send a request, stare at a spinner' — with no way to tell working from hung.模型 API 本身支持流式:client.messages.stream 用 SSE 逐块产出,事件里有 content_block_delta(text_delta / thinking_delta)。1注 1Note 1Anthropic 文档 · Streaming —— Messages API 用 SSE 流式返回,事件含 content_block_delta(text_delta / thinking_delta)等;client.messages.stream 逐块产出。截至 2026-05。Anthropic docs · Streaming — the Messages API streams via SSE, with events like content_block_delta (text_delta / thinking_delta); client.messages.stream yields blocks incrementally. As of 2026-05.但对 agent,token 级流式只解决了一半 —— 它让「等待」变成「在动」,可用户看到的还只是最后那段文字一个字一个字蹦,看不到「它走到哪一步了」。The model API streams natively: client.messages.stream yields blocks over SSE, with content_block_delta events (text_delta / thinking_delta).1注 1Note 1Anthropic 文档 · Streaming —— Messages API 用 SSE 流式返回,事件含 content_block_delta(text_delta / thinking_delta)等;client.messages.stream 逐块产出。截至 2026-05。Anthropic docs · Streaming — the Messages API streams via SSE, with events like content_block_delta (text_delta / thinking_delta); client.messages.stream yields blocks incrementally. As of 2026-05. But for an agent, token-level streaming solves only half — it turns 'waiting' into 'moving,' yet the user still sees only the final text appearing character by character, not 'which step it's on.'
— II
Agent 的流式是事件级的,不只是 tokenAgent Streaming Is Event-Level, Not Just Tokens.
给用户流的,是 agent 的行动轨迹:它在搜什么、调了哪个工具、跑到第几步 —— 而不只是最后那段文字。What you stream to users is the agent's trail of action: what it's searching, which tool it called, which step it's on — not just the final text.在循环里,每一步 emit 一个事件:「搜索中 'X'」「找到 5 个来源」「在沙箱跑分析」「写报告」。这等于把第十章那条 trace 的一部分,直接变成给用户看的进度。我们的研究助手就该这样流 —— 用户看着它搜、读、算、写,而不是盯着一个转圈。3注 3Note 3OpenAI Agents SDK · Streaming —— 把 agent 运行中的事件(工具调用、步骤、增量输出)以流的形式抛给调用方,是「事件级流式」的一个实现参考。OpenAI Agents SDK · Streaming — emits an agent run's events (tool calls, steps, incremental output) as a stream to the caller; a reference implementation of event-level streaming.In the loop, emit an event each step: 'searching X,' 'found 5 sources,' 'running analysis in the sandbox,' 'writing the report.' That turns part of chapter 10's trace directly into user-facing progress. Your research assistant should stream like this — the user watches it search, read, compute, write, instead of watching a spinner.3注 3Note 3OpenAI Agents SDK · Streaming —— 把 agent 运行中的事件(工具调用、步骤、增量输出)以流的形式抛给调用方,是「事件级流式」的一个实现参考。OpenAI Agents SDK · Streaming — emits an agent run's events (tool calls, steps, incremental output) as a stream to the caller; a reference implementation of event-level streaming.
async def run_streamed(goal): emit("开始:" + goal) # 事件级:给用户看的进度 messages = [{"role": "user", "content": goal}] for step in range(MAX_STEPS): async with client.messages.stream( model="claude-opus-4-8", max_tokens=1024, tools=TOOLS, messages=messages, ) as stream: resp = await stream.get_final_message() for b in resp.content: if b.type == "tool_use": emit(f"调用 {b.name}…") # 不是原始 JSON,是人话 ... if resp.stop_reason != "tool_use": emit("完成"); return
在 agent 循环里,向用户流出「人话的步骤」Stream human-readable steps to the user from the loop
但别把内部细节全倒给用户。trace 是给你 debug 的,进度是给用户安心的 —— 流给用户的是「人话的步骤」,不是原始工具 JSON 和完整推理。两者的受众不同,详略也不同。But don't dump every internal detail on the user. A trace is for your debugging; progress is for the user's reassurance — stream human-readable steps, not raw tool JSON and full reasoning. Different audiences, different levels of detail.
— III
流式改变你的架构 —— 它得是异步、可中断的Streaming Reshapes Your Architecture — Async and Interruptible.
一旦流式,你的 agent 就不能是「跑完才返回」的同步函数了 —— 它得边跑边吐,还能被用户中途叫停。Once you stream, your agent can't be a synchronous 'return when done' function — it must emit as it runs, and be stoppable midway.流式要求异步(async generator / SSE),而异步顺带让「中断」变得可能 —— 用户看到它跑偏了,能当场喊停(呼应第九章的人工介入、第十一章的成本闸)。Vercel AI SDK 这类 streaming-first 框架,就是把「异步 + 流式 + 可中断」做成默认(呼应选型那一章)。2注 2Note 2Vercel AI SDK —— streaming-first 的 AI 应用 SDK:把流式 token 与 agent 步骤事件做成给前端用的一等原语。代表「流式优先」那一类框架。Vercel AI SDK — a streaming-first SDK for AI apps: streamed tokens and agent step events as first-class primitives for the frontend. Represents the streaming-first class of frameworks.Streaming demands async (an async generator / SSE), and async incidentally makes interruption possible — seeing it drift, the user can stop it on the spot (echoing chapter 9's human-in-the-loop and chapter 11's cost gates). Streaming-first frameworks like the Vercel AI SDK make 'async + streaming + interruptible' the default (echoing the framework-choice chapter).2注 2Note 2Vercel AI SDK —— streaming-first 的 AI 应用 SDK:把流式 token 与 agent 步骤事件做成给前端用的一等原语。代表「流式优先」那一类框架。Vercel AI SDK — a streaming-first SDK for AI apps: streamed tokens and agent step events as first-class primitives for the frontend. Represents the streaming-first class of frameworks.流式和可中断是一对。能流不能停,用户只能眼睁睁看它烧钱;能停不能流,用户根本不知道该不该停。两个一起上,agent 才既透明又可控。Streaming and interruptibility are a pair. Stream-but-can't-stop, and the user watches it burn money; stop-but-can't-stream, and the user has no idea whether to. Ship both, and the agent is at once transparent and controllable.动手 · 给研究助手装上事件级流式:Hands-on · give the research assistant event-level streaming:
01
在每一步 emit 一句人话进度Emit one human-readable step each round
在 loop 里,每调一个工具、每跨一步,emit 一句话(「搜索中」「读到 X」「在算」),前端打印出来。In the loop, on each tool call and each step, emit one line ('searching,' 'read X,' 'computing'), and print it on the frontend.
02
加一个「中途叫停」Add a midway stop
给流式跑加一个中断入口(按键或一个 stop 信号),让用户看到跑偏时能当场停。Add an interrupt to the streamed run (a keypress or a stop signal) so the user can halt it the moment it drifts.
03
对比黑盒和流式的体感Compare the black-box and streamed feel
同一个任务,跑改造前(等结果)和改造后(看着它干)各一次,记下体感差在哪 —— 那个差,就是 agent 能不能给真实用户用的差。Run the same task before (await the result) and after (watch it work), and note where the feel differs — that difference is whether the agent is usable by real users.
流给用户的不是 token,
是「它走到哪一步了」。.
What you stream to users isn't tokens —
it's which step it's on..
Aklman Library
— 讨论Discussion
讨论Discussion.
评论区初始化中…Initializing comments…
01 / 01
没有匹配结果No matches.
换个关键词,或按 Esc 回到页面Try another keyword, or press Esc to return