用 Node.js 调用 OpenAI LLM:从入门到歌词创作实战

226 阅读6分钟

用 Node.js 调用 OpenAI LLM:从入门到歌词创作实战

引言

近年来,生成式 AI(AIGC)迅速进入工程和创作实践,OpenAI 的大语言模型(LLM)和对应 SDK 成为事实标准。对后端工程师来说,使用 Node.js 调用 OpenAI 的 LLM,是把「强大模型能力」快速接入产品的常规路径。下面将系统讲解如何用 Node.js 初始化项目、安装并使用 OpenAI SDK,逐行解释示例代码,并给出 Prompt 设计和调试的实战建议,最后以“为汪峰写一首歌词”的例子,讲解从 Prompt 到输出的全过程。

一、为什么选 Node.js 作为后端

Node.js 以轻量、事件驱动著称,适合 IO 密集型后端服务。对中小型项目或原型验证(POC)尤其友好:启动快、生态丰富(npm),并能与前端共享部分 JS 代码风格。将 LLM 接入到 Node 服务,可以把「文本生成、对话、代码补全、创意创作」等能力封装成 API,为前端或其它服务消费。

二、初始化后端项目与安装 SDK

  1. 在项目目录运行 npm init -y,生成 package.json。
  2. 安装 SDK :npm i openai@4.71.0
  3. 安装dotenv:npm i dotenv
  4. 在项目根目录创建 .env,放入 OPENAI_API_KEY=your_api_key(注意:不要将 .env 提交到版本库,使用 .gitignore 忽略)。

.env 的用途是把凭据从代码中分离出来,安全性更高,也是生产常见做法。

三、实例代码与逐行解释

import OpenAI from 'openai';
import dotenv from 'dotenv';
dotenv.config();

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: 'https://api.***.ai/v1',  // 示例:可替换为真实 baseURL
});

async function generateLyrics() {
  const response = await client.completions.create({
    model: 'gpt-3.5-turbo-instruct',
    max_tokens: 256,
    prompt: `
      假如你是林夕这样的爱情歌曲作词大家,
      请你写一首100字,为汪峰,写一首他爱上森林北的歌曲。
      森林北是一位美丽,勇敢,会骑马的女孩儿。
    `
  });

  const result = response.choices[0].text;
  console.log('歌词是:' + result);
}

generateLyrics().catch(console.error);

逐行解释:

  • dotenv.config():加载 .env 中的环境变量到 process.env,这样 OPENAI_API_KEY 不会写死在代码中。
  • new OpenAI({...}):实例化客户端。apiKeybaseURL(如果使用代理或私有托管)是必须配置的。
  • client.completions.create({...}):调用 completion 接口,这里指定 modelgpt-3.5-turbo-instruct(你笔记中的模型)。
  • max_tokens:限制返回的 token 数量,影响输出长度与费用。
  • prompt:向模型描述任务。Prompt 的质量直接决定输出质量。
  • response.choices[0].text:读取第一个返回选项的文本结果(传统 Completions API 的返回结构)。

四、Prompt 设计(核心技巧)

Prompt 设计决定了模型输出的方向、风格和可控性。实战建议如下:

  1. 明确身份与风格:在 Prompt 开头给模型一个身份(例如“假如你是林夕这样的作词人”),能显著改变文本风格。
  2. 限制长度与结构:例如明确要求“写一首100字的歌词”或“写四节,每节两行”,这样模型更可能按预期输出。
  3. 提供上下文细节:描述对象(森林北:美丽、勇敢、会骑马)会让模型写出更具象的细节,避免泛泛而谈。
  4. 用例子示范:如果期望某种韵律或押韵,可以先给一两句样例,模型会模仿。
  5. 分步提示(Chain-of-Thought 风格) :复杂任务可先让模型列提纲,再逐步扩展为完整文本。例如:先请求“给出主题与关键意象”,然后请求“根据意象生成歌词”。

五、从 Prompt 到可控输出的实战技巧

  • 多尝试、调参:修改 max_tokens、尝试改变描述详尽度以及添加“不可做”的限制(如“不要出现现代电子设备”)。
  • temperature / top_p(如果可用) :调节生成随机性。较低 temperature(如 0.2)会更保守;较高(如 0.8)更有创造力。
  • 批量生成多个候选:一次性请求多条输出(参数 n 或多次调用),并在应用层选择最满意版本。
  • 后处理(去重/格式化) :生成后可以做正则清理、分行、去掉多余空白或重复段落。

六、实战示例:改良 Prompt 与输出展示

可以把原始 Prompt 做一点改良,使模型生成更贴近“汪峰风格 + 林夕式细腻”的歌词:

示例 Prompt(改良版):

你是林夕风格的资深作词人,要为歌手汪峰写一首歌词(100字左右),主题是“他爱上了森林北”。风格要真挚、有力量、带一点沙哑的城市孤独感;句子要有比喻和动词画面感,不要提及具体年份或现代科技。请输出四行,每行尽量押韵。

这样的 Prompt 会更明确:指定行数、情感基调、避免现代元素、并要求押韵。模型据此往往能给出更合适的成品。

七、对比:Completions vs Chat(实务选择)

  • Completions(示例中的 create) :传统一次性生成,适合单项文本输出(摘要、短文、歌词)。有时候更简单直接。
  • Chat(对话式接口) :在需要多轮交互、上下文管理或系统级指令(system prompt)时更强。对于复杂 Prompt 分步执行、带上下文的创作,chat 更方便管理角色(system/user/assistant)。
    实务上:若只是“生成一句歌词”,completions 足够;若是“把用户的修改意见融入并反复润色”,chat 会更便捷。

八、常见误区与安全注意

  1. 密钥泄露:不要把 API Key 写入公共仓库,.env 文件列入 .gitignore
  2. 费用控制:测试时注意 max_tokens 和调用频率,避免意外费用。
  3. 输出合规:若生成内容涉及版权、名人肖像或敏感话题,审查与合规是必须的(产品上线前做人工/自动审查)。
  4. 模型一致性:不同模型、不同时间点的表现会有差异。线上服务需要设计回退策略和版本控制(例如把 prompt 和模型版本记录在日志中,便于复现)。

九、进阶用法与工程化建议

  • 缓存与重用:对常见 Prompt 的优秀结果可以缓存,降低重复调用成本。
  • Prompt 模板化:把 Prompt 做成可替换模版(例如使用 Mustache / template string),利于 A/B 测试不同语气或长度。
  • 流水线创作:把写作拆成几个阶段:构思 → 提纲 → 初稿 → 润色 → 押韵调整。每一步都用模型不同的 Prompt,能提高质量与可控性。
  • 用户可编辑的交互式创作:前端允许用户调整“情绪强度”“押韵偏好”等参数,后端根据这些选项动态修改 Prompt。

十、结论

通过 Node.js 与 OpenAI SDK 把 LLM 接入后端非常直接,但要获得稳定、高质量输出需要把工程化(密钥管理、费用控制、Prompt 模板化、输出审查)与创作技巧(明确风格、分步提示)结合。以“为汪峰写给森林北的歌”为例:清晰、细节充足的 Prompt 能大幅提升创作效率;分步生成(先列意象再写歌词)则更利于反复迭代与人机协作。