Skip to content

fix(sew): validate refined prompts before adopting them in SEWOptimizer - #269

Open
lamost423 wants to merge 1 commit into
ANative-Lab:mainfrom
lamost423:fix/sew-refined-prompt-validation
Open

fix(sew): validate refined prompts before adopting them in SEWOptimizer#269
lamost423 wants to merge 1 commit into
ANative-Lab:mainfrom
lamost423:fix/sew-refined-prompt-validation

Conversation

@lamost423

Copy link
Copy Markdown

What happened

While running SEWOptimizer (optimize_mode="prompt", order="zero-order") on a HumanEval subset with deepseek-chat, the optimized workflow regressed from pass@1 = 0.4 to 0.1 after 3 optimization steps.

Inspecting the saved workflow showed the first node's prompt had been replaced by a verbatim echo of the optimizer's own meta-instructions:

Given the above information, please refine the instruction for the 1-th task.
Note that you should always use bracket (e.g. `{input_name}`) to wrap the inputs of the tasks in your refined instruction.
Only output the refined instruction and DON'T include any other text!

The original {question} placeholder was lost, so the node produced garbage for every downstream sample.

Root cause

SimplePromptBreeder.generate_prompt returns the LLM response verbatim, and both _wfg_prompt_optimization_step and _action_graph_prompt_optimization_step adopt it directly:

new_prompt = self._prompt_breeder.generate_prompt(...)
graph_info["tasks"][i]["prompt"] = new_prompt   # no validation

When the LLM echoes the refinement request instead of answering it (models occasionally do this with the nested mutation-prompt + meta-instruction structure), the echo silently becomes the node prompt.

Fix

Add SEWOptimizer._validate_refined_prompt, applied at both adoption sites. A refined prompt is rejected (keeping the original prompt, with a warning) when it:

  1. is empty/whitespace,
  2. echoes the refinement meta-instructions ("please refine the instruction" / "only output the refined instruction"), or
  3. drops an input placeholder (e.g. {question}) that was present in the original prompt — matching the contract the meta-prompt itself states ("always use bracket to wrap the inputs").

Tests

tests/src/optimizers/test_sew_prompt_validation.py — 7 cases covering the real-world echoed response above, empty responses, placeholder loss, legitimate refinements, and the fallback/adoption behavior of _wfg_prompt_optimization_step (via a stubbed prompt breeder, no API calls). All pass; existing test_sew_workflow_scheme.py still passes.

🤖 Generated with Claude Code

SimplePromptBreeder.generate_prompt returns the LLM response verbatim, and
SEWOptimizer adopted it as the new task/operator prompt with no validation.
When the LLM echoes the refinement meta-instructions instead of producing a
refined instruction (observed with deepseek-chat), the echoed meta-prompt
replaces the node prompt and silently corrupts the workflow: in a HumanEval
run (optimize_mode=prompt, zero-order) the first node's prompt became the
literal text 'Given the above information, please refine the instruction for
the 1-th task...', losing the {question} placeholder, and test pass@1 dropped
from 0.4 to 0.1 after 3 optimization steps.

Add _validate_refined_prompt, applied in both _wfg_prompt_optimization_step
and _action_graph_prompt_optimization_step: reject empty responses, responses
echoing the refinement meta-instructions, and responses that drop input
placeholders present in the original prompt; fall back to the original prompt
with a warning instead of adopting an invalid refinement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant