Retour aux mises à jour
New releaseAug 9, 2026

monty v0.0.20

Un interpréteur Python minimal et sécurisé écrit en Rust pour utilisation par l'IA.

Partager

Monty

Un interpréteur Python minimal et sécurisé écrit en Rust pour être utilisé par l'IA.

CI Codspeed Coverage PyPI versions license Join Slack

Expérimental - Ce projet est encore en développement et n'est pas prêt pour une utilisation en production.

Un interpréteur Python minimal et sécurisé écrit en Rust pour être utilisé par l'IA.

Monty évite le coût, la latence, la complexité et les tracas d'un sandbox complet basé sur des conteneurs pour exécuter du code généré par un LLM.

Au lieu de cela, il vous permet d'exécuter en toute sécurité du code Python écrit par un LLM intégré à votre agent, avec des temps de démarrage mesurés en microsecondes à un chiffre, et non en centaines de millisecondes.

Ce que Monty peut faire :

  • Exécuter un sous-ensemble raisonnable de code Python - suffisant pour que votre agent exprime ce qu'il veut faire
  • Bloquer complètement l'accès à l'environnement hôte : le système de fichiers, les variables d'environnement et l'accès réseau sont tous implémentés via des appels de fonctions externes que le développeur peut contrôler
  • Appeler des fonctions sur l'hôte - uniquement les fonctions auxquelles vous lui donnez accès
  • Exécuter la vérification de types - monty prend en charge les annotations de types Python modernes complètes et est fourni avec ty inclus dans un seul binaire pour exécuter la vérification de types
  • Être instantanément sérialisé en octets lors des appels de fonctions externes, ce qui signifie que vous pouvez stocker l'état de l'interpréteur dans un fichier ou une base de données, et reprendre plus tard
  • Démarrer extrêmement rapidement (<1μs entre le code et le résultat d'exécution), et avoir des performances d'exécution similaires à celles de CPython (généralement entre 5 fois plus rapides et 5 fois plus lentes)
  • Être appelé depuis Rust, Python ou Javascript - parce que Monty n'a aucune dépendance à CPython, vous pouvez l'utiliser partout où vous pouvez exécuter du Rust
  • Contrôler l'utilisation des ressources - Monty peut suivre l'utilisation de la mémoire, la profondeur de la pile et le temps d'exécution, et annuler l'exécution si elle dépasse les limites prédéfinies
  • Collecter stdout et stderr et les renvoyer à l'appelant
  • Exécuter du code asynchrone ou synchrone sur l'hôte via du code asynchrone ou synchrone sur l'hôte
  • Utiliser un petit sous-ensemble de la bibliothèque standard : sys, os, typing, asyncio, re, datetime, json, dataclasses (bientôt)

Ce que Monty ne peut pas faire :

  • Utiliser le reste de la bibliothèque standard
  • Utiliser des bibliothèques tierces (comme Pydantic) ; la prise en charge de bibliothèques Python externes n'est pas un objectif
  • définir des classes (la prise en charge devrait arriver bientôt)
  • utiliser les instructions match (encore une fois, la prise en charge devrait arriver bientôt)

En bref, Monty est extrêmement limité et conçu pour un seul cas d'usage :

Exécuter du code écrit par des agents.

Pour comprendre pourquoi vous pourriez vouloir faire cela, consultez :

En termes très simples, l'idée de tout ce qui précède est que les LLM peuvent travailler plus vite, à moindre coût et de manière plus fiable si on leur demande d'écrire du code Python (ou Javascript) au lieu de s'appuyer sur l'appel d'outils traditionnel. Monty rend cela possible sans la complexité d'un sandbox ni le risque d'exécuter du code directement sur l'hôte.

Remarque : Monty sera (bientôt) utilisé pour implémenter codemode dans Pydantic AI

Utilisation

Monty peut être appelé depuis Python, JavaScript/TypeScript ou Rust.

Python

Pour installer :```bash uv add pydantic-monty

(Ou `pip install pydantic-monty` pour les boomers)

`pydantic-monty` est un méta-paquet associant `pydantic-monty-client` (le module `pydantic_monty`) avec `pydantic-monty-runtime` (le binaire worker `monty`). Installez `pydantic-monty-client` seul si le binaire provient déjà d'ailleurs.

Utilisation :```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())

L'exécution a lieu dans un pool de sous-processus de travail monty, donc même une erreur mémoire déclenchée par du code hostile (débordement de pile, arrêt de l'allocateur) ne peut jamais faire planter votre processus — le travailleur meurt, lève MontyCrashedError, et est remplacé. Il existe également une API entièrement synchrone :```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

Catégories