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

الوحدة 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، وسجلّ الوسيط هو الوحيد الذي يعطي محاسبة.