You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LangChain实现OpenAI流式响应,无法通过Flask API返回给用户求解决方案

问题分析

你当前的自定义MyCustomSyncHandler存在两个核心问题:

  1. on_llm_new_token是LangChain的回调方法,不能直接通过yield返回内容,LangChain不会处理这个生成器;
  2. 混淆了回调逻辑与Flask流式响应的生成逻辑,回调方法的执行上下文和Flask响应的上下文不兼容。

解决方案

通过线程安全的token收集容器+Flask流式响应生成器的组合实现需求,具体步骤如下:

1. 修正自定义回调Handler

用线程安全的队列收集LLM生成的每个token,同时标记LLM任务结束状态:

from langchain.callbacks.base import BaseCallbackHandler
from queue import Queue
from typing import Any

class StreamingCallbackHandler(BaseCallbackHandler):
    def __init__(self):
        self.token_queue = Queue()
        self.task_done = False

    def on_llm_new_token(self, token: str, **kwargs: Any) -> None:
        # 收集每个新生成的token
        self.token_queue.put(token)

    def on_llm_end(self, response: Any, **kwargs: Any) -> None:
        # 标记LLM任务完成
        self.task_done = True

    def generate_stream(self):
        # 生成Flask需要的流式响应内容
        while not self.task_done or not self.token_queue.empty():
            token = self.token_queue.get()
            # 包装成SSE(Server-Sent Events)格式,兼容前端流式接收
            yield f'data: {{"stream": "{token}"}}\n\n'.encode("utf-8")

2. 编写Flask流式响应接口

在视图函数中异步执行LLM请求,同时通过Handler的生成器返回流式内容:

from flask import Flask, Response
from langchain.chat_models import ChatOpenAI
import threading
import os

app = Flask(__name__)

# 配置OpenAI API密钥
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

@app.route("/stream-chat")
def stream_chat_response():
    handler = StreamingCallbackHandler()
    # 初始化支持流式的ChatOpenAI实例
    llm = ChatOpenAI(
        streaming=True,
        callbacks=[handler],
        temperature=0.7
    )

    # 异步执行LLM请求,避免阻塞Flask响应生成
    def run_llm():
        llm.predict("请详细介绍LangChain的流式响应机制")

    threading.Thread(target=run_llm).start()

    # 返回流式响应,指定SSE类型的MIME
    return Response(handler.generate_stream(), mimetype="text/event-stream")

if __name__ == "__main__":
    app.run(debug=True, threaded=True)

关键要点说明

  • 用queue.Queue实现线程安全的token传递,因为LLM的流式生成和Flask响应生成在不同线程执行;
  • 采用SSE格式返回内容,这是Web端接收流式响应的标准格式,前端可通过EventSource直接监听;
  • 必须异步启动LLM请求,否则Flask会等待LLM执行完成后才开始返回响应,失去流式效果。

内容的提问来源于stack exchange,提问作者Syed Mujeeb H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 09:13:19