前端调用大语言模型:基于 Vite 的工程化实践与 HTTP 请求详解

前端调用大语言模型:基于 Vite 的工程化实践与 HTTP 请求详解

随着人工智能技术的迅猛发展,大语言模型已逐渐从科研实验室走向工业应用。本文将围绕"前端如何以 HTTP 请求方式调用大语言模型"这一核心主题,结合现代前端工程化工具 Vite,详细讲解项目初始化、环境变量配置、fetch 请求封装、安全注意事项等关键环节,帮助读者掌握从前端发起 LLM 调用的全流程。


一、为什么前端可以直接调用 LLM?

传统观点认为,AI 模型应由后端服务代理调用,前端仅负责展示结果。然而,在某些场景下,前端直连 LLM API 是可行且高效的,前提是:

  1. API 支持 CORS(跨域资源共享) :如 DeepSeek、OpenRouter 等部分服务商允许浏览器直接请求。
  2. 安全性可控:通过短期有效的 API Key、IP 白名单、请求频率限制等方式降低风险。
  3. 无需敏感数据处理:用户输入不涉及隐私或机密信息。

以 DeepSeek 为例,其官方 API 支持 CORS,允许前端通过 fetch 直接发起 POST 请求,这为快速原型开发和轻量级应用提供了极大便利。


二、项目初始化:使用 Vite 搭建全栈友好型前端项目

Vite 是新一代前端构建工具,以其极速的冷启动和热更新能力著称。虽然 Vite 本身是前端构建器,但其对环境变量、TypeScript、ESM 模块的原生支持,使其成为调用 LLM 的理想脚手架。

1. 创建项目

sql 复制代码
npm create vite@latest llm-frontend-demo -- --template vanilla
cd llm-frontend-demo
npm install

选择 vanilla 模板即可获得一个纯净的 HTML/CSS/JS 项目结构,适合教学和快速验证。

2. 配置环境变量

出于安全考虑,API Key 绝不能硬编码在源码中 。Vite 提供了 .env 文件机制,所有以 VITE_ 开头的变量会被注入到客户端代码中。

创建 .env.local 文件(该文件通常加入 .gitignore,避免提交到版本控制):

ini 复制代码
VITE_DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

⚠️ 注意:此方法仅适用于 API 服务商允许前端直连的场景。若服务商禁止 CORS 或要求更高安全级别,则必须通过后端代理。


三、HTTP 请求详解:如何正确调用 LLM API

LLM API 通常遵循 RESTful 设计,使用 JSON 格式通信。以 DeepSeek 的 /chat/completions 接口为例,一次完整的请求包含三个部分:请求行、请求头、请求体

1. 请求行(Request Line)

  • Method : POST(因为需要发送消息内容)
  • URL : https://api.deepseek.com/chat/completions
  • HTTP 版本: 通常由浏览器自动处理,无需显式指定

2. 请求头(Headers)

必须包含两个关键字段:

javascript 复制代码
const headers = {
  'Content-Type': 'application/json',
  'Authorization': `Bearer ${import.meta.env.VITE_DEEPSEEK_API_KEY}`
};
  • Content-Type: application/json 告知服务器请求体为 JSON 格式。
  • Authorization: Bearer <token> 是 OAuth 2.0 标准的认证方式,Bearer 为固定前缀。

3. 请求体(Body)

LLM 接口通常要求结构化的消息数组:

css 复制代码
const payload = {
  model: 'deepseek-chat', // 指定模型名称
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "你好 DeepSeek" }
  ]
};

注意:body 必须是字符串 ,不能直接传入 JavaScript 对象。需使用 JSON.stringify() 序列化:

css 复制代码
body: JSON.stringify(payload)
为什么 body 必须是字符串?

这是因为 fetch API 的底层实现遵循 HTTP 协议规范 ,而 HTTP 协议规定:请求体(request body)只能是字节流(即二进制数据) 。在浏览器环境中,JavaScript 无法直接发送对象、数组等高级数据结构------这些结构只存在于运行时内存中,网络传输必须将其转换为可序列化的格式。

当你调用 fetch 并设置 body 字段时,浏览器期望你提供以下几种类型之一:

  • string(如 JSON 字符串)
  • FormData
  • URLSearchParams
  • Blob / ArrayBuffer / ReadableStream 等二进制类型

如果你直接传入一个 JavaScript 对象(例如 { key: "value" }),浏览器会尝试将其隐式转换为字符串,结果通常是 [object Object] ------ 这显然不是服务器期望的 JSON 格式,会导致 API 返回解析错误(如 400 Bad Request)。

因此,必须显式使用 JSON.stringify() 将对象转换为标准的 JSON 字符串 ,确保服务端能正确反序列化并理解你的请求内容。同时,配合设置请求头 'Content-Type': 'application/json',告知服务器:"我发送的是 JSON 格式的文本"。

✅ 正确做法:

css 复制代码
body: JSON.stringify({ message: "hello" })

❌ 错误做法:

css 复制代码
body: { message: "hello" }  // 实际发送的是 "[object Object]"

