الكتابات/blog/2026/06
Blog24 يونيو 2026·6 دقيقة

smolagents: بناء وكلاء ذكاء يكتبون الكود

دليل المطوّر إلى مكتبة smolagents من Hugging Face ونمط CodeAct، حيث يكتب الوكلاء كود بايثون بدل استدعاءات JSON. يغطي الأدوات والعزل والاستضافة الذاتية.

تعمل تقريباً كل أطر بناء وكلاء الذكاء الاصطناعي التي قرأت عنها بالطريقة نفسها: يُصدر النموذج كتلة JSON تصف أيّ أداة يجب استدعاؤها وبأيّ وسائط، ثم يُحلّلها وقت التشغيل، ويشغّل الدالة، ويعيد النتيجة إلى النموذج. أطر مثل LangGraph وCrewAI وOpenAI Agents SDK وPydantic AI — كلها تتحدث بلغة استدعاءات JSON.

تراهن مكتبة smolagents من Hugging Face على شيء مختلف. فبدلاً من أن تطلب من النموذج ملء استمارة JSON، تطلب منه كتابة مقطع من كود بايثون، ثم تنفّذ ذلك الكود داخل بيئة معزولة. يُسمّى هذا النمط CodeAct، وما إن تراه يعمل حتى يبدأ أسلوب JSON كأنه حلّ التفافي.

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

لماذا تتفوّق الوكلاء التي تكتب الكود على استدعاءات JSON

تأمّل هذه المهمة: "ابحث عن النماذج الثلاثة الأكثر تنزيلاً لتصنيف النصوص، ثم احسب متوسط عدد تنزيلاتها."

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

أما وكيل الكود فيكتب كتلة واحدة:

models = search_models("text-classification", limit=3)
counts = [m.downloads for m in models]
average = sum(counts) / len(counts)
final_answer(average)

هذا هو جوهر الفكرة. الكود طبقة تركيب شاملة. الحلقات والشروط والمتغيرات وتداخل الدوال والعمليات الحسابية كلها متاحة مجاناً — فهي أصلاً جزء من اللغة. النموذج الذي يعبّر عن أفعاله بالكود يستطيع تركيب الأدوات كما يفعل المبرمج، بدلاً من أن يُجبَر على استدعاء JSON واحد جامد لكل خطوة.

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

تثبيت smolagents

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

pip install smolagents
# لصندوق الأدوات الافتراضي (البحث على الويب وغيره)
pip install 'smolagents[toolkit]'

أول وكيل CodeAgent لك

يحتاج CodeAgent إلى شيئين: نموذج وقائمة أدوات. إليك وكيلاً بسيطاً مدعوماً بنموذج من واجهة الاستدلال في Hugging Face.

from smolagents import CodeAgent, InferenceClientModel
 
model = InferenceClientModel(model_id="meta-llama/Llama-3.3-70B-Instruct")
 
agent = CodeAgent(tools=[], model=model, add_base_tools=True)
 
agent.run("Could you give me the 118th number in the Fibonacci sequence?")

يُحمّل add_base_tools=True مجموعة صغيرة من الأدوات المدمجة. يفكّر الوكيل، يكتب بايثون، ينفّذه وقت التشغيل، وتستمر الحلقة حتى يستدعي النموذج final_answer().

تأتي smolagents بصنفَي وكلاء، كلاهما يرث من MultiStepAgent:

  • CodeAgent — الافتراضي؛ يكتب أفعاله بصيغة كود بايثون.
  • ToolCallingAgent — يكتب أفعاله بصيغة JSON، للحالات التي تريد فيها النمط الكلاسيكي تحديداً أو حين يكون نموذجك ضعيفاً في كتابة الكود.

تعريف أدواتك الخاصة

الأداة ليست سوى دالة يُسمح للوكيل باستدعائها من داخل كوده. أبسط طريقة لإنشائها هي مُزخرِف @tool. امنحها اسماً واضحاً وتلميحات للأنواع وتوثيقاً يتضمن قسم Args: — يقرأ النموذج كل ذلك ليقرر متى وكيف يستخدم الأداة.

from smolagents import tool
 
@tool
def get_exchange_rate(base: str, quote: str) -> float:
    """
    Returns the current exchange rate between two currencies.
 
    Args:
        base: The base currency code, e.g. "USD".
        quote: The quote currency code, e.g. "TND".
    """
    rates = fetch_rates(base)
    return rates[quote]

وحين تحتاج إلى تحكّم أكبر — سمات ثقيلة تُحمّل مرة واحدة، أو عملاء خارجيون يبقون مفتوحين — اشتقّ من الصنف Tool بدلاً من ذلك:

from smolagents import Tool
 
class ExchangeRateTool(Tool):
    name = "get_exchange_rate"
    description = "Returns the current exchange rate between two currencies."
    inputs = {
        "base": {"type": "string", "description": "Base currency code, e.g. USD."},
        "quote": {"type": "string", "description": "Quote currency code, e.g. TND."},
    }
    output_type = "number"
 
    def forward(self, base: str, quote: str) -> float:
        return fetch_rates(base)[quote]

تُعدّ أداة WebSearchTool المدمجة مثالاً جيداً على أداة جاهزة يمكنك إسقاطها مباشرة في قائمة الأدوات.

