بناء روبوت دردشة ذكاء اصطناعي محلي باستخدام Ollama و Next.js: الدليل الشامل

بياناتك لا تغادر جهازك أبداً. في هذا الدليل، ستبني روبوت دردشة ذكاء اصطناعي يعمل بالكامل على جهازك المحلي باستخدام Ollama و Next.js — بدون مفاتيح API، بدون خدمات سحابية، بدون مشاركة بيانات.
ما ستتعلمه
بنهاية هذا الدليل، ستكون قادراً على:
- تثبيت وتكوين Ollama لتشغيل نماذج اللغة الكبيرة محلياً
- بناء واجهة دردشة Next.js مع بث الردود في الوقت الفعلي
- دمج Ollama مع Vercel AI SDK للحصول على تجربة احترافية
- إضافة اختيار النماذج ليتمكن المستخدمون من التبديل بين النماذج
- التعامل مع الأخطاء بأناقة عندما لا يعمل Ollama
- فهم المفاضلات بين الذكاء الاصطناعي المحلي والسحابي
المتطلبات الأساسية
قبل البدء، تأكد من وجود:
- Node.js 20+ مثبت (
node --version) - معرفة أساسية بـ React و TypeScript
- محرر أكواد — يُنصح بـ VS Code أو Cursor
- ذاكرة 8 جيجابايت على الأقل (16 جيجابايت مُوصى بها للنماذج الأكبر)
- macOS أو Linux أو Windows مع WSL2
لماذا تشغيل الذكاء الاصطناعي محلياً؟
خدمات الذكاء الاصطناعي السحابية مثل OpenAI و Anthropic قوية، لكنها تأتي مع تنازلات:
| الاعتبار | الذكاء الاصطناعي السحابي | الذكاء الاصطناعي المحلي (Ollama) |
|---|---|---|
| الخصوصية | البيانات تُرسل لخوادم خارجية | البيانات تبقى على جهازك |
| التكلفة | دفع لكل رمز (token) | مجاني بعد التحميل |
| زمن الاستجابة | يتطلب رحلة عبر الشبكة | وصول مباشر للعتاد |
| التوفر | يتطلب إنترنت | يعمل بدون اتصال |
| التخصيص | محدود بنماذج المزود | تشغيل أي نموذج مفتوح |
للأدوات الداخلية ومعالجة البيانات الحساسة والتطبيقات التي تعمل بدون إنترنت، الذكاء الاصطناعي المحلي هو الخيار الأفضل.
الخطوة 1: تثبيت Ollama
Ollama هو بيئة تشغيل خفيفة لتشغيل نماذج اللغة الكبيرة محلياً. يتولى تحميل النماذج وتكميمها وتقديمها من خلال واجهة برمجة تطبيقات بسيطة.
macOS
brew install ollamaأو حمّله من ollama.com.
Linux
curl -fsSL https://ollama.com/install.sh | shWindows
حمّل المثبت من ollama.com أو استخدم WSL2 مع تعليمات Linux.
التحقق من التثبيت
ollama --versionشغّل خادم Ollama:
ollama serveهذا يُشغّل خادم API محلي على http://localhost:11434.
الخطوة 2: تحميل أول نموذج
يوفر Ollama الوصول إلى مئات النماذج مفتوحة المصدر. لنبدأ بـ Llama 3.2، نموذج Meta المدمج والقادر:
ollama pull llama3.2هذا يُحمّل نموذج 3 مليار معامل (~2 جيجابايت). للحصول على خيار أخف:
ollama pull llama3.2:1bالنماذج الموصى بها لعام 2026
| النموذج | الحجم | الأفضل لـ |
|---|---|---|
llama3.2:1b | 700 ميغابايت | استجابات سريعة، أجهزة محدودة الموارد |
llama3.2 | 2 جيجابايت | دردشة عامة، توازن جيد |
mistral | 4 جيجابايت | استدلال قوي، متعدد اللغات |
qwen3:4b | 2.5 جيجابايت | استدلال متسلسل |
qwen2.5-coder:7b | 4.5 جيجابايت | توليد ومراجعة الأكواد |
اختبر نموذجك في الطرفية:
ollama run llama3.2
>>> What is the capital of Tunisia?يجب أن ترى رداً مثل: "The capital of Tunisia is Tunis."
الخطوة 3: إنشاء مشروع Next.js
الآن لنبنِ واجهة الدردشة. أنشئ مشروع Next.js جديد:
npx create-next-app@latest ollama-chat --typescript --tailwind --app --src-dir
cd ollama-chatثبّت الحزم المطلوبة:
npm install ai ollama-ai-provider @ai-sdk/reactما يفعله كل حزمة:
ai— نواة Vercel AI SDK معstreamTextوgenerateTextوالمزيدollama-ai-provider— مزود مجتمعي يربط AI SDK بـ Ollama@ai-sdk/react— خطافات React مثلuseChatلبناء واجهات الدردشة
الخطوة 4: تكوين مزود Ollama
أنشئ تكوين عميل Ollama مشترك:
// src/lib/ollama.ts
import { createOllama } from 'ollama-ai-provider';
export const ollama = createOllama({
baseURL: process.env.OLLAMA_BASE_URL ?? 'http://localhost:11434/api',
});
export const DEFAULT_MODEL = process.env.OLLAMA_DEFAULT_MODEL ?? 'llama3.2';أضف متغيرات البيئة:
# .env.local
OLLAMA_BASE_URL=http://localhost:11434/api
OLLAMA_DEFAULT_MODEL=llama3.2الخطوة 5: بناء مسار API للدردشة
هذا هو جوهر تطبيقنا — مسار API في Next.js يبث الردود من Ollama.
// src/app/api/chat/route.ts
import { streamText } from 'ai';
import { ollama, DEFAULT_MODEL } from '@/lib/ollama';
export const maxDuration = 60;
export async function POST(req: Request) {
try {
const { messages, model } = await req.json();
const result = await streamText({
model: ollama(model ?? DEFAULT_MODEL),
system: 'You are a helpful, concise assistant. Answer questions clearly and accurately.',
messages,
});
return result.toDataStreamResponse();
} catch (error) {
if (error instanceof Error && error.message.includes('ECONNREFUSED')) {
return new Response(
JSON.stringify({
error: 'Ollama is not running. Start it with: ollama serve',
}),
{ status: 503, headers: { 'Content-Type': 'application/json' } }
);
}
return new Response(
JSON.stringify({ error: 'An unexpected error occurred' }),
{ status: 500, headers: { 'Content-Type': 'application/json' } }
);
}
}التفاصيل الرئيسية:
maxDuration = 60يمنح المسار حتى 60 ثانية للبث، مهم للنماذج الأكبرstreamTextيتولى بروتوكول البث بين Ollama والعميلtoDataStreamResponse()يحوّل البث إلى الصيغة التي يتوقعهاuseChat- معالجة الأخطاء تلتقط فشل الاتصال عندما لا يعمل Ollama
الخطوة 6: إضافة نقطة نهاية للنماذج
دع المستخدمين يرون النماذج المتاحة محلياً:
// src/app/api/models/route.ts
export async function GET() {
try {
const baseURL = process.env.OLLAMA_BASE_URL?.replace('/api', '')
?? 'http://localhost:11434';
const res = await fetch(`${baseURL}/api/tags`);
if (!res.ok) {
throw new Error('Failed to fetch models');
}
const data = await res.json();
const models = data.models.map((m: { name: string; size: number }) => ({
id: m.name,
label: m.name,
size: `${(m.size / 1e9).toFixed(1)}GB`,
}));
return Response.json({ models });
} catch {
return Response.json({ models: [], error: 'Ollama is not available' });
}
}الخطوة 7: بناء مكون الدردشة
الآن الجزء الممتع — واجهة الدردشة. أنشئ مكون الدردشة الرئيسي:
// src/components/Chat.tsx
'use client';
import { useChat } from '@ai-sdk/react';
import { useState, useRef, useEffect } from 'react';
import { ModelSelector } from './ModelSelector';
export function Chat() {
const [model, setModel] = useState('llama3.2');
const scrollRef = useRef<HTMLDivElement>(null);
const { messages, input, handleInputChange, handleSubmit, isLoading, error } =
useChat({
api: '/api/chat',
body: { model },
});
useEffect(() => {
scrollRef.current?.scrollTo({
top: scrollRef.current.scrollHeight,
behavior: 'smooth',
});
}, [messages]);
return (
<div className="flex flex-col h-screen max-w-3xl mx-auto">
{/* الرأس */}
<header className="flex items-center justify-between p-4 border-b">
<h1 className="text-xl font-semibold">دردشة الذكاء الاصطناعي المحلي</h1>
<ModelSelector value={model} onChange={setModel} />
</header>
{/* الرسائل */}
<div ref={scrollRef} className="flex-1 overflow-y-auto p-4 space-y-4">
{messages.length === 0 && (
<div className="text-center text-gray-500 mt-20">
<p className="text-4xl mb-4">🤖</p>
<p className="text-lg font-medium">مساعدك الذكي الخاص</p>
<p className="text-sm mt-2">
يعمل بواسطة Ollama — كل شيء يعمل على جهازك.
</p>
</div>
)}
{messages.map((m) => (
<div
key={m.id}
className={`flex ${m.role === 'user' ? 'justify-end' : 'justify-start'}`}
>
<div
className={`max-w-[80%] rounded-2xl px-4 py-3 ${
m.role === 'user'
? 'bg-blue-600 text-white'
: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100'
}`}
>
<p className="whitespace-pre-wrap">{m.content}</p>
</div>
</div>
))}
{isLoading && messages[messages.length - 1]?.role === 'user' && (
<div className="flex justify-start">
<div className="bg-gray-100 dark:bg-gray-800 rounded-2xl px-4 py-3">
<span className="animate-pulse">جارٍ التفكير...</span>
</div>
</div>
)}
</div>
{/* عرض الأخطاء */}
{error && (
<div className="mx-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-red-700 dark:text-red-400 text-sm">
{error.message.includes('503')
? 'Ollama لا يعمل. شغّله بالأمر: ollama serve'
: 'حدث خطأ ما. يرجى المحاولة مرة أخرى.'}
</div>
)}
{/* الإدخال */}
<form onSubmit={handleSubmit} className="p-4 border-t">
<div className="flex gap-2">
<input
value={input}
onChange={handleInputChange}
placeholder="اكتب رسالة..."
disabled={isLoading}
className="flex-1 rounded-xl border px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700"
/>
<button
type="submit"
disabled={isLoading || !input.trim()}
className="rounded-xl bg-blue-600 px-6 py-3 text-white font-medium hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
إرسال
</button>
</div>
</form>
</div>
);
}الخطوة 8: بناء مكون اختيار النموذج
هذا المكون يجلب النماذج المتاحة من Ollama ويتيح للمستخدمين التبديل بينها:
// src/components/ModelSelector.tsx
'use client';
import { useState, useEffect } from 'react';
interface Model {
id: string;
label: string;
size: string;
}
interface ModelSelectorProps {
value: string;
onChange: (model: string) => void;
}
export function ModelSelector({ value, onChange }: ModelSelectorProps) {
const [models, setModels] = useState<Model[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/models')
.then((res) => res.json())
.then((data) => {
setModels(data.models ?? []);
setLoading(false);
})
.catch(() => setLoading(false));
}, []);
if (loading) {
return (
<select disabled className="rounded-lg border px-3 py-2 text-sm opacity-50">
<option>جارٍ تحميل النماذج...</option>
</select>
);
}
if (models.length === 0) {
return (
<span className="text-sm text-red-500">لم يتم العثور على نماذج</span>
);
}
return (
<select
value={value}
onChange={(e) => onChange(e.target.value)}
className="rounded-lg border px-3 py-2 text-sm bg-white dark:bg-gray-800 dark:border-gray-700"
>
{models.map((m) => (
<option key={m.id} value={m.id}>
{m.label} ({m.size})
</option>
))}
</select>
);
}الخطوة 9: ربط الصفحة
حدّث الصفحة الرئيسية لعرض مكون الدردشة:
// src/app/page.tsx
import { Chat } from '@/components/Chat';
export default function Home() {
return <Chat />;
}الخطوة 10: التشغيل والاختبار
شغّل خادم التطوير:
npm run devتأكد أن Ollama يعمل في طرفية أخرى:
ollama serveافتح http://localhost:3000 وابدأ بالدردشة. يجب أن ترى:
- محدد النماذج مليء بنماذجك المحلية
- ردود متدفقة في الوقت الفعلي أثناء توليد النموذج للنص
- تجربة دردشة سلسة — كل شيء يعمل محلياً
قائمة فحص الاختبار
- أرسل رسالة بسيطة وتحقق من عمل البث
- بدّل بين النماذج باستخدام المحدد
- أوقف Ollama (
Ctrl+Cعلىollama serve) وتحقق من ظهور رسالة الخطأ - أعد تشغيل Ollama وتحقق من استعادة الدردشة
- أرسل رسالة طويلة وتحقق من كفاية مهلة 60 ثانية
المزيد: المخرجات المنظمة
يدعم Ollama مخرجات JSON منظمة باستخدام مخططات Zod. هذا مفيد لبناء الأدوات واستخراج البيانات أو فرض صيغ الاستجابة:
// src/app/api/analyze/route.ts
import { generateObject } from 'ai';
import { ollama } from '@/lib/ollama';
import { z } from 'zod';
const SentimentSchema = z.object({
sentiment: z.enum(['positive', 'negative', 'neutral']),
confidence: z.number().min(0).max(1),
summary: z.string().max(200),
});
export async function POST(req: Request) {
const { text } = await req.json();
const { object } = await generateObject({
model: ollama('llama3.2'),
schema: SentimentSchema,
prompt: `Analyze the sentiment of this text: "${text}"`,
});
return Response.json(object);
}الاستجابة ستطابق دائماً مخططك:
{
"sentiment": "positive",
"confidence": 0.92,
"summary": "The text expresses strong satisfaction with the product."
}المزيد: التضمينات لـ RAG
يمكنك استخدام Ollama لتوليد التضمينات لبناء نظام توليد معزز بالاسترجاع (RAG):
import { embedMany } from 'ai';
import { ollama } from '@/lib/ollama';
const { embeddings } = await embedMany({
model: ollama.embeddingModel('nomic-embed-text'),
values: [
'Next.js is a React framework for the web.',
'Ollama runs large language models locally.',
'TypeScript adds static types to JavaScript.',
],
});
// كل تضمين هو مصفوفة float32 يمكنك تخزينها في قاعدة بيانات متجهية
console.log(embeddings[0].length); // 768 بُعدادمج هذا مع قاعدة بيانات متجهية مثل pgvector أو ChromaDB لبناء خط أنابيب RAG محلي بالكامل.
استكشاف الأخطاء وإصلاحها
Ollama لا يستجيب
# تحقق مما إذا كان Ollama يعمل
curl http://localhost:11434/api/tags
# إذا لم يكن يعمل، شغّله
ollama serveالنموذج بطيء جداً
جرّب نموذجاً أصغر:
ollama pull llama3.2:1b # مليار معامل، أسرع بكثيرأو تحقق مما إذا كان جهازك يدعم تسريع GPU:
ollama ps # يعرض النماذج المحملة واستخدامها للذاكرةأخطاء CORS في المتصفح
لا تستدعِ Ollama مباشرة من المتصفح أبداً. استخدم دائماً الوكالة عبر مسار API في Next.js — هذا يتجنب مشاكل CORS تماماً ويحافظ على أمان بنيتك.
نفاد الذاكرة
النماذج الكبيرة تتطلب ذاكرة RAM كبيرة. إذا رأيت أخطاء ذاكرة:
- استخدم نسخة نموذج أصغر (
llama3.2:1bبدلاً منllama3.2) - أغلق التطبيقات الأخرى كثيفة استخدام الذاكرة
- تحقق من الذاكرة المتاحة بـ
ollama ps
نظرة عامة على البنية
إليك كيف تتناسب القطع معاً:
┌─────────────────┐ HTTP POST ┌──────────────────┐ HTTP POST ┌──────────────┐
│ │ ──────────────► │ │ ──────────────► │ │
│ React Client │ /api/chat │ Next.js Server │ localhost:11434 │ Ollama │
│ (useChat) │ ◄────────────── │ (Route Handler) │ ◄────────────── │ (Local) │
│ │ SSE stream │ │ NDJSON stream │ │
└─────────────────┘ └──────────────────┘ └──────────────┘
- عميل React يستخدم خطاف
useChatلإرسال الرسائل واستقبال الردود المتدفقة - مسار API في Next.js يستقبل الطلب، يستدعي Ollama عبر مزود AI SDK، ويبث الرد
- Ollama يُشغّل استدلال النموذج محلياً ويُرجع الرموز كـ JSON مفصول بأسطر جديدة
كل الاتصالات تبقى على شبكتك المحلية — لا شيء يصل إلى الإنترنت.
الخطوات التالية
الآن بعد أن لديك روبوت دردشة ذكاء اصطناعي محلي يعمل، فكّر في هذه التحسينات:
- إضافة سجل المحادثات — احفظ الدردشات باستخدام التخزين المحلي أو قاعدة بيانات
- بناء خط أنابيب RAG — استخدم التضمينات وقاعدة بيانات متجهية للإجابة على أسئلة المستندات
- إضافة استدعاء الأدوات — دع النموذج ينفذ وظائف مثل البحث على الويب أو الحسابات
- النشر على شبكتك المحلية — اجعل روبوت الدردشة متاحاً للأجهزة الأخرى على شبكتك
- جرّب نماذج الرؤية — استخدم
llama3.2-visionلتحليل الصور محلياً
دروس ذات صلة على نقطة:
الخلاصة
لقد بنيت روبوت دردشة ذكاء اصطناعي محلي بالكامل:
- يعمل بالكامل على جهازك بدون أي اعتماد على السحابة
- يبث الردود في الوقت الفعلي لتجربة مستخدم سلسة
- يدعم نماذج متعددة من خلال محدد نماذج ديناميكي
- يتعامل مع الأخطاء بأناقة عندما لا يكون Ollama متاحاً
- يستخدم Vercel AI SDK لبنية جاهزة للإنتاج
نظام الذكاء الاصطناعي المحلي نضج بشكل كبير في 2026. مع Ollama الذي يتولى تشغيل النماذج و Vercel AI SDK الذي يوفر تجربة المطور، أصبح بناء تطبيقات الذكاء الاصطناعي الخاصة بنفس سهولة بناء أي تطبيق ويب آخر.
بياناتك تبقى ملكك. ذكاؤك الاصطناعي يعمل بشروطك.
ناقش مشروعك معنا
نحن هنا للمساعدة في احتياجات تطوير الويب الخاصة بك. حدد موعدًا لمناقشة مشروعك وكيف يمكننا مساعدتك.
دعنا نجد أفضل الحلول لاحتياجاتك.
مقالات ذات صلة

