
مترجم بايثون بسيط وآمن مكتوب بلغة Rust لاستخدامه من قبل الذكاء الاصطناعي
تجريبي - هذا المشروع لا يزال قيد التطوير، وغير جاهز بعد للاستخدام الفعلي.
مفسّر بايثون بسيط وآمن مكتوب بلغة Rust ليُستخدم بواسطة الذكاء الاصطناعي.
يتجنّب Monty التكلفة وزمن الاستجابة والتعقيد والمتاعب العامة لاستخدام بيئة حماية (sandbox) كاملة قائمة على الحاويات لتشغيل الكود المولّد بواسطة نماذج اللغة الكبيرة (LLM).
بدلاً من ذلك، يتيح لك تشغيل كود Python المكتوب بواسطة نموذج لغوي كبير (LLM) مدمج في وكيلك بأمان، مع زمن بدء تشغيل يُقاس بوحدات أحادية من الميكروثانية وليس بمئات الميلي ثانية.
ما يمكن أن يفعله Monty:
sys, os, typing, asyncio, re, datetime, json, dataclasses (قريبًا)ما لا يمكن أن يفعله Monty:
باختصار، Monty محدود للغاية ومصمَّم لحالة استخدام واحدة:
لتشغيل الكود المكتوب بواسطة الوكلاء.
للتعرّف على الدافع وراء رغبتك في القيام بذلك، انظر:
بعبارات بسيطة جدًا، الفكرة من كل ما سبق هي أن نماذج اللغة الكبيرة (LLMs) يمكنها العمل بشكل أسرع وأرخص وأكثر موثوقية إذا طُلب منها كتابة كود Python (أو Javascript) بدلاً من الاعتماد على استدعاء الأدوات التقليدي. يجعل Monty ذلك ممكنًا دون تعقيد بيئة الحماية (sandbox) أو مخاطرة تشغيل الكود مباشرة على المضيف.
ملاحظة: سوف يُستخدم Monty (قريبًا) لتنفيذ codemode في Pydantic AI
يمكن استدعاء Monty من Python أو JavaScript/TypeScript أو Rust.
للتثبيت:```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