Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
monty — Um interpretador Python mínimo e seguro escrito em Rust para uso por IA. | Kitploit
Ferramentas/GitHubGitHub/pydantic/monty
Utilitários de Propósito GeralAnálise de CódigoScripting e AutomaçãoAprendizado e EducaçãoSegurança de IA
GitHubpydantic/monty

monty

Um interpretador Python mínimo e seguro escrito em Rust para uso por IA.

Ver Repositório
8.0k401há 16h 42mRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Monty

Um interpretador Python mínimo e seguro escrito em Rust para uso por IA.

CI Codspeed Coverage PyPI versions license Join Slack

Experimental - Este projeto ainda está em desenvolvimento e não está pronto para uso em produção.

Um interpretador Python mínimo e seguro escrito em Rust para uso por IA.

O Monty evita o custo, a latência, a complexidade e o incômodo geral de usar um sandbox baseado em contêiner completo para executar código gerado por LLM.

Em vez disso, ele permite que você execute com segurança código Python escrito por um LLM incorporado ao seu agente, com tempos de inicialização medidos em dígitos únicos de microssegundos, não em centenas de milissegundos.

O que o Monty consegue fazer:

  • Executar um subconjunto razoável de código Python - suficiente para o seu agente expressar o que deseja fazer
  • Bloquear completamente o acesso ao ambiente do host: sistema de arquivos, variáveis de ambiente e acesso à rede são todos implementados via chamadas de funções externas que o desenvolvedor pode controlar
  • Chamar funções no host - apenas funções às quais você concede acesso
  • Executar verificação de tipos - o Monty suporta dicas de tipo modernas completas do Python e vem com ty incluído em um único binário para executar a verificação de tipos
  • Ser capturado (snapshot) em bytes em chamadas de funções externas, o que significa que você pode armazenar o estado do interpretador em um arquivo ou banco de dados e retomá-lo mais tarde
  • Iniciar extremamente rápido (<1μs para ir do código ao resultado de execução) e ter desempenho em tempo de execução semelhante ao CPython (geralmente entre 5x mais rápido e 5x mais lento)
  • Ser chamado a partir de Rust, Python ou Javascript - como o Monty não tem dependências do cpython, você pode usá-lo em qualquer lugar onde consiga executar Rust
  • Controlar o uso de recursos - o Monty consegue monitorar o uso de memória, a profundidade da pilha e o tempo de execução, e cancelar a execução se exceder os limites predefinidos
  • Coletar stdout e stderr e devolvê-los ao chamador
  • Executar código assíncrono ou síncrono no host via código assíncrono ou síncrono no host
  • Usar um pequeno subconjunto da biblioteca padrão: sys, os, typing, asyncio, re, datetime, json, dataclasses (em breve)

O que o Monty não pode fazer:

  • Usar o restante da biblioteca padrão
  • Usar bibliotecas de terceiros (como Pydantic); suporte para bibliotecas Python externas não é um objetivo
  • definir classes (suporte deve chegar em breve)
  • usar declarações match (novamente, suporte deve chegar em breve)

Em resumo, o Monty é extremamente limitado e projetado para um caso de uso:

Executar código escrito por agentes.

Para entender a motivação de por que você pode querer fazer isso, veja:

  • Codemode da Cloudflare
  • Programmatic Tool Calling da Anthropic
  • Code Execution with MCP da Anthropic
  • Smol Agents da Hugging Face

Em termos muito simples, a ideia de tudo isso é que LLMs podem trabalhar mais rápido, de forma mais barata e mais confiável se forem solicitados a escrever código Python (ou Javascript), em vez de depender do chamamento tradicional de ferramentas. O Monty torna isso possível sem a complexidade de um sandbox ou o risco de executar código diretamente no host.

Nota: o Monty será (em breve) usado para implementar o codemode no Pydantic AI

Uso

O Monty pode ser chamado a partir de Python, JavaScript/TypeScript ou Rust.

Python

Para instalar:```bash uv add pydantic-monty

root@kitploit:~
(Ou `pip install pydantic-monty` para os boomers)

`pydantic-monty` é um metapacote que combina `pydantic-monty-client` (o
módulo `pydantic_monty`) com `pydantic-monty-runtime` (o binário do worker
`monty`). Instale apenas `pydantic-monty-client` se o binário já vier de
outro lugar.

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

A execução acontece em um pool de subprocessos workers monty, então até mesmo um erro de memória acionado por código adversarial (estouro de pilha, abort do alocador) nunca pode derrubar seu processo — o worker morre, levanta MontyCrashedError, e é substituído. Também existe uma API totalmente síncrona:```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

root@kitploit:~
### JavaScript / TypeScript