بناء وكيل ذكاء اصطناعي مستقل باستخدام Agentic RAG و Next.js
تعلم كيف تبني وكيل ذكاء اصطناعي يقرر بشكل مستقل متى وكيف يسترجع المعلومات من قواعد البيانات المتجهية. دليل عملي شامل باستخدام Vercel AI SDK و Next.js مع أمثلة قابلة للتنفيذ.

بناء وكلاء الذكاء الاصطناعي من الصفر باستخدام TypeScript: إتقان نمط ReAct مع Vercel AI SDK
تعلّم كيفية بناء وكلاء الذكاء الاصطناعي من الأساس باستخدام TypeScript. يغطي هذا الدليل التعليمي نمط ReAct، واستدعاء الأدوات، والاستدلال متعدد الخطوات، وحلقات الوكلاء الجاهزة للإنتاج مع Vercel AI SDK.

إضافة المصادقة لتطبيق Next.js 15 باستخدام Auth.js v5: البريد الإلكتروني وOAuth والتحكم بالأدوار
تعلم كيفية إضافة نظام مصادقة جاهز للإنتاج لتطبيق Next.js 15 باستخدام Auth.js v5. يغطي هذا الدليل الشامل تسجيل الدخول عبر Google OAuth وبيانات الاعتماد بالبريد الإلكتروني وكلمة المرور والمسارات المحمية والتحكم بالوصول حسب الأدوار.