إصلاح الأخطاء عند تشغيل وكلاء الذكاء الاصطناعي مفتوحة الصورس على جهازك الشخصي
TuBrief 편집팀
2026년 9월 11일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
تُظهر لك دروس الفيديو على يوتيوب أدوات الذكاء الاصطناعي مفتوحة المصدر التي تحتوي على آلاف نجوم غيت هاب وكأنها تعمل ببساطة عبر كتابة بضع أطر. ولكن عندما تفتح الطرفية (Terminal) وتقوم بعمل استنساخ (Clone)، تبدأ شاشة الأخطاء بالظهور تباعاً، بدءاً من تعارضات ثنائيات لغة C++ وحتى تشابك إصدارات الحزم. يعود سبب تعثر المطورين المبتدئين في هذه المرحلة إلى غياب المعايير الخاصة بعزل بيئات بايثون ووقت التشغيل (Runtime)، حيث يتم إغراق النظام بالأدوات بشكل عشوائي. لتجنب قضاء الليل بأكمله في البحث والحل، يجب عليك ضبط عزل العمليات المحلية وتوجيه الوكيل (Proxy Routing) قبل البدء في تنقيح نصوص المطالبات (Prompts).
تتداخل مشاريع الذكاء الاصطناعي مفتوحة المصدر بين مكتبات بايثون المرتبطة بأدوات بناء لغة C++ وحزم Node.js التي تتطلب ارتباطات أصلية (Native Bindings). إذا قمت بالتثبيت في البيئة العامة دون انتباه، فستواجه أخطاء في الروابط الرمزية (Symbol Links) مثل ImportError: dynamic module does not define module export function في وقت تشغيل بايثون. وفي حالة أداة OmniRoute، وهي وسيط (Proxy) مبني على Node.js، فإن حقل engines في ملف package.json يحدد إصدارات Node 22 و Node 24~26، مما يؤدي إلى تعطل الأداة فوراً عند البدء على الإصدار الفردي Node 23.
يمكنك منع أخطاء البناء الأولية عن طريق إنشاء بيئة افتراضية وتثبيت الحزم استناداً إلى ملف قفل الإصدارات (Lock file).
`bash
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip setuptools wheel
if [ -f "poetry.lock" ]; then
poetry install --no-root
elif [ -f "requirements.txt" ]; then
pip install --no-cache-dir -r requirements.txt
fi
node -v # التأكد من إصدار v22.x LTS
pnpm install --frozen-lockfile
`
حتى عند نسخ ملف .env.example وملء ملف .env يدوياً، قد يحدث خطأ في التحليل (Parsing) بسبب خطأ إملائي بسيط. يضع وكيل تشغيل المصادر المفتوحة DeepSeek Harness (dsh) ملف الإعدادات العام (settings.yaml) وملف مفتاح مصادقة واجهة برمجة التطبيقات الفعلي (~/.dsh/.credentials.yaml) بشكل منفصل. إذا قمت بكتابة المفتاح في مكان خاطئ أو أخطأت في بناء جملة المسار، فلن يعمل الوكيل.
| متغير البيئة | مثال صحيح للإدخال | سبب الخطأ وطريقة الحل |
|---|---|---|
| OPENAI_API_BASE | http://localhost:20128/v1 | إضافة شرطة مائلة (/) في نهاية العنوان تؤدي إلى خطأ توجيه 404، قم بإزالة الشرطة المائلة |
| ANTHROPIC_API_KEY | sk-ant-api03-... | وضع علامات اقتباس غير الضرورية ("") في قيم ملف دوكر .env يؤدي إلى فشل المصادقة، قم بإزالة علامات الاقتباس |
| DSH_HOME | /home/developer/.dsh | استخدام الرمز (~) مباشرة يسبب خطأ في صلاحيات المسار، قم بتحديد المسار المطلق |
| SECRET_KEY | قيمة ست عشرية بطول 34 بايت | ترك الحقل فارغاً يؤدي إلى فشل تهيئة الجلسة، قم بتوليده عبر openssl rand -hex 32 |
يعتمد DeepSeek Harness على إطار عمل Cordis ليكون وقت تشغيل يقوم بتركيب محولات الأدوات والنماذج كملفات إضافية (Plugins) مستقلة. أما نظام Omarchy الذي يقوده David Heinemeier Hansson (DHH) من قاعدة الأساس، فيستخدم QuickShell ولقطات Btrfs لاستعادة بيئة التطوير في غضون دقيقة و30 ثانية تقريباً. يتيح لك استخدام هذا المزيج توفير نصف يوم كان سيضيع في إعدادات استكشاف الأخطاء وإصلاحها.
في محرك dsh، يتم دمج مطالبات النظام المدخلة إلى نموذج اللغة الكبير (LLM) بواسطة حزمة النواة dsh-system-prompt في كل دورة. إذا قمت بتغيير النص في بداية المطالبة بشكل ديناميكي بدلاً من تثبيته، فإن ذاكرة التخزين المؤقت لل مفتاح والقيمة (KV Cache) الخاصة بالنموذج ستتلف منذ الفقرة الأولى. ونتيجة لذلك، تبطئ سرعة الاستجابة وتزداد التكاليف بسبب إعادة حساب رموز الإدخال بالكامل في كل دورة.
`yaml
llm-pi-ai:
providers:
local-omniroute:
type: openai-compatible
api:
baseURL: "http://127.0.0.1:20128/v1"
apiKeyEnv: "OMNIROUTE_API_KEY"
models:
- id: "auto/coding"
contextWindow: 128000
maxTokens: 8192
systemPrompt:
includeHarnessIdentity: false
persona: |
أنت مهندس يلتزم بقواعد التطوير المدفوع بالاهتمام بالاختبارات الصارمة (TDD).
1. قبل تعديل الكود، قم كتابة وحدة اختبار تفشل عمداً.
2. قم بإرجاع تنسيق Git diff الواضح وأوامر الأدوات القياسية فقط دون أي شرح إضافي.
`
يجب تثبيت تعريف دور نظام المطالبات كنص ثابت، بينما يتم تمرير قائمة الملفات التي تتغير بشكل متكرر أو تعليمات العمل في نهاية المطالبة أو رسالة المستخدم للاستفادة من ميزات التخزين المؤقت للمطالبات على مستوى المزود.
إذا واجه الوكيل مهلة بوابة 504 (Gateway Timeout) أو انقطاعاً مؤقتاً في المقبس من واجهة برمجة تطبيقات LLM الخارجية أثناء تصفح نظام الملفات المحلي أو تشغيل اختبارات الوحدة، فسوف تتوقف العملية تماماً. لذلك، يجب كتابة نص عاصفة يراقب نقطة نهاية فحص الصحة ويزيد فترات إعادة المحاولة تدريجياً عند حدوث الفشل، ويتم تشغيله في الخلفية.
`bash
#!/usr/bin/env bash
set -euo pipefail
export DSH_HOME="{OMNIROUTE_API_KEY:-sk-local-token}"
MAX_RETRIES=5
INITIAL_BACKOFF=2
PORT=3080
launch_agent_daemon() {
local retry_count=0
local backoff=${INITIAL_BACKOFF}
until curl -s -f "http://127.0.0.1:${PORT}/api/health" > /dev/null 2>&1; do
if [ ${retry_count} -ge ${MAX_RETRIES} ]; then
echo "[ERROR] فشل تشغيل وقت تشغيل الوكيل. تم الوصول إلى الحد الأقصى لمحاولات الإعادة." >&2
exit 1
fi
echo "[INFO] محاولة تشغيل DeepSeek Harness ($((retry_count + 1))/${MAX_RETRIES})..."
npx --yes @deepseek-ai/dsh web --port ${PORT} --no-open >> "${DSH_HOME}/daemon.log" 2>&1 &
local pid=$!
sleep "${backoff}"
if kill -0 ${pid} 2>/dev/null; then
echo "[SUCCESS] تم تشغيل DeepSeek Harness بنجاح (PID: ${pid})"
break
else
echo "[WARN] توقف العملية بشكل غير طبيعي. سيتم إعادة المحاولة بعد ${backoff} ثانية."
retry_count=$((retry_count + 1))
backoff=$((backoff * 2))
fi
done
}
launch_agent_daemon
`
من خلال منح الأذونات عبر chmod +x daemon.sh وتشغيل الملف في الخلفية، يمكنك توفير عناء الركض إلى الطرفية لإعادة تشغيل العملية يدوياً بسبب أخطاء الواجهة البرمجية المؤقتة.
تعتمد مسارات تحليل المستندات المبنية على بايثون على لصق مكتبات بايثون مختلفة لكل من صيغ docx و xlsx و pdf، مما يسهل التعرض لمشاكل مثل دمج خلايا الجداول أو ضياع المعادلات المعقدة بالكامل.
تُقدم أداة AnyDoc التي أطلقتها Firecrawl كورست (Rust) أحادي النواة يعالج 14 صيغة وملفات PDF النصية دون الحاجة إلى تبعيات خارجية ثقيلة. وفقاً لمعايير اختبار أداء Firecrawl، تتراوح سرعة التحويل الوسيطة لـ AnyDoc بين 4.4 إلى 4.7 ميلي ثانية، وهو فرق شاسع مقارنة بمتوسط 1,129 ميلي ثانية الذي تستغرقه حزمة LibreOffice بدون واجهة رسومية (Headless).
| محرك تحويل المستندات | عدد الصيغ المدعومة | سرعة التحويل الوسيطة | تبعيات النظام وخصائص وقت التشغيل | مستوى الحفاظ على التخطيطات المعقدة (الجداول والمعادلات) |
|---|---|---|---|---|
| Firecrawl AnyDoc | 14 صيغة + PDF | 4.4 ~ 4.7 ms | لا توجد تبعيات خارجية (بايت كود Rust أحادي) | عالي (تسوية نموذج التلسلسل الأحادي) |
| LibreOffice (Headless) | 12 صيغة | 1,129 ms | حزم نظام ثقيلة (JVM، حزم الخطوط) | متوسط (تشوهات متكررة في التحويل بين الصيغ) |
| Mammoth (Python) | صيغة واحدة (مخصص لـ DOCX فقط) | 52 ms | مكتبة بايثون خالصة | منخفض (تلف الجداول المدمجة) |
| LangChain Unstructured | دعم متعدد (غلاف خارجي) | 450 ~ 1,800 ms | تبعيات على مستوى نظام التشغيل مثل Poppler و Tesseract | متوسط إلى عالي (عبء تحويل كبير) |
تقوم AnyDoc بالتمييز المباشر بين ملفات PDF النصية وصيغ أوفيس المختلفة على مستوى توقيع البايت (Byte Signature). وإذا تم إدخال ملف PDF ممسوح ضوئياً تحتوي نصوصه على صور، فسيرسل استثناء NeedsOcrError بدلاً من اختلاق نصوص خاطئة.
`python
"""
نص برمجي للتحويل الجماعي متعدد الصيغ وتصحيح مسارات الصور بناءً على AnyDoc
التثبيت: pip install firecrawl-anydoc
"""
import os
import re
from pathlib import Path
import anydoc
class BatchDocumentConverter:
SUPPORTED_EXTENSIONS = {
'.docx', '.doc', '.docm', '.xlsx', '.xls', '.xlsm',
'.pptx', '.ppt', '.rtf', '.odt', '.ods', '.odp',
'.epub', '.csv', '.pdf'
}
def __init__(self, input_dir: Path, output_dir: Path):
self.input_dir = Path(input_dir)
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
def execute_batch(self):
for root, _, files in os.walk(self.input_dir):
for file in files:
source_path = Path(root) / file
if source_path.suffix.lower() in self.SUPPORTED_EXTENSIONS:
self._process_single_document(source_path)
def _process_single_document(self, file_path: Path):
relative_path = file_path.relative_to(self.input_dir)
target_folder = self.output_dir / relative_path.parent / file_path.stem
target_folder.mkdir(parents=True, exist_ok=True)
assets_folder = target_folder / "assets"
try:
with open(file_path, "rb") as f:
raw_bytes = f.read()
format_hint = "csv" if file_path.suffix.lower() == ".csv" else None
doc_model = (anydoc.to_document(raw_bytes, format_hint)
if format_hint else anydoc.to_document(raw_bytes))
image_mapping = {}
if hasattr(doc_model, "assets") and doc_model.assets:
assets_folder.mkdir(exist_ok=True)
for idx, asset in enumerate(doc_model.assets):
mime_ext = asset.media_type.split("/")[-1] if hasattr(asset, "media_type") else "png"
img_name = f"extracted_img_{idx + 1}.{mime_ext}"
with open(assets_folder / img_name, "wb") as img_file:
img_file.write(asset.bytes)
image_mapping[getattr(asset, "id", f"asset_{idx}")] = f"./assets/{img_name}"
raw_markdown = anydoc.to_markdown(str(file_path))
normalized_markdown = self._sanitize_layout(raw_markdown, image_mapping)
result_path = target_folder / f"{file_path.stem}.md"
result_path.write_text(normalized_markdown, encoding="utf-8")
print(f"[نجاح] اكتمال التحويل: {file_path.name} -> {result_path}")
except anydoc.NeedsOcrError:
print(f"[OCR مطلوب] تم اكتشاف مستند ممسوح ضوئياً: {file_path.name}. جاري الإرسال إلى محرك OCR المضيف.")
ocr_markdown = anydoc.to_markdown(str(file_path), ocr="hosted")
(target_folder / f"{file_path.stem}.md").write_text(ocr_markdown, encoding="utf-8")
except Exception as err:
print(f"[فشل] {file_path.name}: {str(err)}")
def _sanitize_layout(self, content: str, img_map: dict) -> str:
lines = content.split("\n")
repaired_lines = []
for line in lines:
trimmed = line.strip()
if trimmed.startswith("|") and trimmed.endswith("|"):
line = re.sub(r"\s+", " ", line)
repaired_lines.append(line)
sanitized = "\n".join(repaired_lines)
for asset_id, local_rel_path in img_map.items():
sanitized = sanitized.replace(f"![{asset_id}]", f"")
return sanitized
if name == "main":
converter = BatchDocumentConverter(Path("./raw_docs"), Path("./processed_md"))
converter.execute_batch()
`
تقوم AnyDoc بإلغاء قفل المفسر العام (GIL - Global Interpreter Lock) عند تشغيل ارتباطات بايثون. وبدون استخدام مكتبات المعالجة المتعددة الثقيلة، يمكنك تحويل مئات مستندات اللوائح الداخلية بالتوازي عبر استخدام ThreadPoolExecutor القياسي في بايثون.
إن عادة إرسال جميع طلبات المطالبات إلى نموذج الرائد الأعلى سعراً تؤدي إلى استنزاف ميزانية واجهة برمجة التطبيقات للشركة بسرعة. فما يزيد عن نصف أعمال البرمجة عبارة عن مهام خفيفة نسبياً مثل تصحيح الأخطاء النحوية، وإنشاء توثيق الشفرات (Docstrings)، أو كتابة أكواد اختبار بسيطة.
وفقاً لبحث RouteLLM الصادر عن جامعة بيركلي وLMSYS (عام 2024)، فإن اعتماد طريقة التفريع الديناميكي للنماذج بناءً على تقييم صعوبة المهمة يحافظ على 95% من أداء مستوى GPT-4 مع تقليل تكاليف الاستدعاء بنسبة 85%. كما تمكن فريق البيانات في شركة الاتصالات الأمريكية AT&T من خفض ميزانية تشغيل الذكاء الاصطناعي التوليدي بنسبة 56% من خلال إدخال وكيل البوابة.
عند تشغيل الوكيل المحلي OmniRoute على المنفذ المحلي (20128)، يمكنك توزيع حركة المرور وفقاً لطبيعة المهمة. كما يدعم ميزة قاطع الدائرة التي تتحول إلى نموذج احتياطي في غضون ثانية واحدة في حال أعادت واجهة برمجة تطبيقات خاصة بمزود معين خطأ 429 (معدل الطلبات المسموح به - Rate Limit) أو انتهت المهلة.
`json
{
"name": "resilient-cost-saver",
"strategy": "priority",
"nodes": [
{
"provider": "anthropic",
"model": "claude-3-7-sonnet",
"priority": 1,
"timeoutMs": 10000
},
{
"provider": "deepseek",
"model": "deepseek-v4-pro",
"priority": 2,
"timeoutMs": 8000
},
{
"provider": "ollama-local",
"model": "qwen2.5-coder:32b",
"priority": 3,
"timeoutMs": 15000
}
],
"circuitBreaker": {
"errorThresholdPercentage": 50,
"recoveryTimeSec": 300,
"minimumRequests": 5
},
"compression": {
"enabled": true,
"engines": ["rtk", "caveman"]
}
}
`
بافتراض بيئة يستهلك فيها فريق مكون من 10 أفراد 400 مليون (400M) رمز شهرياً، تم حساب فرق التكلفة عند تطبيق قواعد توجيه OmniRoute وضغط المطالبات مقارنة باستدعاء النموذج الرائد المنفرد.
| سيناريو التوجيه | نسبة تخصيص حركة المرور حسب النموذج | استهلاك الرموز الشهري | التكلفة الفعالة لكل مليون رمز | إجمالي الإنفاق الشهري | نسبة توفير التكاليف |
|---|---|---|---|---|---|
| تثبيت نموذج رائد منفرد | النموذج الرائد 100% | 400M | $15.00 | $6,000.00 | خط الأساس (0%) |
| توجيه تفريع OmniRoute | مهام بسيطة 60%، متوسطة 25%، عالية الصعوبة 15% | 240M (Haiku) |
100M (Sonnet)
60M (Opus) | $0.25
$3.00
$15.00 | $1,260.00 | توفير بنسبة 79.0% |
| التوجيه + ضغط المطالبات | التوجيه الذكي + ضغط الرموز بنسبة 30% | 280M (الرموز الفعالة) | تطبيق المتوسط المرجح المحول | $882.00 | توفير بنسبة 85.3% |
يمكنك الدخول عبر المتصفح إلى http://localhost:20128/dashboard لمراقبة عدد الطلبات في الثانية، وحالة تعثر قاطع الدائرة، والحصصة المتبقية في الوقت الفعلي.
اكتسب مشروع المحاكي ثلاثي الأبعاد Claude of Tanks الذي نفذه المهندس Kevin Liu باستخدام Three.js و Vite شهرة واسعة بفضل بنيته التي تربط بين وكيل العامل الذي يكتب الكود مباشرة ووكيل المُقيّم الذي يتحقق من شاشة النتائج بشكل متسلسل. ومن جهة أخرى، تقدم بنية Claudex التي تتحكم في التنفيذ المدمر على مستوى المضيف دون الاعتماد فقط على إرشادات المطالبات معياراً واقعياً للتحكم في الوكلاء.
في تطوير واجهات المستخدم أو الرسوميات، إذا تطابق الكود المكتوب من قبل وكيل واحد نحوياً، فلن يلاحظ الوكيل المشكلة حتى لو تضررت الأنسجة (Textures) على الشاشة الفعليّة. لذلك، يجب فصل حاوية العامل التي تكتب الكود عن حاوية المُقيّم التي تتحقق من شاشة العرض باستخدام متصفح بلا واجهة رسومية (Headless browser) عبر دوكر لمنع تداخل نتائج العمل.
`yaml
version: '3.8'
services:
omniroute-core:
image: diegosouzapw/omniroute:latest
container_name: omniroute-core
ports:
- "20128:20128"
environment:
- PORT=20128
- NODE_ENV=production
volumes:
- omniroute-storage:/app/data
restart: unless-stopped
agent-worker:
image: node:22-bookworm-slim
container_name: agent-worker-node
working_dir: /workspace
depends_on:
- omniroute-core
environment:
- OPENAI_API_BASE=http://omniroute-core:20128/v1
- OPENAI_API_KEY=sk-local-dummy
- CLAUDE_CODE_SUBAGENT_MODEL=auto/coding
volumes:
- ./project_workspace:/workspace
- ./agent_hooks:/root/.claude/hooks:ro
- execution-logs:/workspace/.agent_logs
entrypoint: ["/bin/bash", "-c", "npm install -g @anthropic-ai/claude-code && tail -f /dev/null"]
agent-critic:
image: python:3.11-slim-bookworm
container_name: agent-critic-node
working_dir: /evaluator
depends_on:
- agent-worker
volumes:
- ./project_workspace:/workspace:ro
- ./evaluation_scripts:/evaluator
- execution-logs:/workspace/.agent_logs
entrypoint: ["python", "run_evaluator.py"]
volumes:
omniroute-storage:
execution-logs:
`
يتم منح حاوية العامل صلاحية الكتابة على مجلد التعليمات البرمجية، بينما يتم تثبيت حاوية المُقيّم كقراءة فقط (:ro). ويهدف ذلك إلى منع حدوث وضع تتسبب فيه حاوية الوكيلين في الكتابة فوق الملفات بنفس المجلد بالتزامن مما يؤدي إلى تلف الكود.
بغض النظر عن عدد المرات التي تكتب فيها في المطالبة "لا تقم بالالتزام (Commit) مباشرة على الفرع الرئيسي (main)"، فعندما تطول الجلسة ويحدث ضغط للسياق، سينسى الوكيل القاعدة. ولهذا السبب، يتطلب الأمر خط دفاع مادي يعترض الأوامر في منتصف الطريق باستخدام نص خطاف على مستوى النظام.
`bash
#!/usr/bin/env bash
COMMAND="$1"
if echo "${COMMAND}" | grep -qE "git[[:space:]]+commit.*(main|master)"; then
echo "[حظر] يُحظر إجراء الالتزام المباشر على الفرع الرئيسي main. يرجى إنشاء فرع عمل للمتابعة." >&2
exit 1
fi
if echo "${COMMAND}" | grep -qE "rm[[:space:]]+-rf[[:space:]]+(/|..)"; then
echo "[حظر] تم اكتشاف أمر حذف المجلد العلوي، لذا تم إيقاف التنفيذ." >&2
exit 1
fi
LOG_PATH="(dirname "{LOG_PATH}")" echo "{\"timestamp\": \"(date -u +%Y-%m-%dT%H:%M:%SZ)", "command": "{COMMAND}\"}" >> "{LOG_PATH}"
exit 0
`
عند تثبيت هذا البرنامج النصي، يقوم الوكيل برفض الأوامر على مستوى الطرفية مباشرة قبل أن يدفع الكود عن طريق الخطأ إلى الفرع الرئيسي أو يتسبب في حذف المجلدات العليا للمشروع. وبما أن جميع سجلات استدعاء الأدوات يتم الاحتفاظ بها في ملف سجلات JSONL مخصص للإضافات فقط، يمكنك متابعة العمل من اللحظة التي سبقت الانقطاع حتى لو تعطلت العملية بشكل غير متوقع.