Node.js流式调用AI模型入门 - 从零打造“打字机”效果
作为一名独立开发者或小团队的技术负责人,你是否经历过这样的场景:用户在你的应用中点击“生成”按钮,界面转起了加载圈,一秒、两秒、五秒……用户开始焦躁,甚至怀疑程序卡死,最终愤怒地关闭了页面。
传统的同步请求模式下,AI 生成内容的等待时间往往较长,这对用户体验是极大的伤害。而“流式调用”正是解决这一痛点的良药。它能让文字像打字机一样逐字跳出,用户能直观地看到内容正在生成,心理等待感大幅降低,应用也显得更加智能和流畅。
今天这篇教程,将带你从零开始,掌握 Node.js 环境下的 AI 流式调用技术。我们将使用兼容 OpenAI 接口标准的聚合平台 ThisToken.AI 作为示例,帮助你快速跑通第一段代码。
为什么选择流式调用?
在深入代码之前,我们需要理解为什么流式调用已成为现代 AI 应用的标配。
1. 用户体验的质变
心理学上有一个概念叫“感知延迟”。当用户面对一个静止的加载图标时,每一秒的等待都会增加焦虑。而流式输出通过持续的内容输出,给予用户即时反馈。即便总生成时间没变,用户的主观感受也会是“很快”、“很流畅”。
2. 降低首字延迟
对于长文本生成,同步模式需要等待模型计算完所有内容才能返回。而流式模式在模型生成第一个 Token(字/词)时就开始传输,用户几乎可以立刻看到响应。对于需要快速交互的场景(如聊天机器人、代码助手),这是决定留存率的关键。
准备工作:获取 API Key
在写代码之前,我们需要一把“钥匙”。为了降低开发门槛,我们将使用 ThisToken.AI 提供的统一接口。它兼容 OpenAI 的接口规范,这意味着你不需要学习全新的 SDK,只需修改 base_url 即可调用多种主流模型。
第一步:注册账号
访问 ThisToken.AI 官网。作为开发者,我们通常反感繁琐的注册流程,但该平台的设计相对简洁,只需基础信息即可完成注册。
第二步:创建 API Key
登录控制台后,找到“API 密钥”或“API Key 管理”页面。
点击“创建新密钥”。请注意: API Key 只在创建时显示一次。请务必立即复制并妥善保存,不要将其提交到 GitHub 等公开代码库中,以免造成额度盗用或安全风险。
拿到形如 sk-xxxxxxxxxxxxxx 的密钥后,我们就可以开始编码了。
环境搭建
本教程假设你的本地环境已经安装了 Node.js(建议 v18.0.0 以上版本,原生支持 fetch 和更好的异步处理)。
在你的工作目录下初始化项目:
mkdir ai-streaming-demo
cd ai-streaming-demo
npm init -y接下来,安装官方提供的 OpenAI SDK。虽然我们使用的是 ThisToken.AI 的端点,但由于接口协议兼容,我们可以直接复用这个成熟的库,极大地减少学习成本。
npm install openai此外,为了管理 API Key,建议在项目根目录创建一个 .env 文件(并在 .gitignore 中忽略它),用于存放敏感信息:
# .env 文件内容
THIS_TOKEN_API_KEY=sk-你的真实密钥核心代码:跑通第一段流式调用
现在,重头戏来了。我们将编写一个 Node.js 脚本,实现向 AI 发送指令,并以流式的方式在控制台打印出回答。
创建 index.js 文件,复制以下代码。请注意代码中关于 base_url 的配置,这是连接到 ThisToken.AI 的关键。
// index.js
import OpenAI from 'openai';
import 'dotenv/config'; // 确保已安装 dotenv: npm install dotenv
// 1. 初始化客户端
// 这里我们通过 baseURL 指向 ThisToken.AI 的网关
const client = new OpenAI({
apiKey: process.env.THIS_TOKEN_API_KEY,
baseURL: 'https://api.thistoken.ai/v1', // 核心配置:指向 ThisToken.AI
});
async function runStreamingChat() {
console.log('正在连接 AI 模型...\n');
try {
// 2. 创建流式请求
const stream = await client.chat.completions.create({
model: 'gpt-3.5-turbo', // 模型名称,ThisToken.AI 支持多种模型,可视情况替换
messages: [{ role: 'user', content: '请用生动的语言,写一段关于“独立开发者如何保持专注”的短文,不超过200字。' }],
stream: true, // 关键参数:开启流式输出
});
// 3. 处理流式数据
// 使用 for await...of 循环异步迭代数据块
process.stdout.write('AI 回复: ');
for await (const chunk of stream) {
// chunk.choices[0].delta.content 包含当前生成的文本片段
const content = chunk.choices[0]?.delta?.content || '';
// 如果有内容,直接打印到控制台(不换行)
if (content) {
process.stdout.write(content);
}
}
console.log('\n\n[流式传输结束]');
} catch (error) {
console.error('\n请求出错:', error);
}
}
// 执行函数
runStreamingChat();代码深度解析
让我们拆解一下这段代码,理解它背后的逻辑,这对后续处理更复杂的业务至关重要。
1. 客户端初始化
我们通过 new OpenAI() 实例化了一个客户端。默认情况下,它会连接 OpenAI 的官方服务器。但在这里,我们显式传入了 baseURL: 'https://api.thistoken.ai/v1'。
这就是聚合平台的魅力所在:你不需要重写一套 SDK 逻辑,只需修改域名,流量就会被路由到 ThisToken.AI 的服务网关,进而调用其背后的模型资源。这对于独立开发者来说,意味着极低的技术迁移成本。
2. stream: true 参数
在 chat.completions.create 方法中,我们将 stream 设为 true。这告诉服务端:“不要等全部生成完再给我,生成一点就发给我一点”。
此时,API 返回的不再是一个普通的 JSON 对象,而是一个异步可迭代对象。
3. 异步迭代
for await (const chunk of stream) 是 Node.js 处理流数据的标准写法。
每一个 chunk 都是服务端推送过来的一个小数据包。在 OpenAI 协议中,这个数据包的结构通常是:
{
"choices": [
{
"delta": { "content": "某个字" },
"finish_reason": null
}
]
}delta 意为“增量”,即新增的内容。我们通过 chunk.choices[0]?.delta?.content 提取这个字,并立即通过 process.stdout.write 打印。
4. 为什么用 process.stdout.write 而不是 console.log?
console.log 默认会在输出末尾加一个换行符 \n。如果你用 console.log,你会看到文字像这样垂直排列:
独
立
开
发
者而 process.stdout.write 则是原地追加输出,能实现横向流动的“打字机”视觉效果。
进阶:如何将流式数据推送给前端?
独立开发者往往不仅满足于控制台输出。在实际产品中,你需要将流式数据通过 HTTP 接口推送给前端浏览器。
这里有一个经典的架构模式:Node.js 作为中转层。
前端会向 Node.js 后端发起请求,Node.js 再向 AI 模型发起流式请求,并将收到的数据实时“管道化”地传回前端。
结合 Express 或 Fastify 框架,你可以这样修改:
// 伪代码示例 - 结合 Express
app.get('/api/chat', async (req, res) => {
res.setHeader('Content-Type', 'text/event-stream'); // 设置 SSE 响应头
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const stream = await client.chat.completions.create({...});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
if (content) {
// 将内容推送给前端
res.write(`data: ${JSON.stringify({ text: content })}\n\n`);
}
}
res.end(); // 结束响应
});前端通过 fetch 配合 reader.read() 或使用 EventSource 接口,即可实时渲染这些数据。这种“后端转发”的模式,既能保护你的 API Key 不直接暴露在前端,又能让你在后端做鉴权、计费等逻辑处理。
常见问题与避坑指南
在跑通代码的过程中,新手可能会遇到以下问题,这里提前为你排雷:
- API Key 错误
如果控制台报错 401 Unauthorized,请检查 .env 文件中的 Key 是否正确,或者是否被多余的空格包裹。确保 npm install dotenv 并在代码首行引入。
- 模型名称问题
虽然代码中使用了 gpt-3.5-turbo,但 ThisToken.AI 作为一个聚合平台,支持的模型列表
---
想直接跑通示例?访问 https://api.thistoken.ai/register 注册 ThisToken.AI,获取 API Key 后即可开始。