الفهم الصحيح: لماذا لا تحتاج GPU لتطبيق AI؟
هناك فكرة خاطئة شائعة: أن تطوير تطبيق ذكاء اصطناعي يستلزم سيرفراً بـ GPU قوية وعشرات الغيغابايتات من VRAM. هذا صحيح فقط إذا كنت تريد تشغيل النموذج محلياً — وهو ما لا يحتاجه 99% من المطورين.
الواقع أبسط بكثير: Claude API وOpenAI API وGemini API تعمل كلها على نفس المبدأ — النموذج الضخم يعمل على سيرفرات الشركة، وأنت ترسل طلبات (requests) وتستقبل ردوداً. سيرفرك لا يحتاج لأي GPU — فقط يحتاج لتشغيل تطبيقك الذي يتوسط بين المستخدم والـ API.
ما الذي سنبنيه؟
Chatbot متكامل يشمل:
✅ Backend بـ Python (FastAPI) يتصل بـ Claude API
✅ واجهة ويب بسيطة تدعم العربية
✅ ذاكرة محادثة (conversation history)
✅ نشر بـ Docker على VPS
✅ SSL مجاني عبر Let's Encrypt
المتطلبات: Python، Docker، VPS بـ 2GB RAM كافية تماماً، وحساب على Anthropic Console للحصول على API Key.
الخطوة 1: Backend بـ FastAPI
أنشئ مجلد المشروع وثبّت المكتبات:
mkdir ai-chatbot && cd ai-chatbot
python -m venv venv && source venv/bin/activate
pip install fastapi uvicorn anthropic python-dotenv
ملف
main.py
— قلب التطبيق:
from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List
import anthropic, os
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=["*"],
allow_methods=["*"], allow_headers=["*"])
client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
class Message(BaseModel):
role: str
content: str
class ChatRequest(BaseModel):
messages: List[Message]
system: str = "أنت مساعد ذكي ومفيد. أجب دائماً بالعربية."
@app.post("/chat")
async def chat(req: ChatRequest):
try:
res = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=req.system,
messages=[{"role": m.role, "content": m.content}
for m in req.messages]
)
return {"reply": res.content[0].text}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
def health(): return {"status": "ok"}
app.mount("/", StaticFiles(directory="static", html=True), name="static")
الخطوة 2: الواجهة الأمامية
mkdir static && cat > static/index.html << 'HTMLEOF'
<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>مساعد AI</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Segoe UI', Arial, sans-serif;
background: #f0f2f5; height: 100vh; display: flex;
flex-direction: column; align-items: center; justify-content: center; }
.container { width: 100%; max-width: 720px; background: white;
border-radius: 16px; box-shadow: 0 4px 24px rgba(0,0,0,.1);
display: flex; flex-direction: column; height: 85vh; }
header { padding: 18px 24px; background: #1a1a2e;
border-radius: 16px 16px 0 0; color: white; font-size: 18px; font-weight: bold; }
#chat { flex: 1; overflow-y: auto; padding: 20px; display: flex;
flex-direction: column; gap: 12px; }
.msg { padding: 12px 16px; border-radius: 12px; max-width: 78%; line-height: 1.6; font-size: 15px; }
.user { background: #1a1a2e; color: white; align-self: flex-start; border-radius: 12px 12px 4px 12px; }
.assistant { background: #f0f2f5; color: #1a1a2e; align-self: flex-end; border-radius: 12px 12px 12px 4px; }
.typing { color: #888; font-style: italic; font-size: 14px; align-self: flex-end; }
footer { padding: 16px; border-top: 1px solid #eee; display: flex; gap: 10px; }
input { flex: 1; padding: 12px 16px; border: 1.5px solid #ddd;
border-radius: 10px; font-size: 15px; outline: none; direction: rtl; }
input:focus { border-color: #1a1a2e; }
button { padding: 12px 22px; background: #1a1a2e; color: white;
border: none; border-radius: 10px; cursor: pointer; font-size: 15px; }
button:hover { background: #2d2d5e; }
</style>
</head>
<body>
<div class="container">
<header>🤖 مساعد AI مبني بـ Claude API</header>
<div id="chat"></div>
<footer>
<input id="msg" placeholder="اكتب رسالتك..."
onkeypress="if(event.key==='Enter')send()">
<button onclick="send()">إرسال</button>
</footer>
</div>
<script>
const history = [];
async function send() {
const el = document.getElementById('msg');
const text = el.value.trim();
if (!text) return;
el.value = '';
addMsg('user', text);
history.push({role:'user', content: text});
const typing = addMsg('typing', 'يكتب...');
const res = await fetch('/chat', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({messages: history})
});
typing.remove();
const data = await res.json();
history.push({role:'assistant', content: data.reply});
addMsg('assistant', data.reply);
}
function addMsg(cls, text) {
const d = document.createElement('div');
d.className = 'msg ' + cls;
d.textContent = text;
const chat = document.getElementById('chat');
chat.appendChild(d);
chat.scrollTop = chat.scrollHeight;
return d;
}
</script>
</body></html>
HTMLEOF
الخطوة 3: حزم التطبيق بـ Docker
# Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
EOF
# requirements.txt
cat > requirements.txt << 'EOF'
Hostinger
✨ استخدم هذا الرابط للحصول على خصم يبلغ 20% عند إتمام عملية الشراء.
رابط إحالة (قد نربح عمولة عند الشراء)