モンティ:AI 用に設計された、Rustで実装された最小限かつ安全なPythonインタプリタ。

2026/02/07 6:16

モンティ:AI 用に設計された、Rustで実装された最小限かつ安全なPythonインタプリタ。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

改善された概要

MontyはRustで書かれた小型で安全なPythonインタプリタです。大規模言語モデル(LLM)エージェントがユーザー生成コードを高速かつ安全に実行できるよう設計されています。起動時間はマイクロ秒レベルで、ランタイム性能はCPythonと競合します。Montyは直接ホストへのアクセスをブロックし、ファイルシステム、環境変数、およびネットワーク呼び出しは開発者が提供する外部関数を介して仲介されます。これにより言語は安全なサブセットに限定され、メモリ、スタック深さ、実行時間に対する明示的なリソース制限を設定できます。

Pythonの機能は限定的です:クラスはまだ実装されていません。現在標準ライブラリには

sys
typing
asyncio
が含まれ、将来的に
dataclasses
json
が追加予定です。外部関数呼び出しは
start()
/
resume()
を介して反復的に実行できます。Montyの実行状態と解析済みコードはバイト列としてシリアライズでき、キャッシュやプロセス間での再開に利用可能です。Rust、Python(
pydantic_monty
)、JavaScript/TypeScript(
@pydantic/monty
)から呼び出すことができます。出力ストリーム(stdout / stderr)は取得され呼び出し元へ返され、Montyは非同期・同期のホストコードを呼び出せます。

今後のリリースではクラスサポート、追加標準ライブラリモジュール、match 文、外部関数統合の充実が予定されています。Pydantic AI は Monty を「code‑mode」機能に組み込み、LLM が安全に事前定義されたツールを呼び出せるようにする計画です。

AIアシスタントや自動化ワークフローの開発者向けに、Montyはコンテナや複雑なサンドボックス設定なしで高速・低コスト・安全なユーザーコード実行を提供します。

本文

Monty

AI で利用するために Rust で書かれた最小限の安全な Python インタープリター。


実験的

本プロジェクトは現在開発中で、まだ本番レベルではありません。

  • 目的 – LLM が生成したコードを実行する際に、フルコンテナ型サンドボックスを使うコスト・遅延・複雑さ・「面倒」を回避します。
  • 性能 – スタートアップ時間が 1 桁マイクロ秒(対数百ミリ秒)で測定されています。

Monty ができること

機能説明
Python の実用的なサブセットを実行エージェントがやりたいことを表現するのに十分
ホストアクセスを遮断ファイルシステム、環境変数、ネットワークは開発者が提供する外部関数呼び出しで制御されます
ホスト関数の呼び出し明示的に許可されたもののみ
型チェック最新の Python タイプヒントをサポート。単一バイナリで実行
スナップショット外部関数呼び出し時に状態をシリアライズして保存または後で再開可能
高速起動コードから実行結果まで 1 µs 未満
性能CPython とほぼ同等(5 倍程度の差)
マルチ言語 APIRust、Python、JavaScript から呼び出せる(CPython の依存なし)
リソース制限メモリ使用量・割り当て数・スタック深さ・実行時間を追跡。上限超過でキャンセル可能
IO キャプチャ呼び出し側に stdout / stderr を渡す
非同期 & 同期 ホストコード両方の呼び出しをサポート

Monty ができないこと

  • 標準ライブラリは使えません(
    sys
    typing
    asyncio
    以外;
    dataclasses
    json
    は近日リリース予定)
  • サードパーティのライブラリは使用不可(例:Pydantic)
  • クラス定義はできません(今後サポート予定)
  • マッチ文 (
    match
    ) は使えません(今後サポート予定)

まとめ

Monty は極めて限定的で、エージェントが書くコードを実行するという単一用途に設計されています。

