You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add passive benchmark auto-tagging to daily analysis pipeline
What:
- Add BenchmarkTagger class to src/services/model_benchmark.py:
get_current_model_id() reads the active model from Config.litellm_model
or AgentResult.model; enrich_context_snapshot() injects {"model_id",
"benchmark":true, "benchmark_meta":{latency_ms, total_tokens,
prompt_tokens, completion_tokens, estimated_cost_usd}} into any
existing context_snapshot dict
- Inject auto-tagging into StockAnalysisPipeline in both code paths:
Non-agent path (analyzer.analyze): capture latency via time.perf_counter(),
tag context_snapshot before db.save_analysis_history()
Agent path (executor.run): capture latency + full token usage from
AgentResult.stats, tag initial_context before save
- Add Config fields benchmark_auto_tag (default true) and
benchmark_auto_report (default true), parsed from BENCHMARK_AUTO_TAG
and BENCHMARK_AUTO_REPORT env vars
- Add auto benchmark report generation to main.py: after backtest
completes, if benchmark_auto_report is enabled, automatically call
ModelBenchmarkService.generate_report() and log the accuracy leaderboard
and performance leaderboard, saving to reports/benchmark_*.txt
- Sync .env.example with the two new config entries
Why:
- Users should not need to explicitly invoke the benchmark CLI
(python -m src.services.model_benchmark) to compare model accuracy.
Instead, every normal daily analysis run automatically tags the
context_snapshot with model_id and performance metadata, so that
after the backtest evaluation window passes, a cross-model comparison
report is generated without any extra user action
- The system supports multiple models; users may switch models between
runs. Passive tagging accumulates labeled data over time, enabling
statistically meaningful comparisons without dedicated benchmark runs
- Two-path coverage (agent and non-agent) ensures no analysis is missed
Verification:
- Syntax: all 4 .py files pass py_compile
- flake8: 0 critical errors (E9,F63,F7,F82)
- BenchmarkTagger.get_current_model_id(): correctly resolves agent vs
non-agent model (tested with MockConfig)
- BenchmarkTagger.enrich_context_snapshot():
Non-agent path: injects model_id + benchmark flag, tokens=0 ✓
Agent path: injects full tokens (8500 total, 5100 prompt, 3400 completion)
+ cost ($0.0663 for claude-sonnet-4-6 at 5k+3.4k tokens) ✓
Idempotency: already-tagged snapshots are not overwritten ✓
- Config.benchmark_auto_tag and benchmark_auto_report default to true ✓
- AST verification: BenchmarkTagger imported in both pipeline code paths ✓
- AST verification: ModelBenchmarkService + format_benchmark_report imported
in main.py auto-report block ✓
- .env.example: both BENCHMARK_AUTO_TAG and BENCHMARK_AUTO_REPORT added ✓
Not verified (requires live environment):
- End-to-end main.py run with real API calls and database
- Auto-report query joining backtest_results with benchmark-tagged
analysis_history rows
- Non-agent path real-world latency measurement accuracy
Risk:
- Non-agent path tokens are always 0 (traditional analyzer.analyze() does
not expose token usage). Performance leaderboard will be incomplete for
non-agent runs, but accuracy scoring is unaffected (it only depends on
direction_correct from backtest, not on benchmark_meta)
- context_snapshot grows ~200 bytes per record (benchmark_meta JSON).
Negligible at scale (200KB per 1000 records)
- Lazy import of BenchmarkTagger inside the save block avoids pulling
model_benchmark dependencies at module load time; a failed import is
caught and logged at debug level without blocking the analysis save
- Auto-report text is verbose (~50 lines). Users who find this noisy
can set BENCHMARK_AUTO_REPORT=false
Rollback:
- Set BENCHMARK_AUTO_TAG=false and BENCHMARK_AUTO_REPORT=false in .env
to disable all passive benchmarking without code changes
- Revert the 6 changed files to completely remove the feature
- Existing benchmark fields in context_snapshot are inert: no query
depends on them, they are only consumed by ModelBenchmarkService
.generate_report() which checks for "benchmark":true
---
Commit 2: 设计文档更新(被动评分章节)
docs: add passive benchmarking section to design-model-benchmark.html
What:
- Add "Phase 0: Passive Benchmarking (Zero-Click Background Collection)"
section explaining the auto-tag → passive accumulation → auto-report flow
- Document the two new .env config entries (BENCHMARK_AUTO_TAG,
BENCHMARK_AUTO_REPORT)
- Explain agent vs non-agent path coverage differences
- Clarify relationship between explicit benchmark CLI and passive tagging
- Add BenchmarkTagger to the Dependencies list in meta-box
Why:
- AGENTS.md rule: new features must include updated design documentation
- Users and maintainers need to understand that benchmarking now happens
automatically without explicit CLI invocation
Verification:
- All 4 semantic markers present: Passive Benchmarking, BenchmarkTagger,
BENCHMARK_AUTO_TAG, BENCHMARK_AUTO_REPORT, Zero-Click Background Collection
- HTML structural integrity maintained
Risk: None (docs only)
Rollback: Revert design doc to previous version
0 commit comments