Node.js如何调用盘古大模型API实现智能对话?

来源:运维教程作者:清原小日向头衔:网络博主
导读:本期聚焦于清原小日向创作的《Node.js如何调用盘古大模型API实现智能对话?》,敬请观看详情。想让Node.js项目接入华为盘古大模型却不知道从哪里下手?本文手把手教你完成整个接入流程。先介绍盘古模型的开放能力与认证方式,带你申请凭证、配置环境变量,再通过axios封装请求方法,实现流式输出和普通响应两种调用模式。文中还给出完整的封装代码,包含错误重试、超时控制、Token自动刷新等实用细节,并演示了如何在Express接口中对外提供对话服务。针对常见的401鉴权失败、响应超时、编码异常等问题也逐一给出排查思路,帮你少走弯路,快速把大模型能力落地到自己的Node.js应用里。

大模型能力开放之后,越来越多的业务场景开始尝试把智能对话嵌入到自己的系统里。华为云的盘古大模型提供了完善的API接口,而Node.js凭借异步IO的优势,天然适合处理这类网络请求密集型的任务。这篇文章就围绕Node.js调用盘古大模型API展开,从准备工作到代码封装,再到实际部署中的常见问题,完整走一遍流程。

Node.js如何调用盘古大模型API实现智能对话?

调用盘古大模型前的准备工作

盘古大模型的API通过华为云的统一网关对外提供服务,调用之前需要先完成两件事:一是开通盘古服务对应的ModelArts或盘古专属入口,二是获取访问凭证。凭证部分推荐使用IAM用户的AK/SK方式,相比固定Token更安全,也便于后续做权限隔离。如果你只是本地调试,也可以先用华为云控制台生成的临时Token快速跑通流程,再切换到AK/SK方案。

拿到AK/SK之后,需要请求IAM的endpoint换取X-Subject-Token,这个Token会放在后续每次请求的Header里。Token默认有效期约24小时,生产环境一定要做缓存和到期前刷新,否则会出现请求到一半突然401的情况。环境变量建议用dotenv统一管理,不要把密钥硬编码进代码仓库。

require('dotenv').config();
const https = require('https');

// 从环境变量读取凭证
const IAM_USER = process.env.IAM_USER;
const IAM_PASSWORD = process.env.IAM_PASSWORD;
const IAM_DOMAIN = process.env.IAM_DOMAIN;

function getToken() {
  return new Promise((resolve, reject) => {
    const body = JSON.stringify({
      auth: {
        identity: {
          methods: ['password'],
          password: {
            user: {
              name: IAM_USER,
              password: IAM_PASSWORD,
              domain: { name: IAM_DOMAIN }
            }
          }
        },
        scope: { project: { name: 'cn-north-4' } }
      }
    });
    const req = https.request({
      host: 'iam.cn-north-4.myhuaweicloud.com',
      path: '/v3/auth/tokens',
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(body)
      }
    }, res => {
      // Token在响应头X-Subject-Token中返回
      resolve(res.headers['x-subject-token']);
    });
    req.on('error', reject);
    req.write(body);
    req.end();
  });
}

这段代码演示了原生https模块获取Token的写法。实际项目里也可以用axios简化,核心点是Token要从响应头里取,而不是响应体,很多初学者在这里卡很久。另外区域名要与你开通服务的区域一致,比如cn-north-4或ap-southeast-3,写错了会直接报endpoint不存在。

封装盘古对话请求并支持流式输出

有了Token之后,就可以向盘古模型的对话补全接口发请求了。请求体主要包含model名称、messages数组以及temperature、max_tokens等参数。messages里每条消息都有role和content两个字段,role支持system、user、assistant三种,多轮对话就是把历史消息按顺序放进数组即可。

const axios = require('axios');

const PANGU_ENDPOINT = 'https://api.modelarts.cn-north-4.myhuaweicloud.com';
let tokenCache = { token: null, expireAt: 0 };