这一细节看似微小,却是前后端数据通信可靠性的关键保障。

四、使用 fetch 发起异步请求

现代浏览器原生支持 fetch API,它是发起 HTTP 请求的标准方式。

完整调用示例

javascript 复制代码
// main.js
const endpoint = 'https://api.deepseek.com/chat/completions';

async function callDeepSeek(userMessage) {
  const headers = {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${import.meta.env.VITE_DEEPSEEK_API_KEY}`
  };

  const payload = {
    model: 'deepseek-chat',
    messages: [
      { role: "system", content: "You are a helpful assistant." },
      { role: "user", content: userMessage }
    ]
  };

  try {
    const response = await fetch(endpoint, {
      method: 'POST',
      headers,
      body: JSON.stringify(payload)
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return data.choices[0].message.content;
  } catch (error) {
    console.error('调用 DeepSeek 失败:', error);
    return '抱歉,暂时无法获取回复。';
  }
}

// 绑定按钮点击事件
document.getElementById('send-btn').addEventListener('click', async () => {
  const input = document.getElementById('user-input');
  const replyEl = document.getElementById('reply');

  const userMsg = input.value.trim();
  if (!userMsg) return;

  replyEl.textContent = '思考中...';
  const reply = await callDeepSeek(userMsg);
  replyEl.textContent = reply;
  input.value = '';
});

关键点说明

  • 使用 async/await 使异步代码更易读,避免回调地狱。
  • response.ok 进行判断,防止非 2xx 响应被误认为成功。
  • 错误处理必不可少,网络波动或配额耗尽可能导致请求失败。

五、工程化思维:代码如钢筋水泥

在 Trae 所倡导的"工程化"理念中,代码不仅是功能的载体,更是可维护、可扩展、可协作的"建筑材料"。调用 LLM 不应只是复制粘贴一段 fetch 代码,而应思考:

  • 可复用性:将 LLM 调用封装为独立函数或模块。
  • 可配置性:模型名称、系统提示词可通过参数传入。
  • 可测试性:模拟 API 响应进行单元测试。
  • 用户体验:加载状态、错误提示、输入限制等细节。

例如,可进一步抽象为:

kotlin 复制代码
class LLMClient {
  constructor(apiKey, model = 'deepseek-chat') {
    this.apiKey = apiKey;
    this.model = model;
    this.endpoint = 'https://api.deepseek.com/chat/completions';
  }

  async chat(messages, systemPrompt = "You are a helpful assistant.") {
    const fullMessages = [
      { role: "system", content: systemPrompt },
      ...messages
    ];

    const response = await fetch(this.endpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`
      },
      body: JSON.stringify({ model: this.model, messages: fullMessages })
    });

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

这种面向对象的设计更利于大型项目集成。


六、安全与最佳实践

尽管前端直连 LLM 便捷高效,但也存在风险:

  1. API Key 泄露 :一旦 .env 中的 Key 被提取,可能被滥用产生高额费用。

    • 解决方案:使用短期 Token、设置 IP 白名单、监控调用量。
  2. CORS 限制:并非所有 LLM 服务商都开放 CORS。

    • 替代方案:通过 Vite 的代理功能(仅开发环境)或部署轻量后端(如 Cloudflare Workers)中转。
  3. 速率限制:频繁请求可能触发限流。

    • 建议:添加防抖、队列机制或用户提示。

结语

前端调用大语言模型不再是遥不可及的概念,而是触手可及的工程实践。借助 Vite 的现代化开发体验和浏览器原生的 fetch 能力,我们可以快速构建具备 AI 能力的 Web 应用。然而,技术便利的背后是对工程规范、安全意识和用户体验的更高要求。

未来,随着 WebAssembly、WebGPU 等技术的发展,甚至可能在浏览器本地运行小型 LLM,实现完全离线的智能交互。但无论技术如何演进,"工程化"始终是高质量软件开发的基石------正如钢筋水泥之于摩天大楼,代码结构之于数字世界。

代码不是魔法,而是精心设计的工程。

相关推荐
Soonyang Zhang1 小时前
MoeDistributeDispatch算子代码阅读
人工智能·算子·ascendc
sanggou1 小时前
Windsurf AI IDE 完全使用指南
ide·人工智能
2501_941870562 小时前
人工智能与未来的工作:自动化与人类协作的新时代
大数据·人工智能
Blurpath2 小时前
2025 年用ChatGPT+代理构建AI驱动的智能爬虫
人工智能·爬虫·chatgpt·ip代理·住宅ip·动态住宅代理·轮换ip
极客BIM工作室3 小时前
大模型中的Scaling Law:AI的“增长密码“
人工智能
纪伊路上盛名在3 小时前
Alphafold实用指南—官网教程3
数据库·人工智能·机器学习·alphafold·计算生物学·结构生物学
茶杯6753 小时前
数字孪生厂商推荐:跨行业通用型平台与垂直领域专精企业对比指南
人工智能
道可云3 小时前
场景搭桥,产业赋能:新政策如何激活乡村振兴新动能
人工智能