Ollama: أساسيات REST API

REST API هو الواجهة الشاملة لـ Ollama — أي لغة، أي إطار عمل، فقط أرسل طلب HTTP وستكون متصلًا.

⚠️ ملاحظة: واجهة Ollama REST API لا تحتوي على مصادقة مدمجة — أي شخص يمكنه الوصول إلى منفذ الخدمة يمكنه استدعاء النماذج بحرية وعرض قائمة النماذج المثبتة. في الإنتاج، يجب إضافة مصادقة API Key عبر وكيل عكسي (مثل Nginx/Caddy)، وإلا فإن خدمة الذكاء الاصطناعي الخاصة بك تواجه مخاطر الاستخدام غير المشروع وتسريب البيانات واستنزاف الموارد.

📋 المتطلبات المسبقة: يجب أن تتقن ما يلي أولًا

1. ماذا ستتعلم


2. قصة حقيقية من مؤسس SaaS

(1) المشكلة: الردود اليدوية غير فعالة

أسست أليس منصة التجارة الإلكترونية GlobalShop. فريق خدمة العملاء المكون من 50 شخصًا يتعامل مع أكثر من 2000 تذكرة يوميًا. كل تذكرة تستغرق في المتوسط 8 دقائق، ووقت انتظار العملاء يتجاوز 30 دقيقة. تحتاج لدمج نموذج لغوي كبير في نظام خدمة العملاء عبر API لإنشاء مسودات ردود تلقائية.

(2) الحل: REST API يُولّد الردود فورًا

باستخدام curl لاستدعاء واجهة Ollama API، تُنشأ مسودات ردود خدمة العملاء في 3 ثوانٍ — يحتاج الوكلاء فقط للمراجعة والتأكيد:

BASH
curl http://localhost:11434/api/chat -d '{
  "model": "qwen2.5",
  "messages": [{"role": "user", "content": "Refund for order #12345"}]
}'

⚠️ تحذير: واجهة Ollama API لا تحتوي على مصادقة مدمجة — أي شخص يمكنه الوصول إلى المنفذ يمكنه استدعاءها. في الإنتاج، يجب إضافة مصادقة API Key عبر وكيل عكسي (Nginx/Caddy). انظر الدرس 20 لتقوية الأمان.

💡 نصيحة: واجهة API المتدفقة (stream: true) مناسبة لواجهات المحادثة مع تأثير الكتابة الفورية؛ غير المتدفقة (stream: false) أفضل للمعالجة الدفعية وتكامل واجهة برمجة التطبيقات الخلفية. يُوصى بغير المتدفقة لتكامل API لأنها أبسط.

ℹ️ معلومة: الافتراضي في Ollama هو http://127.0.0.1:11434، يمكن الوصول إليه من الجهاز المحلي فقط. للوصول من الشبكة المحلية، اضبط المتغير البيئي OLLAMA_HOST، لكن انتبه للمخاطر الأمنية.

3. دليل نقاط نهاية API الكامل

(1) مقارنة نقطتي النهاية الأساسيتين

البُعد /api/generate /api/chat
الغرض إنشاء نص أحادي الطلقة حوار متعدد الأدوار
الإدخال model + prompt مصفوفة messages
السياق طلب واحد يدعم سجل المحادثة
توافق API سطر الأوامر ollama run سطر الأوامر ollama chat
حالة الاستخدام إنشاء، إكمال، ترجمة خدمة عملاء، مساعدون، استنتاج متعدد الأدوار
100%
sequenceDiagram
    participant C as Client
    participant O as Ollama Server
    C->>O: POST /api/chat {messages, model, stream}
    O-->>C: NDJSON {message, done: false}
    O-->>C: NDJSON {message, done: false}
    O-->>C: NDJSON {message, done: true, stats}

(2) معلمات الطلب الشائعة

المعلمة النوع الافتراضي الوصف
model string مطلوب اسم النموذج
stream bool true هل الإخراج متدفق
options object معلمات الاستنتاج (انظر القسم التالي)
format string تنسيق الإخراج: json
keep_alive string 5m مدة بقاء النموذج في الذاكرة

