概要
OpenEnv は、Gymnasium に似た API を通じて、エージェント実行環境と対話するための標準を提供します。環境作成ツールとデプロイ用のコマンドラインインターフェースが含まれており、分離された、安全で使いやすい RL ポストトレーニング環境をサポートします。
README プレビュー
# OpenEnv: Agentic Execution Environments\n\nAn e2e framework for creating, deploying and using isolated execution environments for agentic RL training, built using Gymnasium style simple APIs.\n\n\n \n \n \n \n \n \n\n\n---\n\n**Featured Example:** Train LLMs to play BlackJack using [torchforge](https://meta-pytorch.org/torchforge/) (PyTorch's agentic RL framework): [`examples/grpo_blackjack/`](examples/grpo_blackjack/)\n\n**Zero to Hero Tutorial:** End to end tutorial from our [GPU Mode](tutorial/README.md) lecture and other hackathons.\n\n## Quick Start\n\nInstall the OpenEnv package:\n\n```bash\npip install openenv\n```\n\nInstall an environment client (e.g., Echo):\n\n```bash\npip install git+https://huggingface.co/spaces/openenv/echo_env\n```\n\nThen use the environment:\n\n```python\nimport asyncio\nfrom echo_env import CallToolAction, EchoEnv\n\nasync def main():\n # Connect to a running Space (async context manager)\n async with EchoEnv(base_url="https://openenv-echo-env.hf.space") as client:\n # Reset the environment\n result = await client.reset()\n print(result.observation.echoed_message) # "Echo environment ready!"\n\n # Send messages\n result = await client.step(\n CallToolAction(\n tool_name="echo_message",\n arguments={"message": "Hello, World!"},\n )\n )\n print(result.observation.result) # "Hello, World!"\n print(result.reward)\n\nasyncio.run(main())\n```\n\n**Synchronous usage** is also supported via the `.sync()` wrapper:\n\n```python\nfrom echo_env import CallToolAction, EchoEnv\n\n# Use .sync() for synchronous context manager\nwith EchoEnv(base_url="https://openenv-echo-env.hf.space").sync() as client:\n result = client.reset()\n result = client.step(\n CallToolAction(\n tool_name="echo_message",\n arguments={"message": "Hello, World!"},\n )\n )\n print(result.obseFAQ (5)
トラブル対応なぜ MCPToolClient で mode="production" を指定すると、HTTP /mcp JSON-RPC ではなく WebSocket /ws が使用されるのですか?
プロダクション用トランスポートのフラグが誤って初期化されています。src/openenv/core/mcp_client.py で、self.use_production_mode = False を以下に置き換えてください:
self.use_production_mode = mode_lower == "production"
これにより、フラグは正規化された _mode の値と一貫した状態に保たれます。一時的な回避策として、クライアントの作成後に手動で設定してください:
client = MCPToolClient(..., mode="production")
client.use_production_mode = True
修正後は、list_tools() が HTTP の /mcp 経由で tools/list を呼び出し、call_tool() が /mcp 経由で tools/call を呼び出し、シミュレーションモードは引き続き WebSocket の /ws の step() パスを使用するようになります。回帰テストを更新し、type="step" メッセージの確認だけでなく、選択されたトランスポートをアサートするようにしてください。
トラブル対応MCPToolClient のプロダクションモードで、HTTP /mcp JSON-RPC トランスポートの代わりに WebSocket が使用されてしまう問題を修正するにはどうすればよいですか?
src/openenv/core/mcp_client.py で、MCPToolClient コンストラクタ内のハードコードされた self.use_production_mode = False を以下に置き換えてください:
self.use_production_mode = mode_lower == "production"
これにより、mode="production" の場合に list_tools() と call_tool() が HTTP /mcp JSON-RPC メソッドの tools/list と tools/call を使用するようになり、シミュレーションモードでは引き続き WebSocket の step() パスが使用されます。
ソースコードを変更しない一時的な回避策として、クライアントの初期化直後にフラグを設定してください:
client = MCPToolClient(mode="production")
client.use_production_mode = True
tests/core/test_mode_selection.py を更新して、プロダクションモードが tools/list と tools/call で /mcp を呼び出すこと、およびシミュレーションモードが引き続き WebSocket の type="step" メッセージを送信することをアサートしてください。
トラブル対応'No such container' エラーメッセージの違いにより Docker 29 および Podman で Docker クリーンアップ検証が失敗する問題を修正する方法
inspect や rm のエラーテキストの一致に依存しないでください。コンテナを一覧表示し、結果が空であることを成功とみなすことで、削除を確認してください:
docker ps --all --filter "name=^/<container-name>$" --format '{{.Names}}'
結果が空の場合はコンテナが削除されたことを意味し、ゼロ以外の終了ステータスはコンテナエンジンに到達できないことを意味します。Podman の場合は、次を指定してコンテナを起動してください:
--stop-timeout 0
これにより、docker rm --force は SIGKILL の前にデフォルトの停止タイムアウトを待機しなくなります。また、CapDrop == ["ALL"] をアサートするのも避けてください。Podman は drop されたケイパビリティを個別に報告するためです。代わりに、コンテナのケイパビリティバウンディングセット(CapBnd)が空であることを確認してください。バウンディングケイパビリティが残っている場合でも、非 root ユーザーでは CapEff が 0 になることがあります。Docker 29 および Podman の出力に対するエンジン固有のユニットテストを追加してください。
informationalOpenEnv RFC 005のステータスはどうなっていますか?また、HarnessEnvironmentはopenenv.core.harnessとどのように異なりますか?
RFC 005 は依然として有効であり、PR #1097〜#1100 で main に実装されています。RFC のマルチターン外部ハーネスパターンには、AgenticHarnessAdapter とともに HarnessEnvironment を使用してください。外部ハーネスは環境内で実行され、OpenEnv が MCP 経由でツールを注入します。各 step() 呼び出しは 1 回の会話ターンを表し、ハーネスはエピソード内のターンをまたいでコンテキストを保持します。τ²-bench 上で Claude Code を動作させる実例は、「Evaluate Claude Code in an Environment」チュートリアルおよび examples/claude_code_harness_eval で確認できます。
#471/#652 で openenv.core.harness 配下に導入された API(ResourceSession、HarnessAdapter、MCPHarnessAdapter、CLIHarnessAdapter、build_harness_rollout_func など)は、RFC 005 の実装ではなく、独立したセッション/ランタイムレイヤーです。低レベルのセッション/リソース管理にはこれらを使用し、RFC 005 スタイルのマルチターン環境内エージェントロールアウトには HarnessEnvironment/AgenticHarnessAdapter を使用してください。更新されたハーネスドキュメントでは、どのコンポーネントがエージェントループを管理するかに基づいてこれらの選択肢を整理しています。
トラブル対応openenv init の実行後に Docker イメージサイズを2倍にしてしまう、重複した Python .venv レイヤーはどうすれば修正できますか?
生成されたDockerfileは、/app/env/.venv を明示的にコピーし、続いてすでに .venv を含んでいる /app/env をコピーするため、約500 MBのレイヤーが2つ作成されてしまいます。サーバーのDockerfileテンプレートの修正を含むリリースにOpenEnvをアップグレードするか、生成されたDockerfileに手動でパッチを適用してください。virtualenvの個別コピーを削除し、プロジェクトのコピーのみを残して、シンボリックリンクを作成します:
# この行を削除します:
# COPY --from=builder /app/env/.venv /app/.venv
# 埋め込まれた .venv を含むプロジェクトを一度だけコピーします:
COPY --from=builder /app/env /app/env
# /app/.venv を想定しているパスとの互換性を提供します:
RUN ln -s /app/env/.venv /app/.venv
テンプレートで --chown を使用している場合は、残す COPY にそれらのフラグを維持してください。キャッシュなしで再ビルドし、レイヤーを確認します:
docker build --no-cache -t your-image .
docker history your-image
# または
dive your-image
これで、virtualenvは1つの大きなレイヤーにのみ存在するようになり、シンボリックリンクによるサイズ増加は無視できる程度になります。