一、下载ollama(官网下载比较慢,可以找个网盘资源下)
二、安装ollama
三、打开cmd,拉取模型deepseek-r1:14b(根据显存大小选择模型大小)
ollama pull deepseek-r1:14b
四、运行模型
ollama run deepseek-r1:14b
五、使用网页api访问,可以使用openweb-ui,也可以自己实现页面,下面是使用vue实现的页面
const ChildOllama = {
data() {
return {
userInput: '',
chatHistory: [],
// 请根据实际情况修改 Ollama API 的 URL
ollamaApiUrl: 'http://localhost:11434/v1/chat',
currentResponse: ''
}
},
watch: {
// 监听 messages 数组的变化
chatHistory: {
handler() {
// 数据变化时将滚动条移动到最下方
this.scrollToBottom();
},
deep: true
}
}
,
methods: {
// 将滚动条移动到最下方的方法
scrollToBottom() {
// 获取滚动 div 的引用
const scrollDiv = this.$refs.scrollDiv;
// 设置滚动条位置到最下方
scrollDiv.scrollTop = scrollDiv.scrollHeight;
}
,
async sendMessage() {
if (this.userInput.trim() === '') return;
// 添加用户消息到历史记录
const userMessage = { role: 'user', content: this.userInput };
this.chatHistory.push(userMessage);
try {
// 构造请求数据
const response = await fetch('http://localhost:11434/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'deepseek-r1:14b', // 使用的模型
messages: this.chatHistory,
stream: true, // 启用流式传输
}),
});
if (!response.ok) {
throw new Error(`请求失败,状态码: ${response.status}`);
}
this.currentResponse = '';
const reader = response.body.getReader();
const decoder = new TextDecoder();
let done = false;
while (!done) {
const { value, done: readerDone } = await reader.read();
done = readerDone;
if (value) {
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\n').filter(line => line.trim() !== '');
for (const line of lines) {
if (line) {
try {
const data = JSON.parse(line.replace(/^data: /, ''));
if (data.done) {
// 流式响应结束,添加完整回复到历史记录
const ollamaMessage = { role: 'assistant', content: this.currentResponse };
this.chatHistory.push(ollamaMessage);
} else {
this.currentResponse += data.message.content || '';
}
} catch (error) {
console.error('Error parsing JSON:', error);
}
}
}
}
}
} catch (error) {
console.error('Error sending message:', error);
}
// 清空输入框
this.userInput = '';
// try {
// // 将当前输入添加到对话历史中
// this.conversationHistory.push({ role: 'user', content: this.inputText });
//
// // 构造完整的提示信息,包含对话历史
// let fullPrompt = '';
// this.conversationHistory.forEach((item) => {
// fullPrompt += `${item.role === 'user' ? '用户: ' : '助手: '}${item.content}\n`;
// });
//
// // 清空之前的响应文本
// this.responseText = '';
// // 发起流式请求
// const response = await fetch('http://localhost:11434/api/generate', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json'
// },
// body: JSON.stringify({
// model: 'deepseek-r1:14b',
// prompt: fullPrompt,
// stream: true // 开启流式响应
// })
// });
//
// if (!response.ok) {
// throw new Error(`请求失败,状态码: ${response.status}`);
// }
//
// // 处理流式数据
// const reader = response.body.getReader();
// const decoder = new TextDecoder();
// let done = false;
// let currentResponse = '';
// while (!done) {
// const { value, done: readerDone } = await reader.read();
// done = readerDone;
// if (value) {
// const chunk = decoder.decode(value, { stream: true });
// // 解析 JSON 数据
// const lines = chunk.split('\n').filter(line => line.trim() !== '');
// for (const line of lines) {
// try {
// const data = JSON.parse(line);
// if (data.response) {
// // 更新响应文本
// currentResponse += data.response;
// this.responseText += data.response;
// }
// } catch (error) {
// console.error('解析 JSON 数据时出错:', error);
// }
// }
// }
// }
// // 将助手的回复添加到对话历史中
// this.conversationHistory.push({ role: 'assistant', content: currentResponse });
// } catch (error) {
// console.error('请求出错:', error);
// }
}
},
template:`<div class="ollama-chat">
<!-- 显示对话历史的区域 -->
<!-- <div class="history-area">-->
<!-- <div v-for="(item, index) in conversationHistory" :key="index" class="response-area">-->
<!-- <span :class="item.role === 'user' ? 'user-message' : 'assistant-message'">-->
<!-- {{ item.role === 'user' ? '用户: ' : '助手: ' }}-->
<!-- </span>-->
<!-- <span>{{ item.content }}</span>-->
<!-- </div>-->
<!-- </div>-->
<!-- <textarea v-model="inputText" placeholder="请输入问题"></textarea>-->
<!-- <button @click="sendRequest">发送请求</button>-->
<!-- -->
<!-- <div class="response-area">{{ responseText }}</div>-->
<h1>Ollama Chat</h1>
<div ref="scrollDiv" class="chat-history response-area">
<div v-for="(message, index) in chatHistory" :key="index">
<p><strong>{{ message.role === 'user' ? 'You' : 'Ollama' }}:</strong> {{ message.content }}</p>
</div>
</div>
<input
v-model="userInput"
placeholder="Type your message..."
@keyup.enter="sendMessage" style="width: 70%;padding: 5px;margin-right: 10px;"
/>
<button @click="sendMessage">Send</button>
<button @click="scrollToBottom">botom</button>
<div class="chat-history response-area">{{ currentResponse }}</div>
</div>`
}