▶ مثال 1: طلب إنشاء أحادي الطلقة

BASH
# طلب إنشاء غير متدفق
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2",
  "prompt": "Write a haiku about coding",
  "stream": false
}'

# الاستجابة (مختصرة)
# {
#   "model": "llama3.2",
#   "response": "Lines of logic flow,\nBug hides in the deep syntax—\nSemicolon found.",
#   "done": true,
#   "total_duration": 2500000000,
#   "eval_count": 18
# }

الإخراج:

TEXT
{"status":"ok","data":{}}

▶ مثال 2: طلب حوار متعدد الأدوار

BASH
# محادثة بسجل رسائل
curl http://localhost:11434/api/chat -d '{
  "model": "qwen2.5",
  "messages": [
    {"role": "system", "content": "You are a helpful customer service agent."},
    {"role": "user", "content": "I want to return my order #12345"},
    {"role": "assistant", "content": "I can help with that. May I ask the reason for the return?"},
    {"role": "user", "content": "The product arrived damaged"}
  ],
  "stream": false
}'

الإخراج:

TEXT
{"status":"ok","data":{}}

4. تحليل الاستجابات المتدفقة

💡 نصيحة: المتدفقة (stream: true) وغير المتدفقة (stream: false) لكل منهما حالات استخدام: المتدفقة لواجهات المحادثة مع تأثير الكتابة الفوري حتى يرى المستخدم المحتوى بدون انتظار الاستجابة الكاملة؛ غير المتدفقة للمعالجة الدفعية وتكامل واجهة برمجة التطبيقات الخلفية حيث الحصول على استجابة JSON كاملة أسهل للتحليل البرمجي. نوصى بالبدء بغير المتدفقة للتحقق من المنطق، ثم التبديل للمتدفقة لتحسين تجربة المستخدم.

(1) شرح صيغة NDJSON

تستخدم الاستجابات المتدفقة NDJSON (JSON المحدد بأسطر جديدة)، كائن JSON واحد لكل سطر:

TEXT
{"model":"llama3.2","message":{"role":"assistant","content":"I"},"done":false}
{"model":"llama3.2","message":{"role":"assistant","content":" can"},"done":false}
{"model":"llama3.2","message":{"role":"assistant","content":" help"},"done":false}
{"model":"llama3.2","message":{"role":"assistant","content":""},"done":true,"total_duration":1500000000}
الحقل الوصف
message.content شظية النص لهذه القطعة
done هل هذه القطعة الأخيرة
total_duration إجمالي وقت الاستنتاج (نانوثانية)
eval_count عدد الرموز المُنشأة
prompt_eval_count عدد رموز الإدخال

(2) مقارنة المتدفقة وغير المتدفقة

البُعد المتدفقة (stream: true) غير المتدفقة (stream: false)
تجربة المستخدم إخراج حرف بحرف فوري انتظار الاستجابة الكاملة
كمون أول رمز منخفض جدًا (~200 مللي ثانية) الانتظار حتى اكتمال الإنشاء
تعقيد التنفيذ يتطلب تحليل NDJSON قراءة JSON مباشرة
حالة الاستخدام واجهات المحادثة، العرض الفوري معالجة دفعية، واجهات خلفية

▶ مثال 3: تحليل الاستجابات المتدفقة

BASH
# طلب متدفق مع إخراج فوري
curl http://localhost:11434/api/chat -d '{
  "model": "llama3.2",
  "messages": [{"role": "user", "content": "Hello!"}],
  "stream": true
}' | while read -r line; do
    # استخراج حقل المحتوى من كل سطر NDJSON
    echo "$line" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if data.get('message', {}).get('content'):
    print(data['message']['content'], end='', flush=True)
"
done

الإخراج:

TEXT
{"status":"ok","data":{}}

5. ضبط معلمات الاستنتاج

(1) جدول المعلمات الأساسية

