انتقل إلى المحتوى الرئيسي

الوحدة 8 — التكامل مع التطبيقات الموجودة

قيمة Ollama تظهر حين يُدمَج في سير عمل قائم لا حين يُستعمل من الطرفيّة. هذه الوحدة تجمع الحالات الأكثر تكرارًا في المكتب: سكربت مهمّة، سلسلة LangChain، واجهة ويب للفريق، وتعرّض آمن للنماذج على الشبكة الداخليّة.

سكربت أعمال مباشر​

قسم الاستقبال يقرأ كلّ صباح مئة رسالة بريديّة ويصنّفها إلى: طلب موعد، شكوى، فاتورة، آخر. سكربت مباشر:

import ollama
from imap_tools import MailBox

with MailBox("imap.mkt-avocat.tn").login("boite@amana.tn", "***") as mb:
for msg in mb.fetch("UNSEEN"):
r = ollama.chat(
model="amana-classifier",
messages=[
{"role": "user", "content": f"صنّف:\n{msg.text[:1500]}"}
],
options={"temperature": 0.0, "num_predict": 8},
)
etiquette = r["message"]["content"].strip()
mb.move(msg.uid, f"INBOX/{etiquette}")

النموذج amana-classifier جاء من الوحدة 5. السكربت 15 سطرًا، يعمل بلا اتّصال بالإنترنت، ولا يخرج أيّ مضمون من المكتب. هذا هو الاستعمال الأنقى لـ Ollama.

LangChain​

المكتبة الرسميّة توفّر ChatOllama وOllamaEmbeddings (راجع الدورة 26 لتفاصيل السلاسل):

from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_core.prompts import ChatPromptTemplate

modele = ChatOllama(model="amana-redaction", temperature=0.4)
embed = OllamaEmbeddings(model="nomic-embed-text")

chaine = (
ChatPromptTemplate.from_template(
"بصفتك محاميًا، اقترح ردًّا مهذّبًا على الرسالة التالية:\n{message}"
)
| modele
)

sortie = chaine.invoke({"message": "أستاذ، لم أتلقّ الفاتورة الأخيرة، هل ثمّة تأخير؟"})

كلّ سلسلة LangChain مكتوبة لـ OpenAI تعمل بالتبديل: يكفي استبدال ChatOpenAI بـ ChatOllama. الوكلاء وأدوات LangGraph مدعومة عبر tool_calls في Ollama (الوحدة 4).

Open WebUI: واجهة ويب للفريق​

Open WebUI (سابقًا Ollama WebUI) يُشغَّل في حاوية Docker على الخادم:

docker run -d -p 3000:8080 \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
-v open-webui:/app/backend/data \
--name open-webui \
ghcr.io/open-webui/open-webui:main

يعطي واجهة تشبه ChatGPT: تسجيل مستخدمين، محادثات محفوظة، اختيار النموذج، رفع ملفّات، RAG مدمج. للمكتب، هذا يوفّر واجهة رسميّة للمساعدين دون أن يكتبوا سطر أوامر.

الأدوار (admin وuser) تسمح بالحدّ من صلاحيّات الجلب والحذف: المساعد يستطيع أن يحادث ويرفع ملفًّا، لا أن يجلب نموذجًا جديدًا.

التعرّض على الشبكة الداخليّة​

إن أردنا أن يستعمل زملاء من محطّات أخرى نموذج المحطّة الرئيسيّة، نغيّر OLLAMA_HOST=0.0.0.0:11434. لكنّ هذا يفتح الواجهة بلا مصادقة. الحلّ: وسيط Nginx يفرض شهادة TLS ومفتاح API:

server {
listen 443 ssl http2;
server_name assistant.interne.amana.tn;

ssl_certificate /etc/ssl/amana.crt;
ssl_certificate_key /etc/ssl/amana.key;

location / {
if ($http_authorization != "Bearer votre-jete-secret") {
return 401;
}
proxy_pass http://127.0.0.1:11434;
proxy_read_timeout 300s;
proxy_buffering off; # مهمّ للبثّ
}
}

