5分钟搞定:Node.js调用大模型API的工程化实战(附代码)

0 阅读7分钟

AI 应用开发已经不再是算法工程师的专属。作为一名前端或 Node 开发者,通过几行代码就能调用大模型 API,快速构建属于自己的 AI 工具。但很多刚入门的同学会遇到几个痛点:

  • API Key 直接写死在代码里,不小心提交到 GitHub 导致泄露
  • 不知道如何管理环境变量
  • 搞不清异步和同步,代码执行顺序一团糟
  • 模块化方案混乱(CommonJS vs ES Module)

本文将从零开始,带你搭建一个工程化的 Node.js 项目,安全调用大模型 API(以 DeepSeek 为例,兼容 OpenAI),并解释每个环节背后的原理。读完你就能独立写出干净、安全、可维护的 AI 调用代码。

一、项目初始化

首先创建一个新目录,并在终端进入:

mkdir ai-caller
cd ai-caller

执行初始化命令,生成 package.json

npm init -y

参数 -y 表示使用默认配置,快速生成。

1.1 为什么要 init -y

  • package.json 是 Node.js 项目的“身份证”,记录了项目名称、依赖、脚本等信息。
  • 后续安装的第三方包(如 openaidotenv)会被记录在这个文件中,方便别人克隆你的项目后快速还原环境。

二、保护 API Key:.gitignore + .env

你从大模型平台(如 DeepSeek、OpenAI)获取的 API Key 是一串敏感字符,绝不能提交到 Git 仓库。正确的做法是:

  1. 在项目根目录创建 .env 文件,写入 key 和接口地址
  2. 创建 .gitignore 文件,把 .env 忽略掉

2.1 创建 .env 文件

# .env
DEEPSEEK_API_KEY=sk-你的真实密钥
DEEPSEEK_BASE_URL=https://api.deepseek.com

注意.env 文件中的变量名通常用大写字母加下划线,值直接写,不要加引号(除非值本身包含空格)。

2.2 创建 .gitignore

# .gitignore
node_modules/
.env

这样执行 git add . 时,.env 和 node_modules 就不会被暂存。

2.3 名词解析:什么是 process.env

  • process 是 Node.js 的全局对象,代表当前正在运行的进程。
  • process.env 是一个对象,包含了操作系统的环境变量(比如 PATHHOME)。
  • 我们用 dotenv 库把 .env 文件中的键值对注入到 process.env 中,这样代码里就能通过 process.env.DEEPSEEK_API_KEY 读取到密钥。

三、安装依赖

安装两个核心库:openai 和 dotenv

npm install openai dotenv

3.1 可选:使用 pnpm 加速

pnpm 是一个比 npm 更快的包管理器,它通过硬链接的方式在全局存储一次依赖,不同项目之间共享,节省磁盘空间。

npm install -g pnpm   # 全局安装 pnpm
pnpm add openai dotenv

后续用法和 npm 基本一致。

3.2 名词解析:什么是 openai 库?

这个库是 OpenAI 官方提供的 SDK,封装了对 https://api.openai.com/v1/chat/completions 等接口的调用。
而且它支持自定义 baseURL,所以我们可以用它来调用任何兼容 OpenAI 格式的 API(比如 DeepSeek、智谱、通义千问等)。


四、编写代码(ES Module 风格)

Node.js 有多种模块化方案,这里我们使用现代化的 ES Module(即 import/export 语法)。

有两种方式启用 ES Module:

  • 文件后缀使用 .mjs
  • 或者在 package.json 中设置 "type": "module"

本文采用第一种 .mjs 后缀,更直观。

4.1 创建 index.mjs

// index.mjs
import dotenv from 'dotenv';
import { OpenAI } from 'openai';

// 加载 .env 文件到 process.env
dotenv.config();

// 实例化 OpenAI 客户端(实际指向 DeepSeek)
const client = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: process.env.DEEPSEEK_BASE_URL,
});

// 主函数:异步调用大模型
const main = async () => {
  console.log('🚀 程序开始运行...');

  // 调用聊天补全 API
  const completion = await client.chat.completions.create({
    model: 'deepseek-chat',
    messages: [
      { role: 'user', content: '请用一句话介绍什么是大模型' }
    ],
  });

  // 取出回复内容并打印
  const reply = completion.choices[0].message.content;
  console.log('🤖 AI 回复:', reply);

  console.log('✅ 程序结束');
};

// 执行主函数
main();

