硅基流动LLM模型调用实战项目
这篇文章介绍了一个基于HTML的硅基流动LLM模型交互界面演示。该界面包含完整的聊天功能,支持用户与AI模型对话,并能将对话内容导出为文章。界面设计采用响应式布局,包含配置面板、聊天窗口和文章输出区域,具有现代化的UI风格,包括卡片布局、渐变背景和阴影效果。文章提供了HTML代码片段,展示了界面结构和样式设计,体现了该演示系统的技术实现方式。
·
硅基流动LLM模型聊天演示
下面是一个完整的HTML演示,实现了与硅基流动LLM模型的交互功能,并可以将对话内容导出为文章。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>硅基流动LLM模型演示</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f5f7fa;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
}
}
header {
grid-column: 1 / -1;
text-align: center;
margin-bottom: 30px;
padding: 20px;
background: linear-gradient(135deg, #6e8efb, #a777e3);
color: white;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
}
.description {
font-size: 1.1rem;
opacity: 0.9;
}
.card {
background: white;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 25px;
margin-bottom: 20px;
}
.config-section {
grid-column: 1 / -1;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
@media (max-width: 768px) {
.config-section {
grid-template-columns: 1fr;
}
}
h2 {
margin-bottom: 15px;
color: #4a5568;
padding-bottom: 10px;
border-bottom: 2px solid #e2e8f0;
}
.input-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #4a5568;
}
input, textarea, select {
width: 100%;
padding: 12px;
border: 1px solid #cbd5e0;
border-radius: 6px;
font-size: 16px;
transition: border-color 0.3s;
}
input:focus, textarea:focus, select:focus {
outline: none;
border-color: #6e8efb;
box-shadow: 0 0 0 3px rgba(110, 142, 251, 0.2);
}
textarea {
min-height: 120px;
resize: vertical;
}
button {
background: linear-gradient(135deg, #6e8efb, #a777e3);
color: white;
border: none;
padding: 12px 20px;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: opacity 0.3s;
width: 100%;
}
button:hover {
opacity: 0.9;
}
button:disabled {
background: #cbd5e0;
cursor: not-allowed;
}
.chat-container {
display: flex;
flex-direction: column;
height: 400px;
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 15px;
background: #f8fafc;
border-radius: 6px;
margin-bottom: 15px;
border: 1px solid #e2e8f0;
}
.message {
margin-bottom: 15px;
padding: 12px;
border-radius: 8px;
max-width: 80%;
}
.user-message {
background-color: #ebf8ff;
margin-left: auto;
border-bottom-right-radius: 0;
}
.assistant-message {
background-color: #f0fff4;
margin-right: auto;
border-bottom-left-radius: 0;
}
.message-content {
word-wrap: break-word;
}
.message-sender {
font-weight: 600;
margin-bottom: 5px;
color: #4a5568;
}
.chat-input {
display: flex;
gap: 10px;
}
.chat-input input {
flex: 1;
}
.chat-input button {
width: auto;
}
.article-output {
min-height: 200px;
background: #f8fafc;
padding: 15px;
border-radius: 6px;
border: 1px solid #e2e8f0;
white-space: pre-wrap;
}
.links {
grid-column: 1 / -1;
display: flex;
justify-content: center;
gap: 20px;
margin-top: 20px;
}
.links a {
color: #6e8efb;
text-decoration: none;
font-weight: 600;
transition: color 0.3s;
}
.links a:hover {
color: #a777e3;
text-decoration: underline;
}
.thinking-budget {
display: flex;
align-items: center;
gap: 10px;
}
.thinking-budget input {
width: 100px;
}
.status {
text-align: center;
padding: 10px;
margin: 10px 0;
border-radius: 6px;
display: none;
}
.status.connecting {
background-color: #ebf8ff;
color: #3182ce;
display: block;
}
.status.error {
background-color: #fed7d7;
color: #e53e3e;
display: block;
}
.status.success {
background-color: #f0fff4;
color: #38a169;
display: block;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>硅基流动LLM模型演示</h1>
<p class="description">与DeepSeek-R1模型交互,并将对话转换为文章</p>
</header>
<div class="config-section">
<div class="card">
<h2>API配置</h2>
<div class="input-group">
<label for="api-key">API密钥</label>
<input type="password" id="api-key" placeholder="输入您的API密钥">
</div>
<div class="input-group">
<label for="model">模型</label>
<select id="model">
<option value="Pro/deepseek-ai/DeepSeek-R1">DeepSeek-R1</option>
</select>
</div>
<div class="input-group thinking-budget">
<label for="thinking-budget">思考预算</label>
<input type="number" id="thinking-budget" value="1024" min="512" max="2048">
</div>
<div class="input-group">
<label for="max-tokens">最大Token数</label>
<input type="number" id="max-tokens" value="4096" min="512" max="8192">
</div>
<button id="save-config">保存配置</button>
</div>
<div class="card">
<h2>初始提示</h2>
<div class="input-group">
<label for="initial-prompt">输入初始问题</label>
<textarea id="initial-prompt" placeholder="例如:奥运会的传奇名将有哪些?">奥运会的传奇名将有哪些?</textarea>
</div>
<button id="start-chat">开始对话</button>
</div>
</div>
<div class="card">
<h2>对话界面</h2>
<div id="chat-status" class="status">状态信息</div>
<div class="chat-container">
<div id="chat-messages" class="chat-messages">
<div class="message assistant-message">
<div class="message-sender">系统</div>
<div class="message-content">请输入API配置和初始问题,然后点击"开始对话"。</div>
</div>
</div>
<div class="chat-input">
<input type="text" id="user-input" placeholder="输入您的消息..." disabled>
<button id="send-message" disabled>发送</button>
</div>
</div>
</div>
<div class="card">
<h2>生成的文章</h2>
<div class="input-group">
<label for="article-title">文章标题</label>
<input type="text" id="article-title" placeholder="输入文章标题">
</div>
<div id="article-output" class="article-output">文章将在这里生成...</div>
<button id="generate-article" style="margin-top: 15px;">生成文章</button>
</div>
<div class="links">
<a href="https://siliconflow.cn/" target="_blank">硅基流动官网</a>
<a href="https://siliconflow.cn/docs" target="_blank">API文档</a>
<a href="https://github.com/siliconflow" target="_blank">GitHub资源</a>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 元素引用
const apiKeyInput = document.getElementById('api-key');
const modelSelect = document.getElementById('model');
const thinkingBudgetInput = document.getElementById('thinking-budget');
const maxTokensInput = document.getElementById('max-tokens');
const saveConfigButton = document.getElementById('save-config');
const initialPromptInput = document.getElementById('initial-prompt');
const startChatButton = document.getElementById('start-chat');
const chatMessages = document.getElementById('chat-messages');
const userInput = document.getElementById('user-input');
const sendMessageButton = document.getElementById('send-message');
const articleTitleInput = document.getElementById('article-title');
const articleOutput = document.getElementById('article-output');
const generateArticleButton = document.getElementById('generate-article');
const chatStatus = document.getElementById('chat-status');
// 对话历史
let conversationHistory = [];
let isChatActive = false;
// 保存配置
saveConfigButton.addEventListener('click', function() {
const apiKey = apiKeyInput.value.trim();
if (!apiKey) {
showStatus('请输入API密钥', 'error');
return;
}
// 在实际应用中,这里应该安全地存储API密钥
showStatus('配置已保存', 'success');
setTimeout(() => {
chatStatus.style.display = 'none';
}, 2000);
});
// 开始对话
startChatButton.addEventListener('click', async function() {
const apiKey = apiKeyInput.value.trim();
const initialPrompt = initialPromptInput.value.trim();
if (!apiKey) {
showStatus('请先配置API密钥', 'error');
return;
}
if (!initialPrompt) {
showStatus('请输入初始问题', 'error');
return;
}
isChatActive = true;
userInput.disabled = false;
sendMessageButton.disabled = false;
conversationHistory = [];
// 添加用户初始消息到对话历史
addMessageToChat('user', initialPrompt);
conversationHistory.push({ role: 'user', content: initialPrompt });
// 显示连接状态
showStatus('正在连接API...', 'connecting');
try {
// 发送请求到硅基流动API
const response = await callSiliconFlowAPI(conversationHistory, true);
// 添加助手回复到对话历史
addMessageToChat('assistant', response.content);
conversationHistory.push({ role: 'assistant', content: response.content });
showStatus('连接成功', 'success');
setTimeout(() => {
chatStatus.style.display = 'none';
}, 2000);
} catch (error) {
showStatus('API调用失败: ' + error.message, 'error');
isChatActive = false;
userInput.disabled = true;
sendMessageButton.disabled = true;
}
});
// 发送消息
sendMessageButton.addEventListener('click', async function() {
if (!isChatActive) return;
const message = userInput.value.trim();
if (!message) return;
// 添加用户消息到对话历史
addMessageToChat('user', message);
conversationHistory.push({ role: 'user', content: message });
// 清空输入框
userInput.value = '';
// 显示连接状态
showStatus('正在获取回复...', 'connecting');
try {
// 发送请求到硅基流动API
const response = await callSiliconFlowAPI(conversationHistory, false);
// 添加助手回复到对话历史
addMessageToChat('assistant', response.content);
conversationHistory.push({ role: 'assistant', content: response.content });
showStatus('回复接收成功', 'success');
setTimeout(() => {
chatStatus.style.display = 'none';
}, 2000);
} catch (error) {
showStatus('API调用失败: ' + error.message, 'error');
}
});
// 生成文章
generateArticleButton.addEventListener('click', function() {
if (conversationHistory.length === 0) {
showStatus('没有对话内容可生成文章', 'error');
return;
}
const title = articleTitleInput.value.trim() || '生成的对话文章';
// 将对话转换为文章格式
let article = `# ${title}\n\n`;
conversationHistory.forEach(msg => {
const role = msg.role === 'user' ? '用户' : '助手';
article += `## ${role}\n\n${msg.content}\n\n`;
});
articleOutput.textContent = article;
});
// 添加消息到聊天界面
function addMessageToChat(role, content) {
const messageDiv = document.createElement('div');
messageDiv.classList.add('message');
messageDiv.classList.add(role === 'user' ? 'user-message' : 'assistant-message');
const senderDiv = document.createElement('div');
senderDiv.classList.add('message-sender');
senderDiv.textContent = role === 'user' ? '您' : '助手';
const contentDiv = document.createElement('div');
contentDiv.classList.add('message-content');
contentDiv.textContent = content;
messageDiv.appendChild(senderDiv);
messageDiv.appendChild(contentDiv);
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// 显示状态信息
function showStatus(message, type) {
chatStatus.textContent = message;
chatStatus.className = 'status ' + type;
chatStatus.style.display = 'block';
}
// 调用硅基流动API
async function callSiliconFlowAPI(messages, isFirstRequest) {
const apiKey = apiKeyInput.value.trim();
const model = modelSelect.value;
const thinkingBudget = parseInt(thinkingBudgetInput.value);
const maxTokens = parseInt(maxTokensInput.value);
// 模拟API调用 - 在实际应用中,这里应该使用fetch或axios发送请求
// 注意:由于跨域限制,前端直接调用API可能会遇到问题
// 建议在实际应用中使用后端代理
return new Promise((resolve, reject) => {
// 模拟网络延迟
setTimeout(() => {
if (Math.random() < 0.1) { // 10%的失败率用于演示
reject(new Error('网络错误或API无响应'));
return;
}
// 模拟API响应
const responses = {
first: {
content: "奥运会历史上涌现了许多传奇名将,以下是一些最著名的:\n\n1. 迈克尔·菲尔普斯(游泳) - 美国" +
"游泳运动员,获得了23枚奥运金牌,是奥运会历史上获得奖牌最多的运动员。\n\n2. 拉里莎·拉特尼娜(体操) - 前苏联" +
"体操运动员,在1956年至1964年三届奥运会上共获得18枚奥运奖牌。\n\n3. 尤塞恩·博尔特(田径) - 牙买加短跑运动员," +
"在2008年、2012年和2016年三届奥运会上获得了8枚金牌,创造了100米和200米世界纪录。\n\n4. 卡尔·刘易斯(田径) - 美国" +
"田径运动员,在四届奥运会上获得了9枚金牌。\n\n5. 纳迪亚·科马内奇(体操) - 罗马尼亚体操运动员,在1976年蒙特利尔奥运会上" +
"成为第一位在体操比赛中获得满分10分的运动员。\n\n您想了解哪位运动员的更多信息?",
reasoning_content: ""
},
followUp: {
content: "除了上述提到的传奇运动员,奥运会历史上还有其他许多值得铭记的名将:\n\n6. 马克·斯皮茨(游泳) - 美国游泳运动员," +
"在1972年慕尼黑奥运会上创造了夺得7枚金牌的纪录,这一纪录直到2008年才被菲尔普斯打破。\n\n7. 帕沃·努尔米(田径) - 芬兰" +
"长跑运动员,在1920年至1928年三届奥运会上共获得了9枚金牌和3枚银牌。\n\n8. 比约恩·戴利(越野滑雪) - 挪威越野滑雪运动员," +
"在1992年至1998年三届冬奥会上共获得了8枚金牌和4枚银牌。\n\n9. 史蒂夫·雷德格雷夫(赛艇) - 英国赛艇运动员,连续五届奥运会" +
"(1984-2000)获得金牌,是奥运史上最伟大的赛艇运动员。\n\n10. 玛丽·卢·雷顿(体操) - 美国体操运动员,在1984年洛杉矶" +
"奥运会上获得团体金牌和个人全能金牌。\n\n这些运动员不仅在各自的领域取得了卓越成就,也体现了奥林匹克精神。",
reasoning_content: ""
}
};
resolve(isFirstRequest ? responses.first : responses.followUp);
}, 1500); // 模拟1.5秒的网络延迟
});
}
// 允许按Enter键发送消息
userInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessageButton.click();
}
});
});
</script>
</body>
</html>
使用说明
- 在API配置部分输入您的硅基流动API密钥
- 设置思考预算和最大Token数(可选)
- 输入初始问题或使用默认的"奥运会的传奇名将有哪些?"
- 点击"开始对话"按钮开始与AI交互
- 在对话界面中继续与AI交流
- 最后可以生成文章并添加标题
相关链接
注意:由于浏览器跨域限制,此演示中的API调用部分是模拟的。在实际部署中,需要通过后端代理来调用硅基流动的API,以避免CORS问题。
更多推荐
所有评论(0)