examples: add evaluation optimization regression loop#161
Conversation
Add a no-key Evaluation and Optimization pipeline that baselines train and validation data, captures every GEPA proposal, independently re-evaluates candidates, applies regression and resource gates, and emits auditable JSON and Markdown reports. Include deterministic replay data, prompt candidates, failure attribution, paired bootstrap confidence intervals, Pareto selection, data-leakage checks, sample output, and regression tests. Fixes trpc-group#91 RELEASE NOTES: Add an auditable offline Evaluation and Optimization regression loop example.
|
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #161 +/- ##
==========================================
Coverage ? 88.12552%
==========================================
Files ? 467
Lines ? 44103
Branches ? 0
==========================================
Hits ? 38866
Misses ? 5237
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I have read the CLA Document and I hereby sign the CLA |
Fail closed on ambiguous replay data, unsafe artifact labels, non-finite metrics, key-case pass regressions, and common tool error payloads. Isolate optimizer prompt writes from source files, reject unsafe in-process concurrency, and add adversarial regression coverage for gate, attribution, path, apply, and concurrency behavior. Fixes trpc-group#91 RELEASE NOTES: Harden the evaluation and optimization example against ambiguous data, unsafe artifacts, and regression-gate edge cases.
There was a problem hiding this comment.
Pull request overview
Adds a new end-to-end Evaluation + Optimization regression-loop example under examples/optimization/eval_optimize_loop, exercising the real AgentOptimizer (GEPA) + TargetPrompt path while independently re-evaluating every unique candidate with AgentEvaluator trace replay and producing auditable JSON/Markdown reports and gates.
Changes:
- Introduces an offline, no-API-key pipeline (
EvalOptimizePipeline.run()) that runs baseline eval → optimizer proposals capture → per-candidate independent replay eval → deltas/gates → atomic reports. - Adds deterministic offline agent/judge/reflector adapters via
ModelRegistry, plus replay trace materialization and evidence-backed failure attribution. - Adds comprehensive regression tests validating deliverables, data-quality protections, gating behavior, and report outputs.
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/evaluation/test_eval_optimize_loop_example.py | Public-interface regression tests covering deliverables, gates, replay attribution, cost handling, and concurrency fail-closed behavior. |
| examples/optimization/eval_optimize_loop/README.md | Usage guide and design rationale for the closed-loop example, including inputs/outputs and gate semantics. |
| examples/optimization/eval_optimize_loop/DESIGN.md | 300–500 Chinese-character design note describing attribution, gates, anti-overfit, and auditing. |
| examples/optimization/eval_optimize_loop/run_pipeline.py | One-command CLI entrypoint to run the pipeline and emit decision + report paths. |
| examples/optimization/eval_optimize_loop/pipeline.json | Example manifest wiring datasets/configs/prompts/candidates and run controls (seed/bootstrap/etc.). |
| examples/optimization/eval_optimize_loop/optimizer.json | Offline-validated GEPA optimizer configuration used by AgentOptimizer. |
| examples/optimization/eval_optimize_loop/regression.metrics.json | Trace-only regression metrics config for independent candidate replay evaluation. |
| examples/optimization/eval_optimize_loop/gate.json | Gate policy config for validation gain, CI floor, regression protections, and budgets. |
| examples/optimization/eval_optimize_loop/sample_output/optimization_report.md | Reproducible sample Markdown report output for the example. |
| examples/optimization/eval_optimize_loop/data/train.evalset.json | Offline train evalset with deterministic per-variant replay traces and usage accounting. |
| examples/optimization/eval_optimize_loop/data/val.evalset.json | Offline validation evalset including a key hard-fail format regression case. |
| examples/optimization/eval_optimize_loop/agent/init.py | Declares prompt assets package for the example. |
| examples/optimization/eval_optimize_loop/agent/prompts/system.md | Baseline system prompt (includes [variant: baseline] tag). |
| examples/optimization/eval_optimize_loop/agent/prompts/candidates/ineffective.md | Deterministic candidate prompt fixture for offline reflection. |
| examples/optimization/eval_optimize_loop/agent/prompts/candidates/overfit.md | Deterministic overfit candidate prompt fixture for regression rejection scenarios. |
| examples/optimization/eval_optimize_loop/agent/prompts/candidates/robust.md | Deterministic robust candidate prompt fixture expected to be accepted. |
| examples/optimization/eval_optimize_loop/loop/init.py | Public seam exports (EvalOptimizePipeline, PipelineSpec, OptimizationReport). |
| examples/optimization/eval_optimize_loop/loop/models.py | Pydantic models for manifests, audits, deltas, gate checks, and report schema. |
| examples/optimization/eval_optimize_loop/loop/offline.py | Patch-free offline LLMModel provider (agent/judge/reflector) and real LlmAgent call path. |
| examples/optimization/eval_optimize_loop/loop/trace.py | Replay trace materialization, SDK evaluation, normalization, and deterministic failure attribution. |
| examples/optimization/eval_optimize_loop/loop/analysis.py | Data-quality checks, paired bootstrap CI, resource accounting, gates, and Pareto marking. |
| examples/optimization/eval_optimize_loop/loop/pipeline.py | Orchestrates baseline, optimization, proposal capture, independent candidate evaluation, gating, and reporting. |
| examples/optimization/eval_optimize_loop/loop/reporting.py | Atomic JSON/Markdown report persistence and Markdown rendering. |
| examples/optimization/eval_optimize_loop/.gitignore | Ignores local runs and selected sample artifacts. |
| examples/optimization/eval_optimize_loop/init.py | Declares the example package. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| no_worse = (other.validation.pass_rate >= candidate.validation.pass_rate | ||
| and other.validation.average_score >= candidate.validation.average_score | ||
| and other.audit.resources.total_tokens <= candidate.audit.resources.total_tokens | ||
| and (other.audit.resources.p95_latency_ms | ||
| or 0.0) <= (candidate.audit.resources.p95_latency_ms or 0.0)) | ||
| strictly_better = (other.validation.pass_rate > candidate.validation.pass_rate | ||
| or other.validation.average_score > candidate.validation.average_score | ||
| or other.audit.resources.total_tokens < candidate.audit.resources.total_tokens | ||
| or (other.audit.resources.p95_latency_ms | ||
| or 0.0) < (candidate.audit.resources.p95_latency_ms or 0.0)) |
| usage = item.audit.resources | ||
| cost = "unavailable" if usage.cost_usd is None else f"${usage.cost_usd:.4f}" | ||
| lines.append(f"| `{item.candidate_id}` | {usage.metric_calls} | {usage.judge_calls} | " | ||
| f"{usage.total_tokens} | {usage.p95_latency_ms or 0.0:.1f} ms | " | ||
| f"{usage.duration_seconds:.3f} s | {cost} | `{usage.cost_measurement}` |") |
Summary
examples/optimization/eval_optimize_loop.AgentOptimizer+ GEPA +TargetPromptpath, capture every unique proposal (including optimizer-rejected proposals), and independently replay each candidate throughAgentEvaluatoron train and validation splits.Why
Issue #91 requires a reproducible closed loop that turns prompt optimization into an auditable promotion decision. Optimizer aggregate scores alone cannot show validation regressions, newly failed hard cases, failure causes, or whether a candidate stayed within its resource budget. This example keeps optimization and release gating separate: every proposal is re-evaluated from materialized traces before it can be selected or applied.
Design and safety
EvalOptimizePipeline.run(); production SDK code is unchanged.ModelRegistry, so the flow still exercisesLlmAgent, rubric parsing, GEPA callbacks, andAgentEvaluatorwithout monkeypatching or network access.--apply-if-acceptedoption and uses atomicTargetPrompt.write_all().Validation
pytest -q tests/evaluation/test_eval_optimize_loop_example.py— 41 passed.pytest -q tests/evaluation— 930 passed.pytest --cov=trpc_agent_sdk --cov-fail-under=80 tests/— 9,386 passed, 1 expected XFAIL, 88.13% coverage.flake8 examples/optimization/eval_optimize_loop tests/evaluation/test_eval_optimize_loop_example.py --max-line-length=120— passed.yapf --diff --recursive examples/optimization/eval_optimize_loop tests/evaluation/test_eval_optimize_loop_example.py— clean.python examples/optimization/eval_optimize_loop/run_pipeline.py --output-dir /tmp/issue91-audit— acceptedrobust, 100% failed-case attribution coverage, no API key, and 1.80 seconds wall time.robustwithout changing the source prompt; same-process concurrency fails closed.The single XFAIL is an existing expected repository test and is unrelated to this branch.
Requested PR type:
type/feature.Fixes #91
RELEASE NOTES: Add a reproducible, auditable Evaluation + Optimization regression-loop example that runs without external model credentials.