4.2 代码逐行解释

  • import dotenv from 'dotenv' :导入 dotenv 库。

  • dotenv.config() :读取根目录下的 .env 文件,把键值对注入 process.env

  • new OpenAI({ apiKey, baseURL }) :创建客户端实例。如果不填 baseURL,默认指向 OpenAI 官方地址。

  • async function main() :定义异步主函数。

  • await client.chat.completions.create(...)

    • create 方法会发起 HTTP 请求,并返回一个 Promise(承诺对象)。
    • await 关键字会暂停当前 async 函数的执行,直到 Promise 完成(拿到结果)。
    • 这样就能保证先拿到回复,再执行后面的打印。
  • completion.choices[0].message.content:标准 OpenAI 响应结构中,回复内容就在这个路径下。

4.3 为什么需要用 async/await

JavaScript 代码的执行顺序并不总是和书写顺序一致。像 API 请求、文件读取、定时器这类操作属于异步任务,它们不会阻塞后面的代码。如果你这样写:

// ❌ 错误示范
let result = client.chat.completions.create(...); // 这是一个 Promise 对象,不是真正的回复
console.log(result);   // 打印出 Promise { <pending> }

await 的作用就是“等一下”,等异步任务完成后再继续。它是处理异步代码最优雅的方式(替代了早期的回调地狱和 .then() 链式调用)。


五、运行项目

使用 Node.js 直接执行 .mjs 文件:

node index.mjs

如果你希望代码文件修改后自动重启(开发时很方便),可以安装 nodemon

npm install -g nodemon
nodemon index.mjs

你应该会看到类似输出:

🚀 程序开始运行...
🤖 AI 回复: 大模型是指通过海量数据训练得到的、包含巨大参数量(通常在十亿级以上)的深度学习模型,能够理解和生成自然语言、图像等多种内容。
✅ 程序结束

六、工程化要点总结

步骤作用关键点
npm init -y初始化项目,生成 package.json记录依赖与脚本
.gitignore防止密钥和依赖被提交必须包含 node_modules/ 和 .env
.env + dotenv安全存储 API Key不要硬编码,用 process.env 读取
openai SDK统一调用接口支持自定义 baseURL,兼容多种模型
ES Module (.mjs)现代化模块语法import/export 比 require 更简洁
async/await控制异步流程只有 await 才能拿到真实 API 返回

七、扩展:如何处理更长的对话?

大模型 API 是无状态的,每次请求需要把历史消息一起传过去。例如实现多轮对话:

const messages = [
  { role: 'system', content: '你是一个乐观的助手' },
  { role: 'user', content: '今天天气不好' },
];

// 调用 API
const completion = await client.chat.completions.create({
  model: 'deepseek-chat',
  messages: messages,
});

// 把 AI 回复追加到历史
messages.push(completion.choices[0].message);
messages.push({ role: 'user', content: '那该怎么办?' });

// 再次调用...

实际开发中,你可以将 messages 数组存储在变量或数据库中,实现真正的会话管理。


八、常见问题与解答

Q1:为什么我的 console.log(process.env) 看不到自定义变量?
A:确保已经执行了 dotenv.config(),并且 .env 文件和 index.mjs 在同一级目录。

Q2:await 能拦住 setTimeout 吗?
A:不能。await 只等待 PromisesetTimeout 是基于回调的宏任务,不会被 await 阻塞。需要把定时器包装成 Promise 才行。

Q3:我用的不是 DeepSeek,是 OpenAI 怎么办?
A:只需修改 .env 中的 BASE_URL 为官方地址(可以不写,默认就是 OpenAI),API_KEY 换成你的 OpenAI Key。模型名改成 gpt-3.5-turbo 或 gpt-4

Q4:代码报错 SyntaxError: Cannot use import statement outside a module
A:说明 Node.js 没有识别你的文件为 ES 模块。解决方法:

  • 将文件后缀改为 .mjs,或者
  • 在 package.json 中添加 "type": "module"

结语

现在你已经掌握了一套完整的 AIGC 后端工程化开发流程

  • 安全配置与读取 API Key
  • 使用现代化 ES Module 编写代码
  • 利用 async/await 优雅处理异步
  • 轻松调用任何兼容 OpenAI 格式的大模型 API

接下来你可以尝试:

  • 搭建一个简单的命令行对话机器人
  • 接入微信公众号或飞书机器人
  • 将 AI 回复存储到数据库

记住:好的工程习惯(密钥隔离、模块清晰、异步正确)会让你的 AI 项目跑得更稳、更安全。

如果你觉得这篇文章有帮助,欢迎点赞、收藏、转发~ 有问题可以在评论区留言,我会尽力解答。


本文示例代码已整理,你可以直接复制使用。只需要去 DeepSeek 平台 或 OpenAI 注册获取免费 API Key 即可。