From ed225cef170e61399a01ae1d2a86b296d9be25af Mon Sep 17 00:00:00 2001 From: tianyouyiwang Date: Wed, 22 Jul 2026 12:05:00 +0800 Subject: [PATCH] examples: add eval-attribution-optimize-gate loop example Add a self-contained example under examples/optimization that demonstrates a six-stage closed loop: baseline evaluation, failure attribution, candidate optimization, gate decision and audit reporting. It ships a deterministic fake backend that needs no API key, plus an optional real backend backed by an OpenAI-compatible model. Updates #214 RELEASE NOTES: Add an evaluation-optimization loop example under examples/optimization. --- .../eval_optimize_loop/.env.example | 17 + .../eval_optimize_loop/.gitignore | 2 + .../optimization/eval_optimize_loop/README.md | 164 +++++ .../artifacts/candidates/baseline.md | 1 + .../artifacts/candidates/candidate_1.md | 1 + .../artifacts/candidates/candidate_2.md | 1 + .../artifacts/candidates/candidate_3.md | 1 + .../artifacts/candidates/candidate_4.md | 1 + .../artifacts/optimization_report.json | 670 ++++++++++++++++++ .../artifacts/optimization_report.md | 71 ++ .../artifacts/optimizer.snapshot.json | 40 ++ .../eval_optimize_loop/attribution.py | 205 ++++++ .../eval_optimize_loop/config/optimizer.json | 40 ++ .../config/real_optimizer.json | 74 ++ .../config/real_optimizer_smoke.json | 71 ++ .../data/real/train.evalset.json | 40 ++ .../data/real/val.evalset.json | 40 ++ .../data/real_smoke/train.evalset.json | 18 + .../data/real_smoke/val.evalset.json | 29 + .../data/train.evalset.json | 40 ++ .../eval_optimize_loop/data/val.evalset.json | 40 ++ .../eval_optimize_loop/fake_agent.py | 115 +++ .../optimization/eval_optimize_loop/gate.py | 131 ++++ .../optimization_report.json | 670 ++++++++++++++++++ .../eval_optimize_loop/optimizer.py | 56 ++ .../eval_optimize_loop/pipeline.py | 296 ++++++++ .../prompts/baseline_real.md | 1 + .../prompts/baseline_system.md | 4 + .../eval_optimize_loop/real_call_agent.py | 107 +++ .../eval_optimize_loop/run_pipeline.py | 194 +++++ .../eval_optimize_loop/verify_real.py | 47 ++ 31 files changed, 3187 insertions(+) create mode 100644 examples/optimization/eval_optimize_loop/.env.example create mode 100644 examples/optimization/eval_optimize_loop/.gitignore create mode 100644 examples/optimization/eval_optimize_loop/README.md create mode 100644 examples/optimization/eval_optimize_loop/artifacts/candidates/baseline.md create mode 100644 examples/optimization/eval_optimize_loop/artifacts/candidates/candidate_1.md create mode 100644 examples/optimization/eval_optimize_loop/artifacts/candidates/candidate_2.md create mode 100644 examples/optimization/eval_optimize_loop/artifacts/candidates/candidate_3.md create mode 100644 examples/optimization/eval_optimize_loop/artifacts/candidates/candidate_4.md create mode 100644 examples/optimization/eval_optimize_loop/artifacts/optimization_report.json create mode 100644 examples/optimization/eval_optimize_loop/artifacts/optimization_report.md create mode 100644 examples/optimization/eval_optimize_loop/artifacts/optimizer.snapshot.json create mode 100644 examples/optimization/eval_optimize_loop/attribution.py create mode 100644 examples/optimization/eval_optimize_loop/config/optimizer.json create mode 100644 examples/optimization/eval_optimize_loop/config/real_optimizer.json create mode 100644 examples/optimization/eval_optimize_loop/config/real_optimizer_smoke.json create mode 100644 examples/optimization/eval_optimize_loop/data/real/train.evalset.json create mode 100644 examples/optimization/eval_optimize_loop/data/real/val.evalset.json create mode 100644 examples/optimization/eval_optimize_loop/data/real_smoke/train.evalset.json create mode 100644 examples/optimization/eval_optimize_loop/data/real_smoke/val.evalset.json create mode 100644 examples/optimization/eval_optimize_loop/data/train.evalset.json create mode 100644 examples/optimization/eval_optimize_loop/data/val.evalset.json create mode 100644 examples/optimization/eval_optimize_loop/fake_agent.py create mode 100644 examples/optimization/eval_optimize_loop/gate.py create mode 100644 examples/optimization/eval_optimize_loop/optimization_report.json create mode 100644 examples/optimization/eval_optimize_loop/optimizer.py create mode 100644 examples/optimization/eval_optimize_loop/pipeline.py create mode 100644 examples/optimization/eval_optimize_loop/prompts/baseline_real.md create mode 100644 examples/optimization/eval_optimize_loop/prompts/baseline_system.md create mode 100644 examples/optimization/eval_optimize_loop/real_call_agent.py create mode 100644 examples/optimization/eval_optimize_loop/run_pipeline.py create mode 100644 examples/optimization/eval_optimize_loop/verify_real.py diff --git a/examples/optimization/eval_optimize_loop/.env.example b/examples/optimization/eval_optimize_loop/.env.example new file mode 100644 index 00000000..f47320b9 --- /dev/null +++ b/examples/optimization/eval_optimize_loop/.env.example @@ -0,0 +1,17 @@ +# 复制本文件为 .env 并填入你的 hy3 凭据(不要把真实 .env 提交到 git) +# +# 三件套是 tRPC-Agent 框架约定(trpc_agent_sdk 直接读 os.environ): +# TRPC_AGENT_API_KEY 你的 hy3 API Key +# TRPC_AGENT_BASE_URL hy3 的 OpenAI 兼容 endpoint,例如 https:///v1 +# TRPC_AGENT_MODEL_NAME 模型名,例如 hy3 +# +# 两种生效方式(二选一): +# A. 直接导出到当前 shell: +# export TRPC_AGENT_API_KEY=xxx +# export TRPC_AGENT_BASE_URL=https:///v1 +# export TRPC_AGENT_MODEL_NAME=hy3 +# B. 用 .env 文件:在 run_pipeline.py 入口加 `from dotenv import load_dotenv; load_dotenv()` +# (python-dotenv 已随 requirements 安装),框架即可从 .env 读到上述变量。 +TRPC_AGENT_API_KEY=your-hy3-api-key +TRPC_AGENT_BASE_URL=https://your-hy3-endpoint/v1 +TRPC_AGENT_MODEL_NAME=hy3 diff --git a/examples/optimization/eval_optimize_loop/.gitignore b/examples/optimization/eval_optimize_loop/.gitignore new file mode 100644 index 00000000..c0b3eab9 --- /dev/null +++ b/examples/optimization/eval_optimize_loop/.gitignore @@ -0,0 +1,2 @@ +# 本地真实凭据,切勿提交(只提交 .env.example 占位模板) +.env diff --git a/examples/optimization/eval_optimize_loop/README.md b/examples/optimization/eval_optimize_loop/README.md new file mode 100644 index 00000000..8f05c72c --- /dev/null +++ b/examples/optimization/eval_optimize_loop/README.md @@ -0,0 +1,164 @@ +# Eval → Attribution → Optimize → Gate 自动闭环示例 + +本示例演示如何把 tRPC-Agent 的 `AgentEvaluator` 与一个"等价扩展机制"的优化器, +串成一个**可复现、可审计、带质量闸门**的自动闭环:先评测,再对失败做可解释归因, +然后生成候选 prompt 并回归验证,最后由 gate 判定候选"是否真的提升、是否牺牲其他 +指标、是否过拟合、是否值得回写源 prompt"。 + +整条流程默认**完全不需要任何 API Key**(确定性 fake 后端),同时提供一个可选的 +真实 LLM 后端(OpenAI 兼容,如 hy3),两套后端共用同一套编排、归因、gate 与审计逻辑。 + +## 关键特性 + +- **六阶段闭环**:评测 → 失败归因 → 优化执行 → 回归验证 → 接受策略(gate) → 产物审计。 +- **无 Key 可跑**:确定性 Fake Model / Fake Judge,秒级完成,结果完全可复现(固定 `seed`)。 +- **可解释失败归因**:把失败稳定归到 6 大类,并给出一句话原因与 `regression` 标记。 +- **防过拟合 gate**:关键 case 退化 / 新增 hard fail 一律拒绝,即使验证集总分提升。 +- **完整审计产物**:结构化 + 人读报告、每轮候选快照、可复现配置全部落盘。 +- **可选真实后端**:`EVAL_BACKEND=real` 一键切换到真实 LLM 生成 + `llm_rubric_response` judge。 + +## 目录结构 + +```text +eval_optimize_loop/ +├── run_pipeline.py # 入口:组装配置、运行闭环、落盘报告 +├── pipeline.py # 编排层:把 6 个阶段串起来 +├── attribution.py # 失败归因(6 大类可解释分类) +├── gate.py # 接受策略(可配置 gate) +├── optimizer.py # 规则式优化器(与 GEPA 等价的确定性机制) +├── fake_agent.py # 确定性 Fake Model / Fake Judge(call_agent) +├── real_call_agent.py # 真实 LLM call_agent(接入 OpenAI 兼容后端,如 hy3) +├── verify_real.py # 真实凭据连通性自检(单条调用) +├── prompts/ +│ ├── baseline_system.md # fake 模式 baseline prompt +│ └── baseline_real.md # 真实模式 baseline prompt +├── config/ +│ ├── optimizer.json # fake 模式配置:指标 / gate / 候选池 / 种子 +│ ├── real_optimizer.json # 真实模式配置:llm_rubric_response judge / gate / 候选池 +│ └── real_optimizer_smoke.json # 真实模式轻量变体(低配额验证用) +├── data/ +│ ├── train.evalset.json # fake 模式 3 条训练 case +│ ├── val.evalset.json # fake 模式 3 条验证 case(含过拟合退化样本) +│ ├── real/ # 真实模式 3 训练 + 3 验证(含退化哨兵 val_robust) +│ └── real_smoke/ # 真实模式轻量变体(1 训练 + 2 验证) +├── .env.example # 环境变量模板(TRPC_AGENT_*) +├── .gitignore # 忽略本地 .env(避免真实凭据入库) +├── artifacts/ # 运行产物(报告 + 候选快照 + 配置快照) +└── optimization_report.json # 示例输出(fake 模式,与 artifacts 一致) +``` + +## 快速开始(无需 API Key,验收主路径) + +```bash +# 首次安装依赖 +pip install -r ../../requirements.txt + +# 从仓库根运行 +python examples/optimization/eval_optimize_loop/run_pipeline.py +``` + +运行结束后,报告写入 `artifacts/`:结构化 `optimization_report.json`、人读 +`optimization_report.md`、每轮候选快照 `candidates/