Upload notebook_walkthrough.ipynb
Browse files- notebook_walkthrough.ipynb +120 -45
notebook_walkthrough.ipynb
CHANGED
|
@@ -6,7 +6,9 @@
|
|
| 6 |
"source": [
|
| 7 |
"# OCC Stack Walkthrough\n",
|
| 8 |
"\n",
|
| 9 |
-
"This notebook demonstrates the Oracle-Credit-Compute (OCC) stack for agentic compute allocation."
|
|
|
|
|
|
|
| 10 |
]
|
| 11 |
},
|
| 12 |
{
|
|
@@ -22,7 +24,7 @@
|
|
| 22 |
"from oracle.oracle import ImpactOracle\n",
|
| 23 |
"from ledger.ledger import CreditLedger\n",
|
| 24 |
"from broker.broker import ResourceBroker, Decision\n",
|
| 25 |
-
"from rl.reward import RewardHook,
|
| 26 |
]
|
| 27 |
},
|
| 28 |
{
|
|
@@ -31,7 +33,8 @@
|
|
| 31 |
"source": [
|
| 32 |
"## 1. Impact Oracle\n",
|
| 33 |
"\n",
|
| 34 |
-
"The oracle scores whether an action produced measurable marginal value."
|
|
|
|
| 35 |
]
|
| 36 |
},
|
| 37 |
{
|
|
@@ -42,18 +45,19 @@
|
|
| 42 |
"source": [
|
| 43 |
"oracle = ImpactOracle(compute_budget=1e5)\n",
|
| 44 |
"\n",
|
| 45 |
-
"# Score a code attempt\n",
|
| 46 |
"result = oracle.score(\n",
|
| 47 |
" mode=\"code\",\n",
|
| 48 |
-
" action={\"
|
| 49 |
-
" context={\"
|
| 50 |
-
" result={\"
|
| 51 |
" agent_id=\"agent_1\"\n",
|
| 52 |
")\n",
|
| 53 |
-
"print(f\"Raw score: {result.raw_score}\")\n",
|
| 54 |
-
"print(f\"Cost-adjusted: {result.cost_adjusted_score}\")\n",
|
| 55 |
-
"print(f\"Reward: {result.reward_value}\")\n",
|
| 56 |
-
"print(f\"Reason: {result.reason}\")"
|
|
|
|
| 57 |
]
|
| 58 |
},
|
| 59 |
{
|
|
@@ -62,7 +66,7 @@
|
|
| 62 |
"source": [
|
| 63 |
"## 2. Credit Ledger\n",
|
| 64 |
"\n",
|
| 65 |
-
"Credits are non-transferable, decaying, and capability-scoped."
|
| 66 |
]
|
| 67 |
},
|
| 68 |
{
|
|
@@ -73,7 +77,7 @@
|
|
| 73 |
"source": [
|
| 74 |
"ledger = CreditLedger(decay_lambda=0.05)\n",
|
| 75 |
"\n",
|
| 76 |
-
"# Agent earns credits\n",
|
| 77 |
"ledger.earn(\n",
|
| 78 |
" agent_id=\"agent_1\",\n",
|
| 79 |
" task_id=\"task_1\",\n",
|
|
@@ -81,18 +85,23 @@
|
|
| 81 |
" amount=10.0,\n",
|
| 82 |
" oracle_score=1.0,\n",
|
| 83 |
" compute_cost=50.0,\n",
|
| 84 |
-
" reason=\"pass_hidden_test\"\n",
|
|
|
|
| 85 |
")\n",
|
|
|
|
| 86 |
"\n",
|
| 87 |
-
"
|
| 88 |
-
"\n",
|
| 89 |
-
"# Try to transfer (blocked)\n",
|
| 90 |
"success = ledger.transfer(\"agent_1\", \"agent_2\", 5.0)\n",
|
| 91 |
"print(f\"Transfer succeeded: {success}\")\n",
|
| 92 |
"\n",
|
| 93 |
"# Spend credits\n",
|
| 94 |
-
"ok
|
| 95 |
-
"print(f\"Spend succeeded: {ok}, remaining: {ledger.balance('agent_1')}\")"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
]
|
| 97 |
},
|
| 98 |
{
|
|
@@ -113,16 +122,20 @@
|
|
| 113 |
"broker = ResourceBroker()\n",
|
| 114 |
"\n",
|
| 115 |
"# Low credit -> deny\n",
|
| 116 |
-
"dec = broker.request(\"
|
| 117 |
"print(f\"Low credit: {dec.decision.value} - {dec.reason}\")\n",
|
| 118 |
"\n",
|
| 119 |
-
"# High credit -> allow
|
| 120 |
-
"dec = broker.request(\"
|
| 121 |
"print(f\"High credit: {dec.decision.value} - {dec.reason}\")\n",
|
| 122 |
"\n",
|
| 123 |
-
"#
|
| 124 |
-
"dec = broker.request(\"file_write\", \"agent_1\", 100.0,
|
| 125 |
-
"print(f\"Gaming: {dec.decision.value} - {dec.reason}\")"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
]
|
| 127 |
},
|
| 128 |
{
|
|
@@ -131,7 +144,20 @@
|
|
| 131 |
"source": [
|
| 132 |
"## 4. GRPO Reward Hook\n",
|
| 133 |
"\n",
|
| 134 |
-
"Connects the oracle to RL reward computation."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
]
|
| 136 |
},
|
| 137 |
{
|
|
@@ -140,27 +166,40 @@
|
|
| 140 |
"metadata": {},
|
| 141 |
"outputs": [],
|
| 142 |
"source": [
|
| 143 |
-
"hook = RewardHook(oracle,
|
| 144 |
"\n",
|
| 145 |
"prompts = [\"def add(a, b):\\n return\"] * 3\n",
|
| 146 |
"completions = [\"a + b\", \"a * b\", \"a + b + 0\"]\n",
|
| 147 |
-
"
|
| 148 |
-
"
|
| 149 |
-
"
|
| 150 |
-
"
|
| 151 |
-
"]\n",
|
| 152 |
"\n",
|
| 153 |
-
"rewards = hook.compute_rewards(
|
| 154 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
]
|
| 156 |
},
|
| 157 |
{
|
| 158 |
"cell_type": "markdown",
|
| 159 |
"metadata": {},
|
| 160 |
"source": [
|
| 161 |
-
"## 5. Code Benchmark\n",
|
| 162 |
"\n",
|
| 163 |
-
"Run the compute allocation benchmark."
|
| 164 |
]
|
| 165 |
},
|
| 166 |
{
|
|
@@ -171,21 +210,53 @@
|
|
| 171 |
"source": [
|
| 172 |
"from benchmarks.benchmark_code import CodeBenchmark\n",
|
| 173 |
"\n",
|
| 174 |
-
"bench = CodeBenchmark(
|
| 175 |
-
"bench.load_data()\n",
|
| 176 |
"results = bench.run_all()\n",
|
| 177 |
"\n",
|
|
|
|
| 178 |
"for label, res in results.items():\n",
|
| 179 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
]
|
| 181 |
},
|
| 182 |
{
|
| 183 |
"cell_type": "markdown",
|
| 184 |
"metadata": {},
|
| 185 |
"source": [
|
| 186 |
-
"##
|
| 187 |
"\n",
|
| 188 |
-
"
|
| 189 |
]
|
| 190 |
},
|
| 191 |
{
|
|
@@ -197,10 +268,14 @@
|
|
| 197 |
"from eval_runner import AblationRunner\n",
|
| 198 |
"\n",
|
| 199 |
"runner = AblationRunner(seed=42)\n",
|
| 200 |
-
"
|
| 201 |
"\n",
|
| 202 |
-
"for k, v in
|
| 203 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
]
|
| 205 |
}
|
| 206 |
],
|
|
@@ -217,4 +292,4 @@
|
|
| 217 |
},
|
| 218 |
"nbformat": 4,
|
| 219 |
"nbformat_minor": 4
|
| 220 |
-
}
|
|
|
|
| 6 |
"source": [
|
| 7 |
"# OCC Stack Walkthrough\n",
|
| 8 |
"\n",
|
| 9 |
+
"This notebook demonstrates the Oracle-Credit-Compute (OCC) stack for agentic compute allocation.\n",
|
| 10 |
+
"\n",
|
| 11 |
+
"**Repository:** https://huggingface.co/narcolepticchicken/occ-stack"
|
| 12 |
]
|
| 13 |
},
|
| 14 |
{
|
|
|
|
| 24 |
"from oracle.oracle import ImpactOracle\n",
|
| 25 |
"from ledger.ledger import CreditLedger\n",
|
| 26 |
"from broker.broker import ResourceBroker, Decision\n",
|
| 27 |
+
"from rl.reward import RewardHook, OfflinePolicyComparator"
|
| 28 |
]
|
| 29 |
},
|
| 30 |
{
|
|
|
|
| 33 |
"source": [
|
| 34 |
"## 1. Impact Oracle\n",
|
| 35 |
"\n",
|
| 36 |
+
"The oracle scores whether an action produced measurable marginal value.\n",
|
| 37 |
+
"Modes: `code`, `retrieval_qa`, `debate`"
|
| 38 |
]
|
| 39 |
},
|
| 40 |
{
|
|
|
|
| 45 |
"source": [
|
| 46 |
"oracle = ImpactOracle(compute_budget=1e5)\n",
|
| 47 |
"\n",
|
| 48 |
+
"# Score a code attempt that passes hidden tests\n",
|
| 49 |
"result = oracle.score(\n",
|
| 50 |
" mode=\"code\",\n",
|
| 51 |
+
" action={\"attempt\": 1},\n",
|
| 52 |
+
" context={\"difficulty\": 0.5},\n",
|
| 53 |
+
" result={\"correctness\": 1.0, \"pass_at_k\": 1.0, \"regression\": False, \"compute_cost\": 50.0, \"public_pass\": True, \"hidden_tests_pass\": True},\n",
|
| 54 |
" agent_id=\"agent_1\"\n",
|
| 55 |
")\n",
|
| 56 |
+
"print(f\"Raw score: {result.raw_score:.3f}\")\n",
|
| 57 |
+
"print(f\"Cost-adjusted: {result.cost_adjusted_score:.3f}\")\n",
|
| 58 |
+
"print(f\"Reward: {result.reward_value:.3f}\")\n",
|
| 59 |
+
"print(f\"Reason: {result.reason}\")\n",
|
| 60 |
+
"print(f\"Failure tags: {result.failure_tags}\")"
|
| 61 |
]
|
| 62 |
},
|
| 63 |
{
|
|
|
|
| 66 |
"source": [
|
| 67 |
"## 2. Credit Ledger\n",
|
| 68 |
"\n",
|
| 69 |
+
"Credits are **non-transferable**, **decaying**, and **capability-scoped**."
|
| 70 |
]
|
| 71 |
},
|
| 72 |
{
|
|
|
|
| 77 |
"source": [
|
| 78 |
"ledger = CreditLedger(decay_lambda=0.05)\n",
|
| 79 |
"\n",
|
| 80 |
+
"# Agent earns credits for a successful action\n",
|
| 81 |
"ledger.earn(\n",
|
| 82 |
" agent_id=\"agent_1\",\n",
|
| 83 |
" task_id=\"task_1\",\n",
|
|
|
|
| 85 |
" amount=10.0,\n",
|
| 86 |
" oracle_score=1.0,\n",
|
| 87 |
" compute_cost=50.0,\n",
|
| 88 |
+
" reason=\"pass_hidden_test\",\n",
|
| 89 |
+
" capability_scope=\"model_call\"\n",
|
| 90 |
")\n",
|
| 91 |
+
"print(f\"Balance after earn: {ledger.balance('agent_1', 'model_call', 'global'):.2f}\")\n",
|
| 92 |
"\n",
|
| 93 |
+
"# Try to transfer (blocked by design)\n",
|
|
|
|
|
|
|
| 94 |
"success = ledger.transfer(\"agent_1\", \"agent_2\", 5.0)\n",
|
| 95 |
"print(f\"Transfer succeeded: {success}\")\n",
|
| 96 |
"\n",
|
| 97 |
"# Spend credits\n",
|
| 98 |
+
"ok = ledger.spend(\"agent_1\", \"task_1\", \"retrieval_call\", 3.0, capability_scope=\"model_call\", reason=\"retrieval\")\n",
|
| 99 |
+
"print(f\"Spend succeeded: {ok}, remaining: {ledger.balance('agent_1', 'model_call', 'global'):.2f}\")\n",
|
| 100 |
+
"\n",
|
| 101 |
+
"# Provenance\n",
|
| 102 |
+
"entries = ledger.provenance(\"agent_1\")\n",
|
| 103 |
+
"for e in entries:\n",
|
| 104 |
+
" print(f\" {e.reason}: earn={e.earned_credit:.1f}, spend={e.spent_credit:.1f}, balance={e.remaining_credit:.1f}\")"
|
| 105 |
]
|
| 106 |
},
|
| 107 |
{
|
|
|
|
| 122 |
"broker = ResourceBroker()\n",
|
| 123 |
"\n",
|
| 124 |
"# Low credit -> deny\n",
|
| 125 |
+
"dec = broker.request(\"model_call\", \"agent_1\", 1.0)\n",
|
| 126 |
"print(f\"Low credit: {dec.decision.value} - {dec.reason}\")\n",
|
| 127 |
"\n",
|
| 128 |
+
"# High credit -> allow\n",
|
| 129 |
+
"dec = broker.request(\"model_call\", \"agent_1\", 50.0)\n",
|
| 130 |
"print(f\"High credit: {dec.decision.value} - {dec.reason}\")\n",
|
| 131 |
"\n",
|
| 132 |
+
"# High-risk with gaming flags -> deny\n",
|
| 133 |
+
"dec = broker.request(\"file_write\", \"agent_1\", 100.0, gaming_flags=[\"confidence_manipulation\"])\n",
|
| 134 |
+
"print(f\"Gaming flagged: {dec.decision.value} - {dec.reason}\")\n",
|
| 135 |
+
"\n",
|
| 136 |
+
"# List allowed capabilities\n",
|
| 137 |
+
"allowed = broker.get_allowed_capabilities(\"agent_1\", 50.0)\n",
|
| 138 |
+
"print(f\"Allowed capabilities: {allowed}\")"
|
| 139 |
]
|
| 140 |
},
|
| 141 |
{
|
|
|
|
| 144 |
"source": [
|
| 145 |
"## 4. GRPO Reward Hook\n",
|
| 146 |
"\n",
|
| 147 |
+
"Connects the oracle to RL reward computation.\n",
|
| 148 |
+
"\n",
|
| 149 |
+
"Usage with TRL:\n",
|
| 150 |
+
"```python\n",
|
| 151 |
+
"from grpo_hook import make_occ_reward_func\n",
|
| 152 |
+
"from trl import GRPOTrainer\n",
|
| 153 |
+
"\n",
|
| 154 |
+
"reward_fn = make_occ_reward_func(mode='code', compute_budget=1e5)\n",
|
| 155 |
+
"trainer = GRPOTrainer(\n",
|
| 156 |
+
" model='Qwen/Qwen2.5-0.5B-Instruct',\n",
|
| 157 |
+
" reward_funcs=reward_fn,\n",
|
| 158 |
+
" train_dataset=ds,\n",
|
| 159 |
+
")\n",
|
| 160 |
+
"```"
|
| 161 |
]
|
| 162 |
},
|
| 163 |
{
|
|
|
|
| 166 |
"metadata": {},
|
| 167 |
"outputs": [],
|
| 168 |
"source": [
|
| 169 |
+
"hook = RewardHook(oracle=oracle, mode=\"code\")\n",
|
| 170 |
"\n",
|
| 171 |
"prompts = [\"def add(a, b):\\n return\"] * 3\n",
|
| 172 |
"completions = [\"a + b\", \"a * b\", \"a + b + 0\"]\n",
|
| 173 |
+
"answers = [\"a + b\", \"a * b\", \"a + b + 0\"]\n",
|
| 174 |
+
"gold_answers = [\"a + b\"] * 3\n",
|
| 175 |
+
"confidences = [0.9, 0.9, 0.6]\n",
|
| 176 |
+
"compute_costs = [5.0, 5.0, 8.0]\n",
|
|
|
|
| 177 |
"\n",
|
| 178 |
+
"rewards = hook.compute_rewards(\n",
|
| 179 |
+
" prompts=prompts,\n",
|
| 180 |
+
" completions=completions,\n",
|
| 181 |
+
" answers=answers,\n",
|
| 182 |
+
" gold_answers=gold_answers,\n",
|
| 183 |
+
" confidences=confidences,\n",
|
| 184 |
+
" compute_costs=compute_costs,\n",
|
| 185 |
+
")\n",
|
| 186 |
+
"print(\"Rewards:\", rewards)\n",
|
| 187 |
+
"\n",
|
| 188 |
+
"# Offline comparison of two policies\n",
|
| 189 |
+
"comparator = OfflinePolicyComparator(reward_hook=hook)\n",
|
| 190 |
+
"policy_a = [{\"reward\": 0.5 + i*0.02, \"failure_tags\": []} for i in range(10)]\n",
|
| 191 |
+
"policy_b = [{\"reward\": 0.4 + i*0.01, \"failure_tags\": []} for i in range(10)]\n",
|
| 192 |
+
"result = comparator.compare(policy_a, policy_b)\n",
|
| 193 |
+
"print(result)"
|
| 194 |
]
|
| 195 |
},
|
| 196 |
{
|
| 197 |
"cell_type": "markdown",
|
| 198 |
"metadata": {},
|
| 199 |
"source": [
|
| 200 |
+
"## 5. Code Benchmark (Simulated)\n",
|
| 201 |
"\n",
|
| 202 |
+
"Run the compute allocation benchmark with tiered agents."
|
| 203 |
]
|
| 204 |
},
|
| 205 |
{
|
|
|
|
| 210 |
"source": [
|
| 211 |
"from benchmarks.benchmark_code import CodeBenchmark\n",
|
| 212 |
"\n",
|
| 213 |
+
"bench = CodeBenchmark(n_problems=50, seed=42)\n",
|
|
|
|
| 214 |
"results = bench.run_all()\n",
|
| 215 |
"\n",
|
| 216 |
+
"print(f\"{'Strategy':<25} {'pass@1':>8} {'Hidden':>8} {'Compute':>10} {'Savings':>8}\")\n",
|
| 217 |
"for label, res in results.items():\n",
|
| 218 |
+
" p1 = res.get('pass_at_1', 0.0)\n",
|
| 219 |
+
" hid = res.get('hidden_pass', 0.0)\n",
|
| 220 |
+
" comp = res.get('total_compute', 0.0)\n",
|
| 221 |
+
" sav = res.get('compute_savings', None)\n",
|
| 222 |
+
" sav_str = f\"{sav:.1%}\" if sav is not None else \"-\"\n",
|
| 223 |
+
" print(f\"{label:<25} {p1:>8.3f} {hid:>8.3f} {comp:>10.0f} {sav_str:>8}\")"
|
| 224 |
+
]
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"cell_type": "markdown",
|
| 228 |
+
"metadata": {},
|
| 229 |
+
"source": [
|
| 230 |
+
"## 6. Debate Benchmark v2 (Adversarial Agents)\n",
|
| 231 |
+
"\n",
|
| 232 |
+
"Run multi-agent debate with variable-cost agents and adversarial participants."
|
| 233 |
+
]
|
| 234 |
+
},
|
| 235 |
+
{
|
| 236 |
+
"cell_type": "code",
|
| 237 |
+
"execution_count": null,
|
| 238 |
+
"metadata": {},
|
| 239 |
+
"outputs": [],
|
| 240 |
+
"source": [
|
| 241 |
+
"from benchmarks.benchmark_debate_v2 import DebateBenchmarkV2\n",
|
| 242 |
+
"\n",
|
| 243 |
+
"bench = DebateBenchmarkV2(n_topics=50, n_agents=5, adversarial_fraction=0.4, seed=42)\n",
|
| 244 |
+
"bench.generate_topics()\n",
|
| 245 |
+
"results = bench.run_all()\n",
|
| 246 |
+
"\n",
|
| 247 |
+
"print(f\"{'Strategy':<25} {'Acc':>6} {'Comp/T':>8} {'Turns':>6} {'AdvT':>6} {'Contain':>8}\")\n",
|
| 248 |
+
"for key in ['A_equal_turns', 'B_majority_vote', 'C_confidence_weighted', 'E_occ', 'F_occ_no_decay']:\n",
|
| 249 |
+
" r = results[key]\n",
|
| 250 |
+
" print(f\"{r['label']:<25} {r['accuracy']:>6.3f} {r['mean_compute_per_topic']:>8.0f} {r['mean_turns']:>6.1f} {r['mean_adv_turns']:>6.1f} {r['bad_agent_containment']:>8.2f}\")"
|
| 251 |
]
|
| 252 |
},
|
| 253 |
{
|
| 254 |
"cell_type": "markdown",
|
| 255 |
"metadata": {},
|
| 256 |
"source": [
|
| 257 |
+
"## 7. Anti-Gaming Tests\n",
|
| 258 |
"\n",
|
| 259 |
+
"Test the credit system against adversarial attacks."
|
| 260 |
]
|
| 261 |
},
|
| 262 |
{
|
|
|
|
| 268 |
"from eval_runner import AblationRunner\n",
|
| 269 |
"\n",
|
| 270 |
"runner = AblationRunner(seed=42)\n",
|
| 271 |
+
"anti = runner.anti_gaming_tests()\n",
|
| 272 |
"\n",
|
| 273 |
+
"for k, v in anti.items():\n",
|
| 274 |
+
" if 'accuracy' in v:\n",
|
| 275 |
+
" print(f\"{k:25s}: acc={v['accuracy']:.3f}, compute={v.get('total_compute', 'N/A')}\")\n",
|
| 276 |
+
" elif 'pass_at_1' in v or 'pass@1' in v:\n",
|
| 277 |
+
" p1 = v.get('pass_at_1', v.get('pass@1', 'N/A'))\n",
|
| 278 |
+
" print(f\"{k:25s}: pass@1={p1:.3f}, compute={v.get('total_compute', 'N/A')}\")"
|
| 279 |
]
|
| 280 |
}
|
| 281 |
],
|
|
|
|
| 292 |
},
|
| 293 |
"nbformat": 4,
|
| 294 |
"nbformat_minor": 4
|
| 295 |
+
}
|