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

This commit is contained in:
2026-08-20 13:12:50 +00:00
commit b119135836
10275 changed files with 3284984 additions and 0 deletions
@@ -0,0 +1,10 @@
"""Helpers for direct execution of tests moved under tests/."""
from pathlib import Path
import sys
def bootstrap_experiment_root() -> None:
experiment_root = Path(__file__).resolve().parents[1]
if str(experiment_root) not in sys.path:
sys.path.insert(0, str(experiment_root))
@@ -0,0 +1,9 @@
"""Test import bootstrap for the elo-leaderboard experiment."""
from pathlib import Path
import sys
EXPERIMENT_ROOT = Path(__file__).resolve().parents[1]
if str(EXPERIMENT_ROOT) not in sys.path:
sys.path.insert(0, str(EXPERIMENT_ROOT))
@@ -0,0 +1,39 @@
"""Empty rating history must not crash analyze_rating_changes / get_rating_history."""
import pandas as pd
from animation import prepare_animation_data
from leaderboard import (
analyze_rating_changes,
build_historical_leaderboards,
get_rating_history,
)
def test_get_rating_history_empty_keeps_columns():
hist = build_historical_leaderboards(
pd.DataFrame(columns=["model_a", "model_b", "winner"]),
[(pd.Timestamp("2020-01-01"), pd.DataFrame(columns=["model_a", "model_b", "winner"]))],
)
rh = get_rating_history(hist)
assert list(rh.columns) == ["date", "model", "rating", "rank", "matches", "wins"]
assert len(rh) == 0
def test_analyze_empty_history_returns_empty_frame():
empty = pd.DataFrame(columns=["date", "model", "rating", "rank", "matches", "wins"])
stats = analyze_rating_changes(empty)
assert len(stats) == 0
assert "model" in stats.columns
def test_analyze_after_empty_historical_leaderboards():
hist = build_historical_leaderboards(
pd.DataFrame(columns=["model_a", "model_b", "winner"]),
[(pd.Timestamp("2020-01-01"), pd.DataFrame(columns=["model_a", "model_b", "winner"]))],
)
rh = get_rating_history(hist)
stats = analyze_rating_changes(rh)
assert len(stats) == 0
anim = prepare_animation_data(rh)
assert anim["frames"] == []
assert anim["total_frames"] == 0
@@ -0,0 +1,11 @@
"""Regression: prepare_animation_data must tolerate empty history."""
import pandas as pd
from animation import prepare_animation_data
def test_empty_history_returns_empty_frames():
df = pd.DataFrame(columns=["date", "model", "rating", "rank", "matches", "wins"])
data = prepare_animation_data(df)
assert data["frames"] == []
assert data["total_frames"] == 0
assert data["start_date"] is None
@@ -0,0 +1,35 @@
"""prepare_animation_data must keep fractional wins from Elo ties."""
import pandas as pd
from animation import prepare_animation_data
def test_tie_half_wins_are_not_truncated():
history = pd.DataFrame(
{
"date": pd.to_datetime(["2024-01-07", "2024-01-07"]),
"model": ["A", "B"],
"rating": [1000.0, 1000.0],
"rank": [1, 2],
"matches": [1, 1],
"wins": [0.5, 0.5],
}
)
data = prepare_animation_data(history, top_n=2)
wins = {m["name"]: m["wins"] for m in data["frames"][0]["models"]}
assert wins["A"] == 0.5
assert wins["B"] == 0.5
def test_whole_wins_still_serialize():
history = pd.DataFrame(
{
"date": pd.to_datetime(["2024-01-07"]),
"model": ["A"],
"rating": [1010.0],
"rank": [1],
"matches": [2],
"wins": [2.0],
}
)
data = prepare_animation_data(history, top_n=1)
assert data["frames"][0]["models"][0]["wins"] == 2.0
@@ -0,0 +1,23 @@
"""
Test suite locking out ZeroDivisionError in benchmark summary print logic
when time_basic is 0.0 or df_sample is empty.
"""
def test_benchmark_pct_reduction_zero_division():
"""
Ensure zero time_basic does not raise ZeroDivisionError during benchmark calculation.
"""
time_basic = 0.0
time_optimized = 0.0
pct_reduction = (1 - time_optimized / time_basic) * 100 if time_basic > 0 else 0.0
assert pct_reduction == 0.0
def test_benchmark_extrapolation_zero_sample():
"""
Ensure empty df_sample does not raise ZeroDivisionError during extrapolation check.
"""
df_sample = []
df_filtered = [1, 2, 3]
should_extrapolate = len(df_sample) > 0 and len(df_sample) < len(df_filtered)
assert not should_extrapolate
@@ -0,0 +1,16 @@
import pandas as pd
from bradley_terry import compute_mle_elo, get_bootstrap_result
def test_bootstrap_is_reproducible():
battles = pd.DataFrame(
[
{"model_a": "a", "model_b": "b", "winner": "model_a"},
{"model_a": "a", "model_b": "b", "winner": "model_b"},
{"model_a": "a", "model_b": "b", "winner": "tie"},
{"model_a": "b", "model_b": "a", "winner": "model_a"},
]
)
first = get_bootstrap_result(battles, compute_mle_elo, num_round=3)
second = get_bootstrap_result(battles, compute_mle_elo, num_round=3)
pd.testing.assert_frame_equal(first, second)
@@ -0,0 +1,11 @@
"""Regression: compute_mle_elo must work on small Arena-shaped battle sets."""
import pandas as pd
from battle_simulator import simulate_battles
from bradley_terry import compute_mle_elo
def test_small_two_model_sample():
df = pd.DataFrame(simulate_battles({"gpt-4": 1200.0, "llama-3": 1000.0}, 10, seed=1))
ratings = compute_mle_elo(df)
assert len(ratings) == 2
assert set(ratings.index) == {"gpt-4", "llama-3"}
@@ -0,0 +1,41 @@
"""Ties must contribute to Bradley-Terry weights (not be zeroed by pivot+T)."""
import pandas as pd
from bradley_terry import compute_mle_elo
def test_all_ties_rates_models_instead_of_sample_weight_error():
df = pd.DataFrame(
[
{"model_a": "A", "model_b": "B", "winner": "tie"},
{"model_a": "A", "model_b": "C", "winner": "tie (bothbad)"},
{"model_a": "B", "model_b": "C", "winner": "tie"},
]
)
ratings = compute_mle_elo(df)
assert set(ratings.index) == {"A", "B", "C"}
# Pure ties -> equal latent skills under BT.
assert abs(float(ratings["A"]) - float(ratings["B"])) < 1e-6
assert abs(float(ratings["A"]) - float(ratings["C"])) < 1e-6
def test_ties_change_ratings_versus_wins_only():
wins_only = pd.DataFrame(
[
{"model_a": "A", "model_b": "B", "winner": "model_a"},
{"model_a": "B", "model_b": "C", "winner": "model_a"},
]
)
with_ties = pd.concat(
[
wins_only,
pd.DataFrame(
[{"model_a": "A", "model_b": "C", "winner": "tie"}] * 8
),
],
ignore_index=True,
)
r1 = compute_mle_elo(wins_only)
r2 = compute_mle_elo(with_ties)
# Extra AC ties pull A and C together relative to the wins-only fit.
assert abs(float(r2["A"]) - float(r2["C"])) < abs(float(r1["A"]) - float(r1["C"]))
@@ -0,0 +1,32 @@
"""Regression test for prepare_animation_data with string or date objects in history_df."""
import pandas as pd
from animation import prepare_animation_data
def test_prepare_animation_data_string_date():
"""prepare_animation_data must handle string dates without raising AttributeError."""
history = pd.DataFrame([
{
"date": "2024-08-01",
"model": "model_a",
"rating": 1050.0,
"rank": 1,
"matches": 10,
"wins": 7.0,
},
{
"date": "2024-08-01",
"model": "model_b",
"rating": 950.0,
"rank": 2,
"matches": 10,
"wins": 3.0,
},
])
data = prepare_animation_data(history, top_n=2)
assert data["total_frames"] == 1
assert data["start_date"] == "2024-08-01"
assert data["end_date"] == "2024-08-01"
assert len(data["frames"]) == 1
assert data["frames"][0]["date"] == "2024-08-01"
assert data["frames"][0]["timestamp"] == 1722470400
@@ -0,0 +1,17 @@
"""Regression test for compare_win_rates when comparisons list is empty."""
import numpy as np
import pandas as pd
from elo_rating import EloRatingSystem
from leaderboard import compare_win_rates
def test_compare_win_rates_empty_has_required_columns():
"""compare_win_rates must return a DataFrame with required columns when no valid comparisons exist."""
elo = EloRatingSystem()
empirical_df = pd.DataFrame(np.nan, index=["model_a", "model_b"], columns=["model_a", "model_b"])
df_comp = compare_win_rates(elo, empirical_df)
assert list(df_comp.columns) == ["model_a", "model_b", "empirical", "predicted", "error"]
assert len(df_comp) == 0
# Accessing columns on empty result must not raise KeyError
assert "error" in df_comp
assert df_comp["error"].empty
+170
View File
@@ -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"])
@@ -0,0 +1,21 @@
"""Regression: filter_data_parallel must tolerate n_jobs > len(df)."""
from unittest.mock import MagicMock, patch
import pandas as pd
from parallel_processing import filter_data_parallel
def test_n_jobs_larger_than_rows():
df = pd.DataFrame({"anony": [True, False, True], "turn": [1, 2, 1]})
def map_inline(fn, chunks):
return [fn(c) for c in chunks]
pool = MagicMock()
pool.__enter__.return_value.map.side_effect = map_inline
pool.__exit__.return_value = False
with patch("parallel_processing.Pool", return_value=pool):
out = filter_data_parallel(df, {"anony_only": True}, n_jobs=8)
assert len(out) == 2
@@ -0,0 +1,37 @@
"""
Regression test for filter_data on empty input (实验 7-7 排行榜).
An empty arena data file (e.g. a failed/truncated download saved as `[]`) used to
crash with ZeroDivisionError at the "After filtering" percentage print.
"""
import pandas as pd
import pytest
from _bootstrap import bootstrap_experiment_root
bootstrap_experiment_root()
from data_loader import filter_data
def test_filter_data_tolerates_empty_dataframe():
"""Empty input no longer raises ZeroDivisionError; returns an empty DataFrame."""
empty = pd.DataFrame({"model_a": [], "model_b": [], "winner": []})
result = filter_data(empty)
assert len(result) == 0
def test_filter_data_normal_case_unchanged():
"""Non-empty input still filters and reports normally."""
df = pd.DataFrame({
"model_a": ["a", "b", "a"],
"model_b": ["b", "a", "c"],
"winner": ["model_a", "model_b", "tie"],
"anony": [True, True, False],
})
result = filter_data(df, anony_only=True, use_dedup=False)
assert len(result) == 2 # 非匿名的一条被过滤
if __name__ == "__main__":
pytest.main([__file__, "-v"])
@@ -0,0 +1,34 @@
"""Empty battles JSON array [] must load as an empty battle frame."""
import json
from pathlib import Path
import cli
def test_load_battles_empty_json_array(tmp_path):
path = tmp_path / "battles.json"
path.write_text("[]", encoding="utf-8")
df = cli._load_battles(str(path))
assert list(df.columns) == ["model_a", "model_b", "winner"]
assert len(df) == 0
def test_load_battles_nonempty_still_requires_columns(tmp_path):
path = tmp_path / "bad.json"
path.write_text(json.dumps([{"x": 1}]), encoding="utf-8")
try:
cli._load_battles(str(path))
assert False, "expected ValueError"
except ValueError as e:
assert "model_a" in str(e)
def test_load_battles_normal(tmp_path):
path = tmp_path / "ok.json"
path.write_text(
json.dumps([{"model_a": "A", "model_b": "B", "winner": "model_a"}]),
encoding="utf-8",
)
df = cli._load_battles(str(path))
assert len(df) == 1
assert df.iloc[0]["winner"] == "model_a"
@@ -0,0 +1,13 @@
"""Regression: optimize_dataframe must tolerate empty object columns."""
import pandas as pd
from parallel_processing import optimize_dataframe
def test_optimize_empty_object_columns():
df = pd.DataFrame({
"model_a": pd.Series([], dtype=object),
"model_b": pd.Series([], dtype=object),
"winner": pd.Series([], dtype=object),
})
out = optimize_dataframe(df)
assert len(out) == 0
@@ -0,0 +1,49 @@
"""
Regression test for 'tie (bothbad)' handling in optimized_elo (实验 7-7 排行榜).
Chatbot Arena battle data has four outcomes; 'tie (bothbad)' was missing from
the outcome map, so Series.map produced NaN. NaN then propagated through the
rating updates and spread to every model that later faced an affected one,
leaving the whole leaderboard NaN.
"""
import numpy as np
import pandas as pd
from optimized_elo import NumpyEloRatingSystem
def test_tie_bothbad_does_not_produce_nan_outcomes():
"""'tie (bothbad)' maps to a tie instead of NaN."""
df = pd.DataFrame({
"model_a": ["a", "a"],
"model_b": ["b", "b"],
"winner": ["model_a", "tie (bothbad)"],
})
_, _, outcomes = NumpyEloRatingSystem()._prepare_data(df)
assert not np.isnan(outcomes).any()
assert outcomes[1] == 0.5
def test_tie_bothbad_does_not_poison_the_leaderboard():
"""One 'tie (bothbad)' battle used to NaN every rating, including model c."""
df = pd.DataFrame({
"model_a": ["a", "a", "b"],
"model_b": ["b", "b", "c"],
"winner": ["model_a", "tie (bothbad)", "model_a"],
})
system = NumpyEloRatingSystem()
system.process_matches_vectorized(df, show_progress=False)
ratings = [rating for _, rating, _, _ in system.get_leaderboard()]
assert len(ratings) == 3
assert not any(np.isnan(r) for r in ratings)
def test_unknown_outcome_falls_back_to_tie():
"""An unrecognized label degrades to a tie rather than NaN."""
df = pd.DataFrame({
"model_a": ["a"],
"model_b": ["b"],
"winner": ["something_new"],
})
_, _, outcomes = NumpyEloRatingSystem()._prepare_data(df)
assert outcomes[0] == 0.5
@@ -0,0 +1,9 @@
"""Regression: documented interval='M' must work on modern pandas."""
import pandas as pd
from data_loader import get_time_slices
def test_monthly_interval_alias():
df = pd.DataFrame({"tstamp": [1_700_000_000, 1_710_000_000]})
slices = get_time_slices(df, interval="M")
assert len(slices) >= 1
@@ -0,0 +1,55 @@
"""
Regression: get_time_slices must not IndexError when the tstamp span is
shorter than the requested interval (default weekly).
Chatbot Arena samples, same-second dumps, and single-row demos all produce an
empty pd.date_range for freq='W'; the old code then crashed on date_ranges[-1].
"""
import pandas as pd
from _bootstrap import bootstrap_experiment_root
bootstrap_experiment_root()
from data_loader import get_time_slices
def test_identical_timestamps_return_one_slice():
"""Two battles at the same unix second (weekly interval) -> one slice."""
ts = 1_700_000_000
df = pd.DataFrame({
"tstamp": [ts, ts],
"model_a": ["a", "c"],
"model_b": ["b", "d"],
"winner": ["model_a", "model_b"],
})
slices = get_time_slices(df, interval="W")
assert len(slices) == 1
end_date, slice_df = slices[0]
assert len(slice_df) == 2
assert end_date == pd.to_datetime(ts, unit="s")
def test_empty_dataframe_returns_empty_list():
"""Empty input returns [] instead of NaT ValueError."""
df = pd.DataFrame({"tstamp": pd.Series(dtype="float64")})
assert get_time_slices(df, interval="W") == []
def test_multi_week_span_still_produces_buckets():
"""A span covering multiple weeks still yields intermediate buckets."""
# ~3 weeks apart
df = pd.DataFrame({
"tstamp": [1_700_000_000, 1_700_000_000 + 21 * 86400],
"model_a": ["a", "c"],
"model_b": ["b", "d"],
"winner": ["model_a", "model_b"],
})
slices = get_time_slices(df, interval="W")
assert len(slices) >= 2
assert all(len(s[1]) > 0 for s in slices)
if __name__ == "__main__":
import pytest
pytest.main([__file__, "-v"])
@@ -0,0 +1,20 @@
import json
from pathlib import Path
def test_canonical_manifest_is_hash_complete():
run_dir = Path(__file__).resolve().parents[1] / "validation" / "runs" / "exp7-7-arena-20260731-v1"
manifest_path = run_dir / "manifest.json"
assert manifest_path.exists()
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
assert manifest["experiment"] == "7-7"
assert manifest["official_complete"] is True
assert all(manifest["gates"].values())
assert set(manifest["artifacts"]) >= {
"summary.json",
"online_elo.json",
"bradley_terry.json",
"win_rate_matrix.json",
"rating_history.json",
"leaderboard_animation.html",
}
@@ -0,0 +1,32 @@
"""Empty battle DataFrame must not crash Bradley-Terry LogisticRegression."""
import pandas as pd
from bradley_terry import compute_bradley_terry_leaderboard, compute_mle_elo
def test_compute_mle_elo_empty_battles():
df = pd.DataFrame(columns=["model_a", "model_b", "winner"])
ratings = compute_mle_elo(df)
assert isinstance(ratings, pd.Series)
assert len(ratings) == 0
def test_compute_bradley_terry_leaderboard_empty():
df = pd.DataFrame(columns=["model_a", "model_b", "winner"])
board = compute_bradley_terry_leaderboard(df)
assert isinstance(board, pd.DataFrame)
assert len(board) == 0
def test_nonempty_still_rates():
df = pd.DataFrame(
[
{"model_a": "A", "model_b": "B", "winner": "model_a"},
{"model_a": "A", "model_b": "B", "winner": "model_a"},
{"model_a": "B", "model_b": "C", "winner": "model_b"},
{"model_a": "A", "model_b": "C", "winner": "model_a"},
]
)
ratings = compute_mle_elo(df)
assert set(ratings.index) >= {"A", "B", "C"}
assert ratings["A"] > ratings["C"]