ابنِ حزمة ذكاء اصطناعي محلية خاصة (من البداية إلى النهاية)
لقد رأيت الأجزاء منفصلة: نموذج محلي، وحلقة وكيل محلية، وأدوات معروضة عبر MCP، وأنماط الهجين بين Claude والمحلي. هذه هي الخلاصة الجامعة — الصفحة التي تُوصّلها في مساعد خاص واحد يعمل على جهازك أنت: نموذج مفتوح الأوزان يعمل محليًا، وحلقة وكيل محايدة تجاه النموذج قادرة على استدعاء الأدوات، وتلك الأدوات معروضة عبر خادم MCP محلي، وحاجز حماية أمام الأدوات الخطرة، و — اختياريًا — Claude كـ"طبقة ذكية" اختيارية لأصعب 5% من الخطوات. الخيط الناظم: كل ما هو حساس يبقى على الجهاز؛ والسحابة اختيارية ومحفوظة للأقلية الصعبة.
- رؤية الحزمة كاملة في مخطط واحد: نموذج محلي + حلقة وكيل + أدوات MCP محلية + حاجز حماية (+ Claude اختياري)
- تشغيل نموذج مفتوح الأوزان محليًا والتأكد من قدرته على استدعاء الأدوات
- إقامة حلقة وكيل بسيطة محايدة تجاه النموذج — نفس الحلقة، بدّل نقطة النهاية
- عرض أداتين اثنتين عبر خادم MCP محلي والسماح للوكيل باستدعائهما
- إضافة حاجز حماية واحد: موافقة على الإجراءات المدمّرة، وسقف للحلقة/الميزانية، ومعالجة النتائج غير الموثوقة
- توجيه أصعب استدلال فقط إلى Claude اختياريًا، مع إبقاء المسار الافتراضي محليًا بالكامل
الحزمة كاملة، في صورة واحدة
النموذج الذهني هو عدد صغير من الصناديق، كلٌّ منها قابلته بالفعل في صفحة شقيقة. المساعد هو ببساطة هذه الصناديق موصّلة معًا:
اقرأها كحلقة. يسأل الوكيل النموذج المحلي عمّا يفعله تاليًا. فإمّا أن يجيب النموذج، أو أن يُصدر استدعاء أداة. كل استدعاء أداة يمرّ عبر حاجز حماية قبل أن يصل إلى خادم MCP المحلي، الذي يؤدّي العمل فعليًا (يقرأ ملفًا، يشغّل أمرًا، يبحث في ملاحظاتك) ويُعيد نتيجة. يُعيد الوكيل النتيجة إلى النموذج ويكرّر حتى تكتمل المهمة. المسار المنقّط إلى Claude اختياري: يصعّد الوكيل فقط الخطوات التي لا يستطيع النموذج المحلي التعامل معها، وفقط حين تسمح أنت بذلك.
ثلاث خصائص تجعل بناء هذه الحزمة مجديًا:
- محلي افتراضيًا. النموذج، والحلقة، والأدوات، وبياناتك كلها تعيش على عتادك أنت. لا شيء يغادر الجهاز ما لم يُفعَّل مسار Claude الاختياري — وحتى حينها، فقط ما تختار أنت إرساله.
- حلقة محايدة تجاه النموذج. يتحدّث الوكيل إلى نقطة نهاية دردشة على شكل OpenAI. وجّهها إلى نقطة نهاية Ollama المحلية اليوم؛ ووجّهها إلى مزوّد مختلف غدًا دون إعادة كتابة الحلقة.
- أدوات خلف معيار واحد. القدرات تعيش في خادم MCP، لا مُثبَّتة في الحلقة. ابنِ الأداة مرة واحدة، وأيّ عميل يتحدّث MCP (وكيلك، أو Claude Code، أو تطبيق آخر) يمكنه استخدامها.
بناء خطوة بخطوة
- ثبّت Ollama وشغّل نموذجًا يدعم استدعاء الأدوات. يُنزّل ollama run عند أول استخدام ويعرض واجهة برمجية محلية متوافقة مع OpenAI على localhost:11434. هذا هو 'دماغك' الافتراضي — خاص وبلا اتصال. (الإعداد الكامل: صفحة تشغيل النماذج محليًا.)
- اكتب حلقة صغيرة: أرسل الرسائل + مخطط أداة إلى نقطة نهاية الدردشة، اقرأ الرد، وإن احتوى على tool_calls فنفّذها، وألحق النتائج، وكرّر حتى يُعيد النموذج إجابة نهائية. الحلقة لا تعرف شيئًا عن أيّ نموذج تتحدّث إليه — فقط شكل دردشة OpenAI.
- ضع قدراتك الحقيقية (قراءة ملف، تشغيل أمر، البحث في الملاحظات) في خادم MCP محلي عبر stdio بدلًا من تثبيتها في الشيفرة. يسرد الوكيل أدوات الخادم، ويربطها بمخطط أدوات النموذج، ويستدعيها عند الطلب. ابنِ مرة واحدة، وأعد الاستخدام عبر العملاء.
- قبل تشغيل أي أداة، قيّدها: اسمح تلقائيًا للأدوات القابلة للقراءة فقط، واطلب موافقة صريحة للأدوات المدمّرة (run_shell، write_file، delete)، وضع سقفًا لعدد دورات الحلقة وإجمالي التوكِنات، وعامِل كل نتيجة أداة كمدخل غير موثوق قد يحاول توجيه النموذج.
- أبقِ المسار المحلي هو الافتراضي. حين تكون خطوة صعبة حقًا — استدلال متعدد الخطوات معقّد، أو خطة يفشل النموذج المحلي في إنجازها مرارًا — دع الوكيل يصعّد تلك الخطوة فقط إلى واجهة Claude البرمجية، ثم يعود إلى الحلقة المحلية. هذه هي فكرة الموجِّه / المسودة-ثم-الصقل من صفحة الهجين، مطبّقة خطوة واحدة في كل مرة.
1. النموذج المحلي (دماغك الافتراضي)
شغّل النموذج وتأكّد من أن نقطة النهاية المحلية عاملة. اختر نموذجًا يُعلن دعم استدعاء الأدوات — فحلقة الوكيل تعتمد عليه.
تشغيل نموذج محلي قادر على استخدام الأدوات + التأكد من الواجهة البرمجية
# Start a model that supports tool/function calling
ollama run llama3.1
# In another terminal, confirm the local OpenAI-compatible endpoint is live.
# Ollama serves it at http://localhost:11434/v1 — no internet required.
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama3.1",
"messages": [{"role": "user", "content": "Reply with the single word: ready"}]
}'2. حلقة الوكيل المحايدة تجاه النموذج
الحلقة غبيّة عمدًا: تُمرّر الرسائل ومخطط أداة إلى نقطة نهاية الدردشة، وكلما طلب النموذج استدعاء أداة، تشغّلها وتُعيد النتيجة إليه. ولأنها لا تتحدّث سوى شكل دردشة OpenAI، فإن نفس الحلقة تعمل مع نقطة النهاية المحلية الآن ومع مزوّد مختلف لاحقًا — تُغيّر base_url، لا المنطق.
from openai import OpenAI
# Point at the LOCAL model. Swap base_url/api_key later to change providers —
# the loop below does not change. That is what "model-agnostic" means here.
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
MODEL = "llama3.1"
MAX_STEPS = 8 # hard cap on loop iterations (a guardrail — see step 4)
def run_agent(user_goal, tool_schemas, dispatch):
messages = [
{"role": "system", "content": "You are a local assistant. Use tools when needed."},
{"role": "user", "content": user_goal},
]
for _ in range(MAX_STEPS):
resp = client.chat.completions.create(
model=MODEL, messages=messages, tools=tool_schemas,
)
msg = resp.choices[0].message
if not msg.tool_calls:
return msg.content # model gave a final answer
messages.append(msg)
for call in msg.tool_calls:
result = dispatch(call) # runs through the guardrail + MCP server
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result,
})
return "Stopped: hit the step cap." # never loop forever
tool_schemas هي قائمة الأدوات (بصيغة استدعاء الدوال الخاصة بـ OpenAI)، وdispatch هي الدالة الوحيدة التي تقرّر ما إذا كانت أداة مطلوبة ستُشغَّل فعلًا وكيف — وهناك يعيش حاجز الحماية وخادم MCP.
3. الأدوات عبر خادم MCP محلي
بدلًا من تثبيت الأدوات داخل الحلقة، اعرضها عبر خادم MCP محلي. MCP معيار مفتوح لربط عميل ذكاء اصطناعي بأدوات خارجية؛ يعمل الخادم المحلي كبرنامج صغير على جهازك ويتحدّث إلى العميل عبر stdio، فتبقى بياناتك وأفعالك على الجهاز. (لماذا هذا هو الحدّ الصحيح، وكيف تبني خادمًا، مشروح في اربط Claude بالأدوات المحلية عبر MCP.)
خادم MCP بايثوني بسيط يعرض أداة واحدة آمنة، للقراءة فقط:
# server.py — a tiny local MCP server exposing one read-only tool.
# Run it over stdio; an MCP client (your agent, Claude Code, ...) connects to it.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("local-tools")
@mcp.tool()
def search_notes(query: str) -> str:
"""Search the user's local notes folder and return matching snippets."""
# ... read from a LOCAL directory only; never reach outside it ...
return f"(stub) matches for: {query}"
if __name__ == "__main__":
mcp.run() # stdio transport by default — local, no network
يتّصل الوكيل بهذا الخادم، ويطلب منه سرد أدواته، ويحوّل كلًّا منها إلى مخطط أداة OpenAI الذي تفهمه حلقتك بالفعل، ويوجّه استدعاءات الأدوات من النموذج إلى الخادم. نفس الحلقة، قدرات حقيقية — والخادم قابل لإعادة الاستخدام من قِبل أيّ عميل يتحدّث MCP.
4. حاجز الحماية (لا تتخطَّ هذا)
هذا هو الفرق بين لعبة وشيء تثق به على جهازك أنت. دالة dispatch من الخطوة 2 هي نقطة الاختناق الوحيدة حيث يُفحَص كل استدعاء أداة قبل تشغيله. ثلاث مهام:
READ_ONLY = {"search_notes", "read_file", "list_dir"}
def dispatch(call):
name = call.function.name
args = call.function.arguments
# 1) APPROVAL: read-only tools auto-run; everything else asks a human first.
if name not in READ_ONLY:
if not human_approves(name, args): # destructive => require consent
return "DENIED by user."
# 2) The MCP server does the actual work (it, too, is sandboxed to safe paths).
result = call_mcp_tool(name, args)
# 3) UNTRUSTED RESULT: a tool result is data, not instructions. Do not let it
# silently become a new command to the model (prompt-injection defense).
return f"<tool_result name={name}>\n{result}\n</tool_result>"
اجمع ذلك مع سقوف الحلقة/الميزانية الموجودة أصلًا في الحلقة (MAX_STEPS، بالإضافة إلى سقف توكِنات تتتبّعه لكل تشغيل) فتحصل على الضوابط الثلاثة المهمّة: إنسان في الحلقة لأي شيء مدمّر، وتوقّف صارم كي لا يدور الوكيل أو يُنفق إلى الأبد، وعادة معاملة مخرجات الأدوات كنصّ غير موثوق.
5. اختياري — Claude كطبقة ذكية
افتراضيًا، لا تستدعِ السحابة أبدًا. لكن بعض الخطوات تتجاوز فعلًا نموذجًا محليًا صغيرًا — تخطيط متعدد الخطوات شائك، أو إعادة هيكلة يجب أن تكون صحيحة، أو تجميع عبر سياق طويل. لتلك الخطوات فقط، يمكن للوكيل أن يصعّد إلى واجهة Claude البرمجية، ويحصل على إجابة أفضل، ويعود إلى الحلقة المحلية. هذه هي فكرة الموجِّه / المسودة-ثم-الصقل من Claude + النماذج المحلية، مطبّقة خطوة واحدة في كل مرة.
import anthropic
cloud = anthropic.Anthropic() # reads ANTHROPIC_API_KEY from env
def hard_step(prompt, allow_cloud=False):
"""Escalate ONE hard step to Claude — only when explicitly allowed."""
if not allow_cloud:
return None # default: stay fully local, send nothing off-device
msg = cloud.messages.create(
model="claude-sonnet-4-5", # check current model ids before pinning
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
return msg.content[0].text
قاعدتان تُبقيان هذا نزيهًا: مسار السحابة اختياري (معطّل افتراضيًا)، ولا ترسل سوى ما تحتاجه تلك الخطوة الواحدة — لا سياقك كله. يبقى النموذج المحلي فرس العمل؛ وClaude هو المختصّ الذي تستدعيه لأصعب 5%. للاطّلاع على معرّفات النماذج وأسعارها الراهنة بالضبط، راجع ملاحظة التحقّق أدناه.
- الوكلاء المحليون ما زالوا يتّخذون إجراءات حقيقية على جهازك — اعزل الأدوات في صندوق رملي، واطلب موافقة على الخطوات المدمّرة، وضع سقفًا للحلقات/الميزانية، وعامِل نتائج الأدوات كغير موثوقة (حقن الأوامر).
اختبر نفسك
اختبر نفسك
0/4- المساعد الخاص أربعة صناديق موصّلة في حلقة: نموذج محلي + وكيل محايد تجاه النموذج + أدوات MCP محلية + حاجز حماية — مع Claude كصندوق خامس اختياري
- المحلي هو الافتراضي وضمانة الخصوصية: النموذج، والحلقة، والأدوات، وبياناتك كلها تبقى على جهازك ما لم تختر أنت مسار السحابة
- أبقِ الحلقة غبيّة ومحايدة تجاه النموذج (شكل دردشة OpenAI) وضع القدرات الحقيقية خلف خادم MCP محلي — ابنِ مرة واحدة، وأعد الاستخدام عبر العملاء
- حاجز الحماية هو الجزء الذي لا يمكنك تخطّيه: وافق على الخطوات المدمّرة، وضع سقفًا للحلقات/الميزانية، واعزل الأدوات، وعامِل نتائج الأدوات كغير موثوقة
- Claude هو الطبقة الذكية الاختيارية لأصعب 5% — صعّد خطوة واحدة في كل مرة وأرسل ما تحتاجه تلك الخطوة فقط
- التفاصيل المتقلّبة (أسماء النماذج، والمعرّفات، والأسعار، وواجهات SDK) تقع خلف ملاحظات التحقّق؛ المعمارية ثابتة، والأرقام ليست كذلك
المصادر والقراءة الإضافية
- Ollama — واجهة برمجية متوافقة مع OpenAI (localhost:11434، معامل tools)
- Ollama — إعلان دعم الأدوات
- مكتبة نماذج Ollama (النماذج الراهنة القادرة على استخدام الأدوات)
- Model Context Protocol — مقدّمة
- Model Context Protocol — حزم SDK الرسمية (Python، TypeScript)
- MCP Python SDK (GitHub)
- MCP TypeScript SDK (GitHub)
- Anthropic — نماذج Claude وأسعارها