SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-25

إعداد dsh: مفتاح API والنماذج ونقاط النهاية

تعرّف على موضع إعداد dsh في Linux، وربط مفتاح DeepSeek أو نقطة Ollama المحلية، وما الذي يغادر جهازك فعلياً في كل وضع.

موضع احتفاظ dsh بإعداده

يحتفظ dsh (DeepSeek Harness) بإعداده في دليل واحد: $DSH_HOME، وتكون قيمته الافتراضية ~/.dsh. تُكتب أي إعدادات تضبطها في واجهة الويب هناك كملفات نصية عادية. انسخ هذا الدليل إلى خادم آخر، وسيعمل الخادم الجديد مثل الخادم القديم.

تحتوي أربعة مسارات على كل ما ستتعامل معه.

  • يحتوي ~/.dsh/settings.yaml على الإعدادات المكتوبة يدوياً وتلك التي تكتبها واجهة الويب، بما في ذلك مسارات المزوّد والنموذج.
  • يحتوي ~/.dsh/.credentials.yaml على الأسرار. لا تحتفظ الإعدادات إلا بمرجع إلى بيانات اعتماد، بينما توجد قيمة المفتاح نفسها في ملف واحد.
  • يحتوي ~/.dsh/profiles/ على الملفات التعريفية المسماة، ويحتوي ~/.dsh/storages/ على الجلسات المحفوظة.
  • يمثّل ~/.dsh/cordis.patch.yml طبقة التصحيحات الخاصة بك. وتُطبَّق هذه الطبقة فوق الإعداد المضمّن لكل ملف تعريفي.

أعلنت DeepSeek عن harness كإصدار معاينة للمطورين مرخّص بموجب MIT في 17 August 2026، ويذكر README أنّه ستكون هناك تغييرات تكسر التوافق. تتطابق أسماء الحقول والمسارات في هذا الدليل مع توثيق المستودع حتى August 2026. تحقّق من هذه الأسماء والمسارات مقابل توثيق الإصدار الذي ثبّتَّه قبل نسخ الإعداد من أي دليل، بما في ذلك هذا الدليل، لأن إصدار المعاينة قد يعيد تسمية العناصر بين الإصدارات.

الحد الأدنى الصادق للوصول إلى أول مخرَج

يحتاج dsh إلى Node.js 22.19 أو إصدار أحدث ضمن سلسلة 22، أو إلى الإصدار 24 وما بعده. الإصدار 23 خارج هذا النطاق. تحقّق من الإصدار أولاً، لأن عدم توافق الإصدارات يؤدي إلى فشل الإقلاع، وتبدو رسالة الخطأ كأنها تشير إلى حزمة معطوبة.

node -v
npx @deepseek-ai/dsh web

ينزّل npx الحزمة من سجل npm ويبدأ واجهة Web UI على http://127.0.0.1:3080. ويربط عنوان loopback، ما يعني أن المنفذ لا يمكن الوصول إليه من جهاز آخر حتى عندما يسمح جدارك الناري بذلك. على VPS، مرّر الاتصال عبر SSH بدلاً من فتح المنفذ 3080 على الإنترنت. إذا كان عنوان URL المطبوع هو الجزء المربك، يشرح سبب بدء dsh على ذلك العنوان ما الذي يحميه ربط loopback وما الذي لا يحميه.

ssh -N -L 3080:127.0.0.1:3080 you@your-server

افتح http://127.0.0.1:3080 على حاسوبك المحمول، ثم انتقل إلى Settings وModels. تحتوي بطاقة DeepSeek على حقل واحد لمفتاح API. الصق المفتاح من platform.deepseek.com واحفظه. يصبح مسار النموذج قابلاً للاستخدام فوراً، من دون إعادة تشغيل، لأن الخادم قيد التشغيل يخزّن بيانات الاعتماد ويحل المرجع مباشرة. يشرح الوصول إلى واجهة dsh Web UI على خادم بعيد حالة النفق وreverse proxy، بينما يشرح تثبيت DeepSeek Harness على VPS إعداد الخادم الذي يفترضه هذا الدليل.

بعد الحفظ، افحص ما أنشأه التطبيق.

ls -la ~/.dsh
stat -c '%a %n' ~/.dsh/.credentials.yaml

