当前位置: 首页 > news >正文

langgraph sse 用法

目录
  • 一、语法层面:Python 允许函数内定义函数(包含 async)
  • 二、运行时语义:这是一个「闭包 + 工厂函数」模式
    • 1️⃣ event_stream 不是立即执行的
    • 2️⃣ 为什么要嵌套,而不是单独定义?
    • 3️⃣ 如果不嵌套,会发生什么?
  • 三、在 FastAPI + SSE 中,这是「惯用模式」
    • FastAPI 官方与社区常见写法
  • 四、从设计角度看,你的写法是「高质量的」
    • 这是一种明确的设计边界
  • 五、再强调一次:这不是“偷懒写法”,而是刻意设计
  • 一句话总结

这是 Python 的语言特性,而且在你这段代码里,嵌套 async def 是一个非常合理、工程上正确的设计选择。下面我从「语法层面 → 运行时语义 → 为什么在 FastAPI + SSE 中尤其常见」三个层次解释。


一、语法层面:Python 允许函数内定义函数(包含 async)

在 Python 中:

  • def 可以出现在任何可执行作用域
  • async def 本质上仍然是函数定义,只是返回 协程函数
  • 因此:
async def outer():async def inner():...

完全合法的

这和 Java / Go 不同,Python 是支持闭包(Closure)的动态语言。


二、运行时语义:这是一个「闭包 + 工厂函数」模式

关键点在于这一句:

return StreamingResponse(event_stream(),media_type="text/event-stream",
)

1️⃣ event_stream 不是立即执行的

event_stream()

返回的是一个:

AsyncIterator[str](异步生成器)

它会在 FastAPI / ASGI 框架真正开始向客户端写数据时 才被消费。


2️⃣ 为什么要嵌套,而不是单独定义?

因为 event_stream 天然依赖外部上下文变量

外部变量 来源
request HTTP 请求体
thread_id 本次请求生成
last_content 请求最后一条消息
langfuse trace 与当前请求绑定
logger / callback 请求级上下文

这些变量:

thread_id
last_content
request
lf_callback
langfuse

event_stream 内部直接可用,因为:

Python 会把它们捕获为 闭包变量

这是一个非常标准的闭包模式


3️⃣ 如果不嵌套,会发生什么?

你只能写成这样:

async def event_stream(request, thread_id, last_content, ...):...

然后在外部:

return StreamingResponse(event_stream(request, thread_id, last_content, ...),
)

这会带来几个问题:

  1. 参数极多,接口污染
  2. SSE 是强请求绑定逻辑,却变成“公共函数”
  3. trace / callback / logger 很容易被误用成全局态
  4. 可读性显著下降

三、在 FastAPI + SSE 中,这是「惯用模式」

你这段代码本质是:

“为当前 HTTP 请求,动态生成一个只属于它的异步事件流函数”

这是 SSE 的本质需求。

FastAPI 官方与社区常见写法

@app.get("/stream")
async def stream():async def event_generator():for i in range(10):yield f"data: {i}\n\n"await asyncio.sleep(1)return StreamingResponse(event_generator())

你现在做的只是 工程级加强版

  • 多 Agent Graph
  • LangGraph astream
  • Langfuse trace
  • SSE 多事件类型

四、从设计角度看,你的写法是「高质量的」

这是一种明确的设计边界

层级 职责
customer_service_chat HTTP 入口 / 参数校验 / Response 封装
event_stream 本次请求的 执行生命周期
Graph / Agent 业务执行

event_stream生命周期 == 一个 HTTP 连接

这点用嵌套函数表达得非常清楚。


五、再强调一次:这不是“偷懒写法”,而是刻意设计

你这里用嵌套 async def,实际上同时实现了:

  • 闭包(request-scope state)
  • 请求隔离
  • 避免全局状态污染
  • SSE 延迟执行
  • Langfuse trace 正确归属

高并发 + 流式 + 可观测性 场景下,这是推荐做法


一句话总结

customer_service_chat 里嵌套定义 event_stream,是利用 Python 的闭包机制,为每个 HTTP 请求动态创建一个只属于它的异步事件流执行器

在 FastAPI + SSE + LangGraph + Langfuse 这种架构下,这是正确、清晰、可维护的工程实践,而不是语法“怪招”。

如果你愿意,下一步我可以帮你 判断这个 @observe 放在 event_stream 上是否是最佳位置,以及 root trace 是否如你预期那样工作

http://www.rkmt.cn/news/131110.html

相关文章:

  • 9.23
  • 为什么你的手势识别总延迟?Open-AutoGLM缩放参数调优指南
  • Open-AutoGLM操作手册导出实战指南(99%工程师忽略的核心细节)
  • Vue响应式数据全解析:从Vue2到Vue3,ref与reactive的实战指南
  • 本地数据加密太慢?Open-AutoGLM优化技巧,让你的系统提速8倍
  • 师夷长技以制夷,二角破壁,五分普惠,AI当雄于地球,今日之责任,不在他人,全在我少年开发者!
  • Open-AutoGLM推理延迟高?:4种优化路径+实测数据对比,立竿见影降本30%
  • 2025粘钉一体机选购指南:口碑领先的供应商都在这里,目前排行前列的粘钉一体机企业聚焦技术实力与行业适配性 - 品牌推荐师
  • 从一次「登录阻塞」说起:我终于理解了 goroutine
  • 工业多缺陷检测漏检多,后来才知道用IoU阈值加权评估
  • 具身智能(Embodied AI)逼近:机器人如何更好地理解物理世界?
  • Open-AutoGLM运行异常?:5步精准定位并解决核心故障
  • Excalidraw支持量子计算线路图绘制
  • 【Open-AutoGLM失败恢复核心技术】:揭秘企业级数据保护的5大关键策略
  • 别再手动设重试了!Open-AutoGLM自学习重试机制即将颠覆你的认知
  • Excalidraw vs Miro:哪个更适合中小团队使用?
  • 多代理系统(MAS):机器人集群如何实现知识共享与协同?
  • Excalidraw与Grafana Tempo分布式追踪结合
  • 公司组织架构调整工具 在线可视化编辑平台
  • Origin科研绘图——手把手教你绘制“子弹图”
  • 反向海淘独立站成功案例全景解析(附可复用策略)
  • 【工业级自动化新标准】:Open-AutoGLM多手指协同的5大关键技术突破
  • 大同市软件公司排名
  • 云测试平台的技术选型与效能评估
  • 基于浣熊优化算法的改进Dvhop定位算法:多通信半径与跳距加权策略下的性能对比研究
  • Excalidraw手绘白板神器:AI赋能下的技术架构图一键生成
  • Open-AutoGLM输入卡顿问题终结者,99%的人都没用对缓存机制
  • 开发者必备工具:Excalidraw手绘白板部署与优化
  • Open-AutoGLM推理延迟降低70%?资深架构师亲授优化清单
  • 12.1 图像生成革命:CV算法与AIGC工具应用场景分析