Skip to content

feat(examples): add evaluation-optimization closed-loop example with report and gate - #255

Open
AsyncKurisu wants to merge 2 commits into
trpc-group:mainfrom
AsyncKurisu:evaluation-optimization-pipeline
Open

feat(examples): add evaluation-optimization closed-loop example with report and gate#255
AsyncKurisu wants to merge 2 commits into
trpc-group:mainfrom
AsyncKurisu:evaluation-optimization-pipeline

Conversation

@AsyncKurisu

Copy link
Copy Markdown

Overview

Resolves #91
This PR adds a complete example-only evaluation and optimization loop under examples/optimization/eval_optimize_loop/. The pipeline runs baseline evaluation, failure attribution, prompt optimization, candidate validation, delta analysis, and gate decisioning, then writes both a machine-readable JSON report and a human-readable Markdown report.

Key Changes

  • Added a self-contained example pipeline with fixed output under examples/optimization/eval_optimize_loop/output/.
  • Implemented baseline evaluation, rule-based failure attribution, candidate delta analysis, and configurable gate evaluation.
  • Added fake-mode behavior so the full flow can run without API keys.
  • Kept the optimization example inside examples/ and did not modify trpc_agent_sdk.
  • Restructured report content to focus on the business flow and removed the standalone audit layer.
  • Split tests into smaller business-oriented files and updated the example documentation in Chinese.

How to Run

Fake mode

cd examples/optimization/eval_optimize_loop
python run_pipeline.py --mode fake
pytest examples/optimization/eval_optimize_loop/tests -q

Real mode

export TRPC_AGENT_MODEL_NAME=...
export TRPC_AGENT_BASE_URL=...
export TRPC_AGENT_API_KEY=...
cd examples/optimization/eval_optimize_loop
python run_pipeline.py --mode real
pytest examples/optimization/eval_optimize_loop/tests -q

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@5ca3bf2). Learn more about missing BASE report.

Additional details and impacted files
@@            Coverage Diff             @@
##             main        #255   +/-   ##
==========================================
  Coverage        ?   87.86456%           
==========================================
  Files           ?         482           
  Lines           ?       45157           
  Branches        ?           0           
==========================================
  Hits            ?       39677           
  Misses          ?        5480           
  Partials        ?           0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@helloopenworld

Copy link
Copy Markdown
Contributor

AI Code Review

已确认。这些测试断言(overall=5, train candidate failed=0, overall_change_type="mixed", new_pass=2, critical_regression=1)与已提交报告中的值(overall=6, train candidate failed=1, "unchanged", new_pass=0, critical_regression=0)存在冲突。由于测试在执行时会重新运行流水线并重新生成报告,因此它们会通过(我的逻辑推导结果与测试一致)——但这意味着仓库中已提交output/optimization_report.json/.md 文件已过时,与实际行为不符。这是一个实际的维护性问题,因为 README 将这些提交的产物作为参考输出展示。

注意:我无法在此沙箱环境中执行测试套件进行验证,但逻辑推导结果是决定性的:模拟候选路径添加了 FINAL_ANSWER_FIX_MARKER,这使得 val_multiply_pass 回归(已知答案 "42" ≠ 预期的 "40"),产生了 1 个 new_fail + 1 个 new_pass + 1 个未改变的结果——与测试相匹配,而非已提交的报告。

让我写出审查意见。

发现的问题

🚨 Critical

  • examples/optimization/eval_optimize_loop/output/optimization_report.jsonoutput/optimization_report.md(整文件):提交的示例报告产物与当前代码/测试的实际运行结果不一致。
    • 提交报告中 overall_change_type="unchanged"new_pass_count=0new_fail_count=0regression_count=0candidate.train.failed_count=1failure_attribution.overall_summary.final_answer_mismatch=6critical_regression_count=0;但 tests/test_pipeline_reports.py:55-81 断言 overall_summary=5candidate.train.failed_count=0overall_change_type="mixed"new_pass_count=2critical_regression_count=1,且该断言与 fake 模式逻辑一致(候选 prompt 注入 FINAL_ANSWER_FIX_MARKERval_multiply_pass 回归为 new_fail,触发 critical 回归)。README 将 output/ 描述为可比较/归档的参考产物,因此提交版本属误导性过时产物。建议重新执行 python run_pipeline.py --mode fake 覆盖这两个文件后再提交。

⚠️ Warning

  • examples/optimization/eval_optimize_loop/pipeline/optimization.py:268-283_run_real_optimizerEvalOptimizePipeline.run 真实分支):真实模式下 write_call_agent_evalsets() 被调用两次——一次在 _run_real_optimizer 内部、一次在 pipeline.run 的真实候选评估分支前,重复写同一对临时 evalset 文件。虽不致功能失败,但属冗余 I/O 且易让维护者误判产物来源;建议仅在一处生成并在两处复用路径。

  • examples/optimization/eval_optimize_loop/tests/test_pipeline_reports.py:92-93_contains_no_absolute_workspace_path):该断言硬编码 /home/kazenke/ 这一特定开发者主目录前缀来检测绝对路径泄露,换机器/换开发者即失效,无法真正守住“报告不含绝对工作区路径”这一意图。建议改为校验报告中所有路径字符串均非绝对路径(或均以 . / output 等相对前缀开头)。

💡 Suggestion

  • examples/optimization/eval_optimize_loop/pipeline/pipeline.py:417-419_trace_from_case):actual = case.actual_conversation[0] if case.actual_conversation else expected 在缺失 actual 时回退到 expected,会使“实际无输出”的失败被记录为“actual 与 expected 一致”,掩盖真实失败信号;可考虑回退为空内容并保留 reason,便于归因准确性。

总结

存在 1 个 Critical:提交的 output/optimization_report.json/.md 与当前代码实际产出(及测试断言)明显不一致,属误导性过时产物,需重新生成后提交。其余为重复写入与测试健壮性等 Warning 级问题,不阻塞但建议修复。

测试建议

  • 补充一条用例:在真实模式(或 fake SDK)下断言生成的 output/optimization_report.json 与仓库提交的 output/ 产物关键字段一致,防止再次出现提交产物与代码漂移(可作为快照校验或直接比对关键 summary 字段)。
  • 暂无其他额外测试建议。

@helloopenworld

Copy link
Copy Markdown
Contributor

AI Code Review

很好,SDK 会展开 ${...},因此 optimizer.json 中的 ${TRPC_AGENT_API_KEY} 等配置会被正确展开。不过,${...} 字面字符串会出现在提交的 optimization_report.json 的 config 快照中(optimizer payload 是原样包含的)。这本身不算泄露(只是占位符),但报告会在 config 部分包含这些字面占位符。不算泄露。OK。

注意:如果设置了 TRPC_AGENT_API_KEY,并且在 os.path.expandvars 中使用 ${TRPC_AGENT_API_KEY} —— 如果环境变量未设置,它会保持为字面量 ${TRPC_AGENT_API_KEY}。不会发生泄露。OK。

现在我已经掌握了足够的信息来定稿。我的结论是:没有 Critical 问题,有几个小的 Warning/Suggestion。鉴于指示要求避免低价值的建议且限制 Suggestion 的数量,我将只报告真正有维护价值的问题。

让我重新考虑 regex 问题是否符合条件。在 match=="regex" 时使用 re.search(expected, actual) —— expected 是一个参考答案字符串,被当作正则表达式处理。在示例数据中 match="contains",因此不会触发此路径。但代码是通用编写的,如果未来配置了 regex,未处理的 re.error 会导致流水线崩溃。值得提出一个低优先级的 Warning。

再重新考虑一下:_validation_pass_rate_rule 没有被 require_validation_improvement 限制。这是一个真实存在但影响较小的逻辑不一致。作为 Warning 提出。

让我再重新考虑一下是否存在真正的资源/超时问题 —— real 模式按顺序运行用例且没有超时设置,依赖 SDK 自身的超时机制。对于示例来说是可以接受的。

我将定稿并附上这些发现。让我再快速验证一下一个可能确实重要的正确性细节:gate.py 中的 _regression_rule 使用了 case.regression,其中包括 score_down。但 score_down 意味着候选者仍然通过但分数较低 —— 根据配置(allow_regressions=False)将其视为回归是预期的。OK。

现在我来写最终审查报告。我会保持简洁。我指出的问题都很轻微;我应该诚实评估是否需要将其提高到 Warning 级别。我将其报告为两个 Warning 级别的问题(它们都是真实的,但不会阻塞合并)。

实际上,让我重新考虑一下 pass-rate 规则是否真的会产生错误行为。当 require_validation_improvement=False 时:score rule 通过(短路)。Pass-rate rule:delta.val.pass_rate_delta >= min_val_pass_rate_gain。默认 min_val_pass_rate_gain=0.0。因此,只有当 pass_rate_delta 为负时才会失败(通过率下降)。通过率下降确实是一种回归形式,所以拒绝是合理的。只有当用户设置 min_val_pass_rate_gain > 0require_validation_improvement=False 时,这种不一致才有意义 —— 这是一种不寻常的组合。影响非常小。我会将其合并或降级。

我将提出 regex 问题作为主要可操作项,pass-rate 不一致作为一个次要问题。我不需要 Suggestion,因为它们价值很低。让我写下来。基于对 pr.diff(新增的 eval-optimize-loop 示例)及其与 trpc_agent_sdk.evaluation 上下游接口的对照审查,结论如下。

发现的问题

⚠️ Warning

  • examples/optimization/eval_optimize_loop/pipeline/pipeline.py:996_text_matchesregex 分支):参考答案被直接当作正则模式使用,未做异常兜底

    • 当 metric 配置 match == "regex" 时,re.search(expected, actual) 把 evalset 中的参考答案字符串当成正则编译;若参考答案含非法正则字符会抛 re.error 并中断整条 pipeline,且该路径没有任何 try/except。当前示例 optimizer.json 用的是 contains,所以不会触发,但该函数是按通用匹配策略实现的,未来改配置即会命中。建议对 regex 分支包一层异常处理,降级为不匹配而非崩溃。
  • examples/optimization/eval_optimize_loop/pipeline/gate.py:1115_validation_pass_rate_rule):通过率规则未受 require_validation_improvement 开关控制,与分数规则语义不一致

    • _validation_score_rulerequire_validation_improvement=False 时直接放行,但 _validation_pass_rate_rule 始终按 min_val_pass_rate_gain 判定。默认 min_val_pass_rate_gain=0.0 时影响有限,但用户显式调高该值并关闭 require_validation_improvement 时会得到与预期不符的拒绝。建议与分数规则保持一致的开关语义。

总结

整体风险较低:fake/real 两条链路与 trpc_agent_sdk.evaluation 的接口(AgentOptimizer.optimizeAgentEvaluator.evaluate_eval_set、call_agent 与 trace 模式互斥、eval_mode 校验等)均对齐,提交产物与测试断言一致,无安全或数据正确性阻塞问题。上述两条均为非立即失败的边界/一致性隐患,不构成必须修复项。

测试建议

暂无额外测试建议。现有测试已覆盖归因分类、delta、gate 各规则与 fake/real 端到端报告;若采纳上面 regex 兜底建议,可补一条 match=="regex" 且参考答案含非法正则时 pipeline 不崩溃的用例。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

构建 Evaluation + Optimization 的自动回归与提示词优化闭环

2 participants