العودة إلى التحديثات
New releaseAug 9, 2026

monty v0.0.20

مترجم بايثون بسيط وآمن مكتوب بلغة Rust لاستخدامه من قبل الذكاء الاصطناعي

مشاركة

Monty

مفسّر بايثون بسيط وآمن مكتوب بلغة Rust ليُستخدم بواسطة الذكاء الاصطناعي.

CI Codspeed Coverage PyPI versions license Join Slack

تجريبي - هذا المشروع لا يزال قيد التطوير، وغير جاهز بعد للاستخدام الفعلي.

مفسّر بايثون بسيط وآمن مكتوب بلغة Rust ليُستخدم بواسطة الذكاء الاصطناعي.

يتجنّب Monty التكلفة وزمن الاستجابة والتعقيد والمتاعب العامة لاستخدام بيئة حماية (sandbox) كاملة قائمة على الحاويات لتشغيل الكود المولّد بواسطة نماذج اللغة الكبيرة (LLM).

بدلاً من ذلك، يتيح لك تشغيل كود Python المكتوب بواسطة نموذج لغوي كبير (LLM) مدمج في وكيلك بأمان، مع زمن بدء تشغيل يُقاس بوحدات أحادية من الميكروثانية وليس بمئات الميلي ثانية.

ما يمكن أن يفعله Monty:

  • تشغيل مجموعة فرعية معقولة من أكواد Python - بما يكفي لوكيلك للتعبير عمّا يريد فعله
  • منع الوصول تمامًا إلى بيئة المضيف: الوصول إلى نظام الملفات ومتغيرات البيئة والشبكة كلها منفّذة عبر استدعاءات دوال خارجية يمكن للمطوّر التحكم بها
  • استدعاء الدوال على المضيف - فقط الدوال التي تمنحه إمكانية الوصول إليها
  • تشغيل فحص الأنواع - يدعم Monty تلميحات الأنواع الحديثة الكاملة في Python ويأتي مع ty مضمّنًا في ملف ثنائي واحد لتشغيل فحص الأنواع
  • إمكانية أخذ لقطة (snapshot) منه إلى بايتات عند استدعاءات الدوال الخارجية، ما يعني أنه يمكنك تخزين حالة المفسّر في ملف أو قاعدة بيانات واستئناف العمل لاحقًا
  • بدء تشغيل سريع للغاية (<1μs من الكود إلى نتيجة التنفيذ)، وأداء وقت تشغيل مشابه لأداء CPython (بشكل عام بين أسرع بخمس مرات وأبطأ بخمس مرات)
  • إمكانية استدعائه من Rust أو Python أو Javascript - ولأن Monty لا يعتمد على cpython، يمكنك استخدامه في أي مكان يمكنك فيه تشغيل Rust
  • التحكم في استخدام الموارد - يمكن لـ Monty تتبّع استخدام الذاكرة وعمق المكدّس وزمن التنفيذ وإلغاء التنفيذ إذا تجاوز الحدود المحددة مسبقًا
  • جمع stdout و stderr وإرجاعهما إلى المتصل
  • تشغيل كود غير متزامن (async) أو متزامن (sync) على المضيف عبر كود غير متزامن (async) أو متزامن (sync) على المضيف
  • استخدام مجموعة فرعية صغيرة من المكتبة القياسية: sys, os, typing, asyncio, re, datetime, json, dataclasses (قريبًا)

ما لا يمكن أن يفعله Monty:

  • استخدام باقي المكتبة القياسية
  • استخدام مكتبات الطرف الثالث (مثل Pydantic)؛ دعم مكتبات Python الخارجية ليس هدفًا
  • تعريف الكلاسات (الدعم قادم قريبًا)
  • استخدام جمل match (مرة أخرى، الدعم قادم قريبًا)

باختصار، Monty محدود للغاية ومصمَّم لحالة استخدام واحدة:

لتشغيل الكود المكتوب بواسطة الوكلاء.

للتعرّف على الدافع وراء رغبتك في القيام بذلك، انظر:

