本文主要介绍如何使用 openai sdk,如何调用第三方deepseek,通义千问等服务,以及如何在浏览器端处理流式响应,这是打造自己的聊天助手的基础,本文使用的版本是js版本,部分代码需要在nodejs环境运行。
openai sdk 是 OpenAI 官方提供的一套软件开发工具包,目的是简化与 OpenAI API 的交互流程。通过这个 SDK,开发者可以用熟悉的编程语言(例如 Python、Node.js 等)方便地调用 OpenAI 的各项服务,如自然语言处理、文本生成、图像生成等。SDK 封装了底层的 HTTP 请求,提供了更友好的接口和错误处理机制,帮助开发者快速构建基于 AI 的应用程序,同时也支持异步操作、自动重试等高级功能。
我们使用npm进行安装 openai 库。
npm install openai
import OpenAI from "openai"; const client = new OpenAI(); const completion = await client.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: "写一个关于独角兽的一句话睡前故事。", }], }); console.log(completion.choices[0].message.content);
const client = new OpenAI();
生成一个 OpenAI 实例,该函数可以传入其他参数,如apiKey、baseURL等。
model: "gpt-4o"
指定使用的语言模型,如o1,o3-mini等,具体要根据平台的模型定义。
messages 参数
这个参数是一个数组,用来传递对话上下文。数组中的每个对象都代表一条消息,每条消息都包含两个关键字段:
role
表示消息的角色。常见的角色有 "user"(用户)、"assistant"(助手)和 "system"(系统),用于区分消息来源和用途。
content
消息的具体文本内容。在此示例中,用户请求生成“一句关于独角兽的睡前故事”,这就是 AI 需要根据指令生成内容的依据。
deepseek 官方开放平台:https://platform.deepseek.com/
你可以在deepseek开放平台申请apikey,或者其他的平台,如阿里云或者kimi等。
const handleTestOpenai =async () => { const openai = new OpenAI({ apiKey: 'sk--------', // 第三方平台的apikey,这里用的deepseek baseURL: 'https://api.deepseek.com/v1', // 第三方接口api地址 }); const response = await openai.chat.completions.create({ model: "deepseek-chat", messages: [{ role: "user", content: "Hello, world!" }], stream: fale, // 控制是否流式响应 }); console.log(response); }
注意,以上代码建议在nodejs环境中运行,在浏览器环境里运行会报错,这是出于安全考虑。 如果配置正确,响应将如下图所示:
因为上面的代码需要在nodejs端运行,实际应用中需要对客户端暴露一个接口服务,下面的接口使用nestjs来处理。
@Post('chat/stream') async streamChat( @Res() response: Response, @Body() body: StreamChatRequestDto, ) { const promptTemplate = body?.promptTemplate || 'default'; const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: 'system', content: PromptsTemplate[promptTemplate] }, ...(body?.messages || []), ]; try { response.setHeader('Content-Type', 'text/event-stream'); response.setHeader('Cache-Control', 'no-cache'); response.setHeader('Connection', 'keep-alive'); const stream = await this.openaiService.createChatCompletionStream(messages); for await (const chunk of stream) { const content = chunk || ''; if (content) { response.write(`data: ${JSON.stringify({ content })}\n\n`); } } response.end(); } catch (error) { console.error('Stream error:', error); response.status(500).json({ error: 'Stream processing failed' }); } }
核心代码解析:
response.setHeader
,这段代码用于设置 HTTP 响应头,主要用于实现 Server-Sent Events (SSE) 流式通信。
Content-Type: text/event-stream
这告诉客户端响应的内容是一个事件流。客户端(通常是浏览器)会将响应解析为持续不断的数据流,从而可以实时接收服务器发送的事件数据。
Cache-Control: no-cache
此设置确保客户端和中间代理服务器不会缓存响应数据,保证客户端每次都能接收到最新的事件数据,而不是缓存的数据。
Connection: keep-alive
这要求客户端保持连接不断开,从而支持长连接。在 SSE 中,服务器会持续不断地发送数据,保持连接处于活跃状态是非常必要的。
因为服务器返回的是流式 HTTP 响应,所以需要使用 Fetch API 读取响应体的流数据。示例代码如下:
async function readStream(url) { try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, // 将 messages 参数序列化后作为请求体发送 body: JSON.stringify({ messages , model: "deepseek-chat"}), }); if (!response.ok) { throw new Error(`HTTP 错误! 状态: ${response.status}`); } const reader = response.body.getReader(); const decoder = new TextDecoder('utf-8'); let result = ''; while (true) { const { done, value } = await reader.read(); if (done) { console.log('数据读取完毕'); break; } // 使用 streaming 选项以正确处理多字节字符 const chunk = decoder.decode(value, { stream: true }); result += chunk; console.log('接收到数据块:', chunk); } } catch (error) { console.error('Fetch 错误:', error); } } readStream('http://localhost:3030/openai/chat/stream');
以上就是基础的服务端调用openai接口和前端处理流式响应的代码,在实际开发中可能需要调整参数和读取的参数,服务端示例代码地址:https://github.com/HelTi/ai-chat-services