Local (CPU) Prompt-Level Co-Evolution¶
EVOSEAL's original Phase 3 co-evolution improves a coding model by fine-tuning its
weights (LoRA/QLoRA) from evolution data — a path that needs a CUDA GPU. On a
CPU-only host that path is impractical, and a cloud model (e.g. the main agent)
has no local weights to tune at all.
This document describes the CPU-feasible substitute implemented in
evoseal/prompt_evolution/: the agents co-evolve at the prompt level instead of
the weight level. Two local Ollama models take distinct roles, and the reviewer's
feedback is distilled into edits of the coder's system prompt. No GPU required.
Roles and models¶
Models are discovered from what is installed in Ollama and matched by family
(evoseal/providers/local_models.py), so a re-quantized or renamed tag keeps working.
| Role | Default family | Job |
|---|---|---|
coder |
DeepSeek-Coder-V2-Lite | Writes code for a task |
reviewer |
Qwen2.5-Coder | Critiques the code, scores it (0–1) |
main |
cloud model (MiMo) | Orchestrator; prompt-only improvement |
Override a role explicitly with EVOSEAL_CODER_MODEL / EVOSEAL_REVIEWER_MODEL.
The loop (one cycle)¶
sequenceDiagram
participant T as Task
participant C as Coder (DeepSeek)
participant R as Reviewer (Qwen)
participant E as PromptEvolver
participant S as PromptStore
T->>C: task + current coder prompt
C-->>R: code attempt
R-->>R: score (0–1) + issues
alt score >= accept_threshold
R-->>S: keep prompt (no change)
else score below threshold
R->>E: task, code, critique
E-->>E: rewrite coder prompt (guardrails)
E->>C: re-run task with candidate prompt
C-->>R: new code attempt
R-->>R: new score
alt new score >= old + min_gain
E->>S: register new prompt version (active)
else no improvement
E->>S: discard candidate, keep previous (rollback)
end
end
Implemented by CoevolutionManager.run_cycle (coevolution_manager.py):
- generate — coder writes code using its active system prompt.
- review — reviewer returns issues and a
SCORE: X/10(normalized to 0–1). - evolve — if the score is below
accept_threshold, the reviewer model rewrites the coder's system prompt to address the issues. - validate — the task is re-run with the candidate prompt; the new prompt is
accepted only if the score improves by at least
min_score_gain, otherwise it is discarded and the previous prompt stays active.
Divergence prevention / "definition of improvement"¶
This mirrors EVOSEAL's "validate or roll back" safety premise so the self-editing loop cannot silently corrupt itself:
- Guardrails on every edit (
PromptEvolver._validate): the candidate must be non-empty, within length bounds, differ from the current prompt, and retain all protected markers (e.g. theROLE: coderheader). A markerless model response is only accepted via fallback extraction when it still carries those markers, so a plain critique cannot masquerade as a prompt. - Regression gate: "improvement" is defined concretely as a measured reviewer-score
gain of at least
min_score_gainon the same task re-run with the candidate prompt. No gain → rollback. - Versioned lineage (
PromptStore): every accepted prompt is a new version with aparent_id; rollback is a pointer move, never a destructive delete.
Usage¶
import asyncio
from evoseal.prompt_evolution import CoevolutionManager, TaskSpec
async def main():
mgr = CoevolutionManager() # discovers coder+reviewer models from Ollama
task = TaskSpec(id="demo", description="Write median(nums) for a list of numbers")
result = await mgr.run_cycle(task)
print(result.reason, result.score_before, "->", result.score_after)
asyncio.run(main())
Prompt versions persist under data/prompt_evolution/<role>/ (registry + one .md
per version), so improvements survive restarts and can be inspected or rolled back.
Relationship to the GPU path¶
The weight-fine-tuning path (evoseal/fine_tuning/, ModelFineTuner,
BidirectionalEvolutionManager) targets a discovered coding model and remains the
option for GPU hosts (a deprecated DevstralFineTuner alias is kept for compatibility).
The two paths share the same premise — collect signal from evolution, improve the
model, validate, and roll back on regression — but operate on different surfaces
(prompt text vs. model weights).