导读:本期聚焦于剑客创作的《如何使用Node.js调用天工Skywork大模型API构建智能应用?》,敬请观看详情。天工Skywork是昆仑万维推出的大语言模型系列,具备强大的中文理解和生成能力,同时提供开放友好的API接口。想在Node.js项目中快速接入天工模型却不知道从哪里入手?本文从API申请、环境搭建讲起,详细演示如何用原生fetch和官方兼容OpenAI格式的接口完成流式对话,涵盖对话历史管理、超时重试、错误处理、流式输出解析等核心环节,并对比不同调用方式的性能差异,最后给出封装成可复用服务模块的完整思路,帮助开发者在实际项目中稳定高效地使用天工模型能力。

天工Skywork是昆仑万维自主研发的大语言模型系列,凭借出色的中文语义理解、代码生成和推理能力,已经成为国内开发者常用的模型选择之一。天工官方提供了兼容OpenAI风格的HTTP接口,这意味着任何能够发送HTTP请求的编程语言都可以直接调用它,Node.js自然也不例外。本文将完整讲解如何在Node.js环境下接入天工Skywork模型,从最基础的接口调用,到流式输出、会话管理,再到封装可复用的服务模块,一步一步带你落地。

如何使用Node.js调用天工Skywork大模型API构建智能应用?

一、准备工作:获取API Key并搭建环境

调用天工模型的第一步是前往天工开放平台注册账号并创建API Key。创建完成后会得到一个以sk-开头的密钥字符串,这个密钥用于请求头中的身份验证,请妥善保管,切勿硬编码到代码仓库中。

天工模型的接口地址与OpenAI兼容,基础端点为https://api.tyqw.cloud.cn/open/compatible-mode/v1(以官方文档最新地址为准)。请求方式为POST,路径为/chat/completions,请求体采用JSON格式。由于Node.js 18以上版本原生内置了fetch,本文示例全部使用原生方式实现,无需引入任何第三方依赖。

建议在项目根目录创建.env文件存放密钥,并通过process.env读取,这样即使代码上传到Git仓库也不会泄露密钥。如果你的Node.js版本低于18,可以先升级,或者使用axiosnode-fetch等库替代,调用逻辑完全一致。

二、基础调用:完成第一次对话请求

先从最简单的非流式调用开始。下面的代码演示了如何向天工模型发送一条用户消息并获取回复,请求头中需要设置AuthorizationContent-Type两个字段。

const API_KEY = process.env.SKYWORK_API_KEY;
const BASE_URL = 'https://api.tyqw.cloud.cn/open/compatible-mode/v1';

async function chat(prompt) {
  const response = await fetch(`${BASE_URL}/chat/completions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'skywork-plus',
      messages: [
        { role: 'user', content: prompt }
      ],
      temperature: 0.7,
      max_tokens: 1024
    })
  });

  if (!response.ok) {
    throw new Error(`请求失败: ${response.status} ${await response.text()}`);
  }

  const data = await response.json();
  return data.choices[0].message.content;
}

chat('用一句话解释什么是事件循环').then(console.log);

返回的JSON中,choices数组的第一项包含完整的回复内容,usage字段记录了本次消耗的token数量。参数方面,model可以按需选择skywork系列的不同版本,temperature控制输出随机性,数值越低回答越确定,max_tokens限制回复长度上限。

需要特别注意错误处理。网络波动、密钥失效、请求频率超限都会导致非200状态码返回,上面的代码通过response.ok做了统一拦截,实际项目中建议进一步区分401(密钥错误)、429(限流)和500(服务端异常),分别采取不同的重试策略。

三、流式输出:实现打字机效果的对话体验

非流式调用需要等待模型生成完整回复后才返回,用户等待时间较长。将stream参数设为true后,接口会以SSE(Server-Sent Events)格式逐块推送内容,前端可以实现打字机效果,体验明显更好。

Node.js中处理SSE流需要读取response.body这个ReadableStream。下面的代码用异步迭代的方式逐行解析数据,每收到一个data:块就取出增量文本并打印:

async function chatStream(prompt) {
  const response = await fetch(`${BASE_URL}/chat/completions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'skywork-plus',
      messages: [{ role: 'user', content: prompt }],
      stream: true
    })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder('utf-8');
  let fullText = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    const chunk = decoder.decode(value, { stream: true });
    // SSE数据以行为单位,按行拆分解析
    for (const line of chunk.split('\n')) {
      if (!line.startsWith('data:')) continue;
      const payload = line.slice(5).trim();
      if (payload === '[DONE]') continue;
      try {
        const json = JSON.parse(payload);
        const delta = json.choices?.[0]?.delta?.content || '';
        fullText += delta;
        process.stdout.write(delta);
      } catch (e) {
        // 忽略不完整的JSON片段
      }
    }
  }
  return fullText;
}

