Audit fixes: tests/ dir, clean imports, reactive corpus, README polish
Browse files- README.md +2 -16
- server/environment.py +23 -11
- server/grader.py +2 -3
- tests/__init__.py +0 -0
- verify_icl.py → tests/test_icl.py +0 -0
- verify_multi_episode.py → tests/test_multi_episode.py +0 -0
README.md
CHANGED
|
@@ -10,6 +10,8 @@ base_path: /dashboard/
|
|
| 10 |
|
| 11 |
**PolicyEvolverEnv** is an OpenEnv-compliant reinforcement learning environment designed for the **Meta × PyTorch × Scaler Hackathon**. It serves as a production-grade benchmark for demonstrating in-context policy improvement using RLVR signals — no weight updates required, making the environment compute-efficient and immediately deployable.
|
| 12 |
|
|
|
|
|
|
|
| 13 |
---
|
| 14 |
|
| 15 |
### Advanced Reward Shaping (RLVR Integration)
|
|
@@ -179,22 +181,6 @@ The agent uses **In-Context Reinforcement Learning (ICL-RL)**: no weight updates
|
|
| 179 |
**Reproducible:** temperature=0.0, seed=42 (**Bit-for-bit identical results verified**)
|
| 180 |
**No fine-tuning required.** The environment provides the learning signal; the model adapts its in-context policy each step.
|
| 181 |
|
| 182 |
-
## Setup
|
| 183 |
-
|
| 184 |
-
### Required Environment Variables
|
| 185 |
-
|
| 186 |
-
| Variable | Description | Example |
|
| 187 |
-
|---|---|---|
|
| 188 |
-
| HF_TOKEN | API key for LLM inference (Groq) | gsk_... |
|
| 189 |
-
| API_BASE_URL | Provider endpoint | https://api.groq.com/openai/v1 |
|
| 190 |
-
| MODEL_NAME | Model identifier | llama-3.1-8b-instant |
|
| 191 |
-
|
| 192 |
-
### Getting a Free Groq API Key
|
| 193 |
-
1. Go to [console.groq.com](https://console.groq.com)
|
| 194 |
-
2. Sign up (no credit card required)
|
| 195 |
-
3. API Keys → Create API Key
|
| 196 |
-
4. Export: `export HF_TOKEN=gsk_your_key_here`
|
| 197 |
-
|
| 198 |
## Strategic Reward Evolution & RLVR
|
| 199 |
PolicyEvolverEnv serves as the **Strategic Sandbox** for the **Reinforcement Learning from Verifiable Rewards (RLVR)** stage of the modern LLM inference pipeline. Unlike static evaluation, this environment enables agents to refine their strategies iteratively based on high-quality, verifiable feedback.
|
| 200 |
|
|
|
|
| 10 |
|
| 11 |
**PolicyEvolverEnv** is an OpenEnv-compliant reinforcement learning environment designed for the **Meta × PyTorch × Scaler Hackathon**. It serves as a production-grade benchmark for demonstrating in-context policy improvement using RLVR signals — no weight updates required, making the environment compute-efficient and immediately deployable.
|
| 12 |
|
| 13 |
+
> **Why this matters:** Meta's Oversight Board reviewed 300K+ content appeals in 2024 due to vague community standards. Amazon's marketplace loses an estimated $700M/year to false-positive seller suspensions. PolicyEvolverEnv directly addresses this gap by training agents to replace subjective governance terms with measurable, enforceable thresholds — turning policy ambiguity into a solvable optimization problem.
|
| 14 |
+
|
| 15 |
---
|
| 16 |
|
| 17 |
### Advanced Reward Shaping (RLVR Integration)
|
|
|
|
| 181 |
**Reproducible:** temperature=0.0, seed=42 (**Bit-for-bit identical results verified**)
|
| 182 |
**No fine-tuning required.** The environment provides the learning signal; the model adapts its in-context policy each step.
|
| 183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
## Strategic Reward Evolution & RLVR
|
| 185 |
PolicyEvolverEnv serves as the **Strategic Sandbox** for the **Reinforcement Learning from Verifiable Rewards (RLVR)** stage of the modern LLM inference pipeline. Unlike static evaluation, this environment enables agents to refine their strategies iteratively based on high-quality, verifiable feedback.
|
| 186 |
|
server/environment.py
CHANGED
|
@@ -141,26 +141,38 @@ class PolicyEvolverEnvironment(Environment[Action, Observation, State]):
|
|
| 141 |
action_type = action_dict.get("action_type", "unknown") if isinstance(action_dict, dict) else "unknown"
|
| 142 |
self._state.actions_taken.append(action_type)
|
| 143 |
|
| 144 |
-
#
|
|
|
|
| 145 |
target_term = action_dict.get("ambiguous_term") or action_dict.get("rule_domain") or ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
for item in self._episode_corpus:
|
| 147 |
-
# For this hackathon, we apply state changes based on generic keyword matching or domain handling
|
| 148 |
-
# If target_term is in the content or properties, we update.
|
| 149 |
-
# Alternatively, if hard task, update broadly.
|
| 150 |
c_type = str(item.get("type", "")).lower()
|
| 151 |
c_text = str(item.get("content", "")).lower()
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
# Simple heuristic mapping
|
| 155 |
if t_term in c_text or t_term in c_type or action_type == "evolve_policy":
|
| 156 |
if reward >= 0.7:
|
| 157 |
item["system_action"] = "policy_applied"
|
| 158 |
elif 0.3 <= reward < 0.7:
|
| 159 |
item["system_action"] = "flagged"
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
done = (
|
| 166 |
reward >= 0.90 or
|
|
|
|
| 141 |
action_type = action_dict.get("action_type", "unknown") if isinstance(action_dict, dict) else "unknown"
|
| 142 |
self._state.actions_taken.append(action_type)
|
| 143 |
|
| 144 |
+
# Reactive Corpus: Prioritize items relevant to the agent's action domain
|
| 145 |
+
# This makes the world visibly react to agent choices
|
| 146 |
target_term = action_dict.get("ambiguous_term") or action_dict.get("rule_domain") or ""
|
| 147 |
+
t_term = str(target_term).lower()
|
| 148 |
+
|
| 149 |
+
# Partition: relevant items first, then remaining
|
| 150 |
+
relevant = []
|
| 151 |
+
remaining = []
|
| 152 |
for item in self._episode_corpus:
|
|
|
|
|
|
|
|
|
|
| 153 |
c_type = str(item.get("type", "")).lower()
|
| 154 |
c_text = str(item.get("content", "")).lower()
|
| 155 |
+
|
| 156 |
+
# Update system_action based on reward (stateful corpus)
|
|
|
|
| 157 |
if t_term in c_text or t_term in c_type or action_type == "evolve_policy":
|
| 158 |
if reward >= 0.7:
|
| 159 |
item["system_action"] = "policy_applied"
|
| 160 |
elif 0.3 <= reward < 0.7:
|
| 161 |
item["system_action"] = "flagged"
|
| 162 |
+
|
| 163 |
+
# Sort into buckets
|
| 164 |
+
if t_term and (t_term in c_text or t_term in c_type):
|
| 165 |
+
relevant.append(item)
|
| 166 |
+
else:
|
| 167 |
+
remaining.append(item)
|
| 168 |
+
|
| 169 |
+
# Rotate the remaining window by step count so agent sees fresh data each step
|
| 170 |
+
step_offset = (self._state.step_count - 1) * 3
|
| 171 |
+
rotated_remaining = remaining[step_offset:] + remaining[:step_offset]
|
| 172 |
+
|
| 173 |
+
# Build shown corpus: relevant items first, then rotated remaining, cap at 10
|
| 174 |
+
prioritized_corpus = relevant + rotated_remaining
|
| 175 |
+
shown_corpus = prioritized_corpus[:10]
|
| 176 |
|
| 177 |
done = (
|
| 178 |
reward >= 0.90 or
|
server/grader.py
CHANGED
|
@@ -5,6 +5,7 @@ All functions return float in [0.0, 1.0].
|
|
| 5 |
"""
|
| 6 |
from __future__ import annotations
|
| 7 |
import re
|
|
|
|
| 8 |
import logging
|
| 9 |
from typing import Dict, List, Any
|
| 10 |
from models import (
|
|
@@ -424,10 +425,9 @@ def grade_evolution(action: EvolveProcessAction, task: Dict) -> float:
|
|
| 424 |
"buyer", "shipment", "return", "velocity", "payment",
|
| 425 |
"review", "refund", "inventory", "drop.?ship", "fulfil"
|
| 426 |
]
|
| 427 |
-
import re as _re
|
| 428 |
domain_hits = sum(
|
| 429 |
1 for kw in HARD_DOMAIN_KEYWORDS
|
| 430 |
-
if
|
| 431 |
)
|
| 432 |
domain_penalty = 0.30 if domain_hits == 0 else 0.0
|
| 433 |
|
|
@@ -716,7 +716,6 @@ if __name__ == "__main__":
|
|
| 716 |
"think": "Standard threshold applied."
|
| 717 |
}
|
| 718 |
|
| 719 |
-
import copy
|
| 720 |
result1 = env.step(copy.deepcopy(repeat_action_dict))
|
| 721 |
result2 = env.step(copy.deepcopy(repeat_action_dict))
|
| 722 |
|
|
|
|
| 5 |
"""
|
| 6 |
from __future__ import annotations
|
| 7 |
import re
|
| 8 |
+
import copy
|
| 9 |
import logging
|
| 10 |
from typing import Dict, List, Any
|
| 11 |
from models import (
|
|
|
|
| 425 |
"buyer", "shipment", "return", "velocity", "payment",
|
| 426 |
"review", "refund", "inventory", "drop.?ship", "fulfil"
|
| 427 |
]
|
|
|
|
| 428 |
domain_hits = sum(
|
| 429 |
1 for kw in HARD_DOMAIN_KEYWORDS
|
| 430 |
+
if re.search(kw, full_text)
|
| 431 |
)
|
| 432 |
domain_penalty = 0.30 if domain_hits == 0 else 0.0
|
| 433 |
|
|
|
|
| 716 |
"think": "Standard threshold applied."
|
| 717 |
}
|
| 718 |
|
|
|
|
| 719 |
result1 = env.step(copy.deepcopy(repeat_action_dict))
|
| 720 |
result2 = env.step(copy.deepcopy(repeat_action_dict))
|
| 721 |
|
tests/__init__.py
ADDED
|
File without changes
|
verify_icl.py → tests/test_icl.py
RENAMED
|
File without changes
|
verify_multi_episode.py → tests/test_multi_episode.py
RENAMED
|
File without changes
|