من المفترض أن ترى settings.yaml و.credentials.yaml وprofiles/. إذا طبع stat وضعاً غير 600، فنفّذ chmod 600 ~/.dsh/.credentials.yaml. يتيح ملف بيانات اعتماد قابل للقراءة من المجموعة أو من جميع المستخدمين تسليم مفتاحك إلى كل حساب آخر على الخادم.

للتشغيل الأول من دون متصفح، يكفي أمر واحد.

npx @deepseek-ai/dsh --profile headless "summarise the files in this directory"

يشغّل ملف التعريف headless جلسة واحدة ويطبع الإجابة النهائية.

متغيرات البيئة أو ملف الإعداد

توجد طريقتان لتزويد dsh بمفتاح، ولا يمكن استخدامهما بالتبادل.

يأخذ موفّر الكتالوج (DeepSeek وAnthropic وOpenAI وبقية القائمة المضمّنة) مفتاحه من خلال صفحة Models. تُحفظ القيمة في ~/.dsh/.credentials.yaml، ولا تحتفظ إعداداتك إلا بمرجع إليها. لا تعرض Web UI المفتاح مرة أخرى بعد حفظه.

يمكن لموفّر مخصّص استخدام متغير بيئة بدلاً من ذلك، عبر apiKeyEnv. هذه هي الصيغة التي توضّحها الوثائق لـ ~/.dsh/settings.yaml.

llm-pi-ai:
  providers:
    my-gateway:
      apiKeyEnv: GATEWAY_API_KEY
      api: openai-completions
      baseURL: https://gateway.example/v1
      models:
        - id: legacy-chat
        - id: vision-preview
          input: [text, image]

أضف موفراً واحداً أولاً من خلال Web UI، ثم افتح ~/.dsh/settings.yaml وانسخ البنية التي أنشأها. أثناء المعاينة للمطورين، تكون البنية المتداخلة هي الجزء الأكثر عرضة للتغيير، والملف الذي أنشأه التطبيق للتو يكون دائماً الأحدث.

يُقرأ apiKeyEnv من بيئة عملية dsh، وليس من shell تسجيل الدخول الخاص بك. يكون المفتاح الذي تصدّره في جلسة تفاعلية غير مرئي لوحدة systemd، لذلك يعيد الإعداد نفسه الذي يعمل عند كتابة dsh web يدوياً القيمة MISSING_CREDENTIAL عند تشغيله كخدمة. امنح الوحدة ملفاً خاصاً بها.

[Service]
EnvironmentFile=/etc/dsh/dsh.env

اضبط صلاحيات هذا الملف على 600، واجعله مملوكاً للمستخدم الذي تعمل الخدمة بحسابه.

اختيار النماذج والمعرّف الذي لا يمكنك إعادة تسميته

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

معرّف الموفّر دائم. إذ تشير إليه الطلبات والجلسات المحفوظة والإعدادات الافتراضية للنماذج ومراجع بيانات الاعتماد، لذلك لا يوجد زر لإعادة تسميته. ويعني تغييره إنشاء موفّر جديد وحذف الموفّر القديم. اختر اسماً يمكنك الإبقاء عليه: local-ollama بدلاً من test2.

تُعدّ النماذج نصية فقط ما لم تصرّح بخلاف ذلك. أضف input: [text, image] إلى إدخال النموذج للإعلان عن دعم الصور، أو عيّن defaultInput على مستوى route كخيار احتياطي للنماذج التي لا يصفها الكتالوج. أما route الخاص بـDeepSeek لـchat-completions فهو نصي فقط ولا يمكن تكوينه بطريقة أخرى، لذلك يُرفض إرفاق صورة بهذا route قبل إرسال أي شيء.

وجّه dsh إلى نقطة نهاية محلية ليبقى الكود على الخادم

يقدّم Ollama واجهة API متوافقة مع OpenAI على http://127.0.0.1:11434/v1. يتصل dsh بأي عنوان أساسي متوافق مع OpenAI عبر موفّر مخصص، لذلك يتصل البرنامجان مباشرةً دون مكوّنات وسيطة. أعدّ خادم النماذج أولاً: يشرح استضافة LLM ذاتياً باستخدام Ollama على VPS عملية التثبيت وتنزيل النموذج.

تحقق من استجابة نقطة النهاية قبل تعديل dsh.

ollama list
curl -s http://127.0.0.1:11434/v1/models