Para instalar:```bash
npm install @pydantic/monty

O pacote JS é um binding nativo (napi) sobre o mesmo pool de workers Rust que o pacote Python usa — o binding e o binário do worker monty são distribuídos via pacotes npm específicos de plataforma:```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' }, })

root@kitploit:~
Para navegadores (ou em qualquer lugar onde subprocessos sejam impossíveis), o mesmo pacote
expõe uma compilação WebAssembly em processo sob o subcaminho `@pydantic/monty/wasm`
(sem isolamento de falhas: uma falha da sandbox é uma falha do host nesse caso).

### Rust

Para executar código não confiável a partir do Rust, recomendamos o
crate [`monty-pool`](https://crates.io/crates/monty-pool) em vez da API em processo abaixo.
O `monty-pool` executa código apenas em subprocessos de trabalho `monty`, o que oferece proteções extras:
uma falha causada por código adversário (estouro de pilha, abort do alocador) mata apenas o worker —
o pool detecta a morte e substitui o worker — e um watchdog do lado do pai pode matar workers
que excedam um timeout rígido. É o mesmo motor no qual os pacotes Python e JavaScript acima são
construídos. Consulte o [README do monty-pool](https://github.com/pydantic/monty/tree/main/crates/monty-pool)
para instruções de uso.

O próprio crate `monty` fornece o interpretador em processo:```rust
use monty::MontyRun;
use monty_types::{CompileOptions, ResourceTracker, MontyObject, PrintWriter, ResourceLimits};

let code = r#"
def fib(n):
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

fib(x)
"#;

let runner = MontyRun::new(code.to_owned(), "fib.py", vec!["x".to_owned()], CompileOptions::default()).unwrap();
let result = runner.run(vec![MontyObject::Int(10)], ResourceTracker::default(), PrintWriter::Stdout).unwrap();
assert_eq!(result, MontyObject::Int(55));

Serialização

Uma sessão de REPL pode ser serializada com dump() e restaurada com Dump::load(). O dump carrega os metadados da sessão (nome do script, stubs de verificação de tipo) juntamente com o estado do interpretador, sob uma versão que a build de carregamento verifica:```rust use monty::{Dump, MontyRepl, Session, SessionRef, dump}; use monty_types::{CompileOptions, MontyObject, PrintWriter, ResourceTracker};

// Snapshot a session between snippets let mut repl = MontyRepl::new("main.py", ResourceTracker::default(), CompileOptions::default()); repl.feed_run("x = 41", vec![], PrintWriter::Stdout).unwrap(); let bytes = dump("main.py", None, SessionRef::Idle(&repl)).unwrap();

// Later, restore and carry on feeding let Session::Idle(mut restored) = Dump::load(&bytes).unwrap().state else { panic!("dumped an idle session") }; let result = restored.feed_run("x + 1", vec![], PrintWriter::Stdout).unwrap(); assert_eq!(result, MontyObject::Int(42));

root@kitploit:~
`MontyRun` e `RunProgress` não têm formato de dump próprio, mas ambos implementam `serde::Serialize`/`Deserialize`, então um host pode serializar código analisado ou uma execução pausada com qualquer formato que já utilize.

## Limites de memória nos workers

O `max_memory` de uma sessão é medido pelo alocador do worker. O interpretador
relata um `MemoryError` elegante após ultrapassar o limite suave; um limite rígido
mais alto mata e substitui o worker se uma alocação saltar longe demais entre checkpoints.

Veja [`limitations/resource_limits.md`](https://github.com/pydantic/monty/blob/HEAD/limitations/resource_limits.md) para saber como
exceder um limite se manifesta para um host, e `monty-alloc` para o alocador
sob o qual os workers de subprocesso e WebAssembly são executados.

## Integração com PydanticAI

Monty será o motor do code-mode no
[Pydantic AI](https://github.com/pydantic/pydantic-ai). Em vez de fazer
chamadas sequenciais de ferramentas, o LLM escreve código Python que chama suas ferramentas
como funções, e Monty o executa com segurança.```python test="skip"
import asyncio
import json

import logfire
from httpx import AsyncClient
from pydantic_ai import Agent, RunContext
from pydantic_ai.toolsets.code_mode import CodeModeToolset
from pydantic_ai.toolsets.function import FunctionToolset
from typing_extensions import TypedDict

logfire.configure()
logfire.instrument_pydantic_ai()


class LatLng(TypedDict):
    lat: float
    lng: float


weather_toolset: FunctionToolset[AsyncClient] = FunctionToolset()


@weather_toolset.tool
async def get_lat_lng(
    ctx: RunContext[AsyncClient], location_description: str
) -> LatLng:
    """Get the latitude and longitude of a location."""
    # NOTE: the response here will be random, and is not related to the location description.
    r = await ctx.deps.get(
        'https://demo-endpoints.pydantic.workers.dev/latlng',
        params={'location': location_description},
    )
    r.raise_for_status()
    return json.loads(r.content)


@weather_toolset.tool
async def get_temp(ctx: RunContext[AsyncClient], lat: float, lng: float) -> float:
    """Get the temp at a location."""
    # NOTE: the responses here will be random, and are not related to the lat and lng.
    r = await ctx.deps.get(
        'https://demo-endpoints.pydantic.workers.dev/number',
        params={'min': 10, 'max': 30},
    )
    r.raise_for_status()
    return float(r.text)


@weather_toolset.tool
async def get_weather_description(
    ctx: RunContext[AsyncClient], lat: float, lng: float
) -> str:
    """Get the weather description at a location."""
    # NOTE: the responses here will be random, and are not related to the lat and lng.
    r = await ctx.deps.get(
        'https://demo-endpoints.pydantic.workers.dev/weather',
        params={'lat': lat, 'lng': lng},
    )
    r.raise_for_status()
    return r.text


agent = Agent(
    'gateway/anthropic:claude-sonnet-4-5',
    # toolsets=[weather_toolset],
    toolsets=[CodeModeToolset(weather_toolset)],
    deps_type=AsyncClient,
)


async def main():
    async with AsyncClient() as client:
        await agent.run('Compare the weather of London, Paris, and Tokyo.', deps=client)


if __name__ == '__main__':
    asyncio.run(main())

Bindings da comunidade

  • Go: gomonty - Bindings em Go para o interpretador Monty
  • Dart/Flutter: dart_monty (github) (pub.dev)- Bindings Dart/Flutter para Monty

Alternativas

Geralmente há duas reações quando você mostra Monty às pessoas:

  1. Oh meu Deus, isso resolve tantos problemas, eu quero.
  2. Por que não X?

Onde X é alguma tecnologia alternativa. Curiosamente, essas respostas costumam vir combinadas, sugerindo que as pessoas ainda não encontraram uma alternativa que funcione para elas, mas ficam incrédulas de que realmente não existe uma boa alternativa para criar uma implementação Python inteira do zero.

Vou tentar percorrer as alternativas mais óbvias e explicar por que elas não são adequadas para o que queríamos.

NOTA: todas essas tecnologias são impressionantes e têm usos difundidos; este comentário sobre suas limitações para o nosso caso de uso não deve ser visto como uma crítica. A maioria dessas soluções não foi concebida com o objetivo de fornecer um sandbox para LLM, e é por isso que elas não são necessariamente ótimas nisso.

Consulte ./scripts/startup_performance.py para ver o script usado para calcular os números de desempenho de inicialização.

Detalhes sobre cada linha abaixo:

Monty

  • Completude da linguagem: Sem classes (ainda), stdlib limitada, sem bibliotecas de terceiros
  • Segurança: Acesso a filesystem, rede e variáveis de ambiente explicitamente controlado, limites rígidos de tempo de execução e uso de memória
  • Latência de inicialização: Inicia em microssegundos
  • Complexidade de configuração: basta pip install pydantic-monty ou npm install @pydantic/monty, download de ~4.5MB
  • Montagem de arquivos: Estritamente controlada, veja #85
  • Snapshotting: A funcionalidade de pausa e retomada do Monty com dump() e load() torna trivial pausar, retomar e bifurcar a execução

Docker

  • Completude da linguagem: CPython completo com qualquer biblioteca
  • Segurança: Isolamento de processos e filesystem, políticas de rede, mas escapes de contêiner existem, e a limitação de memória é possível
  • Latência de inicialização: Overhead de inicialização do contêiner (~195ms medidos)
  • Complexidade de configuração: Requer o daemon do Docker, imagens de contêiner e orquestração; python:3.14-alpine tem 50MB - o docker não pode ser instalado via PyPI
  • Montagem de arquivos: Montagens de volume funcionam bem
  • Snapshotting: Possível com soluções de execução durável como Temporal, ou criando um snapshot de uma imagem e salvando-o como imagem Docker.

Pyodide

  • Completude da linguagem: CPython completo compilado para WASM, quase todas as bibliotecas disponíveis
  • Segurança: Depende do sandbox do navegador/WASM - não foi projetado para isolamento no lado do servidor; código python pode executar código arbitrário no runtime JS; apenas o deno permite isolamento; limites de memória são difíceis/impossíveis de impor com o deno
  • Latência de inicialização: O carregamento do runtime WASM é lento (~2800ms de inicialização a frio)
  • Complexidade de configuração: É preciso carregar o runtime WASM e lidar com a inicialização assíncrona; o pacote NPM do pyodide tem ~12MB, o deno tem ~50MB - o Pyodide não pode ser utilizado apenas com pacotes PyPI
  • Montagem de arquivos: Filesystem virtual via APIs do navegador
  • Snapshotting: Possível com soluções de execução durável como Temporal, presumivelmente, mas difícil

starlark-rust

Veja starlark-rust.

  • Completude da linguagem: Linguagem de configuração, não Python - sem classes, exceções ou async
  • Segurança: Determinística e hermética por design
  • Latência de inicialização: roda embutida no processo como o Monty, daí o tempo de inicialização impressionante
  • Complexidade de configuração: Utilizável em python via starlark-pyo3
  • Montagem de arquivos: Sem manipulação de arquivos por design, pelo que sei?
  • Snapshotting: Impossível, pelo que sei?

WASI / Wasmer

Executando Python em WebAssembly via Wasmer.

  • Completude da linguagem: CPython completo; pacotes externos Python puros funcionam via montagem; pacotes externos com bindings C não funcionam
  • Segurança: Em princípio, o WebAssembly deveria fornecer fortes garantias de sandboxing.
  • Latência de inicialização: O pacote python wasmer não é atualizado há 3 anos e não consegui encontrar documentação sobre como chamar Python no wasmer a partir do Python, então o chamei via subprocess. A latência de inicialização foi de 66ms.
  • Complexidade de configuração: o download do wasmer tem 100mb; o pacote "python/python" tem 50mb.
  • FOSS: Marquei isto como "gratuito *" porque o custo é zero, mas nem tudo parece ser open source. Em 2026-02-10, o pacote wasmer python/python não tem readme, nem licença, nem link para o código-fonte e nenhuma indicação de como é construído; as versões enviadas recentemente mostram o tamanho como "0B", embora o download seja de ~50MB - o processo de build do binário Python não é claro nem transparente. (Se eu estiver errado aqui, por favor crie uma issue para me corrigir)
  • Montagem de arquivos: Suportada
  • Snapshotting: Suportado via journaling

serviço de sandboxing

Serviços como Daytona, E2B, Modal.

Há desafios semelhantes, mais complexidade de configuração, porém menor latência de rede para montar sua própria configuração de sandbox com k8s.

  • Completude da linguagem: CPython completo com qualquer biblioteca
  • Segurança: Isolamento de contêiner gerenciado profissionalmente
  • Latência de inicialização: Round-trip de rede e tempo de inicialização do contêiner. Consegui ~1s de inicialização a frio com a Daytona EU a partir de Londres; a Daytona anuncia latência abaixo de 90ms, presumivelmente para um contêiner existente; não está claro se inclui a latência de rede
  • FOSS: Pague por execução ou tempo de computação; algumas implementações são open source
  • Complexidade de configuração: Integração de API, tokens de autenticação - ok para startups, mas geralmente inviável para empresas
  • Montagem de arquivos: Upload/download via chamadas de API
  • Snapshotting: Possível com soluções de execução durável como Temporal; os serviços também oferecem algumas soluções para isso, acho que baseadas em contêineres docker

YOLO Python

Executando Python diretamente via exec() (~0.1ms) ou subprocess (~30ms).

  • Completude da linguagem: CPython completo com qualquer biblioteca
  • Segurança: Nenhuma - acesso total a filesystem, rede, variáveis de ambiente e comandos do sistema
  • Latência de inicialização: Quase zero para exec(), ~30ms para subprocess
  • Complexidade de configuração: Nenhuma
  • Montagem de arquivos: Acesso direto ao filesystem (esse é o problema)
  • Snapshotting: Possível com soluções de execução durável como Temporal

Parte do Pydantic Stack

O Pydantic Stack é tudo o que você precisa para entregar agentes de IA de nível de produção:

  • Pydantic AI - Framework de agentes type-safe
  • Pydantic Logfire - Observabilidade full-stack, AI-first
  • Logfire AI Gateway - Proxy LLM unificado
Baixar ferramenta
TecnologiaCompletude da linguagemSegurançaLatência de inicializaçãoFOSSComplexidade de configuraçãoMontagem de arquivosSnapshotting
Montyparcialestrita0.06msgratuito / OSSfácilfácilfácil
Dockercompletaboa195msgratuito / OSSintermediáriafácilintermediário
Pyodidecompletafraca2800msgratuito / OSSintermediáriafácildifícil
starlark-rustmuito limitadaboa1.7msgratuito / OSSfácilnão disponível?impossível?
WASI / Wasmerparcial, quase completaestrita66msgratuito *intermediáriafácilintermediário
serviço de sandboxingcompletaestrita1033msnão gratuitointermediáriadifícilintermediário
YOLO Pythoncompletainexistente0.1ms / 30msgratuito / OSSfácilfácil / assustadoradifícil