モチベーションの参照

  • Cloudflare の Codemode
  • Anthropic の Programmatic Tool Calling
  • Anthropic の MCP を使った Code Execution
  • Hugging Face の Smol Agents

LLM が従来のツール呼び出しよりも高速・低コスト・信頼性を向上させるために、Python(または JavaScript)コードを書かせるアイデア。Monty はサンドボックスの複雑さやホストリスクなしでそれを実現します。


使い方

Monty は PythonJavaScript/TypeScript、あるいは Rust から呼び出すことができます。

Python

# インストール:
#   pip install pydantic-monty  # boomers 用

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 = ''
"""

m = pydantic_monty.Monty(
    code,
    inputs=['prompt'],
    external_functions=['call_llm'],
    script_name='agent.py',
    type_check=True,
    type_check_stubs=type_definitions,
)

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():
    output = await pydantic_monty.run_monty_async(
        m,
        inputs={'prompt': 'testing'},
        external_functions={'call_llm': call_llm},
    )
    print(output)  # → example output, message count 2


if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

外部関数を使った反復実行

import pydantic_monty

code = """
data = fetch(url)
len(data)
"""

m = pydantic_monty.Monty(code, inputs=['url'], external_functions=['fetch'])

# 実行開始 – `fetch()` が呼ばれた時点で一時停止
result = m.start(inputs={'url': 'https://example.com'})
print(type(result))          # <class 'pydantic_monty.MontySnapshot'>
print(result.function_name)  # fetch
print(result.args)           # ('https://example.com',)

# 実際にフェッチして結果を返し、再開
result = result.resume(return_value='hello world')
print(type(result))          # <class 'pydantic_monty.MontyComplete'>
print(result.output)         # 11

シリアライズ

import pydantic_monty

# パース済みコードをシリアライズして再パースを省略
m = pydantic_monty.Monty('x + 1', inputs=['x'])
data = m.dump()

# 後で復元して実行
m2 = pydantic_monty.Monty.load(data)
print(m2.run(inputs={'x': 41}))  # 42

# 実行中の状態をシリアライズ
progress = m.start(inputs={'url': 'https://example.com'})
state = progress.dump()

# 後で別プロセス等で復元・再開
progress2 = pydantic_monty.MontySnapshot.load(state)
result = progress2.resume(return_value='response data')
print(result.output)  # response data

Rust

use monty::{MontyRun, MontyObject, NoLimitTracker, StdPrint};

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()], vec![]).unwrap();
let result = runner.run(vec![MontyObject::Int(10)], NoLimitTracker, &mut StdPrint).unwrap();
assert_eq!(result, MontyObject::Int(55));

シリアライズ

use monty::{MontyRun, MontyObject, NoLimitTracker, StdPrint};

let runner = MontyRun::new("x + 1".to_owned(), "main.py", vec!["x".to_owned()], vec![]).unwrap();
let bytes = runner.dump().unwrap();

let runner2 = MontyRun::load(&bytes).unwrap();
let result = runner2.run(vec![MontyObject::Int(41)], NoLimitTracker, &mut StdPrint).unwrap();
assert_eq!(result, MontyObject::Int(42));

PydanticAI 連携

from pydantic_ai import Agent
from pydantic_ai.toolsets.code_mode import CodeModeToolset
from pydantic_ai.toolsets.function import FunctionToolset
from typing_extensions import TypedDict

class WeatherResult(TypedDict):
    city: str
    temp_c: float
    conditions: str

toolset = FunctionToolset()

@toolset.tool
def get_weather(city: str) -> WeatherResult:
    return {'city': city, 'temp_c': 18, 'conditions': 'partly cloudy'}

@toolset.tool
def get_population(city: str) -> int:
    return {'london': 9_000_000, 'paris': 2_100_000, 'tokyo': 14_000_000}.get(
        city.lower(), 0
    )

toolset = CodeModeToolset(toolset)

agent = Agent('anthropic:claude-sonnet-4-5', toolsets=[toolset])

result = agent.run_sync(
    'Compare the weather and population of London, Paris, and Tokyo.'
)
print(result.output)

代替手段

テック言語完全性セキュリティスタート遅延コスト設定の複雑さファイルマウントスナップショット
Monty部分的厳格0.06 ms無料簡単簡単簡単
Docker完全良好195 ms無料中程度簡単中程度
Pyodide完全悪い2800 ms無料中程度簡単難しい
starlark‑rust非常に限定的良好1.7 ms無料簡単利用不可不可能
サンドボックスサービス完全厳格1033 ms有料中程度難しい中程度
YOLO Python完全なし0.1–30 ms無料なし直接可能

./scripts/startup_performance.py
がスタートアップ性能数値を算出するためのスクリプトです。


代替手段に関する備考

  • Docker:フル CPython、任意ライブラリ使用可。コンテナエスケープリスクあり。195 ms の起動時間。
  • Pyodide:CPython を WASM にコンパイル。冷却スタートが遅い(≈2.8 s)。主にブラウザサンドボックス向け。
  • starlark‑rust:設定言語であり Python ではない。決定論的・ヘルメティックだがスナップショット不可。
  • サンドボックスサービス:管理型コンテナ隔離。ネットワーク遅延 + コンテナ起動(≈1 s)。
  • YOLO Python
    exec()
    か subprocess を直接呼び出す。セキュリティ制御なし。

Monty は最速のスタートアップ、厳格なサンドボックス、Rust ベースプロジェクトへの簡単統合、軽量スナップショットを提供し、LLM が生成した Python コードを安全に実行するために特化しています。

同じ日のほかのニュース

一覧に戻る →

2026/02/07 6:51

**OpenCiv3:サイクリズム・III のオープンソースでクロスプラットフォーム化した再構築**

## Japanese Translation: OpenCiv3は、Civilization IIIのオープンソースでクロスプラットフォームなリメイクであり、レガシー制限を取り除き、モッドサポートを拡張しつつもコアゲームプレイを保持します。Godot EngineとC#で構築されており、Windows、Linux、macOS上でネイティブに動作し、専用のCivilization IIIファイルは不要です(ただしローカルコピーがあると互換性が向上します)。 現在のプレアルファ版(v0.3「Dutch」、2025年12月)は、OS固有のzipまたはtgz(「スタンドアロンモード」でプレースホルダーグラフィック付き)として配布されます。インストール手順は以下の通りです。 - **Windows** – zipを解凍し、`OpenCiv3.exe` をダブルクリックします。ブロックされている場合は解除し、自動検出できない場合は環境変数 `CIV3_HOME` にCivilization IIIフォルダーのパスを設定してください。 - **Linux** – `.tgz` を解凍し、`export CIV3_HOME="/path/to/civ3"` としてから `OpenCiv3.x86_64` を実行します。 - **macOS** – zipを解凍し、`xattr -cr /path/to/OpenCiv3.app` でクォータリゼーションを解除し、同様に `CIV3_HOME` を設定してターミナルから起動します。 既知の問題としてはプレースホルダー資産、不完全なBIQ/SAVファイルサポート(クラッシュを引き起こす可能性があります)、および新規ゲーム開始時にマップ生成用保存ファイルが欠如しているためmacOSでクラッシュするケースがあります。最低ハードウェア要件はまだ公開されていません。プロジェクトはMITライセンスの下でリリースされ、Firaxis、CivFanatics.com、その他の団体とは独立しています。 開発者はBIQ/SAVサポートの完全復元、プラットフォーム別クラッシュ(特にmacOS)の修正、後半ゲームコンテンツの追加、およびグラフィックと安定性の向上に積極的に取り組んでいます。バグや機能要望はGitHubで追跡されており、コミュニティからの貢献が奨励されています。 モッドフレンドリーでクロスプラットフォームな基盤を提供することで、OpenCiv3はプレイヤーと開発者にオリジナルIPを侵害せずにクラシックなCivilization体験を拡張する機会を提供します。

2026/02/07 1:20

Waymoワールドモデル

## Japanese Translation: > **Waymoは、Waymo World Modelという生成シミュレーションエンジンを公開しました。このエンジンは、極端な天候・自然災害・象やロングホーンのような珍しいオブジェクト、逆走トラックなど安全に関わるインシデントを含むハイパーリアリスティックな自律運転シナリオを生成します。** > Google DeepMind の Genie 3 をベースにしたこのモデルは、カメラと LiDAR データを融合し、ドライビングアクション制御・シーンレイアウト制御・時間帯、天候、カスタムシナリオを調整する言語プロンプトという3つの制御機構を提供します。録画済みまたは新規生成されたルートに対して代替ドライビング決定を評価する「what‑if」反実仮想シミュレーションもサポートしています。 > Waymo Driver は米国都市で約 2 億マイルの完全自律走行距離を記録し、数十億マイルに相当するバーチャル走行をシミュレートしてきました。World Model はリアルなダッシュカムやモバイルカメラ映像を多模態シミュレーションへ変換し、正確な視覚シーンと一致させることでこの機能を拡張します。効率的なバリアントは実時間の最大4倍速で動作し、計算資源を削減しつつ長時間テストが可能です。 > このシステムは、安全性が証明された自律運転を実現するために Waymo の AI エコシステムの重要柱となっており、Waymo と Google DeepMind からなる大規模チームによって開発されています。

2026/02/05 20:19

**ジオジョインをH3インデックスで400 倍高速化した手法** - **問題点:** 大規模な空間データセットに対する従来のジオジョインクエリは、ポイント‐イン‐ポリゴン判定やテーブル全体のスキャンが必要だったため遅延が大きかった。 - **解決策:** Uber の H3 ヘキサゴナル階層インデックスシステムを利用し、空間情報を固定サイズセルへ事前集約した。 - **実装手順:** 1. すべてのジオメトリ(点・線・多角形)を適切な解像度で対応する H3 インデックスに変換する。 2. 生成されたインデックスを別テーブルに格納し、H3 キーで索引付けする。 3. ジョイン時には、重複した H3 インデックスをキーとしてマッチさせ、膨大な空間判定処理を回避する。 - **結果:** クエリ遅延が数時間から数分へと短縮され、約 400 倍の高速化を実現。また、選択した解像度内であれば空間的正確性は維持された。 ジオメトリ比較を単純な整数キー検索に置き換えることで、データの忠実度を損なうことなく大幅なパフォーマンス向上を達成しました。

## Japanese Translation: ## Summary この記事は、コストの高い空間述語をH3ベースの集合演算に置き換えることで、遅い二次元空間結合をコンパクトなキーで高速ハッシュ結合へと変換する方法を示しています。各ジオメトリを解像度 3 の少数の H3 セルで覆うことにより、結合は最初にセルを共有する候補ペアをフィルタリングし、その後で正確な `ST_Intersects` をその候補のみに適用します。これにより、潜在的に何百万もの交差チェックが、フィルタ済みセットだけに減少し、テストで 400 倍の速度向上を実現しています。この手法は CTE、ビュー、およびサブクエリとシームレスに機能し、追加のマテリアライズドテーブルやスキーマ変更は不要です。したがって、精度を下げるなどの実験も容易になります。高い H3 解像度では偽陽性が減少しますが、形状ごとのセル数が増加し、低解像度ではインデックス作成が簡単ですが、解像度 4 を超えるとセル数の増加により急激に大きくなります。実際には、この書き換えにより 15 ワーカーの Xeon クラスターで結合時間を約 459 秒から約 1.2 秒へ短縮し、正確な一致精度(最終的な `ST_Intersects` によって偽陽性が除去される)を維持したまま高速な空間分析を可能にしています。