يطبع ollama list الوسم الدقيق لكل نموذج نزّلته. انسخ هذه السلسلة. يعرض curl النماذج نفسها بتنسيق JSON. تعني القائمة الفارغة أن Ollama يعمل من دون نماذج منزّلة. يعني Connection refused أن Ollama لا يعمل أو لا يستمع على المنفذ 11434.

أضف الموفّر الآن. يتطلب Ollama حقلاً لمفتاح API ويتجاهل قيمته، لذلك تصلح أي سلسلة غير فارغة.

llm-pi-ai:
  providers:
    local-ollama:
      apiKeyEnv: OLLAMA_API_KEY
      api: openai-completions
      baseURL: http://127.0.0.1:11434/v1
      models:
        - id: <the exact tag printed by ollama list>

صدّر المتغير بحيث تتمكن عملية dsh من رؤيته.

sudo install -d -m 700 /etc/dsh
printf 'OLLAMA_API_KEY=ollama\n' | sudo tee /etc/dsh/dsh.env
sudo chmod 600 /etc/dsh/dsh.env

تغطي ثلاثة أخطاء تقريباً كل محاولة فاشلة هنا. يعني MISSING_CREDENTIAL أن dsh لم يتمكن من قراءة المتغير الذي يسميه apiKeyEnv، لذلك تحقق من بيئة العملية، لا من بيئة الطرفية. يعني UNKNOWN_MODEL أن id لا يطابق نموذجاً مهيّأً، لذلك قارنه مع ollama list حرفاً بحرف، بما في ذلك الوسم الذي يلي النقطتين. ينتج الخطأ 401 أثناء جلب النماذج المتاحة عن اكتشاف النماذج، الذي يستدعي GET /models على عنوانك الأساسي؛ أما نقاط النهاية التي لا تقدّم هذا المسار فتحتاج إلى إدخال نماذجها يدوياً.

هناك مشكلة أخرى محتملة في العنوان الأساسي. اترك /v1 محذوفاً منه، وستصل الطلبات إلى مسارات لا يقدّمها Ollama، لذلك يعيد الاستدعاء الخطأ 404 ولا يعمل النموذج. اللاحقة جزء من الواجهة المتوافقة مع OpenAI وليست زائدة شكلية.

إذا كان Ollama يعمل على جهاز مختلف، يصبح عنوان ذلك الجهاز هو العنوان الأساسي، وستعبر المطالبات الشبكة بنص واضح عبر HTTP العادي. أبقه على المضيف نفسه، أو ضع TLS (أمان طبقة النقل) والمصادقة أمامه: تأمين نقطة نهاية Ollama المكشوفة.

ما الذي يغادر الجهاز في كل وضع

عند استخدام مفتاح DeepSeek، يذهب كل طلب إلى واجهة API الخاصة بـDeepSeek. يحمل الطلب مطالبتك، ومحتويات الملفات التي قرأها الوكيل للإجابة عنها، ومخرجات الأوامر التي شغّلها، وأي نتائج أدوات اختار تضمينها. يكون كود المصدر داخل هذه الحمولة كلما فتح الوكيل ملفاً. هكذا يعمل النموذج المستضاف، ولذلك يجب التفكير في الدليل الذي تبدأ الوكيل منه.

عند استخدام موفّر آخر من الكتالوج أو بوابة تابعة للشركة، تذهب الحمولة نفسها إلى ذلك المورّد بدلاً من ذلك. ويحدّد عنوان URL الأساسي المكان بدقة.

عند استخدام نقطة نهاية محلية، يذهب طلب النموذج إلى 127.0.0.1:11434 ويبقى على الجهاز. لا يصل أي جزء من كودك إلى مورّد نموذج. لكن ثلاثة أشياء لا تزال تعبر الشبكة. ينزّل npx الحزمة من سجل npm. ويمكن لأي أداة يشغّلها الوكيل الوصول إلى الإنترنت بمفردها، بما في ذلك خوادم MCP (بروتوكول سياق النموذج) التي ربطتها، ويشرح تشغيل خوادم MCP على VPS ذلك بالتفصيل. وينتمي المكوّن الإضافي إلى الفئة نفسها، لأن تثبيت واحد يشغّل كود مؤلف آخر بصلاحيات وكيلك؛ لذلك يجدر بك التحقق مما يمكن للمكوّن الإضافي الوصول إليه قبل تثبيته. وينطبق ذلك أيضاً على بيانات القياس عن بُعد إذا فعّلتها.