بعبارات بسيطة جدًا، الفكرة من كل ما سبق هي أن نماذج اللغة الكبيرة (LLMs) يمكنها العمل بشكل أسرع وأرخص وأكثر موثوقية إذا طُلب منها كتابة كود Python (أو Javascript) بدلاً من الاعتماد على استدعاء الأدوات التقليدي. يجعل Monty ذلك ممكنًا دون تعقيد بيئة الحماية (sandbox) أو مخاطرة تشغيل الكود مباشرة على المضيف.

ملاحظة: سوف يُستخدم Monty (قريبًا) لتنفيذ codemode في Pydantic AI

الاستخدام

يمكن استدعاء Monty من Python أو JavaScript/TypeScript أو Rust.

Python

للتثبيت:```bash uv add pydantic-monty

(أو `pip install pydantic-monty` للجيل القديم)

`pydantic-monty` هي حزمة شاملة تقوم بإقران `pydantic-monty-client` (وحدة
`pydantic_monty`) مع `pydantic-monty-runtime` (الملف الثنائي للعامل `monty`
). قم بتثبيت `pydantic-monty-client` وحده إذا كان الملف الثنائي يأتي بالفعل من
مكان آخر.

الاستخدام:```python
from typing import Any

import pydantic_monty

code = """
async def agent(prompt: str, messages: Messages):
    while True:
        print(f'messages so far: {messages}')
        output = await call_llm(prompt, messages)
        if isinstance(output, str):
            return output
        messages.extend(output)

await agent(prompt, [])
"""

type_definitions = """
from typing import Any

Messages = list[dict[str, Any]]

async def call_llm(prompt: str, messages: Messages) -> str | Messages:
    raise NotImplementedError()

prompt: str = ''
"""


Messages = list[dict[str, Any]]


async def call_llm(prompt: str, messages: Messages) -> str | Messages:
    if len(messages) < 2:
        return [{'role': 'system', 'content': 'example response'}]
    else:
        return f'example output, message count {len(messages)}'


async def main():
    async with pydantic_monty.AsyncMonty() as pool:
        async with pool.checkout(
            script_name='agent.py',
            type_check=True,
            type_check_stubs=type_definitions,
        ) as session:
            output = await session.feed_run(
                code,
                inputs={'prompt': 'testing'},
                external_lookup={'call_llm': call_llm},
            )
    print(output)
    #> example output, message count 2


if __name__ == '__main__':
    import asyncio

    asyncio.run(main())

يتم التنفيذ في مجموعة من العمليات الفرعية للعامل monty، لذلك حتى خطأ الذاكرة الناتج عن كود عدائي (تجاوز سعة المكدس، إجهاض المُخصِّص) لا يمكن أبدًا أن يُعطِّل عمليتك — يموت العامل، ويرفع MontyCrashedError، ويُستبدل. هناك أيضًا واجهة برمجة تطبيقات متزامنة بالكامل:```python import pydantic_monty

with pydantic_monty.Monty() as pool: with pool.checkout() as session: # session state persists between feed_run calls session.feed_run('x = 21') print(session.feed_run('x * 2')) #> 42

### JavaScript / TypeScript

للتثبيت:```bash
npm install @pydantic/monty

حزمة JS هي ربط أصلي (napi) فوق نفس تجمّع عمال Rust الذي تستخدمه حزمة Python — حيث يُشحن الربط والملف الثنائي للعامل monty عبر حزم npm الخاصة بالمنصة:```ts import { Monty } from '@pydantic/monty'

await using pool = await Monty.create() await using session = await pool.checkout()

// session state persists between feedRun calls await session.feedRun('x = 21') console.log(await session.feedRun('x * 2')) // 42

// external functions may be async const result = await session.feedRun('await fetch_data()', { externalLookup: { fetch_data: async () => 'data' }, })

بالنسبة للمتصفحات (أو أي مكان يتعذّر فيه استخدام العمليات الفرعية)، تُتيح الحزمة نفسها بناءً على WebAssembly داخل العملية عبر المسار الفرعي `@pydantic/monty/wasm` (بدون عزل الانهيارات: انهيار بيئة الحماية هو انهيار للمضيف هناك).

### Rust

الفئات