/
rosalvak
/
test_sber
Обзор
Документация
Войти
/
rosalvak
/
test_sber
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
scripts/make_report.py
168 строк
6 KB
Test DS
AI-агент проверки целевого использования льготных кредитов
13 июл 2026, 18:02
13 июл 2026, 18:02
70dfa90
Код
Авторство
О чём код?
#!/usr/bin/env python3 """Генерация человекочитаемой таблицы-отчёта и графиков. Читать JSON-отчёт пайплайна (``reports/report.json``) и формировать: 1. Markdown-таблицу «что извлечено корректно, что пропущено» — в stdout и в ``reports/summary.md``. 2. Графики распределения уверенности классификации — в ``reports/figures/`` (если установлены pandas/matplotlib). Использование:: python scripts/make_report.py [--input reports/report.json] """ from __future__ import annotations import argparse import json import sys from pathlib import Path from src.config import REPORTS_DIR def _fields_table(documents: list[dict]) -> str: """Таблица: извлечённые поля по каждому документу.""" lines = [ "## Извлечение полей", "", "| Файл | amount | date | inn | contractor | subject |", "|------|--------|------|-----|-----------|---------|", ] for d in documents: f = d["fields"] amt = f["amount"] amt_s = f"{amt:,.2f}" if amt is not None else "—" def cell(v: object) -> str: return str(v) if v is not None else "—" lines.append( f"| {d['file']} | {amt_s} | {cell(f['date'])} | " f"{cell(f['inn'])} | {cell(f['contractor'])} | " f"{cell(f['subject'])} |" ) return "\n".join(lines) def _classification_table(documents: list[dict]) -> str: """Таблица: классификация и проверка предмета.""" lines = [ "## Классификация и проверка предмета", "", "| Файл | тип | conf | предмет? | matches | conf | причина |", "|------|------|------|----------|---------|------|---------|", ] for d in documents: sc = d.get("subject_check") subj = "да" if sc else "нет" if sc: m = "✓" if sc["matches"] else "✗" c = f"{sc['confidence']:.2f}" reason = sc["reason"].replace("|", "/")[:60] else: m, c, reason = "—", "—", "—" lines.append( f"| {d['file']} | {d['doc_type']} | " f"{d['doc_type_confidence']:.2f} | {subj} | " f"{m} | {c} | {reason} |" ) return "\n".join(lines) def _try_make_figures(documents: list[dict], out_dir: Path) -> list[str]: """Построить графики, если доступны pandas/matplotlib.""" try: import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt import pandas as pd except ImportError: print( "ℹ pandas/matplotlib не установлены — графики пропущены. " "Установите: pip install 'credit-doc-agent[viz]'", file=sys.stderr, ) return [] out_dir.mkdir(parents=True, exist_ok=True) df = pd.DataFrame(documents) created: list[str] = [] # Распределение уверенности классификации. fig, ax = plt.subplots(figsize=(7, 4)) ax.hist(df["doc_type_confidence"], bins=10, edgecolor="white", color="#3b82f6") ax.set_xlabel("Уверенность классификации") ax.set_ylabel("Кол-во документов") ax.set_title("Распределение уверенности classify()") p1 = out_dir / "classify_confidence.png" fig.tight_layout() fig.savefig(p1, dpi=150) plt.close(fig) created.append(str(p1)) # Доля типов документов. counts = df["doc_type"].value_counts() fig, ax = plt.subplots(figsize=(6, 4)) ax.bar(counts.index, counts.values, color="#10b981", edgecolor="white") ax.set_ylabel("Кол-во") ax.set_title("Распределение типов документов") p2 = out_dir / "doc_types.png" fig.tight_layout() fig.savefig(p2, dpi=150) plt.close(fig) created.append(str(p2)) return created def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--input", type=Path, default=REPORTS_DIR / "report.json", help="JSON-отчёт пайплайна", ) parser.add_argument( "--output", type=Path, default=REPORTS_DIR / "summary.md", help="Куда сохранить Markdown-сводку", ) args = parser.parse_args(argv) if not args.input.exists(): print( f"⚠ Файл {args.input} не найден. Сначала запустите run_pipeline.py.", file=sys.stderr, ) return 1 data = json.loads(args.input.read_text(encoding="utf-8")) documents = data.get("documents", []) md = [ "# Сводный отчёт по пайплайну", "", f"- Всего файлов: **{data.get('total', 0)}**", f"- Обработано: **{data.get('processed', 0)}**", f"- Требует ручной проверки: **{data.get('needs_manual', 0)}**", "", _fields_table(documents), "", _classification_table(documents), ] figures = _try_make_figures(documents, REPORTS_DIR / "figures") if figures: md.append("\n## Графики\n") for fig_path in figures: md.append(f"") args.output.parent.mkdir(parents=True, exist_ok=True) args.output.write_text("\n".join(md), encoding="utf-8") print(f"✓ Markdown-отчёт: {args.output}") for fig_path in figures: print(f"✓ График: {fig_path}") return 0 if __name__ == "__main__": raise SystemExit(main())