تظل بيانات القياس عن بُعد متوقفة حتى توافق على تفعيلها. يمثّل DSH_TELEMETRY_MODE مفتاح الموافقة، وتتحول القيم غير المعيّنة أو الفارغة أو غير المعروفة إلى DISABLED. في هذه الحالة، لا ينشئ dsh أي موفّر أو معالج أو مُصدِّر لـOpenTelemetry (OTel)، ولذلك لا يرسل ملف تعريف جديد أي طلب شبكة لبيانات القياس عن بُعد إطلاقاً. يفعّل FEEDBACK_ONLY مشاركة سجلات الجلسات التي يطلقها إرسال الملاحظات. ويسمح FULL أيضاً بإرسال تقارير المشغّل. ويمكن لتغذية الجلسة تصدير محتوى الجلسة وبيانات الأدوات والمطالبات ومسارات مساحة العمل، لذلك تعامل مع FULL على أنه يرسل عملك إلى DeepSeek.

لإيقاف ذلك نهائياً دون الاعتماد على ضبط سلسلة الوضع بشكل صحيح، عيّن DSH_TELEMETRY_DISABLED=1. تمثّل أي قيمة غير فارغة إلغاءَ اشتراك صريحاً، وتُقرأ قبل بدء التشغيل، لذلك لا يستطيع كود المشروع إعادة تفعيلها أثناء الجلسة. العنوان الافتراضي لجامع البيانات هو harness-telemetry.deepseeksvc.com، ومن المفيد معرفة هذا الاسم عند قراءة سجلات جدارك الناري.

تحقق بدلاً من الوثوق بالإعداد. أثناء تشغيل مهمة، اعرض الاتصالات الصادرة التي تحتفظ بها العملية.

sudo ss -tnp | grep -i node

في وضع النموذج المحلي، ينبغي أن ترى اتصال loopback بالمنفذ 11434، وألا ترى أي اتصال بعنوان عام. ويجدر بك تحديد أي اتصال آخر قبل المتابعة. يجري ما الذي يرسله وكيل البرمجة إلى الجهة المشغّلة الفحص نفسه مع أطر تشغيل أخرى، ويشرح كيفية قراءة النتيجة.

أين يجب ألا تضع الأسرار

  • سجل الصدفة. يُكتب export DEEPSEEK_API_KEY=sk-... في ~/.bash_history بنص واضح، ويبقى هناك بعد مدة طويلة من تدوير المفتاح. أضف مسافة في بداية الأمر عندما يكون HISTCONTROL=ignorespace مضبوطاً، أو تجاوز الصدفة واكتب القيمة مباشرةً في ملف بصلاحية mode 600.
  • ملفات dotfiles المرفوعة إلى المستودع. إذا احتفظت بملفات dotfiles في git، فإن وجود مفتاح في ~/.bashrc أو ~/.zshrc يبعده خطوة git add واحدة عن مستودع عام. شغّل git grep -I -n 'sk-' في ذلك المستودع قبل الدفع.
  • settings.yaml. استخدم apiKeyEnv مع الموفرين المخصصين، بحيث يحتوي الملف على اسم متغير بدلاً من سر. تُنسخ ملفات الإعداد إلى تقارير المشكلات ومحادثات الدعم. أما ملفات بيانات الاعتماد فلا تُنسخ إليها.
  • مخرجات env ولقطات شاشة الطرفية. أي أمر يطبع البيئة كاملة سيطبع المفتاح معها.
  • النسخ الاحتياطية. يستحق ~/.dsh النسخ الاحتياطي، لكن .credentials.yaml الموجود داخله سر فعّال. استبعد ذلك الملف، أو شفّر الأرشيف.

لا تقتصر هذه القواعد على dsh، كما يشرح إبقاء الأسرار خارج ملفات env في Compose المشكلة نفسها من جانب الحاويات على الخادم نفسه.

التعامل مع إصدار معاينة للمطورين

ثبّت الإصدار الذي اختبرته، لأن إصدار المعاينة قد يغيّر مفتاح إعدادات في إصدار تصحيحي، وعندها يفشل موفّر الخدمة في التحميل. إذا رفض التثبيت المثبّت بدء التشغيل، أو ظل npx يزوّدك ببنية لم تطلبها، فراجع أخطاء التثبيت والإصدار التي ينتجها إصدار المعاينة؛ إذ يغطي ذلك ذاكرة التخزين المؤقت لـnpx وإصدار npm المرفق مع Node. احتفظ بـsettings.yaml وcordis.patch.yml في نظام التحكم بالإصدارات، مع استثناء ملف بيانات الاعتماد، حتى تتمكن من معرفة ما تغيّر بعد الترقية.

