nodejs 调用智谱ai

nodejs 调用智谱ai

封装 ZhipuSdk 类

为了方便地调用智谱 AI 的接口,我们首先封装一个 ZhipuSDK 类。这个类将初始化 HTTP 客户端,并提供创建补全功能的方法。

import axios from "axios";

export class ZhipuSDK {
  /**
   * 构造函数
   * 初始化HTTP客户端,用于与API服务器进行通信
   * @param {Object} options - 包含API密钥的配置对象
   */
  constructor(options) {
    this.client = axios.create({
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${options.apiKey}`,
      },
      baseURL: "https://open.bigmodel.cn/api/paas/v4",
      // 启用跨域请求中的凭证携带
      withCredentials: true,
    });
  }

  /**
   * 异步创建补全功能
   *
   * 本函数通过POST请求与服务器通信,以生成基于给定消息的补全响应
   * 它支持流式处理,可以通过回调函数实时处理生成的数据
   *
   * @param {Object} options - 包含补全请求配置的选项对象
   * @param {Object} handlers - 包含处理生成数据的回调函数的对象,默认为空对象
   * @returns {Promise<Object>} - 返回一个Promise,解析为补全响应数据
   */
  async createCompletions(options, handlers = {}) {
    try {
      // 清理消息历史,移除空消息和错误消息
      const cleanedMessages = options.messages.filter(
        (msg) =>
          msg.content &&
          msg.content.trim() !== "" &&
          !msg.content.includes("An error occurred")
      );

      // 发起请求
      const response = await this.client({
        method: "POST",
        url: "/chat/completions",
        responseType: options.stream ? "stream" : "json",
        data: {
          model: options.model,
          messages: options.messages,
          stream: !!options.stream,
        },
      });

      // 如果不是流式处理,直接返回响应数据
      if (!options.stream) {
        handlers.onProgress?.(response.data);
        return response.data;
      }

      // 初始化处理流式响应的变量
      let unhandledMessage = "";
      let deltaContent = "";
      let lastResponse;

      // 处理流式响应数据
      for await (const chunk of response.data) {
        const messages = (unhandledMessage + chunk.toString()).split("\n");
        unhandledMessage = "";

        for (const message of messages) {
          if (!message.startsWith("data:")) {
            unhandledMessage += message;
            continue;
          }

          if (message === "data: [DONE]") {
            handlers.onProgressEnd?.(lastResponse);
            continue;
          }

          try {
            if (!message.endsWith("}")) {
              unhandledMessage += message;
              continue;
            }

            const json = JSON.parse(message.replace("data: ", ""));

            if (options.stream === "append") {
              deltaContent += json.choices[0].delta.content;
              json.choices[0].message = deltaContent;
            }

            lastResponse = json;
            handlers.onProgress?.(json);
          } catch (error) {
            unhandledMessage += message;
          }
        }
      }

      return lastResponse;
    } catch (error) {
      console.error("ZhipuSDK Error:", error.response?.data || error.message);
      throw error;
    }
  }
}

创建 API 接口

接下来,我们创建一个 API 接口,用于接收客户端发送的消息,并调用 ZhipuSDK 类的 createCompletions 方法来生成补全响应。


router.post("/chat-zhipu", async (req, res) => {
  const { messages } = req.body;

  if (!messages?.length) {
    return res.status(400).json({ error: "Messages are required" });
  }

  try {
    // 设置SSE响应头
    setupSSE(res);

    const ai = new ZhipuSDK({
      apiKey: process.env.ZHIPU_API_KEY,
    });

    await ai.createCompletions(
      {
        model: "glm-4",
        messages: messages,
        stream: true,
      },
      {
        onProgress: (response) => {
          const { content } = response.choices[0].delta;
          if (content) {
            res.write(`data: ${JSON.stringify({
              type: "message",
              content
            })}\n\n`);
          }
        },
        onProgressEnd: () => {
          res.end();
        }
      }
    );
  } catch (error) {
    console.error("Chat error:", error.response?.data || error);
    res.write(`data: ${JSON.stringify({
      type: "error",
      content: "An error occurred while processing your request."
    })}\n\n`);
    res.end();
  }
});

注意事项

API 密钥:在使用智谱 AI 的接口之前,需要先获取 API 密钥,并将其设置为环境变量 ZHIPU_API_KEY。
URL 的正确性:请确保 baseURL 的值是正确的。如果遇到网络问题或无法解析该 URL,可能需要检查 URL 的合法性,并适当重试。
错误处理:在调用接口时,要妥善处理可能出现的错误,例如网络请求失败、API 限制等。通过捕获异常并返回相应的错误信息,可以提高应用的健壮性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值