WEB项目接入Deepseek(硅基流动)
文末有彩蛋哦!!!
这里调用的api为硅基流动的,如用的是其他平台的请自行改url
核心
URL
POST https://api.siliconflow.cn/v1/chat/completions
headers :
{
'Authorization': 'Bearer XXX',
'Content-Type': 'application/json'
}
请求参数:
{
"model": "你的模型",
"messages": [
{ "role": "user", "content": prompt }
],
"stream": true,
// "max_tokens": 512,
// "stop": ["null"],
// "temperature": 0.7, "top_p": 0.7,
// "top_k": 50, "frequency_penalty": 0.5, "n": 1,
// "response_format": { "type": "text" },
// "tools": [{ "type": "function", "function": { "description": "<string>", "name": "<string>", "parameters": {}, "strict": false } }]
}
使用示例(代码)
这里用react的代码做了个简单的示例
AIApi.jsx:
import { useEffect, useState, useRef } from 'react';
import './AIApi.scss';
export default function AIApi() {
const [dialogRecords, setDialogRecords] = useState([]);
// ref 存储textarea 内容
const inputRef = useRef(null);
// 实例创建时发送 axios
useEffect(() => {
// handleSubmit();
}, []);
let handleSubmit = async (event) => {
event.preventDefault();
streamOllamaResponse(inputRef.current.value);
}
async function streamOllamaResponse(prompt) {
setDialogRecords((dialogRecords) => [...dialogRecords, {
id: new Date().getTime(),
content: prompt,
reasoning_content: '',
type: 'user'
}]);
const data = {
"model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B",
"messages": [
{ "role": "user", "content": prompt }
],
"stream": true,
// "max_tokens": 512,
// "stop": ["null"],
// "temperature": 0.7, "top_p": 0.7,
// "top_k": 50, "frequency_penalty": 0.5, "n": 1,
// "response_format": { "type": "text" },
// "tools": [{ "type": "function", "function": { "description": "<string>", "name": "<string>", "parameters": {}, "strict": false } }]
}
const url = 'https://api.siliconflow.cn/v1/chat/completions';
const headers = {
'Authorization': 'Bearer apikey。。。',
'Content-Type': 'application/json'
}
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
if (!response.ok) {
console.error(`请求失败,状态码: ${response.status}`);
return;
}
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let buffer = '';
const processText = ({ done, value }) => {
if (done) {
// 处理最后可能剩余的数据
processDataChunk(buffer, '');
// Stream complete
return;
}
let chunk = decoder.decode(value, { stream: true });
buffer += chunk;
let eventEndIndex = buffer.indexOf('\n\n');
// console.log("chunk", chunk);
while (eventEndIndex !== -1) {
const eventData = buffer.slice(0, eventEndIndex);
processDataChunk(eventData, '');
buffer = buffer.slice(eventEndIndex + 2);
eventEndIndex = buffer.indexOf('\n\n');
}
// next chunk
return reader.read().then(processText);
};
// 开始读取第一个数据块
return reader.read().then(processText);
}
function processDataChunk(eventData, outputDiv) {
// 检查是否以 "data:" 开头
if (eventData.startsWith('data:')) {
// 提取数据部分
const data = eventData.slice(5).trim();
try {
// 尝试解析为 JSON(如果数据是 JSON 格式)
const parsedData = JSON.parse(data);
// console.log(parsedData);
let id = parsedData.id;
let content = parsedData.choices[0].delta.content || '';
let reasoning_content = parsedData.choices[0].delta.reasoning_content || '';
setDialogRecords((dialogRecords) =>{
let recordIndex = dialogRecords.findIndex(item => item.id == id);
console.log(id, content, recordIndex);
if (recordIndex === -1) {
return [...dialogRecords, {
id,
content,
reasoning_content,
type: 'assistant'
}];
} else {
let newRecords = [...dialogRecords];
newRecords[recordIndex].content += content;
newRecords[recordIndex].reasoning_content += reasoning_content;
console.log(newRecords);
return newRecords;
}
})
}
catch (parseError) {
console.error(data);
}
}
}
return (
<div className='ai-container'>
<h2>AI api Page</h2>
<div className='ai-content'>
<div className='output-container'>
{dialogRecords.map((item, index) => {
return (
<div key={index} className={`output-item ${item.type}`}>
<div className='reasoning-content'>{item.reasoning_content}</div>
<div className='content'>{item.content}</div>
</div>
)
})}
</div>
<div className='input-container'>
<textarea ref={inputRef} name="" id="" placeholder='请输入您的问题'></textarea>
<button onClick={handleSubmit}>提交</button>
</div>
</div>
</div>
)
}
AIApi.scss:
.ai-container{
padding: 20px;
padding-bottom: 140px;
.output-item{
padding: 20px 0;
max-width: 80%;
.reasoning-content{
color: #8b8b8b;
white-space: pre-wrap;
margin: 0;
padding: 0 0 0 13px;
line-height: 26px;
position: relative;
border-left: 1px solid #e0e0e0;
}
&.user{
text-align: right;
margin-left: auto;
}
&.assistant{
text-align: left;
margin-right: auto;
}
}
.input-container{
background-color: #fff;
padding: 0px 40px;
width: 100%;
height: 140px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
position: fixed;
bottom: 0;
left: 0;
border-top: 1px solid #e0e0e0;
textarea{
flex: 1;
padding: 20px;
// width: 100%;
background-color: #f0f0f0;
border-radius: 8px;
border-color: #e0e0e0;
outline: none;
height: 3em;
}
button{
flex-shrink: 0;
margin-left: 10px;
}
}
}
效果
文末彩蛋!!(粉丝福利)
DeepSeek使用技巧大全.rar:https://pan.quark.cn/s/6e769f336d4b