
monty v0.0.20
Ein minimaler, sicherer Python-Interpreter, geschrieben in Rust, zur Verwendung durch KI.
Monty
Ein minimaler, sicherer Python-Interpreter, geschrieben in Rust, für die Nutzung durch KI.
Experimentell – Dieses Projekt befindet sich noch in der Entwicklung und ist noch nicht bereit für den produktiven Einsatz.
Ein minimaler, sicherer Python-Interpreter, geschrieben in Rust, für die Nutzung durch KI.
Monty vermeidet die Kosten, Latenz, Komplexität und den allgemeinen Aufwand einer vollständigen containerbasierten Sandbox für die Ausführung von LLM-generiertem Code.
Stattdessen können Sie damit sicher Python-Code ausführen, der von einem LLM geschrieben wurde und in Ihrem Agenten eingebettet ist – mit Startzeiten im einstelligen Mikrosekundenbereich, nicht in Hunderten von Millisekunden.
Was Monty kann:
- Eine vernünftige Teilmenge von Python-Code ausführen – genug, damit Ihr Agent ausdrücken kann, was er tun möchte
- Den Zugriff auf die Host-Umgebung vollständig blockieren: Dateisystem, Umgebungsvariablen und Netzwerkzugriff werden alle über externe Funktionsaufrufe implementiert, die der Entwickler kontrollieren kann
- Funktionen auf dem Host aufrufen – nur Funktionen, auf die Sie ihm Zugriff gewähren
- Typprüfung ausführen – Monty unterstützt vollständige moderne Python-Typannotationen und enthält ty in einer einzigen Binärdatei, um die Typprüfung auszuführen
- An externen Funktionsaufrufen in Bytes gesnapshotet werden, sodass Sie den Interpreterzustand in einer Datei oder Datenbank speichern und später fortsetzen können
- Äußerst schnell starten (<1μs vom Code zum Ausführungsergebnis), und die Laufzeitleistung ist ähnlich wie bei CPython (in der Regel zwischen 5x schneller und 5x langsamer)
- Aus Rust, Python oder Javascript aufrufbar sein – da Monty keine Abhängigkeiten von CPython hat, können Sie es überall dort einsetzen, wo Sie Rust ausführen können
- Ressourcennutzung kontrollieren – Monty kann Speichernutzung, Stacktiefe und Ausführungszeit verfolgen und die Ausführung abbrechen, wenn sie voreingestellte Grenzwerte überschreitet
- stdout und stderr sammeln und an den Aufrufer zurückgeben
- Async- oder Sync-Code auf dem Host über Async- oder Sync-Code auf dem Host ausführen
- Eine kleine Teilmenge der Standardbibliothek verwenden:
sys,os,typing,asyncio,re,datetime,json,dataclasses(bald)
Was Monty nicht kann:
- Den Rest der Standardbibliothek verwenden
- Drittanbieterbibliotheken (wie Pydantic) verwenden; die Unterstützung externer Python-Bibliotheken ist kein Ziel
- Klassen definieren (Unterstützung sollte bald kommen)
- match-Anweisungen verwenden (auch hier sollte die Unterstützung bald kommen)
Kurz gesagt, Monty ist extrem begrenzt und für einen Anwendungsfall konzipiert:
Um von Agenten geschriebenen Code auszuführen.
Wenn Sie wissen möchten, warum Sie das tun sollten, siehe:
- Codemode von Cloudflare
- Programmatic Tool Calling von Anthropic
- Code Execution with MCP von Anthropic
- Smol Agents von Hugging Face
In einfachen Worten: Die Idee hinter all dem ist, dass LLMs schneller, kostengünstiger und zuverlässiger arbeiten können, wenn sie gebeten werden, Python- (oder Javascript-)Code zu schreiben, anstatt sich auf traditionelles Tool Calling zu verlassen. Monty macht das möglich, ohne die Komplexität einer Sandbox oder das Risiko, Code direkt auf dem Host auszuführen.
Hinweis: Monty wird (bald) zur Implementierung von codemode in Pydantic AI verwendet.
Verwendung
Monty kann aus Python, JavaScript/TypeScript oder Rust aufgerufen werden.
Python
Zur Installation:```bash uv add pydantic-monty
(Oder `pip install pydantic-monty` für die Boomer)
`pydantic-monty` ist ein Metapaket, das `pydantic-monty-client` (das
`pydantic_monty`-Modul) mit `pydantic-monty-runtime` (die `monty`-Worker-
Binärdatei) bündelt. Installiere `pydantic-monty-client` allein, wenn die Binärdatei bereits von
anderswo stammt.
Verwendung:```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())
Die Ausführung erfolgt in einem Pool von monty-Worker-Subprozessen, sodass selbst ein Speicherfehler, der durch adversarischen Code ausgelöst wird (Stack-Overflow, Allocator-Abbruch), niemals deinen Prozess zum Absturz bringen kann – der Worker stirbt, wirft MontyCrashedError und wird ersetzt. Es gibt auch eine vollständig synchrone API:```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
Zur Installation:```bash
npm install @pydantic/monty
Das JS-Paket ist eine native (napi) Bindung über denselben Rust-Worker-Pool, den das Python-Paket verwendet — die Bindung und die monty-Worker-Binärdatei werden über plattformspezifische npm-Pakete ausgeliefert:```ts
import { Monty } from '@pydantic/monty'