chatStream('写一首关于程序员的短诗');

这里有两个容易被忽略的细节。第一,网络传输的分块边界不一定刚好对齐SSE行边界,一个chunk可能包含半行数据,严格来说需要维护缓冲区拼接不完整的行;第二,流结束时服务端会发送data: [DONE]标记,解析时要跳过它。处理好这两点,流式调用就非常稳定了。

四、封装可复用的服务模块

直接在业务代码里写fetch调用会导致逻辑分散、难以维护。推荐封装一个独立的Skywork客户端类,统一处理鉴权、超时、重试和会话历史,业务层只需关心消息本身。

class SkyworkClient {
  constructor(apiKey, model = 'skywork-plus') {
    this.apiKey = apiKey;
    this.model = model;
    this.baseUrl = 'https://api.tyqw.cloud.cn/open/compatible-mode/v1';
  }

  // 带重试的请求封装
  async request(body, retries = 3) {
    for (let i = 0; i < retries; i++) {
      const controller = new AbortController();
      const timer = setTimeout(() => controller.abort(), 60000);
      try {
        const res = await fetch(`${this.baseUrl}/chat/completions`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(body),
          signal: controller.signal
        });
        clearTimeout(timer);
        if (res.status === 429) {
          await new Promise(r => setTimeout(r, 1000 * (i + 1)));
          continue; // 限流时退避重试
        }
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return await res.json();
      } catch (err) {
        clearTimeout(timer);
        if (i === retries - 1) throw err;
      }
    }
  }

  // 多轮对话:外部维护messages数组即可
  async chat(messages, options = {}) {
    const data = await this.request({
      model: this.model,
      messages,
      temperature: options.temperature ?? 0.7,
      max_tokens: options.maxTokens ?? 1024
    });
    return data.choices[0].message.content;
  }
}

// 使用示例:维护对话历史实现多轮上下文
const client = new SkyworkClient(process.env.SKYWORK_API_KEY);
const history = [{ role: 'system', content: '你是一位资深Node.js工程师' }];
history.push({ role: 'user', content: '什么是中间件模式' });
const reply = await client.chat(history);
history.push({ role: 'assistant', content: reply });

多轮对话的关键在于把完整的messages数组每次都传给接口,模型本身是无状态的,上下文记忆完全由客户端维护。同时要注意历史消息会持续消耗token,当对话轮次较多时,可以做一个简单的滑动窗口,只保留最近若干轮,或者对早期内容做摘要压缩,控制成本。

五、结合Express构建对话接口

最后给出一个把天工能力暴露成HTTP服务的例子。前端请求这个接口时,服务端把流式响应原样转发,用户在浏览器中就能看到逐字输出的效果:

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

app.post('/api/chat', async (req, res) => {
  const { prompt } = req.body;
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');

  const upstream = await fetch(`${BASE_URL}/chat/completions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'skywork-plus',
      messages: [{ role: 'user', content: prompt }],
      stream: true
    })
  });

  const reader = upstream.body.getReader();
  const decoder = new TextDecoder();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    res.write(decoder.decode(value, { stream: true }));
  }
  res.end();
});

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

这种代理转发的写法还有额外好处:密钥保存在服务端,前端不接触敏感信息;同时可以在转发前做内容审核、限流、日志记录等统一处理。生产环境建议再加上请求体校验和并发控制,避免恶意刷接口造成费用损耗。

总的来说,Node.js接入天工Skywork模型的门槛并不高,核心就是组织好请求体、处理好SSE流和管理好对话历史。把这三块封装成独立模块后,无论是做智能客服、内容生成还是代码助手,都可以直接复用,快速搭建出稳定的AI能力层。

Node.jsSkywork天工模型修改时间:2026-09-02 19:55:12

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