يساعد خياران عندما لا يتصرف ملف تعريف كما هو متوقع. يطبع --dump-default-config الإعدادات الافتراضية المركّبة من دون بدء التشغيل، بينما يطبع --dump-config الإعدادات المركّبة لملف التعريف بالطريقة نفسها. تكشف مقارنة الناتجين ما غيّرته طبقة التصحيح فعلياً، وهذا أسرع من قراءة الطبقات يدوياً.

dsh --profile web --dump-config

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

FAQ

أين يخزّن dsh مفتاح DeepSeek API الخاص بي؟

في $DSH_HOME/.credentials.yaml، وهو ~/.dsh/.credentials.yaml ما لم تضبط DSH_HOME بنفسك. تكتب صفحة Models المفتاح هناك، ولا تحتوي إعداداتك إلا على مرجع إليه، لذلك يبقى السر في ملف واحد. تحقّق من الوضع باستخدام stat -c '%a %n' ~/.dsh/.credentials.yaml واضبطه على 600 إذا كان أكثر تساهلاً. يمكن لمزوّد مخصّص تجاوز الملف بالكامل عبر تحديد متغير بيئة باستخدام apiKeyEnv.

كيف أجعل dsh يستخدم نموذجاً محلياً بدلاً من DeepSeek API؟

أضف مزوّداً مخصّصاً يكون عنوانه الأساسي هو نقطة النهاية المحلية المتوافقة مع OpenAI. بالنسبة إلى Ollama، يكون العنوان http://127.0.0.1:11434/v1، مع api: openai-completions ونموذج id منسوخاً تماماً من ollama list. تتطلب Ollama قيمة لمفتاح API وتتجاهلها، لذلك تصلح أي سلسلة غير فارغة. أكّد أن نقطة النهاية تستجيب باستخدام curl -s http://127.0.0.1:11434/v1/models قبل تعديل أي إعدادات لـdsh، لأن نقطة النهاية المتوقفة والإعداد الخاطئ ينتجان أخطاء متشابهة.

هل يرسل dsh الشيفرة الخاصة بي إلى أي مكان افتراضياً؟

نعم، عند استخدام نموذج مستضاف. يكون طلبك ومحتوى الملفات التي قرأها الوكيل ضمن طلب API المرسل إلى ذلك المزوّد. عند استخدام نقطة نهاية محلية، يذهب الطلب إلى loopback ويبقى على الجهاز. القياس عن بُعد قناة منفصلة، وهو معطّل افتراضياً: يحل DSH_TELEMETRY_MODE إلى DISABLED عند عدم ضبطه، وفي هذه الحالة لا يتم إنشاء أي exporter. اضبط DSH_TELEMETRY_DISABLED=1 لتعطيل اختياري تتم قراءته قبل بدء التشغيل.

لماذا يعرض dsh الخطأ MISSING_CREDENTIAL عندما يكون المتغير مضبوطاً؟

لأن dsh يقرأ المتغير الذي يسمّيه apiKeyEnv من بيئة العملية الخاصة به. لا يصل المتغير الذي تم تصديره في shell إلى خدمة systemd، أو جلسة مستخدم آخر، أو عملية بدأت قبل تصديره. ضع القيمة في EnvironmentFile مع ضبط الوضع على 600 للوحدة، أو صدّرها في shell نفسه الذي يشغّل dsh. تحقّق مما تحتويه العملية قيد التشغيل فعلياً باستخدام sudo tr '\0' '\n' < /proc/$(pgrep -f dsh | head -1)/environ.

ما إصدار Node.js الذي يحتاج إليه dsh؟

يحتاج إلى Node.js 22.19 أو أحدث ضمن السلسلة 22، أو الإصدار 24 أو أحدث. يقع Node 23 خارج النطاق المدعوم. شغّل node -v قبل أي شيء آخر، لأن فشل بدء التشغيل الناتج عن runtime غير مدعوم يبدو كأنه تثبيت معطّل، ويدفع المستخدمين إلى إعادة تثبيت الحزمة بدلاً من runtime.