Proposer-Solver-Evaluator Pattern
Problem
How do you build a knowledge base through self-directed learning? Traditional approaches require manual curation, but we want a system that can:
- Generate its own learning challenges
- Attempt to solve them using available resources
- Evaluate its own performance
- Adapt difficulty based on results
Solution
Implement a four-component co-evolution loop:
┌──────────────┐ Challenge ┌──────────────┐
│ PROPOSER │ ────────────→ │ SOLVER │
│ │ │ │
└──────────────┘ ←──────────────└──────────────┘
│ Answer │
│ ↓
│ ┌──────────────┐
│ │ KNOWLEDGE │
│ │ SOURCE │
│ └──────────────┘
│ │
└────────────┬──────────────────┘
↓
┌──────────────┐
│ EVALUATOR │
└──────────────┘
│
↓
┌──────────────┐
│ CURRICULUM │
└──────────────┘
Components
Proposer: Generates challenges of varying types and difficulties
- Tracks which challenge types cause struggle
- Adapts generation based on curriculum feedback
- Can use templates or AI generation
Solver: Attempts to answer using RAG against knowledge source
- Query extraction from challenge
- Retrieval from local/offline sources
- Answer generation with citations
- Self-assessed confidence
Evaluator: Multi-dimensional scoring
- Domain-specific metrics (accuracy, correctness, clarity)
- Weighted combination for overall score
- Human-readable feedback generation
Curriculum Manager: Controls difficulty progression
- Promotion when recent average exceeds threshold
- Demotion when performance drops
- Minimum iterations at each level before changes
Usage
TypeScript Interfaces
interface Challenge {
id: string;
text: string;
type: ChallengeType;
difficulty: DifficultyLevel;
topics: string[];
expectedAspects?: string[];
}
interface Answer {
challengeId: string;
text: string;
confidence: number;
sources: SourceCitation[];
reasoning?: string;
}
interface EvaluationResult {
challengeId: string;
scores: Record<string, number>;
overall: number;
feedback: string;
}
interface CurriculumState {
currentDifficulty: DifficultyLevel;
iterationsAtLevel: number;
recentScores: number[];
promotionThreshold: number;
demotionThreshold: number;
}Evolution Loop
async function runIteration(state: CurriculumState): Promise<CurriculumState> {
// 1. Generate challenges at current difficulty
const challenges = await proposer.generate(state.currentDifficulty, CHALLENGES_PER_ITERATION);
// 2. Solve each challenge
const answers = await Promise.all(challenges.map((c) => solver.solve(c)));
// 3. Evaluate each answer
const evaluations = await Promise.all(
answers.map((a, i) => evaluator.evaluate(challenges[i], a))
);
// 4. Update curriculum
const avgScore = evaluations.reduce((sum, e) => sum + e.overall, 0) / evaluations.length;
return curriculum.update(state, avgScore);
}Curriculum Adaptation
function updateCurriculum(state: CurriculumState, score: number): CurriculumState {
const newScores = [...state.recentScores.slice(-9), score];
const avgRecent = newScores.reduce((a, b) => a + b) / newScores.length;
let newDifficulty = state.currentDifficulty;
let newIterations = state.iterationsAtLevel + 1;
if (newIterations >= 3) {
if (avgRecent >= state.promotionThreshold) {
newDifficulty = promoteDifficulty(state.currentDifficulty);
newIterations = 0;
} else if (avgRecent <= state.demotionThreshold) {
newDifficulty = demoteDifficulty(state.currentDifficulty);
newIterations = 0;
}
}
return {
...state,
currentDifficulty: newDifficulty,
iterationsAtLevel: newIterations,
recentScores: newScores,
};
}Examples
Dr. Zero Local (Wikipedia Q&A)
- Knowledge Source: Wikipedia via Kiwix (offline)
- Challenge Types: Factual, Comparative, Causal, Temporal, Multi-hop
- Evaluation: Accuracy (50%), Completeness (30%), Relevance (20%)
- Status: 10 iterations completed, calibrating retrieval
JP Code Academy (Coding Encyclopedia)
- Knowledge Source: freeCodeCamp, language docs (offline)
- Challenge Types: Conceptual, Comparison, Implementation, Debugging, Refactoring, Best Practice
- Evaluation: Correctness (40%), Completeness (30%), Clarity (20%), Best Practices (10%)
- Status: POC scaffolding complete
Trade-offs
Advantages
- Self-directed learning without manual curation
- Automatic difficulty adaptation
- Checkpoint/resume capability
- Structured knowledge output
- Works with local/offline resources
Challenges
- Requires quality offline resources
- Calibration period to tune thresholds
- Evaluation metrics need domain tuning
- RAG retrieval quality critical to success
When to Use
- Building domain-specific knowledge bases
- Testing LLM capabilities systematically
- Creating structured learning progressions
- Generating training/evaluation datasets
When Not to Use
- Real-time applications (loop is iterative)
- When ground truth is unavailable
- Domains without retrievable sources
Source
Validated through Dr. Zero Local POC (10 iterations, 100 questions).
Inspired by Meta’s Dr. Zero paper on self-evolving reasoning models.
Related
- Dr. Zero Local - Primary validation project
- JP Code Academy - Coding domain application