ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
Unit tests for Elo rating system
|
||||
"""
|
||||
import math
|
||||
|
||||
import pytest
|
||||
|
||||
from _bootstrap import bootstrap_experiment_root
|
||||
|
||||
bootstrap_experiment_root()
|
||||
|
||||
from elo_rating import EloRatingSystem
|
||||
|
||||
|
||||
def test_initial_rating():
|
||||
"""Test that models start with initial rating."""
|
||||
elo = EloRatingSystem(initial_rating=1000.0)
|
||||
assert elo.get_rating("model_a") == 1000.0
|
||||
assert elo.get_rating("model_b") == 1000.0
|
||||
|
||||
|
||||
def test_expected_score():
|
||||
"""Test expected score calculation."""
|
||||
elo = EloRatingSystem()
|
||||
|
||||
# Equal ratings should give 50% probability
|
||||
assert elo.expected_score(1000, 1000) == 0.5
|
||||
|
||||
# Higher rated player should have > 50% probability
|
||||
assert elo.expected_score(1200, 1000) > 0.5
|
||||
assert elo.expected_score(1000, 1200) < 0.5
|
||||
|
||||
# 400 point difference should give ~91% probability
|
||||
prob = elo.expected_score(1400, 1000)
|
||||
assert 0.90 < prob < 0.92
|
||||
|
||||
|
||||
def test_rating_update_win():
|
||||
"""Test rating update when model_a wins."""
|
||||
elo = EloRatingSystem(initial_rating=1000.0, k_factor=32.0)
|
||||
|
||||
new_a, new_b = elo.update_ratings("model_a", "model_b", "model_a")
|
||||
|
||||
# Winner should gain rating, loser should lose rating
|
||||
assert new_a > 1000.0
|
||||
assert new_b < 1000.0
|
||||
|
||||
# Total rating should be conserved (zero-sum)
|
||||
assert abs((new_a + new_b) - 2000.0) < 0.01
|
||||
|
||||
|
||||
def test_rating_update_tie():
|
||||
"""Test rating update for a tie."""
|
||||
elo = EloRatingSystem(initial_rating=1000.0, k_factor=32.0)
|
||||
|
||||
new_a, new_b = elo.update_ratings("model_a", "model_b", "tie")
|
||||
|
||||
# With equal ratings, tie should not change ratings much
|
||||
assert abs(new_a - 1000.0) < 0.01
|
||||
assert abs(new_b - 1000.0) < 0.01
|
||||
|
||||
|
||||
def test_upset_gives_larger_change():
|
||||
"""Test that unexpected results cause larger rating changes."""
|
||||
elo = EloRatingSystem(initial_rating=1000.0, k_factor=32.0)
|
||||
|
||||
# Give model_a higher rating
|
||||
elo.ratings["model_a"] = 1200.0
|
||||
elo.ratings["model_b"] = 1000.0
|
||||
|
||||
# If weaker model wins (upset), changes should be larger
|
||||
new_a_upset, new_b_upset = elo.update_ratings("model_a", "model_b", "model_b")
|
||||
|
||||
# Reset
|
||||
elo.ratings["model_a"] = 1200.0
|
||||
elo.ratings["model_b"] = 1000.0
|
||||
|
||||
# If stronger model wins (expected), changes should be smaller
|
||||
new_a_expected, new_b_expected = elo.update_ratings("model_a", "model_b", "model_a")
|
||||
|
||||
# Upset should cause larger change
|
||||
change_upset = abs(new_a_upset - 1200.0)
|
||||
change_expected = abs(new_a_expected - 1200.0)
|
||||
|
||||
assert change_upset > change_expected
|
||||
|
||||
|
||||
def test_leaderboard_sorting():
|
||||
"""Test that leaderboard is sorted by rating."""
|
||||
elo = EloRatingSystem(initial_rating=1000.0, k_factor=32.0)
|
||||
|
||||
# Create some matches to differentiate ratings
|
||||
elo.update_ratings("model_a", "model_b", "model_a")
|
||||
elo.update_ratings("model_a", "model_c", "model_a")
|
||||
elo.update_ratings("model_b", "model_c", "model_b")
|
||||
|
||||
leaderboard = elo.get_leaderboard()
|
||||
|
||||
# Check descending order
|
||||
for i in range(len(leaderboard) - 1):
|
||||
assert leaderboard[i][1] >= leaderboard[i+1][1]
|
||||
|
||||
# model_a should be first (won all matches)
|
||||
assert leaderboard[0][0] == "model_a"
|
||||
|
||||
|
||||
def test_win_probability_symmetry():
|
||||
"""Test that win probabilities sum to 1."""
|
||||
elo = EloRatingSystem()
|
||||
elo.ratings["model_a"] = 1200.0
|
||||
elo.ratings["model_b"] = 1000.0
|
||||
|
||||
prob_a = elo.calculate_win_probability("model_a", "model_b")
|
||||
prob_b = elo.calculate_win_probability("model_b", "model_a")
|
||||
|
||||
# Should sum to 1
|
||||
assert abs(prob_a + prob_b - 1.0) < 0.001
|
||||
|
||||
|
||||
def test_match_counting():
|
||||
"""Test that match and win counts are tracked correctly."""
|
||||
elo = EloRatingSystem(initial_rating=1000.0, k_factor=32.0)
|
||||
|
||||
elo.update_ratings("model_a", "model_b", "model_a") # model_a wins
|
||||
elo.update_ratings("model_a", "model_c", "model_b") # model_a loses (2nd slot wins)
|
||||
elo.update_ratings("model_a", "model_b", "tie") # tie -> 0.5 each
|
||||
|
||||
# model_a played 3 matches
|
||||
assert elo.match_counts["model_a"] == 3
|
||||
|
||||
# model_a won 1 match and tied 1 (1.5 total)
|
||||
assert elo.win_counts["model_a"] == 1.5
|
||||
|
||||
# model_b played 2 matches
|
||||
assert elo.match_counts["model_b"] == 2
|
||||
|
||||
|
||||
def test_copy():
|
||||
"""Test that copy creates independent instance."""
|
||||
elo1 = EloRatingSystem(initial_rating=1000.0, k_factor=32.0)
|
||||
elo1.update_ratings("model_a", "model_b", "model_a")
|
||||
|
||||
elo2 = elo1.copy()
|
||||
|
||||
# Modify elo2
|
||||
elo2.update_ratings("model_a", "model_b", "model_b")
|
||||
|
||||
# elo1 should be unchanged
|
||||
assert elo1.ratings["model_a"] != elo2.ratings["model_a"]
|
||||
|
||||
|
||||
def test_reset():
|
||||
"""Test that reset clears all data."""
|
||||
elo = EloRatingSystem(initial_rating=1000.0, k_factor=32.0)
|
||||
|
||||
elo.update_ratings("model_a", "model_b", "model_a")
|
||||
elo.update_ratings("model_a", "model_c", "model_a")
|
||||
|
||||
assert len(elo.ratings) > 0
|
||||
|
||||
elo.reset()
|
||||
|
||||
assert len(elo.ratings) == 0
|
||||
assert len(elo.match_counts) == 0
|
||||
assert len(elo.win_counts) == 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run tests
|
||||
pytest.main([__file__, "-v"])
|
||||
Reference in New Issue
Block a user