Python实现大模型流式调用

构建高效对话接口

现代AI应用中,大型语言模型(LLM)的流式调用已成为提升用户体验的关键技术。本文将介绍如何使用Python实现大模型的流式调用,按照Token流式返回。

什么是流式调用?

流式调用(Streaming)是指服务器在处理请求时,可以逐步返回部分结果,而不需要等待整个处理完成。对于大模型响应来说,用户可以实时看到模型生成的文本,而不是等待全部内容生成完毕。

技术实现

FastAPI后端实现

使用FastAPI框架来构建流式调用的API接口:

路由编写

from fastapi import FastAPI
from sse_starlette.sse import EventSourceResponse
app = FastAPI()

@app.post("/llm_chat", description="通用")
def llm_chat(
    request: Request,
    question: str
):
    res = get_llm_response(question)
    return EventSourceResponse(res)

这里的关键点:

  1. 使用FastAPI()创建路由

  2. 定义POST接口/llm_chat/

  3. 使用EventSourceResponse返回Server-Sent Events(SSE)格式的响应

流式响应处理

import json
from sse_starlette.sse import ServerSentEvent

def get_llm_response(question):
    try:
        answer = ""
        for chunk in call_llm_chat_streaming_api(conversation_history):
            if chunk and '[DONE]' not in chunk:
                chunk = chunk[len("data: "):]
                data = json.loads(chunk)
                content = data["choices"][0]['delta']['content']
                answer += content
                yield ServerSentEvent(json.dumps({"data": {"answer": content}}, ensure_ascii=False), event="message")
    except Exception as e:
        raise HTTPException(status_code=500, detail="Internal Server Error")
  1. 初始化空字符串answer用于累积完整回答

  2. 遍历流式API返回的数据块

  3. 过滤结束标记[DONE]

  4. 解析JSON格式的响应数据

  5. 提取模型生成的内容片段

  6. 使用ServerSentEvent封装并返回每个内容片段

大模型API调用

def call_llm_chat_streaming_api(messages: list, url=LLM_URL, llm_model_name=LLM_MODEL_NAME, api_key=API_KEY):
    headers = {                
        'Accept': 'application/json, text/plain, */*',
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    payload = json.dumps({
        "model": f"{llm_model_name}",
        "messages": messages,
        "stream": True
    }, ensure_ascii=False)
    with requests.post(url, headers=headers, data=payload.encode("utf-8"), stream=True) as response:
        for chunk in response.iter_content(chunk_size=None):
            if chunk:
                yield chunk.decode("utf-8")

关键点:

  1. 设置必要的请求头,包括认证信息

  2. 构建请求体,特别注意"stream": True参数

  3. 使用requests.poststream=True参数启用流式请求

  4. 使用iter_content逐块读取响应内容

  5. 解码并返回每个数据块

前端对接

前端可以使用EventSource API来接收流式响应:

注意事项

有可能不同大模型解析chunk的方式不同,本文以deepseek为例,其他可以根据返回的chunk内容来解析。

你可能感兴趣的:(python)