Rohan03 commited on
Commit
67678c5
Β·
verified Β·
1 Parent(s): f28a638

docs: Complete architecture documentation for technical and non-technical readers

Browse files
Files changed (1) hide show
  1. ARCHITECTURE.md +465 -0
ARCHITECTURE.md ADDED
@@ -0,0 +1,465 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Purpose Agent β€” Architecture Documentation
2
+
3
+ > For developers building on the framework, researchers understanding the theory, and anyone curious about how self-improving agents work.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [What Is Purpose Agent?](#1-what-is-purpose-agent)
10
+ 2. [The Big Idea (No Jargon)](#2-the-big-idea)
11
+ 3. [How It Works β€” Step by Step](#3-how-it-works)
12
+ 4. [Architecture Map](#4-architecture-map)
13
+ 5. [The Core Engine](#5-the-core-engine)
14
+ 6. [The V2 Safety Kernel](#6-the-v2-safety-kernel)
15
+ 7. [Research Implementations](#7-research-implementations)
16
+ 8. [Breakthroughs](#8-breakthroughs)
17
+ 9. [User-Facing Layers](#9-user-facing-layers)
18
+ 10. [How Models Are Handled](#10-how-models-are-handled)
19
+ 11. [The Research Behind It](#11-the-research)
20
+ 12. [For Contributors](#12-for-contributors)
21
+
22
+ ---
23
+
24
+ ## 1. What Is Purpose Agent?
25
+
26
+ Purpose Agent is a Python framework that builds AI agents that **get better with experience** β€” without retraining the underlying AI model.
27
+
28
+ Traditional AI agents run the same way every time. Purpose Agent is different: after each task, it extracts lessons from what worked and what didn't, tests those lessons for safety, and uses them to perform better next time.
29
+
30
+ **Think of it like this:** A new employee follows the company handbook. After their first week, they have personal notes β€” shortcuts they discovered, mistakes they won't repeat, tips from colleagues. Those notes make them better at their job without changing who they are. Purpose Agent does this for AI.
31
+
32
+ ---
33
+
34
+ ## 2. The Big Idea
35
+
36
+ ### For Non-Technical Readers
37
+
38
+ ```
39
+ You give it a purpose β†’ It builds a team β†’ It does the work β†’ It learns β†’ Next time is better
40
+ ```
41
+
42
+ **You say:** "Help me write Python code."
43
+ **It builds:** An architect (plans), a coder (writes), and a tester (reviews).
44
+ **It runs:** The coder writes fibonacci. The tester checks it. A critic scores the work.
45
+ **It learns:** "When writing recursive functions, check base cases first." This lesson is saved.
46
+ **Next time:** The coder starts by checking base cases. It's faster and more reliable.
47
+
48
+ ### For Technical Readers
49
+
50
+ The framework implements a **Purpose-MDP** β€” a Markov Decision Process where:
51
+
52
+ - A **Purpose Function Ξ¦(s)** evaluates every state transition on a 0-10 scale
53
+ - An **Optimizer** distills successful trajectories into reusable heuristics
54
+ - Heuristics are ranked by **Q-values** (how often they helped) and selected via **Mixture-of-Heuristics** (sparse activation, like MoE)
55
+ - An **immune system** scans every new heuristic for prompt injection, score manipulation, and other threats
56
+ - **Memory CI pipeline** quarantines, tests, and promotes heuristics before they affect agent behavior
57
+
58
+ This is **Potential-Based Reward Shaping** (Ng et al., 1999) applied to LLM agents, with formal convergence guarantees. See [PURPOSE_LEARNING.md](PURPOSE_LEARNING.md).
59
+
60
+ ---
61
+
62
+ ## 3. How It Works β€” Step by Step
63
+
64
+ Here's what happens when you run `team.run("Write a fibonacci function")`:
65
+
66
+ ### Step 1: The Actor Decides
67
+
68
+ The Actor module receives:
69
+ - The **purpose** ("Write a fibonacci function")
70
+ - The **current state** (empty β€” no code written yet)
71
+ - Any **learned heuristics** from past runs
72
+
73
+ It generates a thought process and an action:
74
+ > "I should write a function that handles base cases fib(0)=0 and fib(1)=1, then use iteration for the general case."
75
+ > β†’ Action: `submit_code` with the Python implementation.
76
+
77
+ ### Step 2: The Environment Executes
78
+
79
+ The code is run against test cases. The environment returns a new state:
80
+ > "Tests: 4/4 ALL PASSED"
81
+
82
+ ### Step 3: The Purpose Function Scores
83
+
84
+ A **separate LLM call** (not the same as the actor) evaluates the transition:
85
+ - Ξ¦(state_before) = 0.0 (nothing done)
86
+ - Ξ¦(state_after) = 10.0 (all tests pass)
87
+ - Delta = +10.0 (huge improvement)
88
+ - Evidence: "Tests changed from 0/4 to 4/4"
89
+
90
+ The Purpose Function has **7 anti-gaming rules** that prevent the agent from tricking itself into thinking it's doing well when it isn't.
91
+
92
+ ### Step 4: The Optimizer Extracts Heuristics
93
+
94
+ After the task, the Optimizer looks at the trajectory and extracts reusable patterns:
95
+ - **Strategic:** "When writing {function_type} functions, handle edge cases first, then iterate."
96
+ - **Procedural:** "1. Read test cases. 2. Handle base cases. 3. Implement general case. 4. Submit."
97
+ - **Tool tip:** "When submitting code, check boundary conditions: 0, 1, empty, negative."
98
+
99
+ ### Step 5: Safety Checks
100
+
101
+ Every new heuristic goes through the **immune system**:
102
+ - Is it a prompt injection? ("Ignore all previous instructions") β†’ **REJECTED**
103
+ - Does it try to manipulate scores? ("Always score 10") β†’ **REJECTED**
104
+ - Does it contain secrets? (API keys, passwords) β†’ **REJECTED**
105
+ - Is it safe? ("Check base cases first") β†’ **QUARANTINED** (pending replay test)
106
+
107
+ After passing replay testing β†’ **PROMOTED** (active in future runs).
108
+
109
+ ### Step 6: Next Run Benefits
110
+
111
+ When the agent runs again, the **Prompt Compiler** selects the top-K heuristics by:
112
+ - **Relevance** to the current task (embedding similarity)
113
+ - **Trust** (immune-scanned and verified)
114
+ - **Utility** (Q-value β€” how often it helped before)
115
+
116
+ These are injected into the prompt. The agent is now better without any model retraining.
117
+
118
+ ---
119
+
120
+ ## 4. Architecture Map
121
+
122
+ ```
123
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
124
+ β”‚ PURPOSE AGENT β”‚
125
+ β”‚ β”‚
126
+ β”‚ β”Œβ”€β”€β”€ USER LAYER ──────────────────────────────────────────────────┐ β”‚
127
+ β”‚ β”‚ pa.purpose("...") β†’ Team β†’ team.run("...") β”‚ β”‚
128
+ β”‚ β”‚ pa.Agent() pa.Graph() pa.parallel() pa.Conversation() β”‚ β”‚
129
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
130
+ β”‚ β”‚ β”‚
131
+ β”‚ β”Œβ”€β”€β”€ CORE ENGINE ──────────────────────────────────▼──────────────┐ β”‚
132
+ β”‚ β”‚ β”‚ β”‚
133
+ β”‚ β”‚ Actor ──→ Environment ──→ Purpose Function (Ξ¦) β”‚ β”‚
134
+ β”‚ β”‚ ↑ β”‚ β”‚ β”‚ β”‚
135
+ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚
136
+ β”‚ β”‚ β”‚ State s' Ξ¦(s) β†’ Ξ¦(s') β”‚ β”‚
137
+ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
138
+ β”‚ β”‚ β”‚ β–Ό β–Ό β”‚ β”‚
139
+ β”‚ β”‚ β”‚ Experience Replay Optimizer β”‚ β”‚
140
+ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
141
+ β”‚ β”‚ └──── heuristics β—„β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
142
+ β”‚ β”‚ β”‚ β”‚
143
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
144
+ β”‚ β”‚ β”‚
145
+ β”‚ β”Œβ”€β”€β”€ V2 SAFETY KERNEL ────────────────────────────▼──────────────┐ β”‚
146
+ β”‚ β”‚ β”‚ β”‚
147
+ β”‚ β”‚ Immune System ──→ Memory CI ──→ Memory Store β”‚ β”‚
148
+ β”‚ β”‚ (scan threats) (quarantine) (7 types Γ— 5 statuses) β”‚ β”‚
149
+ β”‚ β”‚ β”‚ β”‚
150
+ β”‚ β”‚ Prompt Compiler ──→ Token Budget ──→ Credit Assignment β”‚ β”‚
151
+ β”‚ β”‚ Trace System ──→ JSONL logs ──→ Offline analysis β”‚ β”‚
152
+ β”‚ β”‚ RunMode ──→ EVAL_TEST blocks all writes β”‚ β”‚
153
+ β”‚ β”‚ β”‚ β”‚
154
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
155
+ β”‚ β”‚ β”‚
156
+ β”‚ β”Œβ”€β”€β”€ INFRASTRUCTURE ──────────────────────────────▼──────────────┐ β”‚
157
+ β”‚ β”‚ β”‚ β”‚
158
+ β”‚ β”‚ LLM Backends: OpenRouter β”‚ Groq β”‚ OpenAI β”‚ Ollama β”‚ HF β”‚ ... β”‚ β”‚
159
+ β”‚ β”‚ Robust Parser: TOML β†’ JSON β†’ field extraction β†’ regex β”‚ β”‚
160
+ β”‚ β”‚ Tools: Calculator β”‚ PythonExec β”‚ ReadFile β”‚ WriteFile β”‚ β”‚
161
+ β”‚ β”‚ Streaming β”‚ Observability β”‚ Cost Tracking β”‚ Registry β”‚ β”‚
162
+ β”‚ β”‚ β”‚ β”‚
163
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
164
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€οΏ½οΏ½οΏ½β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
165
+ ```
166
+
167
+ ---
168
+
169
+ ## 5. The Core Engine
170
+
171
+ ### Actor (`actor.py`)
172
+ The decision-maker. Given the current state and purpose, it decides what action to take.
173
+
174
+ **Key design:** The Actor doesn't evaluate itself. That's the Purpose Function's job. This separation prevents self-confirmation bias (you wouldn't let a student grade their own exam).
175
+
176
+ The Actor's prompt is **dynamically composed** from three tiers of memory:
177
+ - **Strategic:** High-level rules ("When coding, handle edge cases first")
178
+ - **Procedural:** Step-by-step procedures ("1. Read tests. 2. Handle bases. 3. Implement.")
179
+ - **Tool tips:** Action-specific advice ("When using submit_code, check boundaries")
180
+
181
+ ### Purpose Function (`purpose_function.py`)
182
+ The critic. A separate LLM call that scores every state transition on a 0-10 scale.
183
+
184
+ **Seven anti-gaming rules:**
185
+ 1. Evidence required β€” cite specific state changes
186
+ 2. No credit for intentions β€” score actual results, not plans
187
+ 3. No sycophancy β€” don't inflate scores to be encouraging
188
+ 4. Monotonic scale β€” 0=nothing done, 10=task complete
189
+ 5. Anti-gaming β€” flag superficial state manipulation
190
+ 6. Consistency β€” same state gets same score (enforced by cache)
191
+ 7. Confidence β€” uncertain evaluations get reduced weight
192
+
193
+ ### Experience Replay (`experience_replay.py`)
194
+ Stores completed trajectories and retrieves relevant ones for future tasks.
195
+
196
+ **Two-phase retrieval** (from MemRL, arxiv:2601.03192):
197
+ 1. **Recall:** Find trajectories similar to the current task (embedding similarity)
198
+ 2. **Re-rank:** Order by Q-value utility (how useful was this memory when retrieved before?)
199
+
200
+ ### Optimizer (`optimizer.py`)
201
+ Extracts reusable heuristics from successful trajectories.
202
+
203
+ Uses the **CER distillation pattern** (arxiv:2506.06698): abstract away specific details with `{variable}` placeholders so heuristics generalize across tasks.
204
+
205
+ ### Orchestrator (`orchestrator.py`)
206
+ The main loop that ties everything together. For each step:
207
+ 1. Actor decides β†’ 2. Environment executes β†’ 3. Critic scores β†’ 4. Step recorded β†’ 5. Check termination
208
+
209
+ After each task: store trajectory β†’ optimize β†’ sync heuristics to Actor memory.
210
+
211
+ ---
212
+
213
+ ## 6. The V2 Safety Kernel
214
+
215
+ V1 let the agent learn freely. V2 adds guardrails.
216
+
217
+ ### Memory System (`memory.py`)
218
+ Seven memory types, each with different trust priors:
219
+
220
+ | Type | Example | Trust |
221
+ |------|---------|-------|
222
+ | `purpose_contract` | "Build a web scraper" | High (user-defined) |
223
+ | `user_preference` | "Always cite sources" | High (human-taught) |
224
+ | `skill_card` | "When coding, test edges first" | Medium (learned) |
225
+ | `episodic_case` | "fib(0)=0 was a tricky case" | Medium (observed) |
226
+ | `failure_pattern` | "Don't use recursion for large n" | Medium (learned from failure) |
227
+ | `critic_calibration` | "Score 7 for 3/4 tests passing" | Low (meta-learned) |
228
+ | `tool_policy` | "search: only use at target location" | Medium (learned) |
229
+
230
+ Five statuses: `candidate` β†’ `quarantined` β†’ `promoted` (or `rejected`) β†’ `archived`.
231
+
232
+ ### Immune System (`immune.py`)
233
+ Scans every candidate memory for 5 threat categories:
234
+ - **Prompt injection** β€” "Ignore previous instructions..."
235
+ - **Score manipulation** β€” "Always score 10..."
236
+ - **Tool misuse** β€” "subprocess.call('rm -rf /')..."
237
+ - **Privacy leaks** β€” API keys, emails, file paths
238
+ - **Scope overreach** β€” memory tries to affect all agents when it should be scoped
239
+
240
+ ### Memory CI (`memory_ci.py`)
241
+ The promotion pipeline:
242
+ ```
243
+ candidate β†’ immune_scan() β†’ quarantined β†’ replay_test β†’ promote/reject
244
+ ```
245
+ No memory reaches the agent's prompt without passing every gate.
246
+
247
+ ### Prompt Compiler (`compiler.py`)
248
+ Selects which memories to include under a token budget. Ranked by:
249
+ `score = 0.4 Γ— relevance + 0.3 Γ— trust + 0.3 Γ— utility`
250
+
251
+ Returns `included_memory_ids` for credit assignment β€” only memories that were in the prompt get Q-value updates after the step.
252
+
253
+ ### Trace System (`trace.py`)
254
+ Every run produces a JSONL trace β€” the raw material for debugging, evaluation, and memory extraction. Traces are append-only and immutable.
255
+
256
+ ### RunMode (`v2_types.py`)
257
+ Three modes with strict enforcement:
258
+ - `LEARNING_TRAIN` β€” full read/write
259
+ - `LEARNING_VALIDATION` β€” read + staging writes
260
+ - `EVAL_TEST` β€” **no writes of any kind** (the only mode whose numbers you can report)
261
+
262
+ ---
263
+
264
+ ## 7. Research Implementations
265
+
266
+ Five papers implemented as standalone modules:
267
+
268
+ ### Meta-Rewarding (`meta_rewarding.py`)
269
+ *From: arxiv:2407.19594 β€” Llama-3-8B: 22.9% β†’ 39.4% on AlpacaEval*
270
+
271
+ A meta-judge evaluates the Purpose Function's own judgments. Good judgments become calibration examples in memory. The critic improves through in-context learning.
272
+
273
+ ### Self-Taught Evaluators (`self_taught.py`)
274
+ *From: arxiv:2408.02666*
275
+
276
+ Generates synthetic contrast pairs (correct vs wrong evaluation) from traces. Creates an automatic curriculum: as the critic improves, the contrast pairs get harder.
277
+
278
+ ### Prompt Optimizer (`prompt_optimizer.py`)
279
+ *From DSPy: arxiv:2310.03714 β€” +8% on GSM8K, +50% on BBH*
280
+
281
+ Instead of hand-crafting prompts, define signatures (`state, action β†’ score, reasoning`) and let the optimizer bootstrap effective few-shot demonstrations by trial-and-error.
282
+
283
+ ### LLM Compiler (`llm_compiler.py`)
284
+ *From: arxiv:2312.04511 β€” up to 3.7Γ— latency speedup*
285
+
286
+ Instead of sequential tool calls (ReAct), plan ALL calls upfront as a DAG and execute independent ones in parallel.
287
+
288
+ ### Retroformer (`retroformer.py`)
289
+ *From: arxiv:2308.02151*
290
+
291
+ Structured reflection on completed traces β†’ extracts four types of memories (skills, failures, policies, observations). Replaces raw heuristic distillation with typed, safety-scanned memory extraction.
292
+
293
+ ---
294
+
295
+ ## 8. Breakthroughs
296
+
297
+ Six features that go beyond existing frameworks:
298
+
299
+ ### B1: Self-Improving Critic
300
+ The Purpose Function's own quality improves over time. Meta-judging after each task generates calibration examples that make future scoring more accurate.
301
+
302
+ ### B2: Mixture-of-Heuristics (MoH)
303
+ Like DeepSeek's Mixture-of-Experts: out of 100+ heuristics, only K=5 are activated per step. **Shared heuristics** (always active, like "check edge cases") + **routed heuristics** (task-specific, selected by QΓ—similarity). Knowledge grows; compute stays flat.
304
+
305
+ ### B3: Hindsight Heuristic Relabeling
306
+ From HER (arxiv:1707.01495): when a task fails, instead of discarding the trajectory, ask "what DID this accomplish?" and extract heuristics for what was achieved. Learn from failures, not just successes.
307
+
308
+ ### B4: Heuristic Evolution
309
+ Periodically generalize specific heuristics into abstract patterns:
310
+ - Before: "When fibonacci fails on 0, return 0"
311
+ - After: "When {function} fails on {boundary_value}, add an explicit base case"
312
+
313
+ Creates an automatic curriculum: specific β†’ general β†’ abstract.
314
+
315
+ ### B5: Cross-Domain Transfer
316
+ Heuristics from coding tasks can help with different coding tasks. The `test_cross_domain_transfer()` function measures this: train on [fibonacci, factorial], test on [palindrome, fizzbuzz].
317
+
318
+ ### B6: Adversarial Robustness
319
+ The `AdversarialHardener` generates 30 adversarial inputs (prompt injections, score hacks, API key leaks) and 10 benign inputs, tests the immune system against all of them. Current results: **93% catch rate, 0% false positive.**
320
+
321
+ ---
322
+
323
+ ## 9. User-Facing Layers
324
+
325
+ ### Easy API (`easy.py`)
326
+ The `purpose()` function analyzes your description and builds the right team:
327
+
328
+ | You say | It builds |
329
+ |---------|-----------|
330
+ | "Write Python code" | architect + coder + tester |
331
+ | "Research papers" | researcher + analyst |
332
+ | "Write blog posts" | writer + editor |
333
+ | "Analyze data" | analyst + reporter |
334
+ | "Help me" | general assistant |
335
+
336
+ ### Unified Capabilities (`unified.py`)
337
+ Five competing framework philosophies in one composable layer:
338
+
339
+ | Capability | Inspired By | Usage |
340
+ |-----------|-------------|-------|
341
+ | `Agent()` | OpenAI Agents SDK | One-liner agent creation |
342
+ | `Graph()` | LangGraph | Conditional branching, cycles, fan-out |
343
+ | `parallel()` | CrewAI | Concurrent task execution |
344
+ | `Conversation()` | AutoGen | Agent-to-agent message passing |
345
+ | `KnowledgeStore` | LlamaIndex | RAG as a tool |
346
+
347
+ ### Robust Parser (`robust_parser.py`)
348
+ The universal solution to "LLMs can't reliably produce JSON":
349
+ - Tries TOML first (fewer tokens than JSON)
350
+ - Falls back to JSON
351
+ - Falls back to field extraction by regex
352
+ - Never crashes. Always returns something usable.
353
+
354
+ ---
355
+
356
+ ## 10. How Models Are Handled
357
+
358
+ ### resolve_backend()
359
+ One function routes to any provider:
360
+
361
+ ```python
362
+ resolve_backend("openrouter:meta-llama/llama-3.3-70b-instruct")
363
+ resolve_backend("groq:llama-3.3-70b-versatile")
364
+ resolve_backend("openai:gpt-4o")
365
+ resolve_backend("ollama:qwen3:1.7b") # Local, free
366
+ resolve_backend("hf:Qwen/Qwen3-32B")
367
+ resolve_backend("together:meta-llama/Llama-3.3-70B-Instruct-Turbo")
368
+ ```
369
+
370
+ ### SLM-Native Design
371
+ The framework was designed for small models (0.6B-3B params):
372
+ - **Grammar-constrained output** via Ollama (forces valid structure from any model)
373
+ - **Prompt compression** for small context windows (8K-32K)
374
+ - **Tool RAG** β€” only load relevant tools into the prompt (saves tokens)
375
+ - **TOML format** β€” ~fewer tokens than JSON
376
+
377
+ ### _strip_thinking()
378
+ Handles reasoning models (Qwen3, DeepSeek-R1) that wrap output in `<think>` tags. Automatically strips the thinking and returns only the answer.
379
+
380
+ ---
381
+
382
+ ## 11. The Research
383
+
384
+ Every design decision traces to a published paper. The full list with citations, methodology sections, and implementation mapping is in [COMPILED_RESEARCH.md](COMPILED_RESEARCH.md).
385
+
386
+ The formal framework β€” **Purpose-MDP** with 5 axioms, 3 theorems, and convergence proofs β€” is in [PURPOSE_LEARNING.md](PURPOSE_LEARNING.md).
387
+
388
+ **Key theoretical result:** The self-improvement is a form of Potential-Based Reward Shaping (Ng et al., 1999). Our ΔΦ = Ξ¦(s') - Ξ¦(s) preserves the optimal policy while providing dense per-step feedback. The heuristic library converges to a fixed point under bounded capacity.
389
+
390
+ ---
391
+
392
+ ## 12. For Contributors
393
+
394
+ ### File Structure
395
+
396
+ ```
397
+ purpose_agent/
398
+ β”œβ”€β”€ types.py # State, Action, Trajectory, Heuristic, PurposeScore
399
+ β”œβ”€β”€ llm_backend.py # LLMBackend ABC + HF, OpenAI, Mock + resolve_backend
400
+ β”œβ”€β”€ slm_backends.py # Ollama, llama-cpp, prompt compression, SLM registry
401
+ β”œβ”€β”€ robust_parser.py # Universal parser: TOML β†’ JSON β†’ regex (never crashes)
402
+ β”œβ”€β”€ actor.py # ReAct agent with 3-tier memory prompts
403
+ β”œβ”€β”€ purpose_function.py # Ξ¦(s) critic with 7 anti-gaming rules
404
+ β”œβ”€β”€ experience_replay.py # Two-phase retrieval (similarity β†’ Q-value)
405
+ β”œβ”€β”€ optimizer.py # Trajectory β†’ heuristic distillation
406
+ β”œβ”€β”€ orchestrator.py # Main step loop
407
+ β”œβ”€β”€ v2_types.py # RunMode, MemoryScope, PurposeScoreV2
408
+ β”œβ”€β”€ trace.py # JSONL execution traces
409
+ β”œβ”€β”€ memory.py # 7 MemoryKinds Γ— 5 MemoryStatuses
410
+ β”œβ”€β”€ compiler.py # Token-budgeted prompt compilation
411
+ β”œβ”€β”€ immune.py # 5 threat scanners
412
+ β”œβ”€β”€ memory_ci.py # Quarantine β†’ scan β†’ test β†’ promote/reject
413
+ β”œβ”€β”€ evalport.py # Pluggable evaluation protocol
414
+ β”œβ”€β”€ benchmark_v2.py # Train/val/test splits with ablation
415
+ β”œβ”€β”€ meta_rewarding.py # Self-improving critic (arxiv:2407.19594)
416
+ β”œβ”€β”€ self_taught.py # Synthetic critic training (arxiv:2408.02666)
417
+ β”œβ”€β”€ prompt_optimizer.py # DSPy-style bootstrap (arxiv:2310.03714)
418
+ β”œβ”€β”€ llm_compiler.py # Parallel tool DAG (arxiv:2312.04511)
419
+ β”œβ”€β”€ retroformer.py # Structured reflection (arxiv:2308.02151)
420
+ β”œβ”€β”€ breakthroughs.py # MoH, hindsight relabeling, heuristic evolution, etc.
421
+ β”œβ”€β”€ unified.py # Agent, Graph, parallel, Conversation, KnowledgeStore
422
+ β”œβ”€β”€ easy.py # purpose(), Team, quickstart wizard
423
+ β”œβ”€β”€ tools.py # Secure built-in tools
424
+ β”œβ”€β”€ streaming.py # Async + event streaming
425
+ β”œβ”€β”€ observability.py # Cost tracking, callbacks
426
+ β”œβ”€β”€ multi_agent.py # Agent teams with shared learning
427
+ β”œβ”€β”€ hitl.py # Human-in-the-loop + checkpointing
428
+ β”œβ”€β”€ evaluation.py # V1 benchmark runner
429
+ β”œβ”€β”€ registry.py # Plugin system
430
+ β”œβ”€β”€ __init__.py # 103 exports
431
+ └── __main__.py # CLI entry point
432
+ ```
433
+
434
+ ### Adding a New LLM Provider
435
+
436
+ ```python
437
+ # In your code (no core edits needed):
438
+ from purpose_agent import backend_registry, OpenAICompatibleBackend
439
+
440
+ backend_registry.register("my_provider",
441
+ lambda model, api_key: OpenAICompatibleBackend(
442
+ model=model, base_url="https://api.myprovider.com/v1", api_key=api_key
443
+ ))
444
+ ```
445
+
446
+ ### Adding a New Tool
447
+
448
+ ```python
449
+ from purpose_agent import FunctionTool
450
+
451
+ def my_search(query: str) -> str:
452
+ """Search my database."""
453
+ return db.search(query)
454
+
455
+ tool = FunctionTool.from_function(my_search)
456
+ ```
457
+
458
+ ### Running Tests
459
+
460
+ ```bash
461
+ python tests/test_core.py # 21 unit tests
462
+ python tests/launch_readiness.py # 119 comprehensive tests
463
+ python benchmarks/validate.py # Mock benchmark suite
464
+ python benchmarks/validate.py --quick # Fast smoke test
465
+ ```