المعلمة النوع النطاق الافتراضي التأثير
temperature float 0-2 0.8 يتحكم في العشوائية؛ القيم الأخرى أكثر حسمًا
top_p float 0-1 0.9 أخذ العينات النووية، يحد نطاق الرموز المرشحة
top_k int 1-100 40 أخذ عينات من أعلى K مرشحين فقط
num_ctx int 128-131072 2048 حجم نافذة السياق
repeat_penalty float 1-2 1.1 معامل عقاب التكرار
seed int أي -1 بذرة عشوائية (-1 = عشوائي)

(2) ضبط المعلمات حسب السيناريو

السيناريو temperature top_p ملاحظات
توليد الكود 0.1-0.3 0.9 يتطلب الحسم والدقة
ردود خدمة العملاء 0.3-0.5 0.9 مستقر مع سماح بتنوع معتدل
الكتابة الإبداعية 0.7-1.0 0.95 يتطلب تنوعًا وإبداعًا
تحليل البيانات 0.1-0.2 0.9 يجب أن يكون دقيقًا، لا هلاوس مسموحة
⚠️ تحذير: num_ctx يؤثر مباشرة على استخدام الذاكرة. نموذج 8B مع num_ctx=8192 يحتاج حوالي 6 غيغابايت VRAM؛ num_ctx=32768 يحتاج حوالي 12 غيغابايت VRAM. اضبطه حسب الحاجة — لا تزيده بشكل أعمى.

▶ مثال 4: مقارنة ضبط المعلمات

BASH
# temperature منخفض: إخراج حاسم
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2",
  "prompt": "What is 2+2?",
  "stream": false,
  "options": {"temperature": 0.1}
}'
# Response: "2+2 equals 4."

# temperature مرتفع: إخراج إبداعي
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2",
  "prompt": "What is 2+2?",
  "stream": false,
  "options": {"temperature": 1.5}
}'
# Response: "In the realm of mathematics, 2+2 opens the door to 4..."

الإخراج:

TEXT
{"status":"ok","data":{}}

▶ مثال 5: إخراج بصيغة JSON

BASH
# فرض تنسيق إخراج JSON
curl http://localhost:11434/api/chat -d '{
  "model": "llama3.2",
  "messages": [
    {"role": "system", "content": "You are a product catalog API. Return JSON only."},
    {"role": "user", "content": "List 3 laptops under $500"}
  ],
  "format": "json",
  "stream": false,
  "options": {"temperature": 0.3}
}'

# الاستجابة بصيغة JSON صالحة
# {"products":[{"name":"Acer Aspire 5","price":449,"spec":"8GB RAM, 256GB SSD"},...]}

الإخراج:

TEXT
{"status":"ok","data":{}}

6. مثال شامل: النموذج الأولي لواجهة برمجة تطبيقات خدمة العملاء SupportBot

💡 نصيحة: عند استدعاء API في الإنتاج، تأكد من ضبط معلمة keep_alive (مثلاً، "keep_alive": "5m") لتجنب التحميل/التفريغ المتكرر للنموذج الذي يسبب تأخيرات في الاستجابة.

BASH
#!/bin/bash
# ============================================
# شامل: النموذج الأولي لواجهة برمجة تطبيقات SupportBot
# خدمة عملاء متعددة الأدوار عبر REST API
# ============================================

API="http://localhost:11434/api/chat"
MODEL="qwen2.5"

# دالة: إرسال رسالة محادثة واستخراج الرد
chat() {
    local system_prompt="$1"
    local user_msg="$2"
    local temp="${3:-0.4}"

    curl -s "$API" -d "$(cat <<EOF
{
  "model": "$MODEL",
  "messages": [
    {"role": "system", "content": "$system_prompt"},
    {"role": "user", "content": "$user_msg"}
  ],
  "stream": false,
  "options": {"temperature": $temp, "num_ctx": 4096}
}
EOF
)" | python3 -c "import sys,json; print(json.load(sys.stdin)['message']['content'])"
}

