Skip to content

Commit 2dfb167

Browse files
committed
Add inspirations section to prompt evolution history
Introduces an 'inspirations' parameter to PromptSampler and updates the evolution history formatting to include a new inspirations section. Adds logic for formatting, categorizing, and describing inspiration programs, and extends the templates to support this new section. This enhances prompt diversity and creativity by surfacing diverse and creative program examples.
1 parent 9cd0b69 commit 2dfb167

File tree

2 files changed

+164
-2
lines changed

2 files changed

+164
-2
lines changed

openevolve/prompt/sampler.py

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def build_prompt(
5151
program_metrics: Dict[str, float] = {},
5252
previous_programs: List[Dict[str, Any]] = [],
5353
top_programs: List[Dict[str, Any]] = [],
54+
inspirations: List[Dict[str, Any]] = [], # Add inspirations parameter
5455
language: str = "python",
5556
evolution_round: int = 0,
5657
diff_based_evolution: bool = True,
@@ -66,7 +67,8 @@ def build_prompt(
6667
parent_program: Parent program from which current was derived
6768
program_metrics: Dictionary of metric names to values
6869
previous_programs: List of previous program attempts
69-
top_programs: List of top-performing programs
70+
top_programs: List of top-performing programs (best by fitness)
71+
inspirations: List of inspiration programs (diverse/creative examples)
7072
language: Programming language
7173
evolution_round: Current evolution round
7274
diff_based_evolution: Whether to use diff-based evolution (True) or full rewrites (False)
@@ -110,7 +112,7 @@ def build_prompt(
110112

111113
# Format evolution history
112114
evolution_history = self._format_evolution_history(
113-
previous_programs, top_programs, language
115+
previous_programs, top_programs, inspirations, language
114116
)
115117

116118
# Format artifacts section if enabled and available
@@ -227,6 +229,7 @@ def _format_evolution_history(
227229
self,
228230
previous_programs: List[Dict[str, Any]],
229231
top_programs: List[Dict[str, Any]],
232+
inspirations: List[Dict[str, Any]],
230233
language: str,
231234
) -> str:
232235
"""Format the evolution history for the prompt"""
@@ -391,11 +394,150 @@ def _format_evolution_history(
391394
# Combine top and diverse programs
392395
combined_programs_str = top_programs_str + diverse_programs_str
393396

397+
# Format inspirations section
398+
inspirations_section_str = self._format_inspirations_section(inspirations, language)
399+
394400
# Combine into full history
395401
return history_template.format(
396402
previous_attempts=previous_attempts_str.strip(),
397403
top_programs=combined_programs_str.strip(),
404+
inspirations_section=inspirations_section_str,
405+
)
406+
407+
def _format_inspirations_section(
408+
self, inspirations: List[Dict[str, Any]], language: str
409+
) -> str:
410+
"""
411+
Format the inspirations section for the prompt
412+
413+
Args:
414+
inspirations: List of inspiration programs
415+
language: Programming language
416+
417+
Returns:
418+
Formatted inspirations section string
419+
"""
420+
if not inspirations:
421+
return ""
422+
423+
# Get templates
424+
inspirations_section_template = self.template_manager.get_template("inspirations_section")
425+
inspiration_program_template = self.template_manager.get_template("inspiration_program")
426+
427+
inspiration_programs_str = ""
428+
429+
for i, program in enumerate(inspirations):
430+
# Extract a snippet (first 8 lines) for display
431+
program_code = program.get("code", "")
432+
program_snippet = "\n".join(program_code.split("\n")[:8])
433+
if len(program_code.split("\n")) > 8:
434+
program_snippet += "\n# ... (truncated for brevity)"
435+
436+
# Calculate a composite score using safe numeric average
437+
score = safe_numeric_average(program.get("metrics", {}))
438+
439+
# Determine program type based on metadata and score
440+
program_type = self._determine_program_type(program)
441+
442+
# Extract unique features (emphasizing diversity rather than just performance)
443+
unique_features = self._extract_unique_features(program)
444+
445+
inspiration_programs_str += (
446+
inspiration_program_template.format(
447+
program_number=i + 1,
448+
score=f"{score:.4f}",
449+
program_type=program_type,
450+
language=language,
451+
program_snippet=program_snippet,
452+
unique_features=unique_features,
453+
)
454+
+ "\n\n"
455+
)
456+
457+
return inspirations_section_template.format(
458+
inspiration_programs=inspiration_programs_str.strip()
398459
)
460+
461+
def _determine_program_type(self, program: Dict[str, Any]) -> str:
462+
"""
463+
Determine the type/category of an inspiration program
464+
465+
Args:
466+
program: Program dictionary
467+
468+
Returns:
469+
String describing the program type
470+
"""
471+
metadata = program.get("metadata", {})
472+
score = safe_numeric_average(program.get("metrics", {}))
473+
474+
# Check metadata for explicit type markers
475+
if metadata.get("diverse", False):
476+
return "Diverse"
477+
if metadata.get("migrant", False):
478+
return "Migrant"
479+
if metadata.get("random", False):
480+
return "Random"
481+
482+
# Classify based on score ranges
483+
if score >= 0.8:
484+
return "High-Performer"
485+
elif score >= 0.6:
486+
return "Alternative"
487+
elif score >= 0.4:
488+
return "Experimental"
489+
else:
490+
return "Exploratory"
491+
492+
def _extract_unique_features(self, program: Dict[str, Any]) -> str:
493+
"""
494+
Extract unique features of an inspiration program
495+
496+
Args:
497+
program: Program dictionary
498+
499+
Returns:
500+
String describing unique aspects of the program
501+
"""
502+
features = []
503+
504+
# Extract from metadata if available
505+
metadata = program.get("metadata", {})
506+
if "changes" in metadata:
507+
changes = metadata["changes"]
508+
if isinstance(changes, str) and len(changes) < 100:
509+
features.append(f"Modification: {changes}")
510+
511+
# Analyze metrics for standout characteristics
512+
metrics = program.get("metrics", {})
513+
for metric_name, value in metrics.items():
514+
if isinstance(value, (int, float)):
515+
if value >= 0.9:
516+
features.append(f"Excellent {metric_name} ({value:.3f})")
517+
elif value <= 0.3:
518+
features.append(f"Alternative {metric_name} approach")
519+
520+
# Code-based features (simple heuristics)
521+
code = program.get("code", "")
522+
if code:
523+
code_lower = code.lower()
524+
if "class" in code_lower and "def __init__" in code_lower:
525+
features.append("Object-oriented approach")
526+
if "numpy" in code_lower or "np." in code_lower:
527+
features.append("NumPy-based implementation")
528+
if "for" in code_lower and "while" in code_lower:
529+
features.append("Mixed iteration strategies")
530+
if len(code.split("\n")) < 10:
531+
features.append("Concise implementation")
532+
elif len(code.split("\n")) > 50:
533+
features.append("Comprehensive implementation")
534+
535+
# Default if no specific features found
536+
if not features:
537+
program_type = self._determine_program_type(program)
538+
features.append(f"{program_type} approach to the problem")
539+
540+
return ", ".join(features[:3]) # Limit to top 3 features
399541

400542
def _apply_template_variations(self, template: str) -> str:
401543
"""Apply stochastic variations to the template"""

openevolve/prompt/templates.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@
9696
## Top Performing Programs
9797
9898
{top_programs}
99+
100+
{inspirations_section}
99101
"""
100102

101103
# Template for formatting a previous attempt
@@ -113,6 +115,22 @@
113115
Key features: {key_features}
114116
"""
115117

118+
# Template for formatting inspirations section
119+
INSPIRATIONS_SECTION_TEMPLATE = """## Inspiration Programs
120+
121+
These programs represent diverse approaches and creative solutions that may inspire new ideas:
122+
123+
{inspiration_programs}
124+
"""
125+
126+
# Template for formatting an individual inspiration program
127+
INSPIRATION_PROGRAM_TEMPLATE = """### Inspiration {program_number} (Score: {score}, Type: {program_type})
128+
```{language}
129+
{program_snippet}
130+
```
131+
Unique approach: {unique_features}
132+
"""
133+
116134
# Template for evaluating a program via an LLM
117135
EVALUATION_TEMPLATE = """Evaluate the following code on a scale of 0.0 to 1.0 for the following metrics:
118136
1. Readability: How easy is the code to read and understand?
@@ -144,6 +162,8 @@
144162
"evolution_history": EVOLUTION_HISTORY_TEMPLATE,
145163
"previous_attempt": PREVIOUS_ATTEMPT_TEMPLATE,
146164
"top_program": TOP_PROGRAM_TEMPLATE,
165+
"inspirations_section": INSPIRATIONS_SECTION_TEMPLATE,
166+
"inspiration_program": INSPIRATION_PROGRAM_TEMPLATE,
147167
"evaluation": EVALUATION_TEMPLATE,
148168
}
149169

0 commit comments

Comments
 (0)