برنامه Chatbot با استفاده از مدل های موجود در Ollama

اولاما چیست
Ollama ابزاری قدرتمند و منبع باز است که به شما امکان می دهد بدون تکیه بر خدمات مبتنی بر ابر ، مدل های بزرگ زبان (LLM) را به طور کامل روی دستگاه محلی خود اجرا کنید. این یک روش آسان برای بارگیری ، مدیریت و اجرای مدل های AI با عملکرد بهینه شده و در صورت وجود شتاب GPU را اعمال می کند.
ویژگی های کلیدی:
✅ LLMS را به صورت محلی اجرا کنید – پس از بارگیری مدل ها به اینترنت لازم نیست.
management مدیریت مدل آسان – بارگیری ، سوئیچ و به روزرسانی مدل ها را با زحمت.
✅ بهینه سازی شده برای عملکرد – از شتاب GPU برای استنباط سریعتر استفاده می کند.
✅ خصوصی و ایمن – هیچ داده ای دستگاه شما را ترک نمی کند.
the پشتیبانی مدل سفارشی-برای کارهای خاص ، مدل های اصلاح و تنظیم دقیق را اصلاح و تنظیم کنید.
✅ API و CLI ساده – با مدل های برنامه ای یا از طریق خط فرمان با مدل ها ارتباط برقرار کنید.
چگونه کار می کند:
- Ollama را نصب کنید – یک دستور نصب ساده آن را تنظیم می کند.
- یک مدل را بکشید – مثال: اولاما mistral را بکشید برای بارگیری MISTRAL-7B.
- یک مدل را اجرا کنید – مثال: اولاما mistral را اجرا می کند برای شروع تعامل
- با کد ادغام شوید – از API برای اتوماسیون و توسعه برنامه استفاده کنید.
برای تعامل با مدل های Ollama یک میکروسرویس API ایجاد کنید
ما از FastAPI برای ایجاد یک میکروسرویس که با مدل های Ollama در تعامل است استفاده خواهیم کرد.
کد FASTAPI:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import json
import httpx
import asyncio
app = FastAPI()
# Input Schema
class RequestModel(BaseModel):
prompt: str
model_name: str
# Response Schema
class ResponseModel(BaseModel):
response: str
request: str
async def get_response(prompt: str, model_name: str):
url = "http://localhost:11434/api/generate"
headers = {"Content-Type": "application/json"}
data = {"model": model_name, "prompt": prompt}
try:
async with httpx.AsyncClient() as client:
response = await client.post(url, headers=headers, json=data)
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail=f"HTTP error! Status: {response.status_code}")
combined_response = ""
async for line in response.aiter_lines():
line = line.strip()
if not line:
continue
try:
parsed_response = json.loads(line)
if "response" in parsed_response:
response_text = parsed_response["response"]
combined_response += response_text
if parsed_response.get("done", False):
break
except json.JSONDecodeError:
print("Failed to parse line as JSON:", line)
continue
return combined_response
except Exception as e:
print("Error fetching response:", e)
raise HTTPException(status_code=500, detail="Error fetching response")
@app.post("/generate", response_model=ResponseModel)
async def generate_text(request: RequestModel):
response_text = await get_response(request.prompt, request.model_name)
return ResponseModel(response=response_text, request=request.prompt)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
میکروسرویس API را شروع کنید
uvicorn dummy:app --host 0.0.0.0 --port 8000
خروجی در پستچی:
ایجاد یک ربات چت بومی React برای تماس با میکروسرویس API برای پردازش پرس و جو کاربر
حال ، بیایید یک chatbot بومی React بسازیم که با میکروسرویس API ارتباط برقرار کند.
App.js (UI اصلی chatbot)
import React, { useState, useEffect, useRef } from 'react';
import { StyleSheet, Text, View, TouchableOpacity, StatusBar, AppRegistry } from 'react-native';
import ChatbotUI from './components/ChatbotUI';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import { faWindowMinimize, faCircleXmark } from '@fortawesome/free-solid-svg-icons';
const App = () => {
const [isChatVisible, setIsChatVisible] = useState(false);
const toggleChatWindow = () => {
setIsChatVisible(!isChatVisible);
};
return (
Welcome to ChatBot using free models
{isChatVisible && (
<>
Chat with Us
>
)}
💬
);
};
const styles = StyleSheet.create({
chatButton: {
position: 'fixed',
bottom: 20,
right: 20,
backgroundColor: '#0078d4',
padding: 10,
borderRadius: 50,
justifyContent: 'center',
alignItems: 'center',
},
chatIcon: {
color: '#fff',
fontSize: 24,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#1492c1', // Light background for the entire app
},
chatWindow: {
position: 'fixed',
bottom: 60,
right: 60,
height: 500,
width: 350,
backgroundColor: '#dae7ec', // Chat window color
borderRadius: 15,
padding: 10,
shadowColor: '#000',
shadowOffset: { width: 0, height: -2 },
shadowOpacity: 0.2,
shadowRadius: 5,
},
chatHeader: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between', // Ensures space between title and actions
padding: 5,
backgroundColor: '#dae7ec', // Optional styling
},
chatTitle: {
fontSize: 18,
fontWeight: 'bold',
flex: 1, // Ensures the title takes up remaining space
},
chatHeaderActions: {
flexDirection: 'row',
alignItems: 'center',
},
minimizeButton: {
marginRight: 20, // Adds spacing between minimize and close buttons
marginBottom: 20
},
closeButton: {
// Additional button styling if needed
}
});
export default App;
chatbotui.js (رابط چت)/u>
import React, { useState, useEffect, useRef } from 'react';
import {
StyleSheet,
View,
Text,
TextInput,
ScrollView,
KeyboardAvoidingView,
Platform,
Keyboard,
TouchableOpacity,
} from 'react-native';
const ChatbotUI = () => {
const [messages, setMessages] = useState([]);
const [inputMessage, setInputMessage] = useState('');
const scrollViewRef = useRef();
const inputRef = useRef(null);
async function getModelResponse(prompt) {
try {
const response = await fetch("http://localhost:11434/api/generate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ model: "phi", prompt: prompt })
});
// Check if the response is ok (status code 200-299)
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
let combinedResponse = ""; // Initialize an empty string to store the combined response
const reader = response.body.getReader();
const decoder = new TextDecoder();
let done = false;
while (!done) {
const { value, done: readerDone } = await reader.read();
done = readerDone;
const decodedChunk = decoder.decode(value, { stream: true });
try {
// Try to parse the decoded chunk as JSON
const parsedResponse = JSON.parse(decodedChunk);
if (parsedResponse && parsedResponse.response) {
// Check if the response contains a valid 'response' field
let cleanedResponse = parsedResponse.response;
// Remove 'User' wherever it appears in the response, ensuring spaces are preserved
cleanedResponse = cleanedResponse.replace(/\bUser\b/g, '');
// If valid, append the cleaned response incrementally
combinedResponse += cleanedResponse;
// Update the message UI progressively with each chunk
setMessages((prevMessages) => {
const botMessage = {
id: Date.now(),
text: combinedResponse.length > 0 ? combinedResponse : "Please try again",
sender: 'bot',
};
return [...prevMessages.slice(0, prevMessages.length - 1), botMessage]; // Update the last bot message
});
}
} catch (error) {
// If parsing fails (for example, the chunk is not valid JSON), log it and continue
console.warn("Failed to parse chunk as JSON:", decodedChunk);
}
}
} catch (error) {
console.error("Error fetching Falcon response:", error);
}
}
const handleSendMessage = async () => {
if (inputMessage.trim() === '') return;
const userQuery = {
id: Date.now(),
text: inputMessage,
sender: 'user',
};
try {
setMessages((prevMessages) => [...prevMessages, userQuery]);
setInputMessage('');
// Initialize a temporary bot message (empty text) for progressive rendering
setMessages((prevMessages) => [
...prevMessages,
{ id: Date.now() + 1, text: '', sender: 'bot' }
]);
// Start fetching the response, and update as chunks are received
await getModelResponse(inputMessage);
} catch (error) {
console.error('Error sending message:', error);
}
Keyboard.dismiss();
if (inputRef.current) {
inputRef.current.focus();
}
};
const renderMessage = (item) => {
return (
{item.text}
);
};
const handleKeyPress = (e) => {
if (e.nativeEvent.key === 'Enter') {
handleSendMessage();
}
};
return (
<>
scrollViewRef.current.scrollToEnd({ animated: true })
}
style={styles.messagesContainer}
>
{messages.map(renderMessage)}
Send
>
);
};
const styles = StyleSheet.create({
chatContainer: {
flex: 1,
},
messagesContainer: {
flex: 1,
},
messageContainer: {
maxWidth: '80%',
padding: 10,
marginBottom: 10,
borderRadius: 10,
borderWidth: 1,
borderColor: 'black',
backgroundColor: 'white',
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
userMessage: {
backgroundColor: '#30b5e7',
alignSelf: 'flex-start',
},
botMessage: {
backgroundColor: '#73c4e2',
alignSelf: 'flex-end',
},
inputContainer: {
flexDirection: 'row',
alignItems: 'flex-end',
},
input: {
flex: 1,
padding: 10,
borderRadius: 20,
backgroundColor: '#fff',
marginRight: 10,
},
sendButton: {
backgroundColor: '#0078d4',
color: '#fff',
paddingHorizontal: 15,
paddingVertical: 8,
borderRadius: 10,
},
});
export default ChatbotUI;
برنامه React Native را شروع کنید
# npm install
# npm run web
خروجی:
خروجی را می توان در ویدیو تماشا کرد
پایان
ساختن یک چت بابات با استفاده از مدل های Ollama با اجرای مدل های بزرگ زبان به صورت محلی ، یک تجربه قدرتمند و خصوصی را فراهم می کند. با ادغام اولاما با یک میکروسرویس FastAPI و یک جبهه بومی React ، ما یک چت بابات یکپارچه و تعاملی ایجاد کردیم که نمایش داده های کاربر را به طور کارآمد پردازش می کند.
این رویکرد ارائه می دهد:
control کنترل کامل بر روی مدل های AI بدون وابستگی به ابر.
performance عملکرد بهینه سازی شده با استفاده از شتاب GPU در صورت وجود.
✅ حریم خصوصی پیشرفته ، زیرا هیچ داده ای به سرورهای خارجی ارسال نمی شود.
این که آیا شما در حال توسعه یک دستیار هوش مصنوعی ، یک ربات پشتیبانی مشتری یا آزمایش LLMS هستید ، این مجموعه پایه و اساس محکمی را برای پیشرفت های بیشتر و سفارشی سازی فراهم می کند. 🚀