TL;DR
EFRE is a way to maintain a prompt that keeps getting reworked. Instead of one prompt, you keep a set of instructions (a "repertoire"). Every edit is first tested on old examples. If the edit breaks nothing, it goes into the existing instruction. If it does break something, a new instruction is created for it. Before answering, a separate step (the selector) picks which instruction fits the request.
The main finding: a prompt that gets rewritten again and again for new tasks starts forgetting the old ones. You fix the answers about returns, and suddenly the assistant gets worse at shipping questions. The second problem: the prompt piles up one-off rules for specific cases instead of general principles. After edits like these, accuracy on the earlier task dropped by 25 points in the experiments. The reason is simple: every edit is checked only on the current examples. Nobody looks at the old ones.
The method adds two mechanisms. First: an edit is accepted only if quality on the most recent examples this instruction already solved drops by no more than 10%. Second: if the edit fails the check, it gets tried on the other instructions in the set, and only then is a new one created. With this, forgetting fell from 25 to 1.5 points.
Want this for your own case? Apply this study to your task: AI adapts its method to what you are working on and writes the prompt.
Method Blueprint
STEP 1: Run the current instruction on new examples → collect errors/feedback
STEP 2: An editor model proposes an edit to the instruction → candidate
STEP 3: Is the candidate better on the new examples (training and validation)? No → discard
STEP 4: Does the candidate keep ≥90% of quality on this instruction's old examples?
Yes → REFINEMENT: replace the instruction
No → STEP 5
STEP 5: Try the same edit on the other instructions in the set, one by one
One of them fits → REUSE: update it
None fit → EMERGENCE: create a new instruction
INFERENCE: the selector reads the request + the list of instructions → picks one → the model answers
In the paper this is an automated loop in code. You can walk through the same steps by hand or semi-automatically, see the template below.
Example in Practice
Task: You run an AI support assistant for Amazon sellers. At first it answered questions about returns. Then FBA logistics rules were added to the same system prompt. Then rules for disputing fees and penalties. The prompt has ballooned to 3,000 words, and every edit breaks something old.
Prompt:
You are the editor of an instruction set for a support assistant serving Amazon sellers.
Current instruction f1 ("Returns"):
"Identify the reason for the return, check it against the policy, reply politely, state the deadlines."
History of f1 (last 5 of 20 successful cases):
1. "The customer returned the item and the money was taken from me" → answer accepted
2. "Defective item returned, how do I file a claim?" → answer accepted
3. "What's the return window for merchant-fulfilled orders?" → answer accepted
4. "The customer sent back the wrong item" → answer accepted
5. "Return after 30 days" → answer accepted
New cases where f1 gets it wrong:
— "My shipment is stuck at the PHX7 fulfillment center, the inbound wasn't received"
— "Why was my shipment to the Dallas warehouse rejected?"
Feedback: the assistant answers with the returns template even though the question is about inbound shipment receiving.
Do the following:
1. Propose an edit to f1 that solves the new cases.
2. Consistency check: for each of the 5 history examples, judge whether answer
quality would hold with the new version of f1 (yes/no + why). The allowed drop is no more than 10%.
3. If the drop is under 10%, output the updated f1.
4. If it is more, do not edit f1. Output a new instruction f2 ("Logistics and inbound shipments")
and a one-line description of when to choose it.
5. Output the final repertoire: the list of instructions with descriptions.
Result: The model will show the edit and a point-by-point check of each old example. Then it gives a decision: update f1 or create f2. At the end you get an updated list of instructions with short descriptions for the selector. This is a simulated check in chat. It is more reliable to run the old examples through the real assistant.
Why It Works
The weakness. A prompt edit is checked only on whatever you are fixing right now. Nobody looks at what happened to the old stuff. Meanwhile, the editor model loves to patch holes with one-off rules ("if the question is about PHX7, then…"). The prompt accumulates these patches and has no general principles. New requirements eventually don't fit.
The strength. Models are good at two things: rewriting an instruction based on an error analysis, and picking the right one from a short list by its description. Both are pure text operations. The first produces the edit, the second replaces the rigid "one task, one prompt" binding.
How the method uses this. Old examples act as a regression test, not as memory. If an edit fails that test, it conflicts with what the instruction already knows how to do. So it moves into a new instruction and the old one stays untouched. The needed skills separate on their own, without manually sorting things by task.
Control knobs: - Tolerance ε (share of allowed drop on the history). 0 means strict protection, and learning new things slows down. 1 means no protection, and forgetting grows. The best value in the paper is 0.1. - History size. The last 20 examples worked better than 50. A long history makes the check too conservative. - How the instruction is chosen. Model selection by description beats "always the first one", random choice and embedding search. There is still a gap to the ideal "try them all and take the best". - Set limit. The paper caps it at 50 functions. Once the cap is reached, rejected edits are thrown away.
Prompt Template
Template 1: the instruction-set editor (refinement, reuse and emergence steps).
<Role>
You are the editor of an instruction set (repertoire) for {assistant_type}.
You do not answer user requests. You edit instructions.
</Role>
<Repertoire>
f1: {instruction_text_1} — choose when: {condition_1}
f2: {instruction_text_2} — choose when: {condition_2}
</Repertoire>
<History>
History of f1 (up to {H} successful cases): {f1_cases}
History of f2 (up to {H} successful cases): {f2_cases}
</History>
<NewCases>
Cases where the current instruction {fk} gets it wrong: {new_cases}
Feedback: {what_went_wrong}
</NewCases>
<Logic>
1. Propose an edit to {fk} that fixes the new cases.
Edit with a general principle, not a patch for one specific case.
2. Consistency check: for each case in {fk}'s history,
judge whether answer quality holds (yes/no + reason).
If the drop exceeds {ε}%, the edit fails.
3. If the edit passes → REFINEMENT: output the updated {fk}.
4. If it fails → REUSE: try the same edit on the other instructions
in the set, one by one. For each, run step 2 against its history.
The first one that fits gets updated.
5. If none fit → EMERGENCE: create a new instruction
and its selection condition. Leave the old ones alone.
6. Output the final repertoire and a list of changes.
</Logic>
Template 2: the selector (in the paper it runs on fixed instructions, and the function set is plugged in).
You are a selector. Read the request and the list of instructions with their selection conditions.
Choose one instruction. Output only its number.
Instructions:
{repertoire_with_conditions}
Request: {user_request}
What to fill in:
- {assistant_type}: the role of your assistant or agent.
- {cases}: real requests the instruction handled well (the last 20).
- {ε}: the allowed drop, 10 by default.
- {new_cases}: fresh failures with a description of what went wrong.
🚀 Quick start: paste into the chat:
Here is a template for an EFRE editor and selector. Adapt it to my task: [your task].
Ask me questions to fill in the fields.
[paste the template above]
The LLM will ask what instructions or skills you have right now, which cases they handle well and where they fail. It needs this because the history of old examples and the error descriptions are exactly the material the method uses to check edits. It will take the structure from the template and assemble a working set for your assistant.
Limitations
⚠️ You need runs and a metric: in the paper, every edit is checked by an automated loop on benchmarks with verifiable answers. In chat you only get the model's estimate, not a real check. For reliability, run the old cases through the actual assistant.
⚠️ Tested on narrow tasks: the tests covered tool calling, financial questions and biology, all with unambiguous scoring. The method was not tested on creative and subjective tasks where the "right answer" isn't obvious.
⚠️ Small models and benchmarks: the base is one small open model and two current frontier models. Whether it transfers to your production scenario needs to be checked.
⚠️ The selector is the weak spot: model-based selection falls noticeably short of ideal selection (where every instruction is tried). Poor descriptions of selection conditions are the main source of misses.
⚠️ Neither too strict nor too loose: zero tolerance slows learning. No tolerance limit at all leads to forgetting. You need a balance, and you'll have to tune it.
⚠️ Set limit and incomplete data: the paper allows no more than 50 functions, and some tables and appendices in the provided text are cut off, so exact final numbers for individual tasks are not given here.
How They Studied It
The idea was simple: take three tasks in a row (tool calling → FinQA financial questions → SciKE-Bio biology) and see what survives after each one. This mimics the life of a production assistant that keeps getting adapted to new tasks. They compared against model training (GRPO, SFT and others) and against off-the-shelf automatic prompt-improvement methods (GEPA, ACE). The base models were Qwen3-8B and GPT-5.6-Luna, and the experiments were repeated three times.
The main result: after adapting to biology, accuracy on FinQA dropped by only 1.56 points, versus 25.10 for GEPA and 9.43 for ACE. On the overall average, the method beat GRPO by 7.5 points. The most interesting part of the ablations: strict protection of the past (ε=0) turned out worse than moderate protection (ε=0.1). On Bio the gain was +11.46 versus +19.52. And a history of 50 examples was no better than 20.
In the agentic test on six tasks, the method scored an average of 18.0 on Qwen3-8B, while plain in-prompt examples and GEPA scored −3.5 and 9.5. On GPT-5.6-Luna it was 36.3 versus 22.2 and 29.5. The method doesn't just create "one prompt per task": some functions are specialized, some are general. The practical takeaway: making edits without checking against the old leads to forgetting, and splitting into several instructions with a selection condition solves this.
Adaptations and Extrapolations
These are my own ideas, not part of the paper's method.
🔧 Technique: apply it to an agent's instruction file → a set of skills instead of one CLAUDE.md
If your instruction file keeps growing and edits for one type of task spoil another, split them into separate skills. Add a short "selector" at the top of the file:
Before starting, choose one skill based on the task description:
- skill_bugfix — when you need to fix a specific bug
- skill_refactor — when you need to change structure without changing behavior
- skill_docs — when you need to write or update documentation
🔧 Technique: ε in the prompt → state the allowed drop explicitly
Add this to your request to the editor: "The edit is unacceptable if even 2 of the 20 old cases get worse." That way you set the threshold by hand.
Resources
- "From a Prompt to Repertoires: Evolving Functional REpertoires Enable LLM Continual Learning" — preprint.
- Authors: Fengyuan Liu, Yue Wang, Hangxi Guo, Fengyuan Liu, Chenxu Wu, Yanguang Liu, Mengnan Du (corresponding author).
- Affiliations: The Chinese University of Hong Kong (Shenzhen), Shanghai AI Laboratory, University of Science and Technology of China, New Jersey Institute of Technology.
- Baseline methods mentioned: GEPA (Agrawal et al., 2026), ACE (Zhang et al., 2026), GRPO (Shao et al., 2024).