async function ensureToken() {
  // 提前10分钟刷新,避免边界失效
  if (!tokenCache.token || Date.now() > tokenCache.expireAt - 600000) {
    tokenCache.token = await getToken();
    tokenCache.expireAt = Date.now() + 23 * 3600 * 1000;
  }
  return tokenCache.token;
}

async function chat(messages, options = {}) {
  const token = await ensureToken();
  const res = await axios.post(
    PANGU_ENDPOINT + '/v1/infers/pangu-dialogue',
    {
      model: 'pangu-v2',
      messages,
      temperature: options.temperature ?? 0.7,
      max_tokens: options.maxTokens ?? 1024,
      stream: options.stream ?? false
    },
    {
      headers: { 'X-Subject-Token': token },
      timeout: 30000,
      responseType: options.stream ? 'stream' : 'json'
    }
  );
  return res.data;
}

// 流式读取示例
chat(
  [{ role: 'user', content: '用一句话介绍盘古大模型' }],
  { stream: true }
).then(stream => {
  stream.on('data', chunk => {
    const text = chunk.toString('utf-8');
    // SSE格式,按行解析data字段
    text.split('\n').filter(l => l.startsWith('data:')).forEach(l => {
      console.log(JSON.parse(l.slice(5)).choices[0].delta.content);
    });
  });
});

封装里有两个细节值得注意。第一是ensureToken做了缓存和提前刷新,避免每次请求都去换Token,IAM接口有频率限制,频繁调用可能被限流。第二是流式模式下responseType要设为stream,返回的是可读流,需要按照SSE协议逐行解析,每个data字段里包含一小段增量内容,拼接起来才是完整回答。

错误处理方面,建议给axios加一个响应拦截器,针对401自动清空Token缓存并重试一次,针对429做指数退避。盘古接口偶发的502一般是网关抖动,重试基本都能恢复,但要注意流式请求一旦已经开始输出就不能盲目重试,否则前端会收到重复内容。

在Express中对外提供对话服务

封装好底层调用后,通常还需要把它包装成HTTP接口给前端使用。下面是一个简单的Express示例,同时演示普通接口和SSE推送两种形态。前端如果直接消费EventSource,用SSE方式体验更好,用户不用等整个回答生成完才看到内容。

const express = require('express');
const app = express();
app.use(express.json());

app.post('/api/chat', async (req, res) => {
  try {
    const data = await chat(req.body.messages, { stream: false });
    res.json({ code: 0, data });
  } catch (e) {
    res.status(500).json({ code: 1, msg: e.message });
  }
});

// SSE流式接口
app.get('/api/chat/stream', async (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  const stream = await chat(
    [{ role: 'user', content: req.query.q }],
    { stream: true }
  );
  stream.on('data', chunk => {
    res.write(chunk.toString('utf-8'));
  });
  stream.on('end', () => res.end());
  // 客户端断开时及时销毁上游流
  req.on('close', () => stream.destroy());
});

app.listen(3000, () => console.log('服务已启动在3000端口'));

这个服务里最容易忽略的一点是连接清理:浏览器关闭页面会触发req的close事件,此时必须销毁上游流,否则请求会一直挂着占用资源,高并发下可能把Node.js的内存和句柄耗尽。另外SSE响应头里的三个字段缺一不可,尤其是Connection: keep-alive,少写可能导致经过Nginx代理时被缓冲,前端收不到实时数据。

部署时如果前面有Nginx反代,记得关闭代理缓冲:proxy_buffering off,否则流式输出会退化成一次性输出。生产环境还建议给对话接口加上限流和内容长度校验,防止恶意请求把Token额度刷爆。到这里,从鉴权、封装到服务化的完整链路就打通了,你可以在这个骨架上继续扩展上下文管理、敏感词过滤和多模型路由等能力,把盘古大模型真正融合进自己的业务体系。

Node.js盘古大模型API调用修改时间:2026-09-10 11:23:08

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0910/53987.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。