evalrx 0.1.2__py3-none-any.whl
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.
- evalrx/__init__.py +139 -0
- evalrx/agent_assets/__init__.py +2 -0
- evalrx/agent_assets/skills/README.md +28 -0
- evalrx/agent_assets/skills/eval-chart-style/SKILL.md +172 -0
- evalrx/agent_assets/skills/evalrx-report-ui/SKILL.md +116 -0
- evalrx/agent_assets/skills/nature-figure/LICENSE +201 -0
- evalrx/agent_assets/skills/nature-figure/README.md +412 -0
- evalrx/agent_assets/skills/nature-figure/SKILL.md +60 -0
- evalrx/agent_assets/skills/nature-figure/manifest.yaml +59 -0
- evalrx/agent_assets/skills/nature-figure/references/api.md +436 -0
- evalrx/agent_assets/skills/nature-figure/references/backend-selection.md +100 -0
- evalrx/agent_assets/skills/nature-figure/references/chart-types.md +281 -0
- evalrx/agent_assets/skills/nature-figure/references/common-patterns.md +350 -0
- evalrx/agent_assets/skills/nature-figure/references/demos.md +65 -0
- evalrx/agent_assets/skills/nature-figure/references/design-theory.md +439 -0
- evalrx/agent_assets/skills/nature-figure/references/figure-contract.md +93 -0
- evalrx/agent_assets/skills/nature-figure/references/figure-legend-conventions.md +71 -0
- evalrx/agent_assets/skills/nature-figure/references/nature-2026-observations.md +112 -0
- evalrx/agent_assets/skills/nature-figure/references/qa-contract.md +119 -0
- evalrx/agent_assets/skills/nature-figure/references/r-template-index.md +66 -0
- evalrx/agent_assets/skills/nature-figure/references/r-workflow.md +161 -0
- evalrx/agent_assets/skills/nature-figure/references/tutorials.md +251 -0
- evalrx/agent_assets/skills/nature-figure/static/core/contract.md +29 -0
- evalrx/agent_assets/skills/nature-figure/static/core/stance.md +37 -0
- evalrx/agent_assets/skills/nature-figure/static/fragments/backend/python.md +37 -0
- evalrx/agent_assets/skills/nature-figure/static/fragments/backend/r.md +44 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/SKILL.md +213 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/assets/analysis_report_template.md +53 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/references/model_selection.md +72 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.R +130 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.py +150 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.R +181 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.py +186 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.R +149 -0
- evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.py +177 -0
- evalrx/agent_assets/skills.py +27 -0
- evalrx/agent_runtime/__init__.py +78 -0
- evalrx/agent_runtime/_docker_runner.py +89 -0
- evalrx/agent_runtime/cli_runtime.py +103 -0
- evalrx/agent_runtime/cli_transcript.py +138 -0
- evalrx/agent_runtime/cli_types.py +68 -0
- evalrx/agent_runtime/codegen/__init__.py +5 -0
- evalrx/agent_runtime/codegen/runner.py +94 -0
- evalrx/agent_runtime/experiment_harness.py +117 -0
- evalrx/agent_runtime/factory.py +102 -0
- evalrx/agent_runtime/json_shape.py +44 -0
- evalrx/agent_runtime/judges/__init__.py +28 -0
- evalrx/agent_runtime/judges/agy.py +179 -0
- evalrx/agent_runtime/judges/autodetect.py +135 -0
- evalrx/agent_runtime/judges/claude.py +159 -0
- evalrx/agent_runtime/judges/codex.py +120 -0
- evalrx/agent_runtime/providers/__init__.py +21 -0
- evalrx/agent_runtime/providers/antigravity.py +31 -0
- evalrx/agent_runtime/providers/base.py +145 -0
- evalrx/agent_runtime/providers/claude_code.py +49 -0
- evalrx/agent_runtime/providers/codex.py +37 -0
- evalrx/agent_runtime/providers/gemini_cli.py +26 -0
- evalrx/agent_runtime/providers/kimi_cli.py +27 -0
- evalrx/agent_runtime/providers/opencode.py +27 -0
- evalrx/agent_runtime/providers/registry.py +58 -0
- evalrx/agent_runtime/sandbox.py +517 -0
- evalrx/agent_runtime/skill_audit.py +143 -0
- evalrx/agent_runtime/skills/__init__.py +19 -0
- evalrx/agent_runtime/skills/installer.py +68 -0
- evalrx/agent_runtime/skills/prompt_policy.py +86 -0
- evalrx/agent_runtime/skills/resolver.py +19 -0
- evalrx/analysis/__init__.py +132 -0
- evalrx/analysis/adjudicate.py +154 -0
- evalrx/analysis/analysis_module.py +361 -0
- evalrx/analysis/api.py +171 -0
- evalrx/analysis/case_studio.py +651 -0
- evalrx/analysis/cli.py +114 -0
- evalrx/analysis/dashboard.py +350 -0
- evalrx/analysis/eval_case_matrix.py +118 -0
- evalrx/analysis/eval_viz_theme.py +833 -0
- evalrx/analysis/explore_run.py +333 -0
- evalrx/analysis/explorer.py +1276 -0
- evalrx/analysis/failure_modes.py +607 -0
- evalrx/analysis/fused_pipeline.py +489 -0
- evalrx/analysis/holdout.py +300 -0
- evalrx/analysis/hypothesis_agent.py +230 -0
- evalrx/analysis/narration.py +177 -0
- evalrx/analysis/operationalize.py +442 -0
- evalrx/analysis/plain_language.py +42 -0
- evalrx/analysis/planner.py +283 -0
- evalrx/analysis/probe_search.py +203 -0
- evalrx/analysis/profile.py +268 -0
- evalrx/analysis/prompts/__init__.py +0 -0
- evalrx/analysis/prompts/explorer.py +417 -0
- evalrx/analysis/prompts/failure_modes.py +33 -0
- evalrx/analysis/prompts/holdout.py +27 -0
- evalrx/analysis/prompts/hypothesis_agent.py +78 -0
- evalrx/analysis/prompts/run_codebase.py +47 -0
- evalrx/analysis/prompts/stats_agent.py +72 -0
- evalrx/analysis/prompts/stats_tool_generator.py +43 -0
- evalrx/analysis/result_marker.py +47 -0
- evalrx/analysis/run_codebase.py +242 -0
- evalrx/analysis/run_view.py +205 -0
- evalrx/analysis/stage_views.py +93 -0
- evalrx/analysis/stats_agent.py +944 -0
- evalrx/analysis/stats_tool_agent.py +261 -0
- evalrx/analysis/stats_tool_generator.py +415 -0
- evalrx/analysis/stats_tools.py +1153 -0
- evalrx/analysis/trajectory_records.py +193 -0
- evalrx/analysis/workbench.py +431 -0
- evalrx/analyzers/__init__.py +42 -0
- evalrx/analyzers/agent/__init__.py +25 -0
- evalrx/analyzers/agent/counterfactual.py +84 -0
- evalrx/analyzers/agent/first_error_judge.py +96 -0
- evalrx/analyzers/agent/ignored_obs.py +81 -0
- evalrx/analyzers/agent/loop_detect.py +79 -0
- evalrx/analyzers/agent/reliability.py +165 -0
- evalrx/analyzers/agent/tool_shap.py +225 -0
- evalrx/analyzers/agent/trajectory_rubric.py +168 -0
- evalrx/analyzers/attention/__init__.py +19 -0
- evalrx/analyzers/attention/relative_attn.py +610 -0
- evalrx/analyzers/attention/rollout.py +73 -0
- evalrx/analyzers/attention/sink.py +56 -0
- evalrx/analyzers/attention/summary.py +190 -0
- evalrx/analyzers/attribution/__init__.py +6 -0
- evalrx/analyzers/attribution/generic_attn.py +31 -0
- evalrx/analyzers/attribution/gradcam.py +30 -0
- evalrx/analyzers/base.py +12 -0
- evalrx/analyzers/geometry/__init__.py +6 -0
- evalrx/analyzers/geometry/cka.py +70 -0
- evalrx/analyzers/geometry/linear_probe.py +157 -0
- evalrx/analyzers/hallucination/__init__.py +9 -0
- evalrx/analyzers/hallucination/chair.py +78 -0
- evalrx/analyzers/hallucination/opera.py +29 -0
- evalrx/analyzers/hallucination/pope.py +119 -0
- evalrx/analyzers/hallucination/selfcheck.py +155 -0
- evalrx/analyzers/hallucination/vcd.py +29 -0
- evalrx/analyzers/lens/__init__.py +7 -0
- evalrx/analyzers/lens/layer_contrast.py +133 -0
- evalrx/analyzers/lens/logit_lens.py +138 -0
- evalrx/analyzers/lens/tuned_lens.py +30 -0
- evalrx/analyzers/patching/__init__.py +5 -0
- evalrx/analyzers/patching/causal_trace.py +30 -0
- evalrx/analyzers/perturbation/__init__.py +23 -0
- evalrx/analyzers/perturbation/_shapley.py +54 -0
- evalrx/analyzers/perturbation/context_shap.py +174 -0
- evalrx/analyzers/perturbation/cot_faithfulness.py +239 -0
- evalrx/analyzers/perturbation/format_sensitivity.py +237 -0
- evalrx/analyzers/perturbation/mm_shap.py +146 -0
- evalrx/analyzers/perturbation/modality_ablation.py +196 -0
- evalrx/analyzers/perturbation/perturbation_battery.py +274 -0
- evalrx/analyzers/perturbation/prompt_contrast.py +265 -0
- evalrx/analyzers/perturbation/rise.py +94 -0
- evalrx/analyzers/perturbation/vl_shap.py +102 -0
- evalrx/analyzers/reasoning/__init__.py +33 -0
- evalrx/analyzers/reasoning/_text.py +328 -0
- evalrx/analyzers/reasoning/answer_extraction_audit.py +327 -0
- evalrx/analyzers/reasoning/arith_audit.py +226 -0
- evalrx/analyzers/reasoning/contamination.py +214 -0
- evalrx/analyzers/reasoning/knowledge_split.py +253 -0
- evalrx/analyzers/reasoning/self_repair.py +246 -0
- evalrx/analyzers/reasoning/step_rollout_value.py +216 -0
- evalrx/analyzers/reasoning/termination_audit.py +258 -0
- evalrx/analyzers/uncertainty/__init__.py +18 -0
- evalrx/analyzers/uncertainty/calibration.py +174 -0
- evalrx/analyzers/uncertainty/coverage_gap.py +199 -0
- evalrx/analyzers/uncertainty/entropy.py +90 -0
- evalrx/analyzers/uncertainty/logprob_entropy.py +69 -0
- evalrx/analyzers/uncertainty/self_consistency.py +204 -0
- evalrx/analyzers/uncertainty/verbalized_conf.py +64 -0
- evalrx/cli.py +411 -0
- evalrx/config.py +77 -0
- evalrx/contract/__init__.py +179 -0
- evalrx/contract/common.py +452 -0
- evalrx/contract/emit.py +948 -0
- evalrx/contract/export.py +237 -0
- evalrx/contract/m1.py +325 -0
- evalrx/contract/m2.py +317 -0
- evalrx/contract/m3.py +165 -0
- evalrx/contract/m4.py +130 -0
- evalrx/contract/m5.py +292 -0
- evalrx/contract/methodology.py +76 -0
- evalrx/contract/pre_m1.py +58 -0
- evalrx/contract/typescript.py +140 -0
- evalrx/core/__init__.py +85 -0
- evalrx/core/analyzer.py +174 -0
- evalrx/core/capability.py +54 -0
- evalrx/core/case.py +443 -0
- evalrx/core/experiment.py +106 -0
- evalrx/core/model.py +198 -0
- evalrx/core/pipeline.py +42 -0
- evalrx/core/registry.py +142 -0
- evalrx/core/result.py +64 -0
- evalrx/core/spec.py +173 -0
- evalrx/core/tokentype.py +165 -0
- evalrx/core/tool.py +92 -0
- evalrx/datasets/__init__.py +41 -0
- evalrx/datasets/base.py +68 -0
- evalrx/datasets/gui_os.py +52 -0
- evalrx/datasets/llm_qa.py +57 -0
- evalrx/datasets/pure_qa.py +12 -0
- evalrx/datasets/vlm_qa.py +695 -0
- evalrx/datasets/web_search_qa.py +52 -0
- evalrx/eval_agent/__init__.py +341 -0
- evalrx/eval_agent/_tools.py +81 -0
- evalrx/eval_agent/ab_runner.py +50 -0
- evalrx/eval_agent/agentic/__init__.py +43 -0
- evalrx/eval_agent/agentic/actions.py +216 -0
- evalrx/eval_agent/agentic/board.py +107 -0
- evalrx/eval_agent/agentic/loop.py +190 -0
- evalrx/eval_agent/agentic/tools.py +538 -0
- evalrx/eval_agent/checkpoint.py +57 -0
- evalrx/eval_agent/cli_agent.py +59 -0
- evalrx/eval_agent/cli_skills.py +5 -0
- evalrx/eval_agent/evolution.py +396 -0
- evalrx/eval_agent/git_manager.py +215 -0
- evalrx/eval_agent/hypothesis.py +172 -0
- evalrx/eval_agent/label_quarantine.py +209 -0
- evalrx/eval_agent/legacy.py +530 -0
- evalrx/eval_agent/log_schema.py +497 -0
- evalrx/eval_agent/loop.py +2159 -0
- evalrx/eval_agent/loop_reports.py +116 -0
- evalrx/eval_agent/model_instrumentation.py +282 -0
- evalrx/eval_agent/narration.py +193 -0
- evalrx/eval_agent/nl_runner.py +460 -0
- evalrx/eval_agent/orchestrator.py +61 -0
- evalrx/eval_agent/preregister.py +93 -0
- evalrx/eval_agent/prompts/__init__.py +1 -0
- evalrx/eval_agent/prompts/agentic.py +46 -0
- evalrx/eval_agent/prompts/case_discovery.py +25 -0
- evalrx/eval_agent/prompts/diagnosis.py +125 -0
- evalrx/eval_agent/prompts/experiment_writer.py +265 -0
- evalrx/eval_agent/prompts/explore_step.py +37 -0
- evalrx/eval_agent/prompts/fix_agent.py +257 -0
- evalrx/eval_agent/prompts/hypothesis_tester.py +15 -0
- evalrx/eval_agent/prompts/nl_runner.py +38 -0
- evalrx/eval_agent/prompts/probe_agent.py +25 -0
- evalrx/eval_agent/prompts/probe_candidate_generator.py +14 -0
- evalrx/eval_agent/prompts/probe_generator.py +35 -0
- evalrx/eval_agent/prompts/whitebox_probe_generator.py +38 -0
- evalrx/eval_agent/report.py +58 -0
- evalrx/eval_agent/run_context.py +354 -0
- evalrx/eval_agent/run_log.schema.json +1215 -0
- evalrx/eval_agent/run_logger_v2.py +1764 -0
- evalrx/eval_agent/run_metadata.py +208 -0
- evalrx/eval_agent/stages/__init__.py +56 -0
- evalrx/eval_agent/stages/case_discovery.py +293 -0
- evalrx/eval_agent/stages/diagnosis.py +1017 -0
- evalrx/eval_agent/stages/experiment_writer.py +1634 -0
- evalrx/eval_agent/stages/fix_agent.py +3916 -0
- evalrx/eval_agent/stages/fix_internals.py +499 -0
- evalrx/eval_agent/stages/fix_pipeline.py +725 -0
- evalrx/eval_agent/stages/fix_tiers.py +187 -0
- evalrx/eval_agent/stages/fix_tools.py +1034 -0
- evalrx/eval_agent/stages/hypothesis_tester.py +1014 -0
- evalrx/eval_agent/stages/probe.py +439 -0
- evalrx/eval_agent/stages/probe_agent.py +1079 -0
- evalrx/eval_agent/stages/probe_candidate_generator.py +128 -0
- evalrx/eval_agent/stages/probe_generator.py +326 -0
- evalrx/eval_agent/stages/probe_search_agent.py +106 -0
- evalrx/eval_agent/stages/protocol.py +112 -0
- evalrx/eval_agent/stages/repair_catalog.py +273 -0
- evalrx/eval_agent/stages/surgery.py +524 -0
- evalrx/eval_agent/stages/whitebox_probe_generator.py +351 -0
- evalrx/eval_agent/store.py +231 -0
- evalrx/logging_utils.py +112 -0
- evalrx/models/__init__.py +161 -0
- evalrx/models/_discover.py +101 -0
- evalrx/models/agent.py +380 -0
- evalrx/models/backends/__init__.py +58 -0
- evalrx/models/backends/api.py +169 -0
- evalrx/models/backends/base.py +57 -0
- evalrx/models/backends/gemini_compat.py +579 -0
- evalrx/models/backends/hf_local.py +2074 -0
- evalrx/models/backends/openai_compat.py +301 -0
- evalrx/models/backends/vllm_offline.py +116 -0
- evalrx/models/base.py +24 -0
- evalrx/models/blackbox/__init__.py +4 -0
- evalrx/models/blackbox/agent.py +31 -0
- evalrx/models/blackbox/base.py +29 -0
- evalrx/models/blackbox/gemini.py +279 -0
- evalrx/models/blackbox/llm_api.py +17 -0
- evalrx/models/blackbox/vlm_api.py +17 -0
- evalrx/models/compose.py +66 -0
- evalrx/models/inference.py +88 -0
- evalrx/models/paper_methods/__init__.py +8 -0
- evalrx/models/paper_methods/aad.py +53 -0
- evalrx/models/paper_methods/ifcd.py +204 -0
- evalrx/models/paper_methods/pai.py +164 -0
- evalrx/models/paper_methods/tcd.py +202 -0
- evalrx/models/paper_methods/vcd.py +45 -0
- evalrx/models/paper_methods/vicrop.py +137 -0
- evalrx/models/toolcodec.py +143 -0
- evalrx/models/tools/__init__.py +20 -0
- evalrx/models/tools/perception.py +300 -0
- evalrx/models/tools/visual.py +174 -0
- evalrx/models/whitebox/__init__.py +26 -0
- evalrx/models/whitebox/agent.py +31 -0
- evalrx/models/whitebox/base.py +24 -0
- evalrx/models/whitebox/qwen.py +61 -0
- evalrx/models/whitebox/qwen2_5_omni.py +29 -0
- evalrx/models/whitebox/qwen2_audio.py +25 -0
- evalrx/models/whitebox/qwen_omni.py +53 -0
- evalrx/models/whitebox/qwen_vl.py +62 -0
- evalrx/observability/__init__.py +21 -0
- evalrx/observability/envelope.py +122 -0
- evalrx/observability/outbox.py +111 -0
- evalrx/observability/tracer.py +882 -0
- evalrx/reporting/__init__.py +28 -0
- evalrx/reporting/case_study.py +947 -0
- evalrx/reporting/compiler.py +587 -0
- evalrx/reporting/dynamic.py +1882 -0
- evalrx/reporting/html_report.py +2225 -0
- evalrx/reporting/langfuse_exporter.py +38 -0
- evalrx/reporting/langfuse_source.py +155 -0
- evalrx/reporting/model.py +151 -0
- evalrx/reporting/run_events.py +184 -0
- evalrx/reporting/server.py +557 -0
- evalrx/reporting/stages.py +58 -0
- evalrx/reporting/static_export.py +142 -0
- evalrx/reporting/web_dist/index.html +146 -0
- evalrx/specs.py +727 -0
- evalrx/stats/__init__.py +47 -0
- evalrx/stats/api.py +192 -0
- evalrx/stats/bootstrap.py +86 -0
- evalrx/stats/ebh.py +27 -0
- evalrx/stats/evalue.py +98 -0
- evalrx/stats/friedman.py +138 -0
- evalrx/stats/mcnemar.py +40 -0
- evalrx/stats/multiplicity.py +159 -0
- evalrx/stats/subset_sampling.py +55 -0
- evalrx/term_links.py +43 -0
- evalrx/viz/__init__.py +7 -0
- evalrx/viz/labels.py +77 -0
- evalrx/viz/prompts.py +39 -0
- evalrx/viz/renderer.py +590 -0
- evalrx/viz/schema.py +36 -0
- evalrx/viz/style.py +134 -0
- evalrx-0.1.2.dist-info/METADATA +532 -0
- evalrx-0.1.2.dist-info/RECORD +339 -0
- evalrx-0.1.2.dist-info/WHEEL +5 -0
- evalrx-0.1.2.dist-info/entry_points.txt +3 -0
- evalrx-0.1.2.dist-info/licenses/LICENSE +121 -0
- evalrx-0.1.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""Prompt templates for M3 diagnosis."""
|
|
2
|
+
|
|
3
|
+
_DIAGNOSE_PROMPT = """\
|
|
4
|
+
You are an expert ML diagnostician. Based on the analysis report below, propose
|
|
5
|
+
specific, falsifiable hypotheses about the root cause of the model's failures.
|
|
6
|
+
|
|
7
|
+
Each hypothesis is written twice: once for a specialist (HYPOTHESIS, TEST) and
|
|
8
|
+
once for the person who will read the report. That reader builds and runs
|
|
9
|
+
evaluations but does not do statistics — they know what a benchmark, a prompt
|
|
10
|
+
and a failure case are, and they have never met an e-value, a McNemar test or a
|
|
11
|
+
multiple-comparisons correction. The PLAIN_STATEMENT line is written for them.
|
|
12
|
+
{prior_section}
|
|
13
|
+
Model: {model_name}
|
|
14
|
+
Overall severity (threshold rules): {severity}
|
|
15
|
+
|
|
16
|
+
Experiment protocol (authoritative task and response contract):
|
|
17
|
+
{protocol_section}
|
|
18
|
+
|
|
19
|
+
Analysis conclusion (the analyst's interpretation):
|
|
20
|
+
{conclusion}
|
|
21
|
+
{evidence_section}{stats_section}{explore_section}{failure_modes_section}
|
|
22
|
+
Raw findings (JSON):
|
|
23
|
+
{findings_json}
|
|
24
|
+
|
|
25
|
+
{available_signals_section}Propose 1-3 hypotheses. For each write:
|
|
26
|
+
HYPOTHESIS: <one-sentence falsifiable technical claim about the failure mode>
|
|
27
|
+
PLAIN_STATEMENT: <the SAME claim as HYPOTHESIS, restated in ONE everyday
|
|
28
|
+
sentence, written for the reader described above. State what the model is
|
|
29
|
+
doing wrong, not what statistic was computed. Numbers are welcome and make
|
|
30
|
+
it better — but a number must come with what it amounts to ("gets 45 of the
|
|
31
|
+
125 wrong, nearly all of them lists longer than eight words"), never bare
|
|
32
|
+
("fail rate 0.36"). No acronyms, no statistics jargon, no symbols (→, ρ, σ),
|
|
33
|
+
no bare metric identifiers as the subject of the sentence. Do not copy the
|
|
34
|
+
HYPOTHESIS line verbatim — this is checked, and a jargon-y or copy-pasted
|
|
35
|
+
line is sent back for a rewrite.>
|
|
36
|
+
FAILURE_MODE: <short snake_case tag naming the MECHANISM, not the symptom.
|
|
37
|
+
Vision/agent: attention_sink / hallucination / loop / ignored_obs / language_prior_bias
|
|
38
|
+
Text reasoning: computation_slip / chain_break / knowledge_gap / selection_failure /
|
|
39
|
+
overthinking / brittleness / memorization / self_correction_failure
|
|
40
|
+
Harness (suspect these before any mechanism): answer_extraction / truncation /
|
|
41
|
+
degenerate_repetition
|
|
42
|
+
Use a tag from these lists when one fits; invent one only when none does.>
|
|
43
|
+
TEST: <which evidence verifies this claim — name a signal/analyzer from the
|
|
44
|
+
available evidence list when one fits (e.g. "relative_attention.max_relative_weight
|
|
45
|
+
HIGHER on failing cases" or "prompt_contrast describe_first contrast"), and for a
|
|
46
|
+
per-case signal SAY whether it should be HIGHER or LOWER on failing cases — that
|
|
47
|
+
is the prediction the test checks. On a yes/no task a directional claim ("answers
|
|
48
|
+
Yes regardless of the evidence") is tested on the DIRECTION marginals
|
|
49
|
+
answer_extraction_audit.answered_yes (the answer's direction, e.g. HIGHER on
|
|
50
|
+
failing cases) and answer_extraction_audit.gold_yes (the question's), never on
|
|
51
|
+
extracted_answer, labelled_fail or a correctness flag — those are text or the
|
|
52
|
+
label itself and cannot be evidence; otherwise describe the analyzer or
|
|
53
|
+
intervention that should be run next cycle>
|
|
54
|
+
EXPECTED_ASSOCIATION: <higher_on_failures if larger/present values of the named
|
|
55
|
+
signal support the hypothesis, or lower_on_failures if smaller/absent values
|
|
56
|
+
support it. Pre-register this direction from the claim; do not infer it from an
|
|
57
|
+
observed effect. For an intervention expected to repair failures, use
|
|
58
|
+
higher_on_failures for a fixed_by_* signal.>
|
|
59
|
+
|
|
60
|
+
Base your hypotheses on the analysis conclusion and evidence above — an analyzer
|
|
61
|
+
can surface a real failure mode even when no numeric threshold fired, so do NOT
|
|
62
|
+
rely on the threshold severity alone.
|
|
63
|
+
Do NOT repeat hypotheses already listed in the prior cycles above.
|
|
64
|
+
If the conclusion and evidence genuinely show no problem, respond with: NO_ISSUE"""
|
|
65
|
+
|
|
66
|
+
_VALIDATE_PROMPT = """\
|
|
67
|
+
You are an adversarial ML reviewer. Your job is to find reasons to REJECT each
|
|
68
|
+
hypothesis below. Only approve a hypothesis if you cannot find a significant flaw.
|
|
69
|
+
|
|
70
|
+
Check each for:
|
|
71
|
+
1. Unsupported claim — does the cited evidence actually imply this failure mode?
|
|
72
|
+
2. Circular reasoning — does the hypothesis merely restate the symptom?
|
|
73
|
+
3. Overgeneralisation — does it make a claim far broader than the evidence supports?
|
|
74
|
+
4. Confounded alternative — is there a simpler explanation the hypothesis ignores?
|
|
75
|
+
{context_section}
|
|
76
|
+
Findings summary (the evidence the hypotheses were drawn from):
|
|
77
|
+
{findings_json}
|
|
78
|
+
|
|
79
|
+
Hypotheses to review:
|
|
80
|
+
{hypotheses_text}
|
|
81
|
+
|
|
82
|
+
For each hypothesis output two lines:
|
|
83
|
+
KEEP: <hypothesis statement> or REJECT: <hypothesis statement>
|
|
84
|
+
REASON: <one or two sentences naming the flaw you found, or why it survives>
|
|
85
|
+
REASON: <specific flaw, or "evidence directly supports this claim" if keeping>"""
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
_FORMAT_REPAIR_PROMPT = """\
|
|
89
|
+
Your previous answer below could not be read: it contains no line that starts
|
|
90
|
+
with the label HYPOTHESIS:. The hypotheses are only usable in the exact
|
|
91
|
+
line-labelled format.
|
|
92
|
+
|
|
93
|
+
Previous answer:
|
|
94
|
+
{raw}
|
|
95
|
+
|
|
96
|
+
Rewrite the SAME hypotheses (do not invent new ones) so that each one is a block
|
|
97
|
+
of these lines, in this order, each label at the start of its own line:
|
|
98
|
+
HYPOTHESIS: <one-sentence falsifiable technical claim>
|
|
99
|
+
PLAIN_STATEMENT: <the same claim in one everyday sentence, no jargon>
|
|
100
|
+
FAILURE_MODE: <short snake_case tag naming the mechanism>
|
|
101
|
+
TEST: <which signal/analyzer verifies the claim>
|
|
102
|
+
EXPECTED_ASSOCIATION: <higher_on_failures or lower_on_failures>
|
|
103
|
+
|
|
104
|
+
If your previous answer meant that there is no issue to report, reply with the
|
|
105
|
+
single word NO_ISSUE."""
|
|
106
|
+
|
|
107
|
+
_PLAIN_REPAIR_PROMPT = """\
|
|
108
|
+
Your previous answer below proposed hypotheses correctly, but some
|
|
109
|
+
PLAIN_STATEMENT lines fail a plain-language check.
|
|
110
|
+
|
|
111
|
+
PLAIN_STATEMENT must be a one-sentence everyday paraphrase of the matching
|
|
112
|
+
HYPOTHESIS line, written for an engineer who runs evaluations but does no
|
|
113
|
+
statistics: no statistics terms, no acronyms, no symbols, and not a verbatim
|
|
114
|
+
copy of the HYPOTHESIS line. Numbers are welcome, but each one must come with
|
|
115
|
+
what it amounts to rather than standing bare.
|
|
116
|
+
|
|
117
|
+
Previous answer:
|
|
118
|
+
{raw}
|
|
119
|
+
|
|
120
|
+
Problems found:
|
|
121
|
+
{violations}
|
|
122
|
+
|
|
123
|
+
Rewrite the FULL set of hypotheses in the exact same
|
|
124
|
+
HYPOTHESIS/PLAIN_STATEMENT/FAILURE_MODE/TEST/EXPECTED_ASSOCIATION format,
|
|
125
|
+
fixing only the flagged PLAIN_STATEMENT lines. Do not change any other line."""
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""Prompt templates for the M5 experiment writer."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
_BLUEPRINT_SYSTEM = """\
|
|
6
|
+
You are an expert ML debugging engineer. Plan the structure of a multi-file
|
|
7
|
+
Python diagnostic project that will test a specific hypothesis about a model's
|
|
8
|
+
behaviour.
|
|
9
|
+
|
|
10
|
+
Output a YAML specification with this structure:
|
|
11
|
+
```yaml
|
|
12
|
+
description: one-line summary
|
|
13
|
+
files:
|
|
14
|
+
- name: main.py
|
|
15
|
+
generation_order: 3
|
|
16
|
+
description: entry point
|
|
17
|
+
pseudocode: |
|
|
18
|
+
1. Load model
|
|
19
|
+
2. Run cases
|
|
20
|
+
3. Compute metrics
|
|
21
|
+
4. Print metrics in name: value format
|
|
22
|
+
5. Print verdict: 1.0 or verdict: 0.0
|
|
23
|
+
dependencies: [model_probe.py, utils.py]
|
|
24
|
+
- name: utils.py
|
|
25
|
+
generation_order: 1
|
|
26
|
+
description: shared helpers
|
|
27
|
+
pseudocode: |
|
|
28
|
+
- helper functions
|
|
29
|
+
dependencies: []
|
|
30
|
+
output_contract:
|
|
31
|
+
metrics: [mean_consistency, n_cases]
|
|
32
|
+
verdict: "1.0 = hypothesis SUPPORTED, 0.0 = REFUTED"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Rules:
|
|
36
|
+
- Generate 2–4 files maximum
|
|
37
|
+
- main.py must be last in generation_order
|
|
38
|
+
- main.py MUST have `if __name__ == "__main__":` block
|
|
39
|
+
- The last printed line of the entire run MUST be `verdict: 1.0` or `verdict: 0.0`
|
|
40
|
+
- Stay under {timeout_sec} seconds total runtime\
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
_BLUEPRINT_USER = """\
|
|
44
|
+
## Hypothesis to test
|
|
45
|
+
Statement : {statement}
|
|
46
|
+
Failure mode: {failure_mode}
|
|
47
|
+
|
|
48
|
+
## Model setup
|
|
49
|
+
```python
|
|
50
|
+
{import_expr}
|
|
51
|
+
model = {load_expr}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Available capabilities: {capabilities}
|
|
55
|
+
|
|
56
|
+
## Model access policy
|
|
57
|
+
{model_access_note}
|
|
58
|
+
|
|
59
|
+
## Failure cases (JSON)
|
|
60
|
+
```json
|
|
61
|
+
{cases_json_snippet}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Write the YAML blueprint now:\
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
_GENERATE_FILE_SYSTEM = """\
|
|
68
|
+
You are an expert ML debugging engineer. Generate a single Python file
|
|
69
|
+
as part of a multi-file diagnostic experiment project.
|
|
70
|
+
|
|
71
|
+
Rules:
|
|
72
|
+
- Implement EXACTLY the pseudocode in the file spec
|
|
73
|
+
- Use only the evalrx APIs shown
|
|
74
|
+
- Output ONLY the Python code — no markdown prose before or after
|
|
75
|
+
- Code must be complete and immediately executable\
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
_GENERATE_FILE_USER = """\
|
|
79
|
+
## File to generate: {file_name}
|
|
80
|
+
|
|
81
|
+
### File spec
|
|
82
|
+
```json
|
|
83
|
+
{file_spec}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Blueprint (full project)
|
|
87
|
+
```yaml
|
|
88
|
+
{blueprint}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Dependencies already generated
|
|
92
|
+
{dep_summaries}
|
|
93
|
+
|
|
94
|
+
{dep_code}
|
|
95
|
+
|
|
96
|
+
## Model access policy
|
|
97
|
+
{model_access_note}
|
|
98
|
+
|
|
99
|
+
## EvalRX API reference
|
|
100
|
+
```python
|
|
101
|
+
from evalrx.core.case import CaseBatch, FailureCase, Inputs
|
|
102
|
+
output: str = model.generate(case.inputs)
|
|
103
|
+
# logprobs (only if 'LOGPROBS' in capabilities)
|
|
104
|
+
lps = model.logprobs(case.inputs)
|
|
105
|
+
# internals (only if 'ATTENTION' or 'HIDDEN_STATES' in capabilities)
|
|
106
|
+
trace = model.forward(case.inputs, capture={{Capability.ATTENTION}})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Write the complete `{file_name}` now (Python code only):\
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
_WRITE_SYSTEM = """\
|
|
113
|
+
You are an expert ML debugging engineer. Write a concise, self-contained Python
|
|
114
|
+
diagnostic script that gathers evidence for or against a specific hypothesis
|
|
115
|
+
about a model's behaviour.
|
|
116
|
+
|
|
117
|
+
RULES:
|
|
118
|
+
- Use ONLY the evalrx APIs shown in the user message.
|
|
119
|
+
- The script must be completely self-contained — no external files.
|
|
120
|
+
- Print ALL metrics in EXACTLY this format (one per line):
|
|
121
|
+
metric_name: float_value
|
|
122
|
+
- Print a final verdict line as the LAST output:
|
|
123
|
+
verdict: 1.0 # hypothesis is SUPPORTED by the evidence
|
|
124
|
+
verdict: 0.0 # hypothesis is REFUTED
|
|
125
|
+
- Never print anything after the verdict line.
|
|
126
|
+
- Catch exceptions and print error metrics rather than crashing silently.
|
|
127
|
+
- Stay under {timeout_sec} seconds total runtime.
|
|
128
|
+
- The script MUST have `if __name__ == "__main__":` block.\
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
_WRITE_USER = """\
|
|
132
|
+
## Hypothesis to test
|
|
133
|
+
Statement : {statement}
|
|
134
|
+
Failure mode: {failure_mode}
|
|
135
|
+
|
|
136
|
+
## Model setup (copy this verbatim)
|
|
137
|
+
```python
|
|
138
|
+
{import_expr}
|
|
139
|
+
model = {load_expr}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Available capabilities: {capabilities}
|
|
143
|
+
|
|
144
|
+
## Model access policy
|
|
145
|
+
{model_access_note}
|
|
146
|
+
|
|
147
|
+
{blueprint_context}
|
|
148
|
+
|
|
149
|
+
## EvalRX API reference
|
|
150
|
+
```python
|
|
151
|
+
from evalrx.core.case import CaseBatch, FailureCase, Inputs
|
|
152
|
+
from evalrx.core.capability import Capability
|
|
153
|
+
|
|
154
|
+
# Text generation (always available)
|
|
155
|
+
output: str = model.generate(case.inputs)
|
|
156
|
+
|
|
157
|
+
# Token logprobs (only if 'LOGPROBS' in capabilities)
|
|
158
|
+
lps = model.logprobs(case.inputs) # list[TokenLogprob]; each has .token, .logprob
|
|
159
|
+
|
|
160
|
+
# Internals capture (only if 'ATTENTION' or 'HIDDEN_STATES' in capabilities)
|
|
161
|
+
trace = model.forward(case.inputs, capture={{Capability.ATTENTION}})
|
|
162
|
+
# trace.attentions list[Tensor] one per layer, shape [heads, seq, seq]
|
|
163
|
+
# trace.hidden_states list[Tensor] one per layer, shape [seq, hidden]
|
|
164
|
+
# trace.tokens list[str]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Failure cases (JSON — deserialize inside your script)
|
|
168
|
+
```json
|
|
169
|
+
{cases_json}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Required output (EXACTLY this format)
|
|
173
|
+
```
|
|
174
|
+
metric_a: 0.72
|
|
175
|
+
metric_b: 3.0
|
|
176
|
+
verdict: 1.0
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Write the complete Python script now:\
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
_REPAIR_SYSTEM = """\
|
|
183
|
+
You are a Python debugging expert. The script below crashed.
|
|
184
|
+
Return the COMPLETE corrected script — no explanations, just the fixed code.
|
|
185
|
+
Preserve all logic; fix only the error.\
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
_REPAIR_USER = """\
|
|
189
|
+
## Error
|
|
190
|
+
```
|
|
191
|
+
{error}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Script to fix
|
|
195
|
+
```python
|
|
196
|
+
{code}
|
|
197
|
+
```\
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
_REVIEW_SYSTEM = """\
|
|
201
|
+
You are a senior code reviewer. Review this diagnostic experiment code and
|
|
202
|
+
return a JSON object with:
|
|
203
|
+
- "verdict": "APPROVE" or "REQUEST_CHANGES"
|
|
204
|
+
- "score": integer 1-10
|
|
205
|
+
- "critical_issues": list of strings (empty if APPROVE)
|
|
206
|
+
|
|
207
|
+
Focus on: correctness of hypothesis testing logic, metric computation,
|
|
208
|
+
verdict output format, and error handling. Do NOT flag style issues.\
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def build_cli_prompt(
|
|
213
|
+
hypothesis: Any,
|
|
214
|
+
model_context: dict[str, Any],
|
|
215
|
+
timeout_sec: int,
|
|
216
|
+
n_images: int = 0,
|
|
217
|
+
) -> str:
|
|
218
|
+
"""Build the prompt used by external CLI coding agents."""
|
|
219
|
+
caps = ", ".join(model_context.get("capabilities", [])) or "GENERATE"
|
|
220
|
+
access_note = model_context.get("access_note", "")
|
|
221
|
+
image_note = (
|
|
222
|
+
f", and image_path (JPEG path for {n_images} case(s)).\n"
|
|
223
|
+
"Load images and build inputs like this:\n"
|
|
224
|
+
"```python\n"
|
|
225
|
+
"from PIL import Image\n"
|
|
226
|
+
"from evalrx.core.case import Inputs\n"
|
|
227
|
+
"img = Image.open(case['image_path'])\n"
|
|
228
|
+
"inputs = Inputs(prompt=case['prompt'], image=img)\n"
|
|
229
|
+
"# Then: model.generate(inputs) or model.forward(inputs, capture={Capability.ATTENTION})\n"
|
|
230
|
+
"```\n"
|
|
231
|
+
"Do NOT pass raw dicts or lists as inputs — always use Inputs().\n\n"
|
|
232
|
+
if n_images else ".\n\n"
|
|
233
|
+
)
|
|
234
|
+
return (
|
|
235
|
+
"You are an ML debugging engineer. Write a self-contained Python "
|
|
236
|
+
"diagnostic script that tests a specific hypothesis about a model.\n\n"
|
|
237
|
+
"## Hypothesis\n"
|
|
238
|
+
f"Statement : {hypothesis.statement}\n"
|
|
239
|
+
f"Failure mode: {hypothesis.predicted_failure_mode}\n\n"
|
|
240
|
+
"## Model setup (copy verbatim)\n"
|
|
241
|
+
"```python\n"
|
|
242
|
+
f"{model_context.get('import_expr', 'import evalrx')}\n"
|
|
243
|
+
f"model = {model_context.get('load_expr', '# model')}\n"
|
|
244
|
+
"```\n\n"
|
|
245
|
+
f"Available capabilities: {caps}\n\n"
|
|
246
|
+
"## Model access policy\n"
|
|
247
|
+
f"{access_note}\n\n"
|
|
248
|
+
"## Input data\n"
|
|
249
|
+
"Read `cases.json` from the current directory. "
|
|
250
|
+
"Each record has: prompt, label (PASS/FAIL), id, metadata"
|
|
251
|
+
+ image_note
|
|
252
|
+
+ "## Required output (print to stdout, EXACTLY this format)\n"
|
|
253
|
+
"```\n"
|
|
254
|
+
"metric_a: 0.72\n"
|
|
255
|
+
"metric_b: 3.0\n"
|
|
256
|
+
"verdict: 1.0 # 1.0=SUPPORTED 0.0=REFUTED\n"
|
|
257
|
+
"```\n\n"
|
|
258
|
+
"## Rules\n"
|
|
259
|
+
f"- Stay under {timeout_sec} seconds total runtime.\n"
|
|
260
|
+
"- Save the script as `experiment.py` in the current directory.\n"
|
|
261
|
+
"- Print all metrics as `name: float_value` lines.\n"
|
|
262
|
+
"- The last printed line must be `verdict: 1.0` or `verdict: 0.0`.\n"
|
|
263
|
+
"- Use only the evalrx APIs shown above.\n"
|
|
264
|
+
"- Do NOT make external network calls or read files other than `cases.json`.\n"
|
|
265
|
+
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Question template for the loop's optional in-cycle explore step.
|
|
2
|
+
|
|
3
|
+
The explorer (:class:`~evalrx.analysis.explorer.ExploratoryAnalysisAgent`)
|
|
4
|
+
is a free-form EDA coder: it only knows what the question tells it. This
|
|
5
|
+
template turns the run's :class:`~evalrx.eval_agent.stages.protocol.ExperimentProtocol`
|
|
6
|
+
into a question that (a) names the outcome column, (b) says what the columns
|
|
7
|
+
are (M1 analyzer per-case signals), and (c) asks for FROZEN, threshold-explicit
|
|
8
|
+
recipes — the only form a candidate signal can later be re-evaluated in.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
_EXPLORE_QUESTION = (
|
|
16
|
+
"Which per-case signals distinguish the FAIL cases (label=fail) from the "
|
|
17
|
+
"PASS cases (label=pass)?{context} Every other column is a per-case signal "
|
|
18
|
+
"an M1 analyzer computed on the model under diagnosis (column name = "
|
|
19
|
+
"analyzer.metric, sanitized). Compare each signal's distribution between "
|
|
20
|
+
"FAIL and PASS, look for interactions and thresholds, and make every "
|
|
21
|
+
"candidate signal a FROZEN, threshold-explicit recipe over the available "
|
|
22
|
+
"numeric columns (explicit numeric cut-offs, no re-fitting) so it can be "
|
|
23
|
+
"re-evaluated verbatim on held-out cases. Charts are leads for hypotheses, "
|
|
24
|
+
"not proof: this is the exploration half of a diagnosis loop, and a "
|
|
25
|
+
"separate confirmatory stage will test whatever you surface."
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def default_explore_question(protocol: Any | None = None) -> str:
|
|
30
|
+
"""Build the explore question from the run's protocol (or a generic one)."""
|
|
31
|
+
parts: list[str] = []
|
|
32
|
+
for attr in ("description", "task_domain", "failure_patterns"):
|
|
33
|
+
value = getattr(protocol, attr, None) if protocol is not None else None
|
|
34
|
+
if value:
|
|
35
|
+
parts.append(str(value).strip())
|
|
36
|
+
context = (" Context: " + " ".join(parts)) if parts else ""
|
|
37
|
+
return _EXPLORE_QUESTION.format(context=context)
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"""Prompt templates for fix candidate generation and repair."""
|
|
2
|
+
|
|
3
|
+
_L1_PROMPT = """\
|
|
4
|
+
You are designing PROMPT-LEVEL fixes (tier L1: the input space only) for a \
|
|
5
|
+
model failure. The model may be text-only or vision-language.
|
|
6
|
+
|
|
7
|
+
VERIFIED FAILURE HYPOTHESES:
|
|
8
|
+
{hypotheses}
|
|
9
|
+
{context}
|
|
10
|
+
EXAMPLE CASES — read the model's own outputs: what it does when it fails, what
|
|
11
|
+
it does when it succeeds, and the answer format the scorer expects:
|
|
12
|
+
{examples}
|
|
13
|
+
|
|
14
|
+
Propose up to {k} prompt rewrite strategies that could repair these failures
|
|
15
|
+
WITHOUT changing the model or adding pipeline steps. Each strategy is a
|
|
16
|
+
template applied to every case prompt; it MUST contain the literal placeholder
|
|
17
|
+
{{prompt}}. Keep the final-answer format the scorer expects recoverable; do
|
|
18
|
+
not ask the model to suppress its reasoning if the task needs it. If your
|
|
19
|
+
template asks the model to write intermediate work (a transcription, a list, a
|
|
20
|
+
check) that may not fit the baseline decode budget, add "generation_kwargs":
|
|
21
|
+
{{"max_tokens": <int>}} to that strategy — it can only RAISE the budget (a
|
|
22
|
+
lower value is raised to the baseline), and no other decoding control is
|
|
23
|
+
allowed at this tier.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
"what_it_does" is shown to a reader who has never heard of this model, this
|
|
27
|
+
benchmark, or this field -- write it for a bright high-school student. One
|
|
28
|
+
sentence, present tense, plain words, saying what CHANGES for the model. Do
|
|
29
|
+
not name the tier, do not use metric or method jargon, and do not restate the
|
|
30
|
+
snake_case name in English.
|
|
31
|
+
Good: "Asks the model to describe what it hears before it answers."
|
|
32
|
+
Bad: "L1 audio-evidence-first prompt scaffold with deferred answering."
|
|
33
|
+
|
|
34
|
+
Reply with ONLY a JSON array (generation_kwargs is optional; omit it unless
|
|
35
|
+
the rewrite needs the extra room):
|
|
36
|
+
[{{"name": "<short_snake_case>", "what_it_does": "<one plain sentence>",
|
|
37
|
+
"prompt_template": "<template with {{prompt}}>",
|
|
38
|
+
"generation_kwargs": {{"max_tokens": <int>}}}}]"""
|
|
39
|
+
|
|
40
|
+
_L2_PROMPT = """\
|
|
41
|
+
You are designing SCAFFOLD-LEVEL fixes (tier L2: a pipeline around the \
|
|
42
|
+
unchanged model) for a model failure. The model may be text-only or
|
|
43
|
+
vision-language.
|
|
44
|
+
|
|
45
|
+
VERIFIED FAILURE HYPOTHESES:
|
|
46
|
+
{hypotheses}
|
|
47
|
+
{context}
|
|
48
|
+
EXAMPLE CASES — read the model's own outputs: what it does when it fails, what
|
|
49
|
+
it does when it succeeds, and the answer format the scorer expects:
|
|
50
|
+
{examples}
|
|
51
|
+
|
|
52
|
+
IMAGE TOOLS (only meaningful when the case has an image):
|
|
53
|
+
{catalog}
|
|
54
|
+
|
|
55
|
+
Propose up to {k} pipelines. Each may chain image tools, rewrite the prompt
|
|
56
|
+
(template MUST contain {{prompt}}), sample the model n_samples times (1..5;
|
|
57
|
+
applies to EVERY strategy — a multi-call strategy is repeated end-to-end and
|
|
58
|
+
its final answers vote on the extracted final answer), select one reviewed
|
|
59
|
+
multi-call strategy (direct, least_to_most, self_refine,
|
|
60
|
+
chain_of_verification), and set bounded decoding controls in
|
|
61
|
+
generation_kwargs (temperature, top_p, stop, max_tokens). max_tokens can only
|
|
62
|
+
RAISE the baseline budget — a value below it is raised to the baseline, so
|
|
63
|
+
never try to shorten the model's chain of thought; temperature 0 makes
|
|
64
|
+
n_samples>1 pointless. For structured answer tasks, output_key_pattern may be
|
|
65
|
+
a regex with one capture group used for answer-only voting; it must not
|
|
66
|
+
contain gold answers.
|
|
67
|
+
|
|
68
|
+
"what_it_does" is shown to a reader who has never heard of this model, this
|
|
69
|
+
benchmark, or this field -- write it for a bright high-school student. One
|
|
70
|
+
sentence, present tense, plain words, saying what CHANGES for the model. Do
|
|
71
|
+
not name the tier, do not use metric or method jargon, and do not restate the
|
|
72
|
+
snake_case name in English.
|
|
73
|
+
Good: "Asks the model to describe what it hears before it answers."
|
|
74
|
+
Bad: "L1 audio-evidence-first prompt scaffold with deferred answering."
|
|
75
|
+
|
|
76
|
+
Reply with ONLY a JSON array:
|
|
77
|
+
[{{"name": "<short_snake_case>", "what_it_does": "<one plain sentence>",
|
|
78
|
+
"image_ops": [{{"tool": "<catalog name>", "params": {{}}}}],
|
|
79
|
+
"prompt_template": "{{prompt}}", "n_samples": 1,
|
|
80
|
+
"generation_kwargs": {{}}, "strategy": "direct",
|
|
81
|
+
"output_key_pattern": ""}}]"""
|
|
82
|
+
|
|
83
|
+
_L2_CODE_PROMPT = """\
|
|
84
|
+
You are writing a PYTHON PIPELINE (tier L2: a scaffold around the unchanged \
|
|
85
|
+
model) that repairs the failures described below. Design any
|
|
86
|
+
pipeline you want — the only constraint is that the model itself is unchanged.
|
|
87
|
+
|
|
88
|
+
VERIFIED FAILURE HYPOTHESES:
|
|
89
|
+
{hypotheses}
|
|
90
|
+
{context}
|
|
91
|
+
EXAMPLE CASES — read the model's own outputs: what it does when it fails, what
|
|
92
|
+
it does when it succeeds, and the answer format the scorer expects:
|
|
93
|
+
{examples}
|
|
94
|
+
|
|
95
|
+
EXECUTION CONTRACT:
|
|
96
|
+
- "{cases_file}" in the current directory: {{"cases": [{{"id": str, "prompt": str,
|
|
97
|
+
"baseline_output": str|null}}]}} — baseline_output is the model's ORIGINAL
|
|
98
|
+
recorded answer to that prompt: the DIRECT BASELINE. It may be wrong; it is
|
|
99
|
+
NOT a label and carries no correctness information. Use it directly as the
|
|
100
|
+
baseline answer (compare against it, vote with it, ask the model to
|
|
101
|
+
double-check it) — you do NOT need to call model_generate(case_id) to
|
|
102
|
+
obtain it; a plain model_generate(case_id) is answered from this record.
|
|
103
|
+
- A function model_generate(case_id, prompt=None, image_ops=None,
|
|
104
|
+
generation_kwargs=None) -> str is ALREADY DEFINED in your namespace (do NOT
|
|
105
|
+
import or redefine it). It runs the ORIGINAL model on that case: optional
|
|
106
|
+
prompt override, optional image transforms applied to the case's image
|
|
107
|
+
first, optional bounded decoding controls (temperature, top_p, stop,
|
|
108
|
+
max_tokens — max_tokens can only RAISE the baseline budget; a lower value is
|
|
109
|
+
raised to it). IMPORTANT: ``prompt`` REPLACES the original prompt; it is
|
|
110
|
+
not prepended automatically. Every answer-producing override must include
|
|
111
|
+
``case["prompt"]`` itself (for example, ``instruction + "\\n\\n" +
|
|
112
|
+
case["prompt"]``), or the model will never see the question. image_ops MUST
|
|
113
|
+
be a list of
|
|
114
|
+
{{"tool": "<name>", "params": {{...}}}} dicts using ONLY these tools
|
|
115
|
+
(anything else is rejected with an error):
|
|
116
|
+
{catalog}{attend_hint}
|
|
117
|
+
- You may call the model SEVERAL times per case, but keep it to at most
|
|
118
|
+
4 calls per case that hit the model (genuinely independent enhanced/reasoned
|
|
119
|
+
passes: a different prompt and/or image_ops each); the host enforces this
|
|
120
|
+
per-case cap. A plain model_generate(case_id) (no prompt override, no
|
|
121
|
+
image_ops, no generation_kwargs) is answered from the recorded
|
|
122
|
+
baseline_output, costs nothing and does not count. Branch on outputs
|
|
123
|
+
within that budget — e.g. describe first, then decide; vote over
|
|
124
|
+
independent variants.
|
|
125
|
+
- model_generate is thread-safe and concurrent calls are serviced in
|
|
126
|
+
parallel: fan out over CASES with concurrent.futures.ThreadPoolExecutor
|
|
127
|
+
(max_workers=8) — a serial loop over every case x several calls is slow and
|
|
128
|
+
risks the wall-clock limit.
|
|
129
|
+
- SELECTION RULE (enforced by the host, without labels): for each case the
|
|
130
|
+
host anchors on baseline_output (or on your plain direct call when a case
|
|
131
|
+
has no record). Your final "output" may differ from that anchor only when
|
|
132
|
+
at least {min_support} of your enhanced calls with DISTINCT prompt/image_ops
|
|
133
|
+
returned the same answer; otherwise the host reverts that case to the
|
|
134
|
+
anchor. Return the model's own reply text (or the tagged answer you asked
|
|
135
|
+
it to emit, e.g. "FINAL: <answer>" — the host strips such tags when
|
|
136
|
+
matching); never rewrite, reformat or compute the answer yourself.
|
|
137
|
+
Pattern the host accepts:
|
|
138
|
+
base = case["baseline_output"] or ""
|
|
139
|
+
question = case["prompt"]
|
|
140
|
+
votes = [model_generate(cid, prompt=p1 + "\\n\\n" + question),
|
|
141
|
+
model_generate(cid, prompt=p2 + "\\n\\n" + question, image_ops=ops)]
|
|
142
|
+
final = the answer that >= {min_support} votes agree on if it differs from base, else base
|
|
143
|
+
{selection_guidance}
|
|
144
|
+
- The LAST line of stdout MUST be exactly:
|
|
145
|
+
{marker}{{"per_case": [{{"sample_id": "<case id>", "output": "<final answer text>"}}]}}
|
|
146
|
+
- Emit an entry for EVERY case. The "output" is scored externally against the
|
|
147
|
+
original question, so it must answer that question faithfully (e.g. contain
|
|
148
|
+
a clear yes/no for yes/no questions).
|
|
149
|
+
- Standard library + numpy only. No network, no file writes. Keep it under
|
|
150
|
+
~80 lines.
|
|
151
|
+
- REPAIR THE MODEL, NOT THE TASK. Your code is re-run a second time with every
|
|
152
|
+
model_generate() call answered by the model's ORIGINAL recorded answer. Any
|
|
153
|
+
failing case your pipeline gets right in THAT run was solved by your code,
|
|
154
|
+
not the model, and is excluded from the fix score — a pipeline that computes
|
|
155
|
+
the answer itself (sorting, arithmetic, lookup, a hard-coded default) scores
|
|
156
|
+
zero. Verify, vote, re-ask, re-prompt, zoom: make the model get it right.
|
|
157
|
+
|
|
158
|
+
The FIRST line of your code must be a WHAT_IT_DOES comment, on ONE line, for a
|
|
159
|
+
reader who has never heard of this model, this benchmark, or this field: plain
|
|
160
|
+
words, present tense, saying what your pipeline makes the model do differently.
|
|
161
|
+
No jargon, no tier names, no restating the code. For example:
|
|
162
|
+
# WHAT_IT_DOES: Asks the model twice with different wording and keeps the answer both tries agree on.
|
|
163
|
+
|
|
164
|
+
Return ONLY the Python code{fences_hint}."""
|
|
165
|
+
|
|
166
|
+
_REPAIR_PROMPT_BODY = """\
|
|
167
|
+
Your previously written repair pipeline FAILED TO EXECUTE.
|
|
168
|
+
|
|
169
|
+
ERROR:
|
|
170
|
+
{error}
|
|
171
|
+
|
|
172
|
+
YOUR PREVIOUS CODE:
|
|
173
|
+
```python
|
|
174
|
+
{code}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Fix the code. Follow the execution contract EXACTLY:
|
|
178
|
+
- the ONLY model access is the predefined model_generate(case_id, prompt=None, \
|
|
179
|
+
image_ops=None, generation_kwargs=None){attend_clause} — do not import or redefine it;
|
|
180
|
+
- image_ops must be a list of {{"tool": "<name>", "params": {{...}}}} dicts \
|
|
181
|
+
using ONLY these tools:
|
|
182
|
+
{catalog}
|
|
183
|
+
- baseline_output in "{cases_file}" IS the direct baseline answer — use it as \
|
|
184
|
+
the baseline; a plain model_generate(case_id) is answered from that record and \
|
|
185
|
+
is free; the TOTAL number of enhanced model_generate(...) PLUS model_attend(...) \
|
|
186
|
+
calls must be at most 4 per case (model_attend is not free);
|
|
187
|
+
- the host's selection guard reverts a case to its baseline unless at least \
|
|
188
|
+
{min_support} DISTINCT enhanced calls returned your final answer (answer tags \
|
|
189
|
+
such as "FINAL: <answer>" are stripped when matching);
|
|
190
|
+
{selection_guidance}
|
|
191
|
+
- read "{cases_file}", emit an entry for EVERY case, and end stdout with \
|
|
192
|
+
exactly:
|
|
193
|
+
{marker}{{"per_case": [{{"sample_id": "<case id>", "output": "<final answer text>"}}]}}
|
|
194
|
+
- standard library + numpy only; no network, no file writes; under ~80 lines.
|
|
195
|
+
- overwrite pipeline.py with ONLY the corrected user pipeline; do not copy or \
|
|
196
|
+
modify fix_pipeline_exec.py and do not append the old program after the repair.
|
|
197
|
+
- repair the MODEL, not the task: the code is re-run with every model_generate() \
|
|
198
|
+
call answered by the model's original recorded answer, and failing cases it still \
|
|
199
|
+
gets right then are excluded from the score. If it timed out, make FEWER model \
|
|
200
|
+
calls per case — do not replace them with code that computes the answer itself.
|
|
201
|
+
- keep (or add) the one-line `# WHAT_IT_DOES: ...` first line describing, in \
|
|
202
|
+
plain words for a reader with no background, what your pipeline makes the model \
|
|
203
|
+
do differently.
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
_L3_PROMPT = """\
|
|
207
|
+
You are configuring WHITE-BOX intervention primitives (tier L3: the model's \
|
|
208
|
+
internals) against the failures below. The primitives are pre-audited host \
|
|
209
|
+
code — you choose which to run and with what parameters.
|
|
210
|
+
|
|
211
|
+
VERIFIED FAILURE HYPOTHESES:
|
|
212
|
+
{hypotheses}
|
|
213
|
+
|
|
214
|
+
AVAILABLE PRIMITIVES:
|
|
215
|
+
{catalog}
|
|
216
|
+
|
|
217
|
+
Propose up to {k} configurations. Reply with ONLY a JSON array:
|
|
218
|
+
[{{"primitive": "<name from the list>", "params": {{...}}}}]"""
|
|
219
|
+
|
|
220
|
+
_REPAIR_CATALOG_PROMPT = """\
|
|
221
|
+
You are selecting which REGISTERED repair capability, if any, applies to the \
|
|
222
|
+
failure(s) below. Each candidate is a specific, pre-audited \
|
|
223
|
+
intervention that targets ONE named failure mechanism — read what mechanism \
|
|
224
|
+
each one actually targets, then select it ONLY when the verified hypotheses \
|
|
225
|
+
describe that same mechanism, not merely because it is technically able to \
|
|
226
|
+
run on this model and task (that eligibility has already been checked for \
|
|
227
|
+
you; your only job is judging whether the mechanism matches).
|
|
228
|
+
|
|
229
|
+
VERIFIED FAILURE HYPOTHESES:
|
|
230
|
+
{hypotheses}
|
|
231
|
+
|
|
232
|
+
ELIGIBLE CANDIDATES (already filtered to what this model/task can run):
|
|
233
|
+
{catalog}
|
|
234
|
+
|
|
235
|
+
Propose up to {k} candidates whose targeted mechanism is genuinely \
|
|
236
|
+
consistent with the hypotheses above. A hypothesis naming a DIFFERENT \
|
|
237
|
+
mechanism (e.g. a flat knowledge gap, a positional/answer-choice bias, or a \
|
|
238
|
+
hallucination cause when the candidate targets something else entirely) is \
|
|
239
|
+
NOT a match, even if the candidate would run without error. If none of the \
|
|
240
|
+
candidates address the diagnosed mechanism, reply with an empty array — do \
|
|
241
|
+
not select one just because it is available. Reply with ONLY a JSON array:
|
|
242
|
+
[{{"name": "<name from the list>", "rationale": "<one sentence: how the hypothesis's mechanism matches this candidate's>"}}]"""
|
|
243
|
+
|
|
244
|
+
_L4_PROMPT = """\
|
|
245
|
+
You are writing a PARAMETER-SPACE repair recipe (tier L4: fine-tuning) for \
|
|
246
|
+
the failures below. The recipe is RECORDED for a human decision — it will \
|
|
247
|
+
not be executed automatically.
|
|
248
|
+
|
|
249
|
+
VERIFIED FAILURE HYPOTHESES:
|
|
250
|
+
{hypotheses}
|
|
251
|
+
|
|
252
|
+
Reply with ONLY a JSON object:
|
|
253
|
+
{{"dataset_recipe": "<how to build training data that generalises the failure
|
|
254
|
+
mechanism — never just the observed failing cases>",
|
|
255
|
+
"method": "lora|sft", "target": "vision_encoder|llm|projector|full",
|
|
256
|
+
"eval_protocol": "<held-out repair effect + regression battery>",
|
|
257
|
+
"rationale": "<why parameter-space change is the minimum effective tier>"}}"""
|