العميل يستعمل نفس واجهة Ollama مع رأس Authorization:

import httpx

r = httpx.post(
"https://assistant.interne.amana.tn/api/chat",
headers={"Authorization": "Bearer votre-jete-secret"},
json={"model": "amana-assistant", "messages": [...]},
timeout=300,
)

proxy_buffering off ضروريّ حين نستعمل البثّ، وإلّا خزّن Nginx الجواب كاملًا قبل تسليمه، فضاعت فائدة البثّ.

قواعد أمنيّة لا تفاوض فيها​

  1. لا Ollama عاريًا على الإنترنت أبدًا. حتّى على IP ديناميكيّ، بوتات المسح ستجده في ساعات.
  2. مصادقة قبل الوصول: مفتاح ثابت للسكربتات، مصادقة مستخدم (OIDC مثلًا) للواجهات البشريّة.
  3. حدّ نداءات: Nginx limit_req يمنع تشبّع النموذج بسبب تطبيق مخطئ يستدعي بلا سقف.
  4. جدار حماية داخليّ: القاعدة أنّ الشبكة الداخليّة ليست موثوقة تلقائيًّا. اسمح فقط لعناوين IP التي تحتاج فعلًا.
  5. سجلّات: Nginx يسجّل كلّ نداء بمَن؛ Ollama لا يعرف مَن نادى. السجلّ الوحيد الذي يعطي محاسبة هو سجلّ الوسيط.

أنماط تكامل خاصّة​

VS Code Continue​

إضافة مفتوحة المصدر تستدعي Ollama لإكمال الشيفرة أو المحادثة داخل المحرّر. تُستعمل نماذج شيفرة (qwen2.5-coder:7b، deepseek-coder) وتشتغل تمامًا محلّيًّا. مفيدة لفريق تطوير المكتب الداخليّ الذي لا يريد إرسال شيفرة عملائه إلى GitHub Copilot.

n8n وMake​

منصّات الأتمتة تستعمل عقدة HTTP عاديّة لاستدعاء /api/chat أو /v1/chat/completions. هكذا تصير Ollama جزءًا من سير عمل بلا كتابة سكربت.

تطبيقات سطح المكتب​

Enchanted (macOS)، Msty، LM Studio: كلّها تتّصل بخادم Ollama محلّيّ أو بعيد. يعطي هذا للمكتب واجهات جاهزة بلا تطوير.

الخيط الأحمر​

في المكتب، البنية تصير هكذا:

[محطّة الشريك]              [حاسوب مساعد 1]         [حاسوب مساعد 2]
Ollama + Open WebUI VS Code + Continue Enchanted (macOS)
↑ ↓ ↓
└──────── Nginx TLS + Bearer ← ─────────── جدار حماية داخليّ

كلّ من الأجهزة يخاطب https://assistant.interne.amana.tn بمفتاح ثابت. Open WebUI يُدار من المحطّة الرئيسيّة ويستعمل النماذج المُعرَّفة في Modelfile (amana-assistant، amana-classifier، amana-embeddings).

إعادة استعمال شيفرة OpenAI ليست هجرة كاملة

واجهة /v1 تكفي 90 % من الحالات، لكنّها ليست مطابقة تمامًا: بعض معلمات OpenAI الحديثة (JSON Schema المفصّل، Prompt Caching) غير مدعومة. اختبر شيفرتك فعلًا بعد التبديل، لا تفترض التطابق التامّ.

الخلاصة​

  • سكربت أعمال بضعة أسطر يكفي لأتمتة مهامّ متكرّرة بلا خروج بيانات من المكتب.
  • LangChain (الدورة 26) وأدوات LangGraph مدعومة عبر ChatOllama وtool_calls.
  • Open WebUI يعطي واجهة رسميّة للفريق، مع أدوار وصلاحيّات، بلا تطوير.
  • التعرّض على الشبكة الداخليّة يمرّ حصرًا عبر وسيط بمصادقة وTLS، وسجلّ الوسيط هو الوحيد الذي يعطي محاسبة.