@crewhaus/prompt-optimizer-claude 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11 -1
- package/dist/index.js +31 -10
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -115,7 +115,17 @@ export declare class ClaudeMutationProvider implements MutationProvider {
|
|
|
115
115
|
next(state: OptimizerState): Promise<ProviderMutation>;
|
|
116
116
|
/** Build the user message for the meta-prompt. */
|
|
117
117
|
private buildUserMessage;
|
|
118
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* Identify the failing samples to show the model. When the fitness
|
|
120
|
+
* function supplied per-sample grades (`state.bestGrades`, wired by the
|
|
121
|
+
* CLI's eval-runner closure), we surface the samples the current best
|
|
122
|
+
* prompt ACTUALLY fails — worst-scoring first — together with the
|
|
123
|
+
* grader's rationale, so the meta-prompt can address the named root
|
|
124
|
+
* cause. This is the signal the system prompt promises. When grades are
|
|
125
|
+
* absent (a fitness fn returning a bare number, or an all-passing dev
|
|
126
|
+
* set), we fall back to surfacing the dev-set inputs with the aggregate
|
|
127
|
+
* score — the pre-failure-signal behaviour — so the search still runs.
|
|
128
|
+
*/
|
|
119
129
|
private selectFailures;
|
|
120
130
|
/**
|
|
121
131
|
* Fallback when the model can't produce a usable rewrite. Returns
|
package/dist/index.js
CHANGED
|
@@ -42,11 +42,12 @@ export class ClaudeMutationProviderError extends CrewhausError {
|
|
|
42
42
|
super("adapter", message, cause);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
const META_PROMPT_SYSTEM = `You are a prompt-engineering optimiser. You will receive a CURRENT PROMPT and a SAMPLE OF DEV-SET FAILURES
|
|
45
|
+
const META_PROMPT_SYSTEM = `You are a prompt-engineering optimiser. You will receive a CURRENT PROMPT and a SAMPLE OF DEV-SET FAILURES. Each failure shows the input the model received, its observed score (0..1, lower is worse), and — when available — the grader's feedback explaining WHY the output lost points. Your job is to produce a single rewrite of CURRENT PROMPT that you believe will improve grader scores on the dev set.
|
|
46
46
|
|
|
47
47
|
Hard rules:
|
|
48
48
|
- Output exactly one JSON object: {"rewrite": "...", "rationale": "..."}
|
|
49
49
|
- The "rewrite" field is the new prompt verbatim. Do NOT include any wrapper text outside the JSON.
|
|
50
|
+
- Read the grader feedback and address the ROOT CAUSE it names (e.g. "cites no source", "too verbose", "wrong format") with a general instruction — not a fix hard-coded to these specific inputs.
|
|
50
51
|
- Never copy verbatim text from a failure's expected_output into the rewrite (that would leak dev-set answers).
|
|
51
52
|
- Do not introduce instructions that override safety, compliance, or permission rules — your job is to improve task accuracy, not to bypass guardrails.
|
|
52
53
|
- The rationale should be 1-3 sentences explaining WHY this rewrite is likely to help. Keep it specific.`;
|
|
@@ -190,21 +191,41 @@ export class ClaudeMutationProvider {
|
|
|
190
191
|
const failureBlock = failures.length === 0
|
|
191
192
|
? "(No dev-set failures available yet — propose a refinement that improves clarity, specificity, or instruction-following.)"
|
|
192
193
|
: failures
|
|
193
|
-
.map((f, i) => `--- Failure ${i + 1} (observed score ${f.observedScore.toFixed(2)}) ---\nInput: ${f.input}\n${f.expected !== undefined ? `Expected output (do NOT copy this verbatim into the rewrite): ${f.expected}\n` : ""}`)
|
|
194
|
+
.map((f, i) => `--- Failure ${i + 1} (observed score ${f.observedScore.toFixed(2)}) ---\nInput: ${f.input}\n${f.expected !== undefined ? `Expected output (do NOT copy this verbatim into the rewrite): ${f.expected}\n` : ""}${f.rationale !== undefined ? `Grader feedback: ${f.rationale}\n` : ""}`)
|
|
194
195
|
.join("\n");
|
|
195
196
|
return `CURRENT PROMPT:\n${currentPrompt}\n\nSAMPLE OF DEV-SET FAILURES:\n${failureBlock}\n\nReturn one JSON object: {"rewrite": "...", "rationale": "..."}`;
|
|
196
197
|
}
|
|
197
|
-
/**
|
|
198
|
+
/**
|
|
199
|
+
* Identify the failing samples to show the model. When the fitness
|
|
200
|
+
* function supplied per-sample grades (`state.bestGrades`, wired by the
|
|
201
|
+
* CLI's eval-runner closure), we surface the samples the current best
|
|
202
|
+
* prompt ACTUALLY fails — worst-scoring first — together with the
|
|
203
|
+
* grader's rationale, so the meta-prompt can address the named root
|
|
204
|
+
* cause. This is the signal the system prompt promises. When grades are
|
|
205
|
+
* absent (a fitness fn returning a bare number, or an all-passing dev
|
|
206
|
+
* set), we fall back to surfacing the dev-set inputs with the aggregate
|
|
207
|
+
* score — the pre-failure-signal behaviour — so the search still runs.
|
|
208
|
+
*/
|
|
198
209
|
selectFailures(state) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
210
|
+
const graded = state.bestGrades;
|
|
211
|
+
if (graded !== undefined && graded.length > 0) {
|
|
212
|
+
const byWorst = [...graded].sort((a, b) => a.score - b.score);
|
|
213
|
+
// Prefer genuine failures (below the threshold); if the dev set is
|
|
214
|
+
// already strong, fall back to the lowest scorers so the mutator
|
|
215
|
+
// still has a concrete target to push on.
|
|
216
|
+
const belowThreshold = byWorst.filter((g) => g.score < this.failureThreshold);
|
|
217
|
+
const window = (belowThreshold.length > 0 ? belowThreshold : byWorst).slice(0, this.maxFailuresInPrompt);
|
|
218
|
+
return window.map((g) => ({
|
|
219
|
+
input: g.input,
|
|
220
|
+
observedScore: g.score,
|
|
221
|
+
...(g.expected !== undefined ? { expected: g.expected } : {}),
|
|
222
|
+
...(g.rationale !== undefined ? { rationale: g.rationale } : {}),
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
// No per-sample grades wired: surface the dev set as raw inputs with
|
|
226
|
+
// the aggregate score. The model still sees the dev-set distribution.
|
|
205
227
|
return state.devSet.slice(0, this.maxFailuresInPrompt).map((s) => ({
|
|
206
228
|
input: s.input,
|
|
207
|
-
// Use the trajectory's most recent score as a coarse signal.
|
|
208
229
|
observedScore: state.best.score,
|
|
209
230
|
...(s.expected_output !== undefined ? { expected: s.expected_output } : {}),
|
|
210
231
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewhaus/prompt-optimizer-claude",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Pillar-2 model-driven MutationProvider — asks Claude to rewrite the prompt given dev-set failures. Closes the v0 prompt-optimizer's L91 'rule-based-only' gap.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@anthropic-ai/sdk": "^0.96.0",
|
|
19
|
-
"@crewhaus/adapter-anthropic": "0.1.
|
|
20
|
-
"@crewhaus/errors": "0.1.
|
|
21
|
-
"@crewhaus/prompt-optimizer": "0.1.
|
|
19
|
+
"@crewhaus/adapter-anthropic": "0.1.7",
|
|
20
|
+
"@crewhaus/errors": "0.1.7",
|
|
21
|
+
"@crewhaus/prompt-optimizer": "0.1.7",
|
|
22
22
|
"zod": "^3.23.8"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@crewhaus/eval-dataset": "0.1.
|
|
25
|
+
"@crewhaus/eval-dataset": "0.1.7"
|
|
26
26
|
},
|
|
27
27
|
"license": "Apache-2.0",
|
|
28
28
|
"author": {
|