news 2026/9/20 7:45:45

Pydantic AI 流式输出:从首个 token 到完整校验的 4 步实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pydantic AI 流式输出:从首个 token 到完整校验的 4 步实践

Pydantic AI 流式输出:从首个 token 到完整校验的 4 步实践

【免费下载链接】pydantic-aiHow Python does AI. Agents, realtime voice, image generation, embeddings. Every model, every interface, typed end to end.项目地址: https://gitcode.com/GitHub_Trending/py/pydantic-ai

Pydantic AI 的agent.run_stream()是流式输出的入口:模型输出不再等整段生成完才返回,而是逐块推送到你的业务层,首个 token 就能先到前端。装好包之后不用改任何安装配置,直接看下面四步。

一个场景:整段等待和逐块返回的差别

假设你在做一个聊天界面,用户提问后要干等 5 秒,然后一大段文字一次性砸到屏幕上。换成流式推送后,界面上文字是"长出来"的,体感延迟明显下降。代价是你要处理两件事:中间状态的输出可能不合法(半截 JSON 永远校验不过),以及什么时候能拿到"最终版"。Pydantic AI 的流式输出把这两件事封装成了"部分校验 + 最终校验"两段式:中间块用宽松校验先推,结束那一刻再做一次严格校验。

四步跑通 run_stream 的流式输出

第一步:用 run_stream 拿到流式结果对象

这段代码在做什么:用异步上下文管理器启动流式运行,通过stream_text()逐块打印文本,最后用get_output()拿完整结果和用量。注意stream_text()默认delta=False,每次 yield 的是"到目前为止的全文",不是增量片段。

from pydantic_ai import Agent agent = Agent('openai:gpt-5.2') async def main(): async with agent.run_stream('What is the capital of the UK?') as response: async for text in response.stream_text(): print(text) print(await response.get_output())

示例来源:docs/agent.mdget_output()的实现在pydantic_ai_slim/pydantic_ai/result.py

第二步:结构化数据也能"流"出来

这段代码在做什么:定义一个TypedDict作为输出类型,模型边生成边被校验,每凑出合法的部分就 yield 一次,前端表格随数据逐行"长"出来。stream_output()内部对中间块用allow_partial=True做校验,校验失败的块直接跳过,最后一定会再 yield 一次完整校验过的结果。

class Whale(TypedDict): name: str length: Annotated[float, Field(description='Average length in meters.')] weight: NotRequired[Annotated[float, Field(..., ge=50)]] agent = Agent('openai:gpt-5.2', output_type=list[Whale]) async def main(): async with agent.run_stream('Details of 5 species of Whale.') as result: async for whales in result.stream_output(debounce_by=0.01): render_table(whales) # your own Rich/HTML rendering

示例来源:examples/pydantic_ai_examples/stream_whales.py

第三步:想看到中间事件就接 event_stream_handler

这段代码在做什么:给run_stream()传一个event_stream_handler,在最终输出产生之前观察工具调用、thinking、文本增量等事件。完整的事件类型清单(PartStartEventPartDeltaEventFunctionToolCallEventFinalResultEvent等)见pydantic_ai_slim/pydantic_ai/messages.py

async def event_stream_handler(ctx, event_stream): async for event in event_stream: if isinstance(event, FunctionToolCallEvent): print(f'Tool call: {event.part.tool_name}') elif isinstance(event, FinalResultEvent): print('Final result started') async with agent.run_stream(prompt, event_stream_handler=event_stream_handler) as run: async for text in run.stream_text(): print(text)

事件处理示例来源:docs/agent.md

这里有个容易误会的点:run_stream()第一个匹配输出类型的结果当最终输出,模型在"最终输出"之后生成的工具调用默认不会被执行。如果你的 Agent 必须把工具全部跑完,改用agent.run_stream_events()agent.iter(),或者把end_strategy设为'graceful'/'exhaustive'

第四步:收尾时拿完整输出、消息历史和用量

response属性随时能拿当前响应快照(流式中state'incomplete',结束后为'complete');usage属性在流结束后才有完整 cost;想中途放弃就调cancel(),它只停当前这条模型响应,整个 run 还在继续。这几个属性都在同一个StreamedRunResult对象上,见pydantic_ai_slim/pydantic_ai/result.py

避坑清单:症状 → 原因 → 修复

症状原因修复
结构化输出在中间几块时前端解析报 JSON 错误中间块是部分数据,Pydantic 用宽松校验放行,半截 JSON 本来就解析不了中间块只做展示用兜底值(例子里的占位),只把最后一次yield 当权威结果
流式模式下工具没被执行run_stream()遇到首个匹配输出的结果就结束,之后的工具调用被丢弃run_stream_events()/iter(),或设置end_strategy='graceful'
调用stream_text()UserErrorAgent 的output_type是结构化类型,文本流只支持纯文本输出结构化类型改用stream_output(),纯文本才用stream_text()
delta=True时发现校验器没生效文档写明了:delta=True时 result validators 不会被调用需要校验器参与就用stream_text(delta=False)stream_output()

debounce_by:流式输出校验频率怎么选

debounce_by控制"合并多少秒内的块再校验/推送一次",默认0.1秒,传None表示每个块都触发。它本质是用一点延迟换校验次数:结构化输出越长,默认 0.1 秒省下的校验开销越明显(stream_text()的 docstring 里也专门提了这一点)。

debounce_by 取值校验触发时机推送块数适用场景
None每个块都校验最多短文本、极端低延迟需求
0.01约 10ms 合并一次中等表格式结构化输出(whales 示例的取值)
0.1(默认)约 100ms 合并一次最少常规聊天文本,CPU 与体验平衡

如果接了 logfire 之类的观测,可以直接看每次运行的追踪图确认请求、工具调用和输出的时序:

跑通examples/pydantic_ai_examples/stream_whales.py之后,把debounce_by0.01改成None,对比表格刷新频率和终端的校验日志量,你会直观感受到这两个值的差别。更多参数语义见 docs/agent.md 的 Running Agents 一节和 docs/output.md 的结构化输出部分。

【免费下载链接】pydantic-aiHow Python does AI. Agents, realtime voice, image generation, embeddings. Every model, every interface, typed end to end.项目地址: https://gitcode.com/GitHub_Trending/py/pydantic-ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 7:45:41

如何给 Qwen Code 桌面客户端换品牌:从 brand.json 到安装包

如何给 Qwen Code 桌面客户端换品牌:从 brand.json 到安装包 【免费下载链接】qwen-code An open-source AI coding agent that lives in your terminal. 项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code 你手上有一个 AI 产品,想出…

作者头像 李华
网站建设 2026/9/20 7:45:27

GetQzonehistory 使用指南:5 分钟完成 QQ 空间数据备份

GetQzonehistory 使用指南:5 分钟完成 QQ 空间数据备份 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 跑完一次 GetQzonehistory,一次 QQ空间数据备份就完成了&…

作者头像 李华
网站建设 2026/9/20 7:45:25

华为IPD研发质量管理:流程裁剪、决策评审与质量成本模型落地

简介:这是一份以华为IPD与质量管理体系融合为核心的研发质量管理培训PPT,面向研发管理者、质量工程师、流程改进人员以及希望系统学习IPD方法的产品经理。内容先解读IPD主业务流框架与核心思想,包括跨职能团队、市场导向、并行工程和产品生命…

作者头像 李华