تثبيت وإعداد قاعدة بيانات ChromaDB مفتوحة المصدر محلياً

دقائق القراءة: 5

لماذا نحتاج إلى ChromaDB محلياً في تطبيقات الذكاء الاصطناعي؟

عند بناء تطبيقات تعتمد على LLMs، تظهر مشكلة جوهرية: النموذج اللغوي لا “يعرف” ملفاتك المحلية أو وثائقك الداخلية أو قاعدة المعرفة الخاصة بمشروعك ما لم تقم أنت بتجهيز آلية استرجاع مناسبة. هنا يأتي دور قواعد البيانات المتجهة مثل Vector Databases، وبالأخص ChromaDB عندما تريد حلاً مفتوح المصدر وسهل التشغيل محلياً.

فكرة ChromaDB بسيطة هندسياً لكنها قوية: تقوم بتحويل النصوص إلى Embeddings رقمية، ثم تحفظ هذه المتجهات مع النصوص الوصفية والبيانات المرافقة. لاحقاً، عند إرسال سؤال من المستخدم، يتم تحويل السؤال نفسه إلى متجه ومقارنته رياضياً بالمتجهات المخزنة لاستخراج المقاطع الأقرب دلالياً. هذه هي النواة العملية لمعمارية RAG.

المعمارية الداخلية لتدفق البيانات داخل ChromaDB

لفهم التثبيت بشكل صحيح، لا يكفي تنفيذ الأوامر فقط؛ بل يجب فهم خط سير البيانات. في التطبيق العملي، يمر النظام غالباً بالمراحل التالية:

  • تحميل الملفات أو النصوص الخام من مصدر محلي أو خارجي.
  • تقسيم النص إلى مقاطع صغيرة Chunks لرفع جودة الاسترجاع.
  • توليد Embeddings لكل مقطع.
  • إدخال المقاطع والمتجهات والبيانات الوصفية إلى Collection داخل قاعدة البيانات.
  • عند وصول استعلام جديد، يُحوَّل إلى متجه ثم تُنفذ عملية Similarity Search.
  • تُرسل النتائج الأقرب إلى النموذج اللغوي ليبني عليها جواباً أكثر دقة وسياقاً.

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

تثبيت ChromaDB محلياً داخل بيئة Python

قبل التثبيت، يُفضل أن تكون قد أعددت بيئتك البرمجية كما في مقال إعداد بيئة العمل الذكية: تثبيت مكتبات Python الأساسية للتعامل مع الذكاء الاصطناعي. بعد ذلك، نبدأ بالتثبيت المباشر.

pip install chromadb

إذا كنت تنوي ربطها مع LangChain لبناء خطوط استرجاع تلقائية، فثبّت أيضاً الحزم المرتبطة:

pip install langchain langchain-community langchain-openai

وفي حال كنت ستولد المتجهات عبر OpenAI API، تأكد من أنك أنجزت الإعدادات الأساسية كما في مقال الاتصال الأول: جلب مفاتيح API وكتابة أول سكربت اتصال.

تشغيل أول قاعدة محلية قابلة للحفظ

واحدة من أهم مزايا ChromaDB أنها تعمل محلياً بدون إعدادات خوادم معقدة. يمكنك تحديد مجلد حفظ دائم عبر الوسيط path بحيث لا تضيع البيانات بعد إغلاق السكربت.

import chromadb

client = chromadb.PersistentClient(path="./chroma_storage")

collection = client.get_or_create_collection(name="local_docs")

print("ChromaDB is ready.")

في هذا المثال، يقوم PersistentClient بإنشاء مساحة تخزين محلية على القرص. أما Collection فهي تشبه جدولاً منطقياً مخصصاً لمجموعة معينة من المستندات.

إدخال البيانات النصية والمتجهات إلى القاعدة

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

collection.add(
    documents=[
        "ChromaDB is an open-source vector database for AI applications.",
        "Embeddings transform text into numerical vectors for semantic search."
    ],
    metadatas=[
        {"source": "intro_doc", "topic": "chromadb"},
        {"source": "embedding_doc", "topic": "embeddings"}
    ],
    ids=["doc_1", "doc_2"]
)

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

