jpskill.com
🛠️ 開発・MCP コミュニティ

generate-verifiers-env

PrimeIntellectのVerifiersを使って、ツール利用や報酬設定が柔軟な強化学習環境を簡単に構築し、高速な試作とTRLトレーニングへの移行を支援するSkill。

📜 元の英語説明(参考)

Builds a Verifiers (PrimeIntellect) variant of an RL environment. Use whenever someone asks to scaffold a Verifiers env, port to Verifiers, build an in-process toolkit, set up a `vf.ToolEnv` with a Rubric, or wire up a TRL `GRPOTrainer` rollout. Verifiers is the right framework when the user wants in-process tools (no HTTP server), structured tool calling driven by plain Python functions, composable reward rubrics with multiple grader functions, fast iteration with no Docker, or the cleanest path from prototype to TRL training. Output is a runnable `<env_dir>/verifiers/` folder with `env.py` (toolkit + standalone tool functions + `create_verifiers_env`), `rollout.py`, and `pyproject.toml`. Use for prompts like "make a verifiers env for X", "wrap my game in verifiers", or "set up a vf.ToolEnv".

🇯🇵 日本人クリエイター向け解説

一言でいうと

PrimeIntellectのVerifiersを使って、ツール利用や報酬設定が柔軟な強化学習環境を簡単に構築し、高速な試作とTRLトレーニングへの移行を支援するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o generate-verifiers-env.zip https://jpskill.com/download/9661.zip && unzip -o generate-verifiers-env.zip && rm generate-verifiers-env.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9661.zip -OutFile "$d\generate-verifiers-env.zip"; Expand-Archive "$d\generate-verifiers-env.zip" -DestinationPath $d -Force; ri "$d\generate-verifiers-env.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して generate-verifiers-env.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → generate-verifiers-env フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

generate-verifiers-env

envのVerifiers版を構築します。Verifiersはインプロセスです。HTTPサーバー、Docker、HF Spaceは不要です。トレーナー(または手動ロールアウト)は、env.pyから直接ツール関数をインポートします。

概念

PrimeIntellect Verifiersは、サーバーフレームワークではなく、Pythonライブラリです。TRLのGRPOTrainerに、vf.ToolEnv(マルチターンロールアウト)、vf.Rubric(構成可能な非同期グレーダー)、およびアダプターを提供します。トレーナーまたはロールアウトはLLMクライアントを所有し、envはツールとグレーダーを所有します。

ユーザーが共有ドメインモジュール(<domain>.py)を持っており、Verifiers版が必要な場合は、ツールキットクラスとスタンドアロンのツール関数としてラップします。ドメインロジックを複製しないでください。

アーキタイプ

アーキタイプ 特徴
Pure-Python game 1つの@toolスタイルの関数、軌跡をチェックするルーブリックによるターミナル報酬。
Stateful sandbox in-process ツールキットはサンドボックス(E2B、ブラウザ)を所有します。initialize()は遅延初期化です。cleanup()finallyで必須です。
Vision env ツールキットを手動で駆動します(verifiersのロールアウトではビジョンコンテンツブロックが第一級ではないため、vf.ToolEnvをスキップします)。各ターンのユーザーメッセージでスクリーンショットを送信します。

2つの消費パス(常に両方を提供する)

パスA — DesktopToolkit-スタイルのクラス(TRLアダプター+手動ロールアウトで使用)

class WordleToolkit:
    def __init__(self): ...
    def initialize(self): ...     # 遅延 E2B / 状態初期化
    def cleanup(self): ...        # サンドボックスを強制終了
    def reset(self): ...          # 新しいエピソード
    def guess(self, word: str) -> str:
        """5文字の単語の推測を送信します。色付きのフィードバックを返します。"""
        ...

パブリックメソッドは、TRLアダプターによってツールとしてイントロスペクトされます。ドキュメンテーション文字列はツール説明になります。

パスB — ネイティブ verifiers env.evaluate(client, model)用のvf.ToolEnv

def create_verifiers_env():
    import verifiers as vf
    from datasets import Dataset
    dataset = Dataset.from_list([{"question": t["task"], "answer": t["expected_output"]} for t in TASKS])
    async def correctness(completion, answer, **kwargs) -> float:
        # 完了軌跡から読み取り、0.0〜1.0を返します
        ...
    rubric = vf.Rubric(funcs=[correctness])
    return vf.ToolEnv(tools=TOOL_FUNCTIONS, max_turns=8, dataset=dataset, rubric=rubric, system_prompt="...")

TOOL_FUNCTIONSは、プレーンなPython関数のリストです(バインドされたメソッドではありません)。モジュールレベルのツールキットインスタンスを介して状態を共有できます。

推奨されるファイルレイアウト

ユーザーは実際のパスを選択します。標準的な形状:

<env_dir>/verifiers/
├── pyproject.toml      # verifiers + e2b-* + datasets + python-dotenv + openai
├── __init__.py
├── env.py              # ツールキットクラス + スタンドアロンツール関数 + create_verifiers_env()
├── rollout.py          # openaiクライアントでツールキットを手動で駆動
└── README.md

実装順序

1. ツールキットクラス

  • __init__は設定(api_key=""app="firefox"など)を受け取ります。ここではサンドボックスを作成しないでください。早すぎます。
  • initialize()は遅延作成フックです。常に各ツールメソッドから呼び出します。
  • cleanup()はサンドボックスを強制終了します。常にロールアウトのfinallyから呼び出します。
  • reset()cleanup()を呼び出し、再初期化します。TRLアダプターによってエピソード間で使用されます。
  • 各ツールメソッド:
    • 型付き引数を受け取ります(inspectを介したOpenAIツールスキーマ生成に使用されます)
    • ドキュメンテーション文字列があります(ツール説明になります — 最初の段落のみ)
    • 最初にself.initialize()を呼び出し、状態を変更し、文字列を返します

2. vf.ToolEnv用のスタンドアロンツール関数

モジュールレベルの共有ツールキット、およびシンラッパー:

_shared: Optional[WordleToolkit] = None
def _kit():
    global _shared
    if _shared is None:
        _shared = WordleToolkit()
    return _shared

def guess(word: str) -> str:
    """5文字の単語の推測を送信します。"""
    return _kit().guess(word)

TOOL_FUNCTIONS = [guess]

なぜ両方?TRLアダプターはツールキットクラス(ロールアウトごとのインスタンス、分離された状態)を必要とします。vf.ToolEnvはフリー関数を必要とします。1つを選択しないでください — 両方を提供してください。

3. ルーブリック

ルーブリックは構成可能なグレーダーです。各グレーダーはasync def func(completion, answer, **kwargs) -> floatです。vf.Rubric(funcs=[...])で複数組み合わせると、平均化されます(または重み付けされます。verifiersドキュメントを参照してください)。

単一基準のenvの場合、1つのグレーダーで十分です。

async def correctness(completion, answer, **kwargs) -> float:
    if not completion: return 0.0
    last = completion[-1].get("content", "") if isinstance(completion[-1], dict) else str(completion[-1])
    return 1.0 if answer.strip() in last.strip() else 0.0

複数基準の場合(例:terminate(success)と状態チェックの両方が必要なコンピューター使用env):

async def correctness(completion, answer, **kwargs) -> float:
    seen_success = any("terminated: success" in str(m) for m in completion)
    seen_expected = any(answer in str(m) for m in completion)
    return 1.0 if (seen_success and seen_expected) else (0.5 if seen_success else 0.0)

4. ロールアウト — rollout.py

inspectを介して、関数のシグネチャ+ドキュメンテーション文字列からOpenAIツールスキーマを構築します。


def func_to_openai_tool(fn):
    sig = inspect.signature(fn)
    hints = get_type_hints(fn)
    doc = (fn.__doc__ or "").strip().split("\n\n")[0]
    properties, required = {}, []
    for name, p in sig.parameters.items():
        ann = hints.get(name, str)
        origin = get_origin(ann)
        if origin in (list, "list"):
            inner = get_args(ann)
            properties[name] = {"type": "array", "items": {"type": "integer" if (inner and inner[0] is int) else "string"}}
        elif ann is int:    properties[name] = {"type": "integer"}
        elif ann is float:  properties[name] = {"type": "number"}
        elif ann is bool:   properties[name] = {"type": "boolean"}
        else:               properties[name] = {"type": "string"}
        if p.default is inspect.Parameter.empty:
            require

(原文がここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

generate-verifiers-env

Build the Verifiers variant of an env. Verifiers is in-process — no HTTP server, no Docker, no HF Space. The trainer (or a manual rollout) imports tool functions directly from env.py.

Concept

PrimeIntellect Verifiers is a Python library — not a server framework. It provides vf.ToolEnv (multi-turn rollout), vf.Rubric (composable async graders), and adapters into TRL GRPOTrainer. The trainer or rollout owns the LLM client; the env owns the tools and the grader.

When the user has a shared domain module (<domain>.py) and wants a Verifiers variant, wrap it as a toolkit class plus standalone tool functions. Don't duplicate domain logic.

Archetypes

Archetype Hallmarks
Pure-Python game One @tool-style function, terminal reward via rubric checking the trajectory.
Stateful sandbox in-process Toolkit owns the sandbox (E2B, browser); initialize() is lazy; cleanup() is mandatory in finally.
Vision env Drive the toolkit manually (skip vf.ToolEnv since vision content blocks aren't first-class in verifiers' rollout). Send the screenshot in the user message each turn.

Two consumption paths (always provide both)

Path A — DesktopToolkit-style class (used by TRL adapter + manual rollout)

class WordleToolkit:
    def __init__(self): ...
    def initialize(self): ...     # lazy E2B / state init
    def cleanup(self): ...        # kill sandbox
    def reset(self): ...          # new episode
    def guess(self, word: str) -> str:
        """Submit a 5-letter word guess. Returns colored feedback."""
        ...

Public methods are introspected as tools by the TRL adapter. Docstrings become tool descriptions.

Path B — vf.ToolEnv for native verifiers env.evaluate(client, model)

def create_verifiers_env():
    import verifiers as vf
    from datasets import Dataset
    dataset = Dataset.from_list([{"question": t["task"], "answer": t["expected_output"]} for t in TASKS])
    async def correctness(completion, answer, **kwargs) -> float:
        # read from the completion trajectory; return 0.0–1.0
        ...
    rubric = vf.Rubric(funcs=[correctness])
    return vf.ToolEnv(tools=TOOL_FUNCTIONS, max_turns=8, dataset=dataset, rubric=rubric, system_prompt="...")

TOOL_FUNCTIONS is a list of plain Python functions (not bound methods). They can share state via a module-level toolkit instance.

Recommended file layout

The user picks the actual paths. The canonical shape:

<env_dir>/verifiers/
├── pyproject.toml      # verifiers + e2b-* + datasets + python-dotenv + openai
├── __init__.py
├── env.py              # Toolkit class + standalone tool fns + create_verifiers_env()
├── rollout.py          # Drives the toolkit manually with the openai client
└── README.md

Implementation order

1. The toolkit class

  • __init__ takes config (api_key="", app="firefox", etc.). Don't create the sandbox here — too eager.
  • initialize() is the lazy creation hook. Always call it from each tool method.
  • cleanup() kills the sandbox. Always call it from finally in the rollout.
  • reset() calls cleanup() + reinitializes. Used between episodes by the TRL adapter.
  • Each tool method:
    • takes typed args (used for OpenAI tool-schema generation via inspect)
    • has a docstring (becomes the tool description — first paragraph only)
    • calls self.initialize() first, mutates state, returns a string

2. Standalone tool functions for vf.ToolEnv

Module-level shared toolkit, plus thin wrappers:

_shared: Optional[WordleToolkit] = None
def _kit():
    global _shared
    if _shared is None:
        _shared = WordleToolkit()
    return _shared

def guess(word: str) -> str:
    """Submit a 5-letter word guess."""
    return _kit().guess(word)

TOOL_FUNCTIONS = [guess]

Why both? The TRL adapter wants the toolkit class (per-rollout instance, isolated state). vf.ToolEnv wants free functions. Don't pick one — provide both.

3. The rubric

Rubrics are composable graders. Each grader is async def func(completion, answer, **kwargs) -> float. Combine multiple in a vf.Rubric(funcs=[...]) and they're averaged (or weighted, see verifiers docs).

For a single-criterion env, one grader suffices:

async def correctness(completion, answer, **kwargs) -> float:
    if not completion: return 0.0
    last = completion[-1].get("content", "") if isinstance(completion[-1], dict) else str(completion[-1])
    return 1.0 if answer.strip() in last.strip() else 0.0

For multi-criterion (e.g. computer-use envs that need both terminate(success) AND a state check):

async def correctness(completion, answer, **kwargs) -> float:
    seen_success = any("terminated: success" in str(m) for m in completion)
    seen_expected = any(answer in str(m) for m in completion)
    return 1.0 if (seen_success and seen_expected) else (0.5 if seen_success else 0.0)

4. Rollout — rollout.py

Build OpenAI tool schemas from the function signatures + docstrings via inspect:

def func_to_openai_tool(fn):
    sig = inspect.signature(fn)
    hints = get_type_hints(fn)
    doc = (fn.__doc__ or "").strip().split("\n\n")[0]
    properties, required = {}, []
    for name, p in sig.parameters.items():
        ann = hints.get(name, str)
        origin = get_origin(ann)
        if origin in (list, "list"):
            inner = get_args(ann)
            properties[name] = {"type": "array", "items": {"type": "integer" if (inner and inner[0] is int) else "string"}}
        elif ann is int:    properties[name] = {"type": "integer"}
        elif ann is float:  properties[name] = {"type": "number"}
        elif ann is bool:   properties[name] = {"type": "boolean"}
        else:               properties[name] = {"type": "string"}
        if p.default is inspect.Parameter.empty:
            required.append(name)
    return {"type": "function", "function": {
        "name": fn.__name__, "description": doc,
        "parameters": {"type": "object", "properties": properties, "required": required},
    }}

This pattern works for any toolkit. Use it as the standard adapter from Python signatures to OpenAI tool schemas.

For multimodal envs, drive the toolkit manually (don't use vf.ToolEnv since vision-content blocks aren't first-class in verifiers' rollout). Send the latest screenshot in the user message every turn:

text, b64 = kit._ctrl.screenshot()      # if you exposed _ctrl
messages.append({"role": "user", "content": [
    {"type": "text", "text": "Latest screenshot:"},
    {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
]})

Validation gates

  1. Toolkit imports cleanlyuv run python -c "from env import DesktopToolkit, TOOL_FUNCTIONS"
  2. vf.ToolEnv buildsuv run python -c "from env import create_verifiers_env; env = create_verifiers_env(); print(env)"
  3. Manual rolloutMAX_TURNS=3 uv run python rollout.py runs end-to-end. Hits a real backend (E2B or whatever the env uses).

Gotchas

  • ModuleNotFoundError: attrse2b-desktop transitively needs attrs but doesn't pin it. Add attrs>=23.0 to dependencies.
  • TypedDict vs dataclass for verifiers data structures — most are TypedDicts. Access by key, not attribute. (Same trap exists in skyrl-gym; we hit it during the desktop_env port.)
  • Tool-schema `kwargsis forbidden** — vLLM (used by some trainers) can't introspect**kwargs` for JSON schema generation. Define explicit params, even if empty.
  • Don't return huge strings — verifiers passes the result through to the model verbatim. A 100KB log dump will blow your context. Truncate / summarize in the tool method.

Reference

  • references/architecture.mdvf.ToolEnv internals + Rubric composition + TRL adapter shape

Official documentation