import logging import os from typing import Dict, Any, List from datetime import datetime from py_markdown_table.markdown_table import markdown_table class ReportGenerator: """Генератор отчетов в формате Markdown.""" def __init__(self): self.logger = logging.getLogger(__name__) def generate_benchmark_report(self, results: Dict[str, Any], output_dir: str = "results", model_name: str = None) -> str: """ Генерация отчета для одного бенчмарка. Args: results: Результаты бенчмарка output_dir: Директория для сохранения отчета model_name: Имя модели (для структурирования результатов) Returns: Путь к сгенерированному файлу """ if model_name: model_dir = os.path.join(output_dir, model_name) os.makedirs(model_dir, exist_ok=True) output_dir = model_dir os.makedirs(output_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"{results['benchmark_name']}_{timestamp}.md" file_path = os.path.join(output_dir, filename) with open(file_path, 'w', encoding='utf-8') as f: f.write(f"# Отчет бенчмарка: {results['benchmark_name']}\n\n") f.write(f"**Дата:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n") f.write(f"**Общее количество тестов:** {results['total_tests']}\n\n") f.write(f"**Успешно выполнено:** {results['successful_tests']}\n\n") # Таблица с результатами table_data = [ { "Тест": "Тест", "Скор": "Скор", "Время (с)": "Время (с)", "Промпт": "Промпт", "Ожидаемый": "Ожидаемый", "Ответ модели": "Ответ модели" } ] for result in results['results']: if 'error' in result: table_data.append({ "Тест": result['test_case'], "Скор": "Ошибка", "Время (с)": "-", "Промпт": result['prompt'][:50] + "..." if len(result['prompt']) > 50 else result['prompt'], "Ожидаемый": result['expected'][:50] + "..." if len(result['expected']) > 50 else result['expected'], "Ответ модели": result['error'] }) else: table_data.append({ "Тест": result['test_case'], "Скор": str(result['score']), "Время (с)": f"{result['latency']:.2f}", "Промпт": result['prompt'][:50] + "..." if len(result['prompt']) > 50 else result['prompt'], "Ожидаемый": result['expected'][:50] + "..." if len(result['expected']) > 50 else result['expected'], "Ответ модели": result['model_response'][:50] + "..." if len(result['model_response']) > 50 else result['model_response'] }) f.write("## Результаты тестов\n\n") f.write(markdown_table(table_data).get_markdown()) f.write("\n\n") # Статистика successful = [r for r in results['results'] if 'score' in r] if successful: avg_score = sum(r['score'] for r in successful) / len(successful) avg_latency = sum(r['latency'] for r in successful) / len(successful) f.write("## Статистика\n\n") f.write(f"- **Средний скор:** {avg_score:.3f}\n") f.write(f"- **Среднее время ответа:** {avg_latency:.3f} секунд\n") self.logger.info(f"Report saved to {file_path}") return file_path def generate_summary_report(self, all_results: List[Dict[str, Any]], output_dir: str = "results", model_name: str = None) -> str: """ Генерация сводного отчета по всем бенчмаркам. Args: all_results: Список результатов всех бенчмарков output_dir: Директория для сохранения отчета model_name: Имя модели (для структурирования результатов) Returns: Путь к сгенерированному файлу """ if model_name: model_dir = os.path.join(output_dir, model_name) os.makedirs(model_dir, exist_ok=True) output_dir = model_dir os.makedirs(output_dir, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"summary_{timestamp}.md" file_path = os.path.join(output_dir, filename) with open(file_path, 'w', encoding='utf-8') as f: f.write("# Сводный отчет по всем бенчмаркам\n\n") f.write(f"**Дата:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n") if model_name: f.write(f"**Модель:** {model_name}\n\n") # Таблица с общими результатами table_data = [ { "Бенчмарк": "Бенчмарк", "Тестов": "Тестов", "Успешно": "Успешно", "Средний скор": "Средний скор", "Среднее время": "Среднее время" } ] for result in all_results: successful = [r for r in result['results'] if 'score' in r] avg_score = sum(r['score'] for r in successful) / len(successful) if successful else 0 avg_latency = sum(r['latency'] for r in successful) / len(successful) if successful else 0 table_data.append({ "Бенчмарк": result['benchmark_name'], "Тестов": str(result['total_tests']), "Успешно": str(result['successful_tests']), "Средний скор": f"{avg_score:.3f}" if successful else "0", "Среднее время": f"{avg_latency:.3f}" if successful else "0" }) f.write("## Общие результаты\n\n") f.write(markdown_table(table_data).get_markdown()) f.write("\n\n") # Подробности по каждому бенчмарку f.write("## Подробности\n\n") for result in all_results: f.write(f"### {result['benchmark_name']}\n\n") f.write(f"- **Тестов:** {result['total_tests']}\n") f.write(f"- **Успешно:** {result['successful_tests']}\n") successful = [r for r in result['results'] if 'score' in r] if successful: avg_score = sum(r['score'] for r in successful) / len(successful) avg_latency = sum(r['latency'] for r in successful) / len(successful) f.write(f"- **Средний скор:** {avg_score:.3f}\n") f.write(f"- **Среднее время:** {avg_latency:.3f} секунд\n") f.write("\n") self.logger.info(f"Summary report saved to {file_path}") return file_path