from smolagents import CodeAgent, WebSearchTool
 
agent = CodeAgent(tools=[WebSearchTool()], model=model)
agent.run("What changed in the latest Python release?")

العزل: القاعدة التي لا يمكنك تجاوزها

إليك الحقيقة غير المريحة عن وكلاء الكود: نموذج يكتب ويشغّل بايثون على جهازك يمثّل خطراً أمنياً إذا شُغّل ذلك الكود من دون عزل. الوكيل القادر على import os ولمس نظام الملفات يبعد توليداً سيئاً واحداً عن إحداث ضرر.

تعالج smolagents هذا عبر وسيط executor_type. تدعم Docker وE2B وModal وBlaxel جاهزةً، ويعمل الوكيل كمدير سياق بحيث تُنظَّف البيئة المعزولة تلقائياً.

from smolagents import CodeAgent, InferenceClientModel
 
with CodeAgent(model=InferenceClientModel(), tools=[], executor_type="docker") as agent:
    agent.run("Can you give me the 100th Fibonacci number?")

استبدل "docker" بـ "e2b" أو "modal" أو "blaxel" بحسب ما إذا كنت تريد عزلاً محلياً أم بيئة سحابية مُدارة. وللتنفيذ المحلي، تتحكّم أيضاً بأيّ عمليات استيراد مسموح بها عبر additional_authorized_imports، بحيث لا يصل الوكيل إلا إلى المكتبات التي تثق بها صراحةً:

agent = CodeAgent(
    tools=[WebSearchTool()],
    model=model,
    additional_authorized_imports=["pandas", "numpy"],
    max_steps=10,
)

عامِل العزل كأمر إلزامي لا اختياري. مُنفّذ Docker هو أبسط طريق لتشغيل وكلاء الكود على خوادمك الخاصة من دون كشف المضيف.

شغّله على بنيتك التحتية الخاصة

هنا تصبح smolagents مثيرة للاهتمام بالنسبة إلى فرق المنطقة العاملة بموجب قواعد إقامة البيانات لدى الهيئة الوطنية لحماية المعطيات الشخصية (INPDP) وقوانين حماية البيانات (PDPL). فالإطار محايد تجاه النموذج، ولا شيء يجبرك على إرسال الأوامر إلى سحابة أمريكية.

عبر LiteLLMModel يمكنك توجيه الوكيل إلى خادم Ollama محلي:

from smolagents import CodeAgent, LiteLLMModel
 
model = LiteLLMModel(
    model_id="ollama_chat/llama3.2",
    api_base="http://localhost:11434",
    num_ctx=8192,
)
 
agent = CodeAgent(tools=[], model=model, add_base_tools=True)
agent.run("Could you give me the 118th number in the Fibonacci sequence?")

أو وجّهه إلى أيّ نقطة نهاية متوافقة مع OpenAI — خادم vLLM مستضاف ذاتياً مثلاً — عبر OpenAIModel:

from smolagents import OpenAIModel
 
model = OpenAIModel(
    model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
    api_base="http://your-vllm-host:8000/v1",
    api_key="not-needed-for-local",
)

وكيل كود يشغّل أوزاناً مفتوحة على خادم vLLM، ويُنفّذ داخل بيئة Docker معزولة على الشبكة نفسها، لا يرسل بيانات العملاء خارج مقرّك أبداً. هذه قصة استضافة ذاتية نظيفة للنشر الواعي بالسيادة.

فرق متعددة الوكلاء

للأحمال الأكبر يمكنك بناء تسلسل هرمي: وكيل مدير يفوّض إلى وكلاء عاملين متخصصين. أيّ وكيل تريد إدارته يجب أن يحمل name وdescription ليعرف المدير ماذا يفعل ومتى يستدعيه.

from smolagents import CodeAgent, ToolCallingAgent, WebSearchTool, InferenceClientModel
 
model = InferenceClientModel()
 
web_agent = ToolCallingAgent(
    tools=[WebSearchTool()],
    model=model,
    name="web_search_agent",
    description="Searches the web and returns relevant findings for a query.",
)
 
manager = CodeAgent(
    tools=[],
    model=model,
    managed_agents=[web_agent],
)
 
manager.run("Research recent open-source agent frameworks and summarise the trade-offs.")

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

متى تختار smolagents

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

وهي أقل ملاءمة لسير العمل الصارم المُدقَّق حيث تريد تقييد كل فعل بمخطط ثابت — فهناك يمنحك إطار استدعاءات JSON أو ToolCallingAgent تحكّماً أدق.

التحوّل الأوسع هو ما يستحق الاستيعاب: أقوى الوكلاء بدأت تعامل الكود نفسه بوصفه فضاء الأفعال. كانت استدعاءات JSON جسراً مؤقتاً. أما السماح للنماذج بكتابة وتشغيل كود حقيقي، معزول بأمان، فهو الوجهة التي يتجه إليها جزء كبير من منظومة الوكلاء — وsmolagents أنظف مكان تبدأ منه تعلّم النمط اليوم.

إن كنت توازن بين هذا وبين الأطر المعتمدة على JSON أولاً، فإن مقارنتنا بين LangGraph وCrewAI وOpenAI Agents SDK رفيق مفيد، وكذلك دليلنا إلى استضافة النماذج اللغوية ذاتياً عبر Ollama.