Skip to main content
A reward function turns a model completion into a number. GRPO uses these scores to compute advantages — completions above the group mean get reinforced, completions below get penalized. You upload a .py file once and reference its id from any number of training jobs.

Format

Veri runs reward functions in the trl shape — the format the production GRPO runner uses. The validator checks the function signature on upload — wrong shape rejects with HTTP 422.

TRL format

Receives a batch of completions, returns one score per completion.
  • completions — list of strings OR list of message-dict lists (depending on how the runner formats prompts)
  • answer — list of ground-truth strings (from the dataset’s answer column)
  • Return — list of floats, same length as completions

Upload

The CLI runs an AST check (file parses + at least one function defined). Use --skip-validation to bypass, but the upload will still fail at job submission if the signature is wrong.

Sandbox + limits

Reward functions run inside the training runner. They have:
  • No network egress — calls to external APIs will silently fail or hang
  • Standard library + the runner image’s pre-installed packages only — no pip install at runtime
  • A timeout per rollout batch — exceeding it fails the job with error.code = "training_error"
For PoC, treat this as “trusted users only.” Real isolation (gVisor / Firecracker) is on the Phase 2 roadmap.

Composing rewards

A common pattern is to weight multiple signals:
Keep each component bounded so the total stays in a stable range — [0, 1] is conventional. GRPO normalizes scores within a group, so the absolute scale matters less than the spread.

Multiple weighted reward functions

Instead of summing signals inside one function, you can upload several reward functions and let GRPO combine them with weights. TRL’s GRPOTrainer scores each completion with every function and sums the results, scaled by reward_weights. This keeps each signal in its own file (reusable and independently testable) and lets you retune the mix without editing code. Each function has the standard trl signature and returns one score per completion. Upload each file, then pass the ids and matching weights:
reward_weights is optional; omit it to weight every function equally. When provided, its length must match reward_function_ids (the SDK and API reject a mismatch). A single reward_function_id still works for the one-reward case.

Reuse across jobs

Once uploaded, a reward function is reusable. The same id can drive any number of training jobs.

Lifecycle

Reward functions are deduped by content hash — uploading the same file twice returns the same id. There is no DELETE endpoint today; programmatic delete is on the roadmap.

Where to go next

GRPO algorithm

What the score actually does inside the training loop.

Submit a job

Wire the reward into training_jobs.create.

Quickstart

End-to-end with the example math reward.