# موجه نظام خدمة العملاء
SYSTEM="You are SupportBot, a customer service agent for an e-commerce store. Be polite, concise, and helpful. If you cannot answer, say 'Let me connect you with a human agent.'"

# محاكاة تفاعلات العملاء
echo "=== Query 1: Order Status ==="
chat "$SYSTEM" "Where is my order #88765? It has been 5 days."

echo ""
echo "=== Query 2: Return Request ==="
chat "$SYSTEM" "I received a damaged item. Order #12345. I want a refund."

echo ""
echo "=== Query 3: Product Question ==="
chat "$SYSTEM" "Does the wireless headphone support Bluetooth 5.3?"

echo ""
echo "=== Benchmark ==="
time chat "$SYSTEM" "Hello" > /dev/null
💻 الإخراج:

TEXT
=== Query 1: Order Status ===
I'd be happy to check on your order #88765. Based on our tracking system, your order is currently in transit and expected to arrive within 2-3 business days. You can track it at track.example.com/88765.

=== Query 2: Return Request ===
I'm sorry to hear about the damaged item. For order #12345, I've initiated a return request. You'll receive a prepaid shipping label via email within 24 hours. Once we receive the item, a full refund will be processed within 3-5 business days.

=== Query 3: Product Question ===
Yes, our wireless headphones support Bluetooth 5.3 with a range of up to 15 meters. They also feature active noise cancellation and 30-hour battery life.

❓ أسئلة شائعة

س لماذا يُرجع طلب curl خطأ connection refused؟
ج خدمة Ollama لا تعمل. شغّل ollama serve أو تحقق من خدمة systemd: sudo systemctl status ollama.
س هل أختار stream: true أم stream: false؟
ج استخدم stream: true لواجهات المحادثة الأمامية للحصول على تأثير الكتابة الفورية. استخدم stream: false للمعالجة الخلفية الدفعية للحصول على استجابات كاملة مباشرة. يُوصى بغير المتدفقة لتكامل API لأنها أبسط.
س كيف أحدّ من طول الإخراج؟
ج اضبط معلمة num_predict، مثلاً، "num_predict": 200 لتحديد الإنشاء بـ 200 رمز. لاحظ أن هذا عدد رموز وليس أحرف.
س هل يضمن format: json إخراج JSON صالح؟
ج يعمل في معظم الحالات، لكن ليس مضمونًا بنسبة 100%. نوصي بإضافة تحقق JSON في طبقة التطبيق، مع إعادة المحاولة أو الرجوع للمعالجة النصية عند فشل التحليل.
س كيف يحافظ الحوار متعدد الأدوار على السياق؟
ج يجب على العميل الحفاظ على مصفوفة messages بنفسه، وإرسال سجل المحادثة الكامل مع كل طلب. خادم Ollama لا يخزن حالة الجلسة.
س هل هناك حدود تزامن على استدعاءات API؟
ج افتراضيًا، يُعالج طلب واحد فقط في كل مرة. اضبط المتغير البيئي OLLAMA_NUM_PARALLEL لزيادة التزامن، لكن هذا يتطلب VRAM إضافية. انظر الدرس 19 لضبط الأداء.

📖 ملخص


📝 تمارين

  1. أساسي (صعوبة ⭐): استخدم curl لاستدعاء /api/generate لتوليد وصف منتج، وجرّب كلتا stream: true وstream: false لمراقبة الفرق.
  2. متوسط (صعوبة ⭐⭐): استخدم /api/chat لتنفيذ حوار من 3 أدوار، مع الحفاظ يدويًا على مصفوفة messages، وإخراج الرد الكامل في كل دور.
  3. متقدم (صعوبة ⭐⭐⭐): اكتب سكربت Shell يحاكي سير عمل خدمة عملاء SupportBot — يستقبل أسئلة، يستدعي API، يُرجع نتائج تصنيف (نية + رد) بصيغة JSON، مع دعم الإخراج المتدفق الفوري.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%