كيف يتم الاستعلام الدلالي؟

بدلاً من البحث النصي الحرفي، تعتمد ChromaDB على التقارب المعنوي بين المتجهات. لذلك إذا سأل المستخدم عن “قاعدة لتخزين المعرفة واسترجاعها لتطبيقات الذكاء الاصطناعي”، فقد تعثر القاعدة على نصوص تتحدث عن vector search حتى لو لم تُستخدم الكلمات نفسها حرفياً.

results = collection.query(
    query_texts=["What is a vector database used for in AI?"],
    n_results=2
)

print(results)

الناتج عادة يحتوي على الوثائق الأقرب، والمسافات أو الدرجات، وبياناتها الوصفية. هنا تبدأ القيمة الحقيقية: لا ترسل كل قاعدة المعرفة إلى النموذج، بل فقط المقاطع الأكثر صلة. وهذا يخفض التكلفة ويحسن الجودة، وهو ما يرتبط أيضاً بمقال حساب التكلفة وإدارة الرموز Tokens.

دمج ChromaDB مع LangChain

عند الانتقال من تجارب بسيطة إلى تطبيق إنتاجي، يفضل كثير من المهندسين استخدام LangChain لأنه يوفر طبقة تجريد للتعامل مع المحملات، المقسمات، المضمنات، والمسترجعات. بهذا تصبح ChromaDB جزءاً من خط معالجة أكبر.

from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

embedding_model = OpenAIEmbeddings()

vectorstore = Chroma(
    collection_name="project_docs",
    embedding_function=embedding_model,
    persist_directory="./chroma_langchain_store"
)

texts = [
    "RAG connects retrieval with generation for accurate answers.",
    "ChromaDB stores embeddings locally for semantic search."
]

vectorstore.add_texts(texts)

retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
docs = retriever.get_relevant_documents("How does local retrieval help LLM apps?")

for doc in docs:
    print(doc.page_content)

هذا الأسلوب يتكامل مباشرة مع بناء السلاسل كما في مقال إنشاء أول سلسلة Chain باستخدام LangChain، لأن المسترجع Retriever يمكن تمريره مباشرة إلى طبقة التوليد.

أفضل ممارسات هندسية عند الإعداد المحلي

  • قسّم النصوص إلى مقاطع منطقية بدلاً من تخزين مستندات ضخمة دفعة واحدة.
  • احرص على ثبات نموذج Embeddings بين مرحلتي الفهرسة والاستعلام.
  • استخدم metadata للفصل بين الأقسام أو المستخدمين أو أنواع الملفات.
  • اجعل مجلد الحفظ خارج المسارات المؤقتة حتى لا تفقد البيانات بعد إعادة التشغيل.
  • اختبر جودة الاسترجاع عملياً، لأن نجاح النظام لا يعتمد على القاعدة وحدها بل على جودة التقسيم والمتجهات.

مثال برومبت بعد الاسترجاع

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

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

متى يكون ChromaDB خياراً ممتازاً؟

يصبح هذا الحل مثالياً عندما تريد بدء مشروع RAG محلي بسرعة، أو تطوير نموذج أولي دون تكاليف بنية سحابية، أو بناء مساعد داخلي يسترجع من ملفات خاصة. كذلك يفيد في بيئات الاختبار، والمختبرات التعليمية، ومشاريع الشركات الصغيرة التي تريد التحكم الكامل بالبيانات.

باختصار هندسي، ChromaDB ليست مجرد أداة تخزين، بل طبقة استرجاع دلالي محلية تمثل العمود الفقري لكثير من تطبيقات الذكاء التوليدي الحديثة. وعندما تُضبط جيداً مع Embeddings مناسبة وسير عمل منظم، فإنها تمنح مشروعك قدرة عملية على “تذكر” المعرفة الخارجية بطريقة قابلة للتوسع والاختبار والإنتاج.

10 comments

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *