🌈 前端也能玩转大模型!WebLLM:用Fetch将DeepSeek引入你的网页
本文你将学到:如何使用JavaScript的Fetch API调用DeepSeek大模型,实现一个智能聊天前端。
引言:WebLLM,智能前端的战场
还记得Web 1.0时代吗?那时候的前端只是简单的HTML、CSS,交互全靠服务器渲染。进入Web 2.0,前端开始使用Ajax、Fetch等技术,动态获取数据,实现富交互体验。如今,AI时代来临,WebLLM(Web + Large Language Model)正成为新的战场!
什么是WebLLM? 简单来说,就是在前端直接调用大模型的能力,让网页变得"聪明"起来。比如,你可以在网页里集成一个智能助手,直接与用户对话,而这一切只需要几行JavaScript代码!
今天,我们就以DeepSeek大模型为例,教你如何用Fetch API将它引入你的前端项目。
一、传统Web应用的数据获取方式
在深入WebLLM之前,我们先回顾一下传统Web应用的数据获取方式:
1. 服务器端渲染(SSR)
- 用户输入URL或点击链接
- 服务器(如Node.js、Java)处理请求,从数据库获取数据
- 服务器生成HTML字符串,返回给浏览器
- 浏览器渲染页面
这种方式简单直接,但每次获取新数据都需要刷新页面,体验不够流畅。
举个例子来说:
-
用户行为:在浏览器地址栏输入
https://example.com/products/123 -
服务器处理:
- Node.js 服务器接收到请求,解析路径参数
123 - 从数据库查询 ID 为 123 的商品数据(如名称、价格、描述)
- 将数据填充到 HTML 模板中,生成完整的 HTML 字符串
- Node.js 服务器接收到请求,解析路径参数
-
浏览器渲染:
-
服务器返回类似这样的 HTML:
<!DOCTYPE html> <html> <body> <h1>iPhone 15 Pro</h1> <p>价格:¥8,999</p> <p>颜色:钛金属灰</p> <!-- 其他商品信息 --> </body> </html> -
浏览器直接渲染这个完整的 HTML 页面
-
-
局限性:
- 如果用户切换到另一个商品(如 /products/456),需要重新请求服务器
- 服务器返回全新的 HTML,页面会完全刷新,产生 "闪烁" 感
2. Fetch请求(客户端渲染)
Web 2.0时代,我们开始使用fetch:
// 示例:获取GitHub仓库列表
fetch('https://api.github.com/users/shunwuyu/repos')
.then(res => res.json())
.then(data => {
// 动态更新DOM
document.querySelector('#repoList').innerHTML = data
.map(repo => `<li>${repo.name}</li>`)
.join('');
});
这种方式的好处是:
- 无需刷新页面,即可获取数据
- 动态更新DOM,提供更流畅的用户体验
- 适用于"加载更多"、点赞、评论等交互
二、进入AI时代:用Fetch调用DeepSeek API
现在,我们进入AI时代!大模型如DeepSeek提供了HTTP API,让我们可以像获取普通数据一样获取AI生成的内容。
DeepSeek API 简介
DeepSeek的聊天API端点(Endpoint)是:
POST https://api.deepseek.com/chat/completions
这个API遵循OpenAI的格式,主要参数包括:
model:使用的模型,如deepseek-chatmessages:对话消息数组,包含system、user、assistant三种角色
调用API的四个步骤
- 构建请求行:指定方法(POST)和URL
- 设置请求头:包括内容类型和API密钥
- 准备请求体:JSON格式的对话数据
- 发送请求并处理响应
下面是一个完整示例:
// 1. 定义API端点
const endpoint = 'https://api.deepseek.com/chat/completions';
// 2. 设置请求头
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk-你的API密钥' // 替换成你的真实密钥
};
// 3. 准备请求体(payload)
const payload = {
model: 'deepseek-chat',
messages: [
{ role: 'system', content: '你是一个有用的助手' },
{ role: 'user', content: '你好,DeepSeek!' }
]
};
// 4. 发送Fetch请求
fetch(endpoint, {
method: 'POST',
headers: headers,
body: JSON.stringify(payload) // 注意:body必须是字符串
})
.then(response => response.json())
.then(data => {
// 提取AI回复
const aiReply = data.choices[0].message.content;
document.querySelector('#reply').innerHTML = aiReply;
});
三、解剖HTTP请求:请求行、头、体
HTTP请求就像一封信✉️,它由三个主要部分组成:
1. 请求行(Request Line)
POST /chat/completions HTTP/1.1
- 方法:
POST(因为我们发送数据给服务器) - 路径:
/chat/completions(API的具体路径) - 协议:
HTTP/1.1
2. 请求头(Headers)
请求头就像信封上的"备注信息",告诉服务器如何处理这封信。我们设置了两个关键头:
{
'Content-Type': 'application/json', // 告诉服务器:内容是JSON格式
'Authorization': 'Bearer sk-xxx' // 身份验证令牌
}
接下来我将介绍如何获取你自己的身份令牌:
进入这个网址 DeepSeek 开放平台
在这之前要耗费巨款1元,获得使用资格(问一次问题大概耗费0.001元,反正可以用挺久的)
注意要实名认证
点击创建api key
然后你就会获得一个key,将key放入'Bearer sk-xxx' sk-xxx这个位置即可
3. 请求体(Body)
请求体是信的具体内容。对于DeepSeek API,我们发送一个JSON对象:
{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "你是一个有用的助手"},
{"role": "user", "content": "你好DeepSeek!"}
]
}
注意:在Fetch中,body必须是字符串,所以我们要用JSON.stringify()转换。
messages数组中的role字段支持以下几种角色,且有不同的使用规则:
1. 系统角色(system)
-
作用:设定助手的行为和身份,提供全局指令或背景信息。
-
限制:
- 通常只需设置一次,放在
messages数组的第一个元素。 - 部分 API 允许多次使用
system(如 OpenAI 的 GPT-4),但后续的system可能覆盖或补充之前的指令。
- 通常只需设置一次,放在
-
示例:
{"role": "system", "content": "你是一个精通编程的助手,用简洁易懂的语言回答问题。"}
2. 用户角色(user)
-
作用:表示用户的输入或提问。
-
使用频率:可多次出现(每轮对话至少一次)。
-
示例:
{"role": "user", "content": "如何用Python实现快速排序?"}
3. 助手角色(assistant)
-
作用:存储模型之前的回复,用于上下文对话。
-
使用场景:
- 在多轮对话中,需要将历史对话的
assistant回复加入messages数组。 - 例如,用户连续提问时,API 需要知道之前的回复内容才能保持连贯。
- 在多轮对话中,需要将历史对话的
-
示例:
{"role": "assistant", "content": "可以使用Python的内置函数sorted():\n```python\narr = [3, 1, 4, 1, 5]\nprint(sorted(arr)) # 输出: [1, 1, 3, 4, 5]\n```"}
4. 函数调用角色(function_call)
-
作用:当模型需要调用外部函数时,会返回此角色。
-
结构:包含函数名和参数。
-
示例:
{ "role": "assistant", "function_call": { "name": "get_weather", "parameters": { "location": "北京", "date": "2023-10-01" } } }这种情况下,用户需要调用对应的函数(如
get_weather),并将结果作为新的user消息返回给模型。
多轮对话示例
{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "你是一个翻译助手,将中文翻译成英文。"},
{"role": "user", "content": "你好"},
{"role": "assistant", "content": "Hello"},
{"role": "user", "content": "谢谢"},
// 模型会基于历史对话,生成新的回复
]
}
关键规则总结
-
system通常只需一次,但某些 API 允许多次使用(需查阅文档)。 -
历史对话需完整保留:多轮对话时,
messages数组要包含所有user和assistant的历史记录。 -
函数调用需特殊处理:若模型返回
function_call,需调用函数并将结果作为新的user消息。
四、实战:构建一个WebLLM聊天应用
现在,让我们动手实现一个简单的聊天界面!
HTML结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>DeepSeek Web聊天</title>
<style>
/* 简单样式 */
body { font-family: Arial, sans-serif; }
#chatbox { height: 400px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; }
#input { width: 80%; padding: 10px; }
button { padding: 10px; }
</style>
</head>
<body>
<h1>🤖 DeepSeek 聊天机器人</h1>
<div id="chatbox"></div>
<input type="text" id="input" placeholder="输入消息...">
<button onclick="sendMessage()">发送</button>
<script src="app.js"></script>
</body>
</html>
JavaScript代码 (app.js)
const endpoint = 'https://api.deepseek.com/chat/completions';
const apiKey = 'sk-你的API密钥'; // 替换成你的真实密钥
//挂载点
const chatbox = document.getElementById('chatbox');
const input = document.getElementById('input');
// 初始系统消息
const messages = [
{ role: 'system', content: '你是一个乐于助人的AI助手,回答简洁明了。' }
];
// 发送消息函数
function sendMessage() {
const userMessage = input.value;
//输入验证逻辑,用于检查用户输入是否为空或仅包含空白字符
if (!userMessage.trim()) return;
// 添加用户消息
messages.push({ role: 'user', content: userMessage });
updateChatbox();
// 清空输入框
input.value = '';
// 调用DeepSeek API
fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify({
model: 'deepseek-chat',
messages: messages
})
})
// 处理API响应,需要时间,所以使用.then()异步处理
.then(response => response.json())
.then(data => {
const aiReply = data.choices[0].message.content; // 提取AI回复
messages.push({ role: 'assistant', content: aiReply }); // 存储到消息历史
updateChatbox(); // 更新聊天框
});
}
// 更新聊天框
function updateChatbox() {
// 清空当前聊天内容(避免重复追加)
chatbox.innerHTML = '';
// 遍历所有消息记录
messages.forEach(msg => {
// 过滤系统提示消息(仅后台使用)
if (msg.role === 'system') return;
// 创建消息容器div
const div = document.createElement('div');
// 设置CSS类(便于区分用户/AI样式)
div.className = msg.role;
// 构建消息文本内容
div.textContent = `${
msg.role === 'user'
? '👤 你' // 用户消息前缀
: '🤖 AI' // AI消息前缀
}: ${msg.content}`;
// 将消息元素添加到聊天框
chatbox.appendChild(div);
});
// 自动滚动到底部(显示最新消息)
chatbox.scrollTop = chatbox.scrollHeight;
}
效果图
五、安全提示:保护你的API密钥
⚠️ 重要提醒:在前端代码中直接暴露API密钥(如sk-xxx)是非常危险的!恶意用户可能窃取你的密钥并滥用。
解决方案:
- 对于学习项目,可以使用临时密钥。
- 生产环境中,应该通过自己的后端服务器转发请求:
- 前端发送请求到你的服务器
- 服务器添加密钥后转发给DeepSeek
- 服务器将响应返回给前端
结语:智能前端的未来已来
通过本文,你已经学会了如何用Fetch API将DeepSeek大模型引入前端。这只是一个起点,WebLLM的世界充满无限可能:
- 在表单中集成AI辅助输入
- 创建实时翻译聊天室
- 开发智能代码助手
💡 思考题:你能用DeepSeek的代码模型(deepseek-coder)做一个在线代码解释器吗?
让我们的网页,从此拥有智慧!
相关阅读:
欢迎在评论区分享你的WebLLM作品! 🚀