LLEnvs¶
MDP-style access to evaluation environments for LLM research.
Stateless environments, multi-signal rewards, and 17+ adapters — one unified interface for benchmarking, evaluating, and training language model agents.
-
Stateless Environments
step()is a pure function — state in, state out. Enables branching, checkpointing, and parallel exploration with no side effects. -
Multi-Signal Rewards
Each step produces a
SignalBundlewith named, weighted signals carrying numeric rewards, textual feedback, or both. -
17+ Adapters
ReasoningGym, HuggingFace, GEM, Gymnasium, WebShop, AlfWorld, Jericho, AgentGym, LMRL-Gym, Aviary, Verifiers, OpenEnv, and more.
-
Tool & Function Calling
Built-in tool environments with auto-monitoring, text-based tool parsers, and MCP support for open-source and API models.
-
RL Training Integration
Drop-in scoring, dataset provision, and token masking for veRL, TRL, and OpenRLHF training loops.
-
Branching & Containers
Checkpoint and branch environment states with zero-copy, process fork, or action replay. Run environments in Docker or isolated subprocesses.
Design Principles¶
Stateless Environments¶
Traditional RL environments maintain internal state. llenvs uses stateless environments where step() is a pure function:
This enables branching, checkpointing, and parallel exploration.
Observation/Hidden Split¶
Each State separates what the model sees from what's needed for rewards:
State(
observation: ObsT, # Model sees this (prompt, messages)
hidden: HiddenT, # For reward computation (ground truth)
metadata: StateMetadata
)
Multi-Signal Rewards¶
Transitions produce a SignalBundle with multiple named, weighted Signal instances. Each signal can carry a numeric reward, textual feedback, or both:
SignalBundle(signals=(
Signal(name="correctness", reward_type=OUTCOME, reward=1.0, weight=1.0),
Signal(name="format", reward_type=FORMAT, reward=1.0, weight=0.5),
Signal(name="judge", reward_type=PROCESS, feedback="Consider edge cases..."),
))
# bundle.total = 1.0*1.0 + 1.0*0.5 = 1.5 (feedback-only signals don't contribute)
# bundle.feedback_texts() = ("Consider edge cases...",)