add-reward
Standardizes the creation of reward computation logic in AReaL.
Install
mkdir -p .claude/skills/add-reward && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3006" && unzip -o skill.zip -d .claude/skills/add-reward && rm skill.zipInstalls to .claude/skills/add-reward
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Guide for adding a new reward function to AReaL. Use when user wants to create a reward function.Key capabilities
- →Generates boilerplate reward function structure
- →Implements answer extraction logic
- →Registers reward functions in the engine
- →Handles token-based reward computation
- →Logs evaluation warnings and exceptions
How it works
Writes a Python file containing the reward logic and automatically updates the module's initialization to include the new function.
Inputs & outputs
When to use add-reward
- →Implementing custom reward logic
- →Defining reward computation
- →Automating model evaluation
About this skill
Add Reward
Add a new reward function to AReaL.
When to Use
This skill is triggered when:
- User asks "how do I add a reward function?"
- User wants to implement custom rewards
- User mentions reward computation
Step-by-Step Guide
Step 1: Create Reward File
Create areal/reward/<name>.py:
from typing import Any
from areal.utils import logging
logger = logging.getLogger("MyReward")
def <name>_reward_fn(
prompt: str,
completions: str,
prompt_ids,
completion_ids,
answer: str | None = None,
**kwargs: Any,
) -> float:
"""Compute reward for a single completion.
Args:
prompt: Prompt string
completions: Completion string (model output)
prompt_ids: Tokenized prompt IDs
completion_ids: Tokenized completion IDs
answer: Ground truth answer from dataset (optional)
**kwargs: Additional data from dataset
Returns:
Reward value (float), typically 0.0 or 1.0
"""
try:
# Extract answer from completion
extracted = _extract_answer(completions)
# Compare with ground truth
if answer is not None and extracted == str(answer):
return 1.0
return 0.0
except Exception:
logger.warning("Exception in reward computation", exc_info=True)
return 0.0
def _extract_answer(completion: str) -> str:
"""Extract the answer from a completion string.
Implement your extraction logic here.
"""
# Example: Extract content from \boxed{}
import re
match = re.search(r"\\boxed\{([^}]+)\}", completion)
if match:
return match.group(1).strip()
return completion.strip()
Step 2: Register in init.py
Update areal/reward/__init__.py:
# Add to VALID_REWARD_FN
VALID_REWARD_FN = [
# ... existing reward functions
"<name>",
]
# Add to get_reward_fn function
def get_reward_fn(name: str, **kwargs):
# ... existing code
elif name == "<name>":
from areal.reward.<name> import <name>_reward_fn
return <name>_reward_fn
Step 3: Handle Blocking Operations
If your reward function uses blocking operations (e.g., API calls, model inference), the
workflow will wrap it with AsyncRewardWrapper:
# In your workflow
from areal.reward import AsyncRewardWrapper
self.reward_fn = AsyncRewardWrapper(reward_fn)
# Then call it asynchronously
rewards = await self.reward_fn(prompt, completions, **data)
Step 4: Add Tests
Create tests/test_<name>_reward.py:
import pytest
from areal.reward.<name> import <name>_reward_fn
def test_reward_correct_answer():
reward = <name>_reward_fn(
prompt="What is 2+2?",
completions="The answer is \\boxed{4}",
prompt_ids=None,
completion_ids=None,
answer="4",
)
assert reward == 1.0
def test_reward_wrong_answer():
reward = <name>_reward_fn(
prompt="What is 2+2?",
completions="The answer is \\boxed{5}",
prompt_ids=None,
completion_ids=None,
answer="4",
)
assert reward == 0.0
Reference Implementations
| Reward | File | Description |
|---|---|---|
| GSM8K | areal/reward/gsm8k.py | Math answer verification |
| Geometry3K | areal/reward/geometry3k.py | Geometry answer verification |
| CLEVR | areal/reward/clevr_count_70k.py | Counting verification |
| MathVerify | areal/reward/math_verify.py | General math verification |
Function Signature
All reward functions must follow this signature:
def reward_fn(
prompt: str, # Input prompt string
completions: str, # Model completion string
prompt_ids, # Tokenized prompt
completion_ids, # Tokenized completion
**kwargs: Any, # Additional data from dataset (e.g., answer)
) -> float: # Reward value (typically 0.0 or 1.0)
Note: The reward function is called once per sample. Batching is handled by
AsyncRewardWrapper in the workflow.
Key Requirements
- Deterministic: Same inputs should produce same outputs
- Return float: Output is a single float value per sample
- No blocking in async context: Use
AsyncRewardWrapperif needed - Logging: Use
areal.utils.logging, notprint - Handle exceptions: Return 0.0 on error, don't raise
Common Mistakes
- ❌ Returning a tensor instead of a float
- ❌ Expecting batched inputs (reward is called per sample)
- ❌ Non-deterministic behavior
- ❌ Blocking operations without
AsyncRewardWrapper - ❌ Raising exceptions instead of returning 0.0
<!-- ================================================================================ MAINTAINER GUIDE ================================================================================ Location: .claude/skills/add-reward/SKILL.md Invocation: /add-reward <name> ## Purpose Step-by-step guide for adding new reward functions. ## How to Update ### When Reward API Changes 1. Update the function signature section 2. Update the code template 3. Update key requirements ### When New Reward Patterns Emerge 1. Add to "Reference Implementations" table 2. Add examples for new patterns ================================================================================ -->
When not to use it
- →Generic evaluation tasks
- →Models without reward function support
Prerequisites
Limitations
- →Custom extraction logic must be manually coded
- →Limited to AReaL framework compatibility
- →Requires testing against actual model output
How it compares
It automates the integration steps into the AReaL framework rather than creating loose scripts.
Compared to similar skills
add-reward side by side with the closest alternatives in the catalog.
Try saying
Example prompts that trigger this skill in your AI assistant.
More by inclusionAI
View all by inclusionAI →You might also like
llama-cpp
zechenzhangAGI
Runs LLM inference on CPU, Apple Silicon, and consumer GPUs without NVIDIA hardware. Use for edge deployment, M1/M2/M3 Macs, AMD/Intel GPUs, or when CUDA is unavailable. Supports GGUF quantization (1.5-8 bit) for reduced memory and 4-10× speedup vs PyTorch on CPU.
langchain
zechenzhangAGI
Framework for building LLM-powered applications with agents, chains, and RAG. Supports multiple providers (OpenAI, Anthropic, Google), 500+ integrations, ReAct agents, tool calling, memory management, and vector store retrieval. Use for building chatbots, question-answering systems, autonomous agents, or RAG applications. Best for rapid prototyping and production deployments.
unsloth
zechenzhangAGI
Expert guidance for fast fine-tuning with Unsloth - 2-5x faster training, 50-80% less memory, LoRA/QLoRA optimization
llama-factory
zechenzhangAGI
Expert guidance for fine-tuning LLMs with LLaMA-Factory - WebUI no-code, 100+ models, 2/3/4/5/6/8-bit QLoRA, multimodal support
llava
zechenzhangAGI
Large Language and Vision Assistant. Enables visual instruction tuning and image-based conversations. Combines CLIP vision encoder with Vicuna/LLaMA language models. Supports multi-turn image chat, visual question answering, and instruction following. Use for vision-language chatbots or image understanding tasks. Best for conversational image analysis.
cocoindex
cocoindex-io
Comprehensive toolkit for developing with the CocoIndex library. Use when users need to create data transformation pipelines (flows), write custom functions, or operate flows via CLI or API. Covers building ETL workflows for AI data processing, including embedding documents into vector databases, building knowledge graphs, creating search indexes, or processing data streams with incremental updates.