Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/gepa/adapters/cepo_adapter/cepo_coding_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ def evaluate(
if not candidate:
raise ValueError("Candidate must contain at least one component text.")

# Ensure all required prompts are in candidate
required_prompts = ["cepo_planning_prompt", "cepo_execution_prompt", "cepo_reflection_prompt"]
for prompt in required_prompts:
if prompt not in candidate:
raise ValueError(f"Candidate must contain '{prompt}'")

n = len(batch)

# ---------- Phase 1: parallelize ONLY the LLM calls (cepo_simple) ----------
Expand All @@ -108,8 +114,8 @@ def _run_cepo(idx: int, data: CepoCodingDataInst) -> Tuple[int, str]:
final_output, plans, executions = cepo_simple(
system_prompt="",
planning_prompt=candidate["cepo_planning_prompt"],
execution_prompt=global_candidate["cepo_execution_prompt"],
reflection_prompt=global_candidate["cepo_reflection_prompt"],
execution_prompt=candidate["cepo_execution_prompt"],
reflection_prompt=candidate["cepo_reflection_prompt"],
question=data["question"],
client=self.client,
model=self.model,
Expand Down
6 changes: 5 additions & 1 deletion src/gepa/examples/cepo/train_cepo.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,12 @@ def reflection_lm(prompt: str):
print("Initial prompt test set score", sum(initial_test_scores) / len(initial_test_scores))

# Training and validation
candidates = {"cepo_planning_prompt": candidate["cepo_planning_prompt"],
"cepo_execution_prompt": candidate["cepo_execution_prompt"],
"cepo_reflection_prompt": candidate["cepo_reflection_prompt"]}

optimized_results = optimize(
seed_candidate={"cepo_planning_prompt": candidate["cepo_planning_prompt"]},
seed_candidate=candidates,
trainset=trainset,
valset=valset,
adapter=cepo_adapter,
Expand Down
31 changes: 22 additions & 9 deletions src/gepa/strategies/instruction_proposal.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,36 @@ class InstructionProposalSignature(Signature):

# Provide the new instructions within ``` blocks."""

prompt_template = """I provided an assistant with the following PLANNING instruction:
prompt_template = """I provided an assistant with the following {PROMPT_TYPE} instruction:
```
<curr_instructions>
```

The following are examples of different task inputs, the assistant’s responses, and feedback on how the PLANNING could be improved:
The following are examples of different task inputs, the assistant’s responses, and feedback on how the {PROMPT_TYPE} could be improved:
```
<inputs_outputs_feedback>
```

Your task is to propose a revised PLANNING instruction for the assistant.
Your task is to propose a revised {PROMPT_TYPE} instruction for the assistant.

Guidelines:
- Focus ONLY on improving the *structure and clarity of planning* (e.g., require decomposition into steps, explicit input/output contracts, consideration of boundary cases, and a self-check).
- DO NOT include any dataset-specific content, numeric constraints, input/output formats, examples, or code.
- Keep the instruction general so it can apply to many tasks.
- The revision should be concise, clear, and in natural language.
Guidelines {GUIDELINES}

Return only the new instruction inside ``` blocks."""

input_keys = ["current_instruction_doc", "dataset_with_feedback"]
input_keys = ["current_instruction_doc", "dataset_with_feedback", "prompt_type"]
output_keys = ["new_instruction"]

@classmethod
def get_guidelines(cls, prompt_type):
guidelines = {
"PLANNING": "- Focus ONLY on improving the *structure and clarity of planning* (e.g., require decomposition into steps, explicit input/output contracts, consideration of boundary cases, and a self-check).\n- DO NOT include any dataset-specific content, numeric constraints, input/output formats, examples, or code.\n- Keep the instruction general so it can apply to many tasks.\n- The revision should be concise, clear, and in natural language.",

"EXECUTION": "- Focus ONLY on improving how the assistant should *execute a plan* (e.g., methodical implementation, validation of intermediate steps, error checking).\n- Emphasize careful execution especially for steps where confidence is lower.\n- DO NOT include any dataset-specific content, numeric constraints, input/output formats, examples, or code.\n- Keep the instruction general so it can apply to many tasks.\n- The revision should be concise, clear, and in natural language.",

"REFLECTION": "- Focus ONLY on improving how the assistant should *reflect on and validate* their work (e.g., reviewing for inconsistencies, verifying solutions, refining approaches).\n- Emphasize careful review of the entire problem-solving process.\n- DO NOT include any dataset-specific content, numeric constraints, input/output formats, examples, or code.\n- Keep the instruction general so it can apply to many tasks.\n- The revision should be concise, clear, and in natural language."
}
return guidelines.get(prompt_type, guidelines["PLANNING"])

@classmethod
def prompt_renderer(cls, input_dict: dict[str, str]) -> str:
def format_samples(samples):
Expand Down Expand Up @@ -79,10 +86,16 @@ def convert_sample_to_markdown(sample, examplenum):
return s

return "\n\n".join(convert_sample_to_markdown(sample, i + 1) for i, sample in enumerate(samples))

prompt_type = input_dict.get("prompt_type", "PLANNING").upper()
guidelines = cls.get_guidelines(prompt_type)

prompt = cls.prompt_template
prompt = prompt.replace("{PROMPT_TYPE}", prompt_type)
prompt = prompt.replace("{GUIDELINES}", guidelines)
prompt = prompt.replace("<curr_instructions>", input_dict["current_instruction_doc"])
prompt = prompt.replace("<inputs_outputs_feedback>", format_samples(input_dict["dataset_with_feedback"]))

return prompt

@classmethod
Expand Down