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,283 @@
|
||||
"""
|
||||
Visualization tools for Elo leaderboard analysis
|
||||
"""
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
from typing import List, Tuple, Optional
|
||||
import plotly.graph_objects as go
|
||||
import plotly.express as px
|
||||
|
||||
|
||||
def plot_leaderboard(leaderboard_data: list, top_n: int = 20, save_path: Optional[str] = None):
|
||||
"""
|
||||
Plot static leaderboard bar chart.
|
||||
|
||||
Args:
|
||||
leaderboard_data: List of (model, rating, matches, wins) tuples
|
||||
top_n: Number of top models to display
|
||||
save_path: If provided, save figure to this path
|
||||
"""
|
||||
# Convert to DataFrame and get top N
|
||||
df = pd.DataFrame(leaderboard_data, columns=['model', 'rating', 'matches', 'wins'])
|
||||
df = df.head(top_n)
|
||||
|
||||
# Create figure
|
||||
fig, ax = plt.subplots(figsize=(12, 8))
|
||||
|
||||
# Create horizontal bar chart
|
||||
bars = ax.barh(range(len(df)), df['rating'], color=plt.cm.viridis(np.linspace(0, 1, len(df))))
|
||||
|
||||
# Customize
|
||||
ax.set_yticks(range(len(df)))
|
||||
ax.set_yticklabels(df['model'])
|
||||
ax.set_xlabel('Elo Rating', fontsize=12)
|
||||
ax.set_title(f'Model Leaderboard - Top {top_n} Models', fontsize=14, fontweight='bold')
|
||||
ax.invert_yaxis() # Highest rating at top
|
||||
|
||||
# Add value labels on bars
|
||||
for i, (rating, matches) in enumerate(zip(df['rating'], df['matches'])):
|
||||
ax.text(rating + 10, i, f'{rating:.0f} ({matches} matches)',
|
||||
va='center', fontsize=9)
|
||||
|
||||
ax.grid(axis='x', alpha=0.3)
|
||||
plt.tight_layout()
|
||||
|
||||
if save_path:
|
||||
plt.savefig(save_path, dpi=300, bbox_inches='tight')
|
||||
print(f"Saved leaderboard to {save_path}")
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_win_rate_matrix(win_rate_df: pd.DataFrame,
|
||||
top_n: int = 15,
|
||||
save_path: Optional[str] = None):
|
||||
"""
|
||||
Plot heatmap of win rate matrix.
|
||||
|
||||
Args:
|
||||
win_rate_df: DataFrame with win rates (rows beat columns)
|
||||
top_n: Number of models to include
|
||||
save_path: If provided, save figure to this path
|
||||
"""
|
||||
# Get top N models by average win rate
|
||||
avg_win_rates = win_rate_df.mean(axis=1).sort_values(ascending=False)
|
||||
top_models = avg_win_rates.head(top_n).index.tolist()
|
||||
|
||||
# Subset matrix
|
||||
subset = win_rate_df.loc[top_models, top_models]
|
||||
|
||||
# Create figure
|
||||
fig, ax = plt.subplots(figsize=(14, 12))
|
||||
|
||||
# Plot heatmap
|
||||
sns.heatmap(subset, annot=True, fmt='.2f', cmap='RdYlGn', center=0.5,
|
||||
vmin=0, vmax=1, square=True, linewidths=0.5,
|
||||
cbar_kws={'label': 'Win Rate'}, ax=ax)
|
||||
|
||||
ax.set_title(f'Win Rate Matrix - Top {top_n} Models\n(Row vs Column)',
|
||||
fontsize=14, fontweight='bold')
|
||||
ax.set_xlabel('Opponent (Column)', fontsize=12)
|
||||
ax.set_ylabel('Model (Row)', fontsize=12)
|
||||
|
||||
plt.tight_layout()
|
||||
|
||||
if save_path:
|
||||
plt.savefig(save_path, dpi=300, bbox_inches='tight')
|
||||
print(f"Saved win rate matrix to {save_path}")
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_rating_history(history_df: pd.DataFrame,
|
||||
models: Optional[List[str]] = None,
|
||||
top_n: int = 10,
|
||||
save_path: Optional[str] = None):
|
||||
"""
|
||||
Plot rating evolution over time for selected models.
|
||||
|
||||
Args:
|
||||
history_df: DataFrame with columns: date, model, rating
|
||||
models: List of specific models to plot (if None, plot top N)
|
||||
top_n: If models not specified, plot top N models by final rating
|
||||
save_path: If provided, save figure to this path
|
||||
"""
|
||||
if models is None:
|
||||
# Get top N models by final rating
|
||||
final_date = history_df['date'].max()
|
||||
final_ratings = history_df[history_df['date'] == final_date].nlargest(top_n, 'rating')
|
||||
models = final_ratings['model'].tolist()
|
||||
|
||||
# Filter data
|
||||
plot_data = history_df[history_df['model'].isin(models)].copy()
|
||||
|
||||
# Create figure
|
||||
fig, ax = plt.subplots(figsize=(14, 8))
|
||||
|
||||
# Plot each model
|
||||
for model in models:
|
||||
model_data = plot_data[plot_data['model'] == model].sort_values('date')
|
||||
ax.plot(model_data['date'], model_data['rating'], marker='o',
|
||||
label=model, linewidth=2, markersize=4)
|
||||
|
||||
ax.set_xlabel('Date', fontsize=12)
|
||||
ax.set_ylabel('Elo Rating', fontsize=12)
|
||||
ax.set_title('Model Rating Evolution Over Time', fontsize=14, fontweight='bold')
|
||||
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=9)
|
||||
ax.grid(alpha=0.3)
|
||||
|
||||
plt.xticks(rotation=45)
|
||||
plt.tight_layout()
|
||||
|
||||
if save_path:
|
||||
plt.savefig(save_path, dpi=300, bbox_inches='tight')
|
||||
print(f"Saved rating history to {save_path}")
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_rating_distribution(leaderboard_data: list, save_path: Optional[str] = None):
|
||||
"""
|
||||
Plot distribution of ratings across all models.
|
||||
|
||||
Args:
|
||||
leaderboard_data: List of (model, rating, matches, wins) tuples
|
||||
save_path: If provided, save figure to this path
|
||||
"""
|
||||
df = pd.DataFrame(leaderboard_data, columns=['model', 'rating', 'matches', 'wins'])
|
||||
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
|
||||
|
||||
# Histogram
|
||||
ax1.hist(df['rating'], bins=30, color='steelblue', edgecolor='black', alpha=0.7)
|
||||
ax1.axvline(df['rating'].mean(), color='red', linestyle='--',
|
||||
linewidth=2, label=f'Mean: {df["rating"].mean():.1f}')
|
||||
ax1.axvline(df['rating'].median(), color='green', linestyle='--',
|
||||
linewidth=2, label=f'Median: {df["rating"].median():.1f}')
|
||||
ax1.set_xlabel('Elo Rating', fontsize=12)
|
||||
ax1.set_ylabel('Count', fontsize=12)
|
||||
ax1.set_title('Rating Distribution', fontsize=13, fontweight='bold')
|
||||
ax1.legend()
|
||||
ax1.grid(alpha=0.3)
|
||||
|
||||
# Box plot
|
||||
ax2.boxplot(df['rating'], vert=True)
|
||||
ax2.set_ylabel('Elo Rating', fontsize=12)
|
||||
ax2.set_title('Rating Box Plot', fontsize=13, fontweight='bold')
|
||||
ax2.grid(alpha=0.3)
|
||||
|
||||
plt.tight_layout()
|
||||
|
||||
if save_path:
|
||||
plt.savefig(save_path, dpi=300, bbox_inches='tight')
|
||||
print(f"Saved rating distribution to {save_path}")
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
def create_interactive_leaderboard(history_df: pd.DataFrame, top_n: int = 15) -> go.Figure:
|
||||
"""
|
||||
Create interactive Plotly visualization of ranking evolution.
|
||||
|
||||
Args:
|
||||
history_df: DataFrame with columns: date, model, rating, rank
|
||||
top_n: Number of top models to include
|
||||
|
||||
Returns:
|
||||
Plotly Figure object
|
||||
"""
|
||||
# Get top N models by final rating
|
||||
final_date = history_df['date'].max()
|
||||
final_ratings = history_df[history_df['date'] == final_date].nlargest(top_n, 'rating')
|
||||
top_models = final_ratings['model'].tolist()
|
||||
|
||||
# Filter data
|
||||
plot_data = history_df[history_df['model'].isin(top_models)].copy()
|
||||
|
||||
# Create figure
|
||||
fig = go.Figure()
|
||||
|
||||
for model in top_models:
|
||||
model_data = plot_data[plot_data['model'] == model].sort_values('date')
|
||||
|
||||
fig.add_trace(go.Scatter(
|
||||
x=model_data['date'],
|
||||
y=model_data['rating'],
|
||||
mode='lines+markers',
|
||||
name=model,
|
||||
hovertemplate='<b>%{fullData.name}</b><br>' +
|
||||
'Date: %{x}<br>' +
|
||||
'Rating: %{y:.0f}<br>' +
|
||||
'<extra></extra>'
|
||||
))
|
||||
|
||||
fig.update_layout(
|
||||
title='Interactive Model Rating Evolution',
|
||||
xaxis_title='Date',
|
||||
yaxis_title='Elo Rating',
|
||||
hovermode='closest',
|
||||
height=600,
|
||||
legend=dict(
|
||||
yanchor="top",
|
||||
y=0.99,
|
||||
xanchor="left",
|
||||
x=0.01
|
||||
)
|
||||
)
|
||||
|
||||
return fig
|
||||
|
||||
|
||||
def create_rank_evolution_chart(history_df: pd.DataFrame, top_n: int = 15) -> go.Figure:
|
||||
"""
|
||||
Create interactive rank evolution chart (lower rank number is better).
|
||||
|
||||
Args:
|
||||
history_df: DataFrame with columns: date, model, rating, rank
|
||||
top_n: Number of models to track
|
||||
|
||||
Returns:
|
||||
Plotly Figure object
|
||||
"""
|
||||
# Get models that were ever in top N
|
||||
models_in_top = history_df[history_df['rank'] <= top_n]['model'].unique()
|
||||
|
||||
# Filter data
|
||||
plot_data = history_df[history_df['model'].isin(models_in_top)].copy()
|
||||
|
||||
# Create figure
|
||||
fig = go.Figure()
|
||||
|
||||
for model in models_in_top:
|
||||
model_data = plot_data[plot_data['model'] == model].sort_values('date')
|
||||
|
||||
fig.add_trace(go.Scatter(
|
||||
x=model_data['date'],
|
||||
y=model_data['rank'],
|
||||
mode='lines+markers',
|
||||
name=model,
|
||||
hovertemplate='<b>%{fullData.name}</b><br>' +
|
||||
'Date: %{x}<br>' +
|
||||
'Rank: #%{y}<br>' +
|
||||
'<extra></extra>'
|
||||
))
|
||||
|
||||
fig.update_layout(
|
||||
title=f'Model Rank Evolution (Top {top_n})',
|
||||
xaxis_title='Date',
|
||||
yaxis_title='Rank',
|
||||
yaxis=dict(autorange='reversed'), # Lower rank at top
|
||||
hovermode='closest',
|
||||
height=600,
|
||||
legend=dict(
|
||||
yanchor="top",
|
||||
y=0.99,
|
||||
xanchor="right",
|
||||
x=0.99
|
||||
)
|
||||
)
|
||||
|
||||
return fig
|
||||
|
||||
Reference in New Issue
Block a user