function calling بيخلّي اللفّة آلية ومضبوطة: النموذج بيولّد JSON مطابق للـ schema، والـ runtime بيتحقق ويشغّل ويرجّع النتيجة.1. SYSTEM BUILD — runtime يجمّع الأدوات ويحوّلها لـ function definitions
2. MODEL OUTPUT — { "name": "read_file",
"input": { "path": "README.md" } }
3. RUNTIME EXEC — تحقّق: الأداة موجودة؟ الصلاحيات؟ الـ schema؟
← تشغيل فعلي على القرص + secret redaction
4. TOOL RESULT — { "role": "tool",
"content": "1|# Velox Academy\n2|..." }
5. FINAL ANSWER — النموذج بيقرأ النتيجة ويرد شفهي
| المفهوم | في OpenClaw | في Hermes |
|---|---|---|
| الوحدة الأساسية | Tool groups + profiles | Toolsets + platform presets |
| عدد الأدوات | groups + plugins + MCP | ~83 أداة مدمجة |
write وapply_patch | أداتين منفصلتين | patch تغطي كل الحالات |
| Skill | يشرح إزاي تشتغل | skills toolset |
| Plugin | يضيف قدرات runtime | ~/.hermes/plugins/ |
# شوف الأدوات المتاحة (واجهة تفاعلية)
hermes tools
# عرض فقط
hermes tools list
# تفعيل / تعطيل بالاسم
hermes tools enable browser
hermes tools disable x_search
# لأداة واحدة في هذه الجلسة فقط (override مؤقت)
hermes chat --toolsets "web,terminal"
| الفئة | OpenClaw | Hermes |
|---|---|---|
| تشغيل الأوامر | exec, process, terminal | terminal, process |
| الملفات | read, write, edit, apply_patch | read_file, write_file, patch |
| إدخال بشري | ask_user, secrets | clarify, browser_vault_* |
| ويب | web_search, x_search, web_fetch | web_search, web_extract |
| المتصفح | browser (profile مُدار + CDP) | 10 أدوات browser_* + 2 أدوات CDP |
| الذاكرة | memory_search, memory_get | memory + memory providers |
| الأتمتة | cron, heartbeat_respond | cronjob |
| تنفيذ الكود | بعيد على xAI | محلي |
| أدوات MCP | bundle-mcp plugin | mcp_{server}_{tool} |
| الوكلاء الفرعيون | sessions_spawn, subagents | delegate_task, session_search |
| الصوت | via tools.media | text_to_speech |
| Code Mode | ✔ tools.codeMode | ✘ غير متاح |
config.yaml في نص محادثة بيكسر الـ prompt caching. في الـ gateway استخدم /reset أو /restart، وفي الـ CLI اقفل وافتح من جديد. الاستثناء الوحيد هو ضغط السياق.LINE_NUM|CONTENT، يعني كل سطر مسبوق برقمه — فالنموذج يقدر يشير لسطر محدد بدقة. فيها ترقيم صفحات بـ offset وlimit، سقف ~100KB، واستخراج تلقائي للمستندات (PDF، docx، ipynb، SQLite وغيرها).read_file(path="config.yaml", offset=1, limit=2000)
# تعديل جزئي — بيرجع unified diff وبيعمل syntax check
patch(path="src/config.py",
old_string="timeout = 30",
new_string="timeout = 180")
# بحث في المحتوى أو بالاسم (rg-backed) مع file_glob وحدود
search_files(pattern="database", path=".", file_glob="*.yaml", limit=20)
| الوظيفة | Hermes | OpenClaw |
|---|---|---|
| قراءة ملف نصي بأرقام أسطر | read_file | read |
| كتابة/استبدال محتوى بالكامل | write_file | write |
| تعديل مستهدف (find-and-replace) | patch | edit / apply_patch |
| بحث في المحتوى أو بالاسم | search_files | via read/exec |
write_file بيكتب الملف بالكامل (overwrite). على ملف كبير = فقدان كل اللي مش موجود في الـ payload. ولو التعديل جزئي، استخدم patch.ssh هو الأكثر أماناً: الوكيل بيشتغل على جهاز تانية، فمش يقدر يعدّل الكود اللي شغّال، ولو السيرفر اتخرب الكود عندك في local سالم.terminal:
backend: ssh # local | docker | ssh | singularity | modal | daytona | vercel_sandbox
cwd: "."
timeout: 180 # مهلة الأمر بالثواني
TERMINAL_SSH_HOST=my-server.example.com
TERMINAL_SSH_USER=myuser
TERMINAL_SSH_KEY=~/.ssh/id_rsa
# نفّذ npm test على الـ sandbox بمهلة 300 ثانية
openclaw exec --host auto --timeout 300 "npm test"
# نفّذ في الخلفية (مثل npm run dev) — timeoutSeconds: 0 يلغي المهلة
openclaw exec --background "npm run dev"
| المحور | Hermes | OpenClaw |
|---|---|---|
| الافتراضي | local على جهازك | الـ sandbox مقفول |
| الخيارات | local, docker, ssh, singularity, modal, daytona, vercel_sandbox | Docker, Podman, SSH, OpenShell, Crabbox |
| الاستمرارية | حاوية Docker واحدة دائمة | sandbox لكل مهمة |
| الخروج من العزل | بتغيير الـ backend | elevated + tools.elevated.allowFrom |
| نطاقات التحكم | approvals.mode, command_allowlist | tools.exec.* + approvals + tools.elevated |
| Gateway process | — | يفضل على المضيف دايماً |
~/.bashrc — الـ guard في الأول والـ init التقيل تحته.web_extract بياخد 5 URLs في نداء واحد — أسرع بكتير من 5 نداءات منفصلة.results = web_search("RAG best practices 2026", limit=5) # رخيص جداً
pages = web_extract(["https://a.com", "https://b.com"]) # أغلى: بيفتح الصفحة
# اضبط إعدادات البحث والجلب من الـ CLI
openclaw configure --section web
| الأداة | بتعمل إيه | التكلفة |
|---|---|---|
web_search | بحث — قوائم نتائج (عناوين + URLs) | رخيصة جداً |
web_extract | استخراج — بتفتح الـ URL وترجع النص | أغلى |
browser | أتمتة متصفح كامل | أغلى بكتير |
web_search في Hermes بيخزّن 20 دقيقة وweb_search في OpenClaw 15 دقيقة. إعادة جلب نفس الـ URL بيبان كـ «موقعي مش بيتحدث» وهو في الحقيقة stale cache. بتطوّر موقع وتختبره على الإنترنت العلني؟ DNS العلني مش مستثنى تلقائياً.web:
cache_exempt_hosts: # دايماً fetched live؛ يسري فوراً
- mysite.vercel.app
- "*.ngrok-free.app"
- mysite.dev # suffix match
browser_navigate لازم تتنادى الأول قبل أي أداة تانية. بعد كده الـ browser_snapshot بيرجّع شجرة إمكانية الوصول كنص، والعناصر التفاعلية بتاخد ref IDs زي @e1 — النموذج بيستخدمها للـ click والـ type.browser_navigate(url) # أول نداء دائماً — يثبّت الجلسة
browser_snapshot(full=false) # العناصر التفاعلية بس (compact)
browser_click(@e5) # نقرة على عنصر بمعرّف من الـ snapshot
browser_type(@e3, "text") # كتابة في input (بيمسح الحقل الأول)
browser_press("Enter") # Enter للإرسال، Escape للإغلاق
browser_console() # console + أخطاء JS ← لكشف الأخطاء الصامتة
# أداتين إضافيتين — بيتسجلوا بس لو في endpoint CDP متاح
browser_cdp("Page.captureScreenshot")
browser_dialog(action="accept") # بعد ما الـ snapshot يعرض pending_dialogs
# افتح الـ CLI بتاع المتصفح
openclaw browser --help
# اضبط الـ profile من الإعدادات
openclaw configure --section browser
| Profile | بيعمل إيه |
|---|---|
openclaw | المتصفح المُدار المعزول (الافتراضي، والأمني) |
user | يرتبط بجلسة Chrome الحقيقية الموقّعة عبر CDP |
execute_code بيكتب سكربت Python بينادي الأدوات برمجياً، واللي بيرجع للـ context هو الـ print النهائي بس.from hermes_tools import web_search, web_extract
import json
queries = [
"vector database 2026",
"RAG best practices 2026",
"LLM agent frameworks 2026",
"MCP servers directory",
"prompt caching explained",
]
all_results = []
for q in queries:
results = web_search(q, limit=3)
urls = [r["url"] for r in results["data"]["web"]]
for i in range(0, len(urls), 5):
batch = urls[i:i+5] # 5 URLs في نداء واحد
page = web_extract(batch)
for p in page.get("results", []):
if p.get("content"):
all_results.append({"q": q, "url": p["url"],
"text": p["content"][:800]})
print(json.dumps(all_results, indent=2)) # بس ده اللي بيرجع
code_execution:
mode: project # أو "strict"
| الخاصية | project | strict |
|---|---|---|
| مجلد العمل | مجلد الجلسة (نفس terminal()) | مجلد staging معزول |
| المفسر | الـ venv النشط | sys.executable always |
| مناسب لإيه | import pandas ومسارات نسبية | أقصى قابلية للتكرار |
| fallback | لو الـ venv مكسور → sys.executable | — |
execute_code بشكل recursive ولا delegate_task ولا أدوات MCP.mcp_{server}_{tool}، 4 يحقنها في كل الـ platform toolsets. من بعد كده استخدمها طبيعياً.mcp_servers:
time: # stdio — command-based
command: "uvx"
args: ["mcp-server-time"]
timeout: 120 # مهلة كل نداء بالثواني
connect_timeout: 60
docs: # HTTP — url-based
url: "https://mcp.example.com/mcp"
headers:
Authorization: "Bearer sk-..."
timeout: 180
hermes mcp # picker تفاعلي (افتراضي)
hermes mcp catalog # قائمة نصية قابلة للـ scripting
hermes mcp install n8n # تثبيت entry من الكتالوج بالاسم
hermes mcp configure NAME # تبديل اختيار الأدوات (الفلترة)
hermes mcp serve # تشغيل Hermes كـ MCP server
# سيرفر stdio محلي
openclaw mcp add local-tools --command node --arg ./dist/mcp-server.js
openclaw mcp doctor local-tools --probe
# سيرفر HTTP بعيد، يعرض جزء من أدواته بس
openclaw mcp add docs --url https://mcp.example.com/mcp \
--transport streamable-http --include 'search,read_*'
# اتأكد إن السيرفرات المفعّلة بتتصل فعلاً
openclaw mcp probe context7 --json
| الإعداد | النوع | الافتراضي |
|---|---|---|
command | string | — (required for stdio) |
args | list | [] |
env | dict | {} |
url | string | — (required for HTTP) |
headers | dict | {} |
timeout | int | 120 |
connect_timeout | int | 60 |
mcp.servers، وأدواتها بتعدّي نفس ضوابط tool-profile و tool-policy زي أي حاجة تانية — ربط سيرفر مش بيلفّ على سياستك.delete_workspace وwipe_database وtransfer_funds. لو كلهم اتعرضوا للنموذج، احتمال misuse بيتفعّل. الفلترة بتقلّل الـ surface area والـ tokens في نفس الوقت.mcp_servers:
company_api:
command: "npx"
args: ["-y", "company-mcp"]
env:
DATABASE_URL: "postgresql://..." # لازم صريح — مش بينتقل تلقائياً
tools:
include: ["db_read", "db_query", "db_schema"]
# حدّث فلاتر الأدوات لكل سيرفر (أسماء و globs بسيطة بـ *)
openclaw mcp tools context7 --include 'resolve-library-id,get-library-docs'
openclaw mcp configure docs --include 'search,read_*'
# موافقات Codex: auto | prompt | approve (approve بس للسيرفرات الموثوقة)
openclaw mcp add memory --command npx --arg -y \
--arg @modelcontextprotocol/server-memory --approval approve
openclaw mcp set docs '{"url":"https://mcp.example.com/mcp","transport":"streamable-http","auth":"oauth","oauth":{"scope":"docs.read"}}'
# شغّل login — callback loopback + تخزين في SQLite مشترك
openclaw mcp login docs
openclaw mcp status --verbose
openclaw mcp doctor docs --probe
openclaw mcp logout docs
| الطبقة | Hermes | OpenClaw |
|---|---|---|
| فلترة الأدوات | tools.include in the config | --include / toolFilter |
| عزل الـ environment | متغيرات صريحة بس + baseline آمن | allowlist للمتغيرات المعروفة |
| OAuth | متصفح يفتح عند أول اتصال | دورة كاملة + per-requester |
| موافقة على الأداة | ✘ غير متاحة | ✔ --approval |
| تنقية الـ credentials | من رسائل الخطأ | allowlist للـ env vars |
Authorization headers الثابتة بتتجاهل لأي سيرفر طول ما auth: "oauth" مفعّل. وفي Hermes، لو approvals.mode — ده بيمسك أوامر shell بس، مش نداءات MCP.~/.hermes/plugins/my-plugin/
├── plugin.yaml # manifest
├── __init__.py # register() — بيربط الـ schemas بالـ handlers
├── schemas.py # tool schemas (اللي النموذج بيشوفه)
└── tools.py # tool handlers (اللي بيشتغل لما الأداة تنادى)
def register(ctx):
schema = {
"name": "hello_world",
"description": "Returns a friendly greeting for the given name.",
"parameters": {
"type": "object",
"properties": {"name": {"type": "string"}},
"required": ["name"],
},
}
def handle_hello(params, **kwargs):
del kwargs
name = params.get("name", "World")
return json.dumps({"success": True, "greeting": f"Hello, {name}!"})
ctx.register_tool(name="hello_world", toolset="hello_world",
schema=schema, handler=handle_hello)
ctx.register_hook("post_tool_call", on_tool_call)
openclaw plugins init my-plugin --name "My Plugin" # scaffolding
npm run plugin:build # بناء
npm run plugin:validate # تحقق
openclaw plugins install ./my-plugin
openclaw plugins enable my-plugin
openclaw plugins inspect my-plugin --runtime --json
| القدرة | Hermes |
|---|---|
| إضافة أدوات | ctx.register_tool(...) |
| إضافة hooks | ctx.register_hook("post_tool_call", cb) |
| Slash commands | ctx.register_command(name, handler, description) |
| نداء LLM من المضيف | ctx.llm.complete(...) |
| نداء أداة MCP | ctx.call_mcp(server, tool, args) |
| تسجيل مزوّد صور | ctx.register_image_gen_provider(...) |
| اشتراط متغيرات | requires_env in plugin.yaml |
| التوزيع | a pip entry-point or a ~/.hermes/plugins/ directory |
HERMES_ENABLE_PROJECT_PLUGINS=true بس للمستودعات الموثوقة. وفي OpenClaw: كل plugin APIs تجريبية — ثبّت إصدار المضيف.exec هي أخطر أداة في القائمة، لأنها بتلغي كل الفلاتر التانية. فلاتر الأدوات مش بديل عن review بشري.# الوسط الموصى به
hermes config set approvals.mode smart
# يتخطى كل موافقات الأوامر (مش موصى به)
hermes config set approvals.mode off
{
tools: {
profile: "coding",
deny: ["group:fs"], // group denies بتتجاوز allow صريح
byProvider: { anthropic: { profile: "minimal" } },
toolsBySender: {
"channel:discord:1234567890123": { alsoAllow: ["group:fs"] },
"*": { deny: ["exec", "process", "write", "edit", "apply_patch"] },
},
},
}
| الوضع | السلوك |
|---|---|
smart | موافقة تلقائية لأمر منخفض المخاطر، رفض للعالي، وسؤال عند عدم اليقين (افتراضي) |
manual | دايماً يسأل |
off | يتخطى كل موافقات الأوامر (يعادل --yolo) |
write وapply_patch أداتين منفصلتين: deny: ["write"] ما بتمنعش apply_patch. الحل: deny الـ group بالكامل أو سمّي كل أداة تعديل بالاسم.session_id — استخدم process (poll/wait/kill) لإدارتها. لاحظ: delegate_task(background=True) مش durable — لو العملية الأبا خرجت، الطفل ضاع.from hermes_tools import terminal
import json
# شغّل عملية طويلة في الخلفية وكمّل اللفّة
sid = terminal(command="hermes chat -q 'Set up CI/CD for ~/myapp'",
background=True, notify_on_complete=True)
print(json.dumps({"session_id": sid}))
image_gen:
max_parallel_requests: 4 # صور متوازية في batch نداء واحد (افتراضي 4)
{
mcp: { servers: { "fast-server": {
url: "https://mcp.example.com",
supportsParallelToolCalls: true } } },
tools: { media: { concurrency: 2 } },
}
| طبقة التوازي | Hermes | OpenClaw |
|---|---|---|
| نداءات متوازية في نفس اللفّة | ✔ model + runtime | ✔ |
| Batch في نداء واحد | web_extract (5 URLs) | web_fetch |
| توازي على مستوى الوكلاء | delegate_task(tasks=[...]) — افتراضي 3 | sessions_spawn |
| توازي منطقي بالبرمجة | execute_code | tools.codeMode |
| تلميح على مستوى السيرفر | ✘ | ✔ supportsParallelToolCalls |
| سقف التوازي | image_gen.max_parallel_requests | tools.media.concurrency |
| خلفية + إشعار | terminal(background=True) | exec(background: true) + process |
config.yaml.# المعالج التفاعلي: صور + صوت + كل الأدوات
hermes tools
# Hermes: 11 موديل FAL من غير مفتاح، و Edge TTS مجاني من غير مفتاح
image_gen:
model: fal-ai/flux-2/klein/9b # افتراضي: سريع، نص واضح، $0.006/MP
use_gateway: false # true لو مشترك Nous Portal
max_parallel_requests: 4
tts:
provider: "edge" # edge | elevenlabs | openai | minimax | mistral | xai | piper
speed: 1.0
edge:
voice: "en-US-AriaNeural" # 322 صوت، 74 لغة
stt:
enabled: true
provider: local # faster-whisper مجاني
{
tools: { media: {
concurrency: 2,
models: [
{ provider: "openai", model: "gpt-4o-mini-transcribe", capabilities: ["audio"] },
{ provider: "xai", model: "grok-imagine-image", capabilities: ["image"] },
],
} },
}
| الميزة | Hermes | OpenClaw |
|---|---|---|
| أداة توليد الصور | image_generate | image_generate |
| عدد الموديلات | 11 (FAL) | 9+ مزوّدات |
| تحرير الصور | ✔ image_url + مراجع | ✔ image / images |
| اختيار الموديل | hermes tools | agents.defaults.mediaModels.image |
| توليد غير متزامن | ✘ متزامن | ✔ background task |
| TTS | text_to_speech — 11 مزوّد | tools.media models |
| STT | 6 مزوّد (faster-whisper، Groq، Openai…) | capabilities: [audio] |
| صوت محلي | ✔ NeuTTS, KittenTTS, Piper | ✘ |
| بدون مفتاح | ✔ Nous Tool Gateway | ✘ |
image_url — الصورة المصدر الأساسية، وreference_image_urls — مراجع تنسيق/ستايل إضافية (لكل موديل سقف مختلف: FAL 9، OpenAI 16، Krea 10، xAI 1).| المحور | OpenClaw | Hermes |
|---|---|---|
| اللغة | Node.js (TypeScript ESM) | Python |
| ملف الإعدادات | ~/.openclaw/openclaw.json (JSON5) | ~/.hermes/config.yaml + .env |
| وحدة التنظيم | tools.* policy keys | toolsets + hermes tools |
| عدد الأدوات | groups + plugins + MCP | ~83 أداة مدمجة |
| Node required | Node 24.16+ / 26.1+ | ✘ Python بس |
| تنفيذ الكود | بعيد على xAI | محلي |
| Code Mode | ✔ tools.codeMode | ✘ |
| المتصفح | browser (profile مُدار) | 10 أدوات browser_* + 2 CDP |
| أدوات MCP | bundle-mcp plugin | mcp_{server}_{tool} |
| تشغيل كـ MCP server | openclaw mcp serve | hermes mcp serve |
| إعادة تحميل الـ config | hybrid hot reload | ✘ إعادة تشغيل مطلوبة |
| الافتراضي الآمن | sandbox مقفول + coding profile | approvals.mode: smart + redaction |
| موافقات exec | 6 أوضاع | 3 أوضاع |
| موافقات MCP | ✔ --approval | ✘ |
| التصفية حسب المزوّد/المرسل | ✔ byProvider + toolsBySender | ✘ |
| بدون مفتاح | ✘ | ✔ Nous Tool Gateway |
# OpenClaw
openclaw doctor
openclaw mcp status --verbose
openclaw plugins inspect my-plugin --runtime --json
# Hermes
hermes doctor
hermes tools list
hermes mcp catalog
note_read وnote_write، وأضفهم لـ Hermes بـ stdio، مع فلترة صريحة على أدوات القراءة، ومراجعة كل حقل في الـ manifest قبل التثبيت.mkdir serena-mcp && cd serena-mcp
npm init -y
npm install @modelcontextprotocol/sdk
# سجّل الأداتين في السيرفر
node index.js
mcp_servers:
serena:
command: "node"
args: ["/home/you/serena-mcp/index.js"]
timeout: 60
tools:
include: ["note_read"] # أدوات القراءة بس
# اختبر السيرفر قبل ما تعتمد عليه
hermes mcp test serena
hermes mcp configure serena
# OpenClaw: نفس السيرفر بنفس الفلاتر
openclaw mcp add serena --command node --arg /home/you/serena-mcp/index.js
openclaw mcp tools serena --include 'note_read'
openclaw mcp probe serena --json
{"name": "read_file", "input": {"path": "README.md"}}. ليه الـ framework بينفّذ الأداة مش النموذج نفسه؟{ tools: { deny: ["write"] } } بس الوكيل لسه بيعدّل الملفات بـ apply_patch. ليه؟ وإيه الحل؟delegate_task(background=True) على مهمة طويلة، وبعدين عملية الوكيل الأبا اتقفلت فجأة. إيه اللي هيحصل؟delegate_task مش durable؛ استخدم cronjob أو terminal(background=True)
db_wipe وtransfer_funds، والـ env فيه DATABASE_URL. عايز الوكيل يشوف أدوات القراءة بس. إيه أفضل إعداد؟approvals.mode بس
tools.include لأدوات القراءة + env صريح لـ DATABASE_URL
web_search + web_extract، (ب) web_search + متصفح كامل، ولا (ج) execute_code فوق الاتنين؟execute_code مبالغة