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        ?   88.56991%           
==========================================
  Files           ?         491           
  Lines           ?       46885           
  Branches        ?           0           
==========================================
  Hits            ?       41526           
  Misses          ?        5359           
  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 不崩溃的用例。

@raychen911

Copy link
Copy Markdown
Contributor

Closing as related to #92.

@raychen911 raychen911 closed this Aug 2, 2026
@AsyncKurisu

Copy link
Copy Markdown
Author

@raychen911
I would like to kindly ask for some clarification regarding the closure of this PR.
I noticed that the PR was closed with the note "Closed as related to #92," while both the PR title and description indicate that it "Resolves #91." Additionally, the implementation appears to have addressed the requirements described in #91, and the AI review did not identify any critical issues.
Could you please help clarify the reason for closing this PR? I would also appreciate knowing whether there is a possibility of reopening it or if any further changes are needed from my side before it can proceed with the review process.
Thank you very much for your time and guidance.

@helloopenworld

Copy link
Copy Markdown
Contributor

AI Code Review

好的。现在让我重新考虑一个真正的潜在问题:在 _fake_metric_score 中,当 metric_name == "tool_trajectory_avg_score" 时,它使用 _raw_tool_calls(expected) == _raw_tool_calls(actual) 进行比较,但在伪记录(fake record)中,工具调用列表为空(没有 intermediate_data),因此两者均为 [] == [] → 1.0。这对本示例来说是可以的。

让我确认一下本示例中是否没有配置 tool_trajectory 指标(优化器配置中只有 final_response_avg_score)。已确认 —— 只有 final_response_avg_score。所以工具调用路径是无效代码,但不构成 bug。

现在,关于严重程度,让我重新考虑一下 _validation_pass_rate_rule 的不对称性 —— 实际上,如果用户设置了 min_val_pass_rate_gain=0.1 但同时设置了 require_validation_improvement=False,分数规则会被绕过,但通过率规则仍然强制要求 0.1 的增益,这可能会意外地拒绝候选者。这是一个值得注意的轻微设计不一致,但属于边缘情况。我顶多将其标记为建议(suggestion)。

让我对总结进行最后定稿。实际上,鉴于我有严格的要求,只报告可验证的问题,且真正的正确性 bug 很少,让我再重新审视一下 _costs 的相关行:

_costs 计算了所有 train+val 的 case delta,汇总了 case.baseline.costcase.candidate.cost。对于 _missing_ref(),cost 为 None → _cost 返回 0.0。对于额外的候选者,baseline 是 _missing_ref() (cost None→0),candidate 有 cost。没问题。_cost_ratio 在基准 cost==0 时返回 None → ratio_ok = None or cost_ratio <= max。当 cost_ratio 为 None 时,ratio_ok 变为 None,这是 falsy 值!让我重新检查一下:

ratio_ok = cost_ratio is None or cost_ratio <= self.config.max_cost_ratio

如果 cost_ratio 为 None → ratio_ok = (None is None) or ... = True。很好,短路运算了。没问题。

现在让我重新考虑 _cost_rulecost_deltafloat(summary["cost_delta"])cost_delta_round(...) = float。没问题。

鉴于代码质量相当高且测试覆盖良好,且我找不到 Critical 级别的 bug,让我做最终定稿。我需要诚实 —— 并没有明显的阻塞问题。让我报告我确信的内容,避免编造问题。

让我重新考虑测试可发现性(test-discoverability)问题,判断它是否为真正的 Warning 级别问题。根目录的 pyproject.toml 中的 testpaths=["tests"] 意味着在仓库根目录执行普通的 pytest 命令会跳过 examples/optimization/eval_optimize_loop/tests/。README 中说明了在示例目录下运行 pytest tests -q。这与其他示例的模式一致。这是一个真正的可发现性缺口,但符合仓库惯例,所以我将其标记为低价值的建议,甚至不标记。

再检查一件事 —— test_pipeline_reports.py 中的 _path_like_values_are_relative 使用了 Path(value).is_absolute()。在 Windows 上,像 output/optimization_report.json 这样的相对路径不会被判定为绝对路径,这没问题。这不是 bug。

让我重新考虑是否真的存在任何 Critical 问题。鉴于检查结果,我会诚实地说明没有阻塞性问题,并给出 1 个真正的 Warning(通过率规则的不对称性),或许再加上 1 个关于代码重复的建议。

实际上,通过率规则的不对称性确实是一个真正的行为不一致,值得标记。让我确认一下:_validation_score_rule 首先检查 require_validation_improvement;而 _validation_pass_rate_rule 则没有。如果有人设置 require_validation_improvement: false 以禁用验证增益要求,他们可能会惊讶地发现 pass-rate-gain 规则仍然会拒绝候选者。这是一个真正的可维护性/兼容性缺口。Warning 级别。

让我确认一下默认配置和 committed gate.json 中的 min_val_pass_rate_gain=0.0 —— 意味着在实践中它总是通过。所以影响较小。Warning(低优先级)/Suggestion。我会将其标记为 Suggestion 以保持诚实,因为影响很小。

让我写出最终结论。Based on my review of the pr.diff (a new self-contained example examples/optimization/eval_optimize_loop/ plus committed fake-mode report artifacts), I've examined the pipeline logic (attribution, delta, gate, optimization, pipeline, report, types), the config/evalset/prompt files, and the test suite, and cross-checked against the trpc_agent_sdk.evaluation public API and sibling optimization examples.

发现的问题

⚠️ Warning

  • examples/optimization/eval_optimize_loop/pipeline/gate.py:660-674validation_pass_rate_gain 规则未受 require_validation_improvement 控制
    • _validation_score_rule 会在 require_validation_improvement=False 时直接放行,但 _validation_pass_rate_rule 无条件执行 delta.val.pass_rate_delta >= min_val_pass_rate_gain。当用户显式关闭验证集提升要求时,pass-rate 规则仍可能因 min_val_pass_rate_gain>0 拒绝候选,行为与配置语义不一致。建议在该规则开头同样判断 require_validation_improvement,或将两者统一由同一开关控制。当前默认 min_val_pass_rate_gain=0.0 使其恒通过,影响有限。

💡 Suggestion

总结

整体实现质量较高,attribution/delta/gate 的规则覆盖完整且对应测试(含真实模式 SDK 桩)齐备,未发现安全漏洞或导致核心功能失败的逻辑错误。仅有一处 Gate 规则开关不对称的轻微不一致(Warning),以及一处真实模式评测方法重复(Suggestion),均不阻塞合并。

测试建议

暂无额外测试建议;现有测试已覆盖归因分类、delta 变化类型、Gate 各拒绝路径、fake 端到端报告与真实模式 SDK 接缝。如采纳上述 Warning,可补一条 require_validation_improvement=Falsemin_val_pass_rate_gain>0 时 pass-rate 规则应放行的用例。

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 的自动回归与提示词优化闭环

3 participants