前端项目如何引入大语言模型

4 阅读2分钟

引言

关于前端项目引入大语言模型,需分为4步
注意:⚠️ 此方式会将 API Key 暴露在浏览器中,任何人都可以通过开发者工具查看,所以请勿将项目部署到公网,仅供本地开发使用。

步骤

一、创建 api key

在模型官网上面注册账号并创建api key

  1. 什么是api key? -- 它是程序访问某个服务器的“钥匙”,发送请求时要带上它
  2. 如何创建? -- 可直接搜索“大模型名字+api key”

二、创建.env文件

  1. 在哪里创建? -- 项目根目录下

  2. 为什么要创建.env文件? -- 添加api key

  3. 怎么写.env文件? -- VITE_平台名_KEY=api key,如VITE_DEEPSEEK_KEY

    (1)将api key换成我们生成的api key,通常以sk-开头

    (2) VITE_平台名_KEY=api key不一定适用,需查对应构建工具的写法

三、发送请求

await fetch("/api/compatible-mode/v1/chat/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${import.meta.env.VITE_平台名_KEY}`,
    },
    body: JSON.stringify(params),
  });
  1. 为什么用fetch发送请求? -- fetch原生支持流式读取,代码更直观。用axios不方便,需要添加其他配置项

  2. params需根据官方资料写,博主见到的一般是这种

    {
        messages: [{ role: "user", content: "Hello" }],
        model: 所使用模型的完整名称
    }
    ​
    // 还需自查所使用的大模型的开启流式输出的写法
    
解决跨域问题

设置代理服务器,以下是前端构建工具为vite时的写法

// 在vite.config.js文件中
// 添加如下配置项
  server: {
    proxy: {
      '/api': { // 检测到有以/api开头的请求地址才会开启代理
        // 所以baseUrl写成'/api'即可,以下代码会将/api去掉再指向target
        target: 'https://dashscope.aliyuncs.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^/api/, '')
      }
    }
  }

🚩改变vite的配置项后,需要重启才能生效

四、如何接收流式数据

  // fetch ReadableStream
​
  const stream=res.body
  const reader = stream.getReader(); // 后续通过read()方法返回读取流的结果
  const decoder = new TextDecoder(); // 将二进制转为字符串,为JS内置API
​
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
​
    const str = decoder.decode(value); // str是读取结果,是字符串
​
    // step1:按换行分割,可能有多行
    const lines = str.split("\n");
​
      // 因为一次read到的结果就可能是以下样子,也就是多个data: JSON格式,所以应先改为数组,接下来通过for依次对每一行的结果进行处理
      // data: {"choices":[{"delta":{"content":"你"}}]}
      // data: {"choices":[{"delta":{"content":"好"}}]}
      // data: {"choices":[{"delta":{"content":"!"}}]}
      
    // step2:遍历每一行
    for (const line of lines) {
      // step3:跳过空行和 [DONE]
      if (!line.startsWith("data: ") || line.includes("[DONE]")) continue;
​
      // step4:去掉 'data: ' 前缀,再JSON.parse
      const obj = JSON.parse(line.slice(6));
​
      // step5:取内容
      const content = obj.choices[0].delta.content;
      if (content) console.log(content); // 加这行,null 和空字符串都跳过
    }
  }