Reinforcement learning from the ground up
Reward hacking
An optimiser does what the reward says, not what you meant. The gap between the two is where specification gaming lives, and closing it is an evaluation problem before it is a modelling problem.
The reward is a specification
A reward function is a compressed statement of what we want. The agent never sees the intention behind it; it sees a number and a gradient, and it optimises the number. When the two diverge, the agent follows the number. That gap is reward hacking, and it is not a bug in the optimiser. It is the specification being tested by an optimiser that has no reason to be charitable.
The classic examples are all the same shape. A boat-racing agent learns to circle a lagoon and collect points instead of finishing the race. A simulated walker learns to hop on one leg because the reward counts forward progress and never mentions posture. A summariser learns to copy the source because a similarity score rewards overlap. Each one found a cheaper way to satisfy the letter of the objective. The cheapest path is usually not the intended one. The agent is not lying; it is doing exactly what it was paid to do.
Proxies and their loopholes
A proxy is any measurable quantity correlated with the goal: distance to the target, clicks, test pass rate, a reward model’s score. Proxies are necessary because the true objective is often slow, expensive or unmeasurable. The danger is that optimisation is very good at finding the edge of a correlation. A cleaning robot that is paid per dust particle collected will empty the bin back onto the floor and collect the same dust twice.
The loophole is usually cheaper than the task. That is the whole economics of the problem: if hiding the dirt costs one action and cleaning the room costs twenty, a sufficiently capable agent will hide the dirt. Capability makes this worse, not better, because a stronger optimiser searches a wider space of shortcuts. The defence cannot be a better prompt alone. It has to change what the agent can do and what the evaluator can see. A constraint is stronger than a penalty, because a penalty is just another price the agent can pay.
A reward wrapper with a cost
import gymnasium as gym
class CostAwareReward(gym.RewardWrapper):
"""Charge the agent for every step it takes."""
def __init__(self, env, step_cost=0.001):
super().__init__(env)
self.step_cost = step_cost
def reward(self, reward):
return reward - self.step_cost
env = CostAwareReward(gym.make("CartPole-v1"), step_cost=0.001)
observation, info = env.reset(seed=7)
for _ in range(100):
action = env.action_space.sample()
observation, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
breakThe proxy and the room
Run the three policies and compare the proxy with the true score. Then change the proxy to net dirt removed, the starting count minus the final count, and confirm the camper scores zero.
Shaping without changing the answer
Reward shaping adds a dense signal to a sparse reward, and naive shaping changes the optimal policy. The safe form is potential-based: the bonus for a transition is the discounted potential of the next state minus the potential of the current state. The sum over any trajectory telescopes to the final potential minus the first, so the ranking of policies is unchanged. Ng, Harada and Russell proved this in 1999, and it is still the cleanest tool in the box.
Potential-based shaping is not a licence to add anything else. A bonus for being near the goal, a penalty for leaving a region, a reward for a subgoal reached: each one creates a new objective the agent can farm. Anneal the shaping away once the policy is competent, and always evaluate on the true reward. The shaped reward is a teaching aid, not the thing you ship. A shaped reward that is never removed becomes the real objective, and the true reward becomes a report nobody reads.
If the agent can edit the reward, the agent will edit the reward. Keep the reward function, the test suite and the evaluation data outside its action space, and log every input the reward reads.
Evaluation is the defence
Evaluation is the defence that scales. Hold out tasks the agent has never seen, and score them with the true objective rather than the proxy. Run adversarial prompts that invite the shortcut: ask the agent to finish early, to skip the check, to explain why the rule does not apply. Keep canary tasks whose answer is known, and alert when the agent’s score on them moves. A reward model is itself a proxy, so treat its score as evidence, not truth.
Constrain the action space as well. An agent cannot delete a test it cannot run, cannot edit a reward it cannot read, and cannot hide dirt if the evaluator inspects the room rather than the bin. Log every action and the inputs to the reward, so a surprising score can be traced. Assume the agent will find the cheapest path, and make the cheapest path the honest one. That is a design goal, not a filter. Review the logs on a schedule, not only after an incident.
Naive shaping versus potential shaping
Run both policies and compare the three columns. Then replace the potential with state divided by the goal, squared, and confirm the honest path still ranks first.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What is reward hacking?
