OpenAI流式解析

OpenAI 流式的代码:

首选一般请使用os.getenv 去读环境变量的内容

注意使用pip install python-dotenv 的安装方法

load_dotenv 是这个库提供的一个函数,用于读取 .env 文件并将其中定义的键值对设置为系统的环境变量。

默认情况下,load_dotenv() 会自动查找当前目录下的 .env 文件。如果文件不在默认路径,可以通过参数指定,例如 load_dotenv('/path/to/.env')。

为什么代码里用 dotenv 而不是 python_dotenv?

在 Python 中,导入模块时使用的是库的模块名,而不是 PyPI 上的包名。python-dotenv 这个包安装后,提供了一个名为 dotenv 的模块供导入。这是由库开发者决定的命名约定。例如:

  • PyPI 包名:python-dotenv
  • 导入时的模块名:dotenv

流式代码 类 (一键运行)

jsx 复制代码
from openai import  AsyncOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

class AsyncOpenAIOut:
    def __init__(self):
        self.api_key = os.getenv("OPENAI_API_KEY")
        self.base_url = os.getenv("OPENAI_BASE_URL")
        self.oai_client = AsyncOpenAI(api_key=self.api_key, base_url=self.base_url)
        self.model = os.getenv("OPENAI_MODEL")
    async def gpt_stream(self, user_message: str,model: str = os.getenv("OPENAI_MODEL"),history: list[dict] = [],system_prompt: str = "") :
        messages = []
        if history:
            messages.extend(history)
        
        if system_prompt:
            messages.extend([{"role": "system", "content": system_prompt}])
        
        messages.append({"role": "user", "content": user_message})
        response = await self.oai_client.chat.completions.create(
            model=model,
            messages=messages,
            stream=True
        )
        
        async for chunk in response:
            if chunk.choices[0].delta.content:
                yield chunk.choices[0].delta.content

async_openai_out = AsyncOpenAIOut()

if __name__ == "__main__":
    async def test_gpt_stream():
        async for chunk in async_openai_out.gpt_stream(user_message="写300字作文",system_prompt="You are a helpful assistant."):
            print(chunk)

    import asyncio
    
    asyncio.run(test_gpt_stream())

这里面有几点需要注意:

简短回答 :print(chunk) 是 同步操作会在当前事件循环中执行完毕后才继续但它不是 I/O 密集型操作,所以不会造成实际的"阻塞"问题,特别是在异步函数中逐步输出内容的场景下,它是可接受的。

想确保异步非阻塞输出:

python 复制代码
        async for chunk in async_openai_out.gpt_stream(user_message="写300字作文",system_prompt="You are a helpful assistant."):
            # print(chunk)
            await asyncio.to_thread(print, chunk)  # 在后台线程执行 print

异步生成器(Async Generator) 的用法,结合了 Python 的异步编程(async for)和生成器(yield)机制。

在异步迭代 response 中的每个 chunk,如果它有内容,就通过 yield 一块一块地"流式返回"。

python 复制代码
async for chunk in response:
    if chunk.choices[0].delta.content:
        yield chunk.choices[0].delta.content

对比for : 普通for是同步迭代

async for是异步迭代,比如网络流、WebSocket、OpenAI 的 Stream 响应等。

yield 是生成器的关键,它不是"返回"值,而是"产出"值(可以被迭代一次)。

相关推荐
华玥作者11 小时前
[特殊字符] VitePress 对接 Algolia AI 问答(DocSearch + AI Search)完整实战(下)
前端·人工智能·ai
好家伙VCC13 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
前端玖耀里14 小时前
如何使用python的boto库和SES发送电子邮件?
python
serve the people14 小时前
python环境搭建 (十二) pydantic和pydantic-settings类型验证与解析
java·网络·python
小天源14 小时前
Error 1053 Error 1067 服务“启动后立即停止” Java / Python 程序无法后台运行 windows nssm注册器下载与报错处理
开发语言·windows·python·nssm·error 1053·error 1067
喵手14 小时前
Python爬虫实战:HTTP缓存系统深度实战 — ETag、Last-Modified与requests-cache完全指南(附SQLite持久化存储)!
爬虫·python·爬虫实战·http缓存·etag·零基础python爬虫教学·requests-cache
喵手14 小时前
Python爬虫实战:容器化与定时调度实战 - Docker + Cron + 日志轮转 + 失败重试完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·容器化·零基础python爬虫教学·csv导出·定时调度
2601_9491465315 小时前
Python语音通知接口接入教程:开发者快速集成AI语音API的脚本实现
人工智能·python·语音识别
寻梦csdn15 小时前
pycharm+miniconda兼容问题
ide·python·pycharm·conda
冰糖猕猴桃16 小时前
【AI】把“大杂烩抽取”拆成多步推理:一个从单提示到多阶段管线的实践案例
大数据·人工智能·ai·提示词·多步推理