💻 源码
import json
from typing import Any

from backend.evaluation import format_match_label
from backend.extract_schema import EXTRACT_FIELDS


DIFFICULTY_LABELS = {
    "easy": "简单",
    "medium": "中等",
    "hard": "困难",
}

TASK_LABELS = {
    "classify": "金融文本分类",
    "extract": "金融信息抽取",
    "match": "金融文本匹配",
}


def preview_text(text: str, max_length: int) -> str:
    value = str(text or "").strip().replace("\n", " ")
    if len(value) <= max_length:
        return value
    return f"{value[:max_length]}..."


def format_input_text(task: str, input_data: dict[str, Any], max_length: int) -> str:
    if task == "match":
        text_a = preview_text(input_data.get("text_a", ""), max_length)
        text_b = preview_text(input_data.get("text_b", ""), max_length)
        return f"文本 A: {text_a}\n文本 B: {text_b}"

    return preview_text(input_data.get("text", ""), max_length)


def _format_value(value: Any) -> str:
    if isinstance(value, bool):
        return "true" if value else "false"
    return str(value)


def format_expected_lines(task: str, expected: dict[str, Any] | None) -> list[str]:
    if not expected:
        return ["标准: (无标准标签)"]

    if task == "classify":
        return [f"标准: category = {expected.get('category', '(无)')}"]

    if task == "match":
        return [f"标准: is_match = {_format_value(expected.get('is_match'))}"]

    if task == "extract":
        lines = ["标准:"]
        has_value = False
        for key in EXTRACT_FIELDS:
            value = expected.get(key, [])
            if isinstance(value, list) and value:
                has_value = True
                preview = "、".join(str(item) for item in value[:3])
                suffix = "..." if len(value) > 3 else ""
                lines.append(f"  {key}: {preview}{suffix}")
        if not has_value:
            lines.append("  (无必填字段)")
        return lines

    return [f"标准: {json.dumps(expected, ensure_ascii=False)}"]


def format_result_lines(task: str, result: dict[str, Any] | None) -> list[str]:
    if not result:
        return ["模型: (无)"]

    if task == "classify":
        return [f"模型: category = {result.get('category', '(无)')}"]

    if task == "extract":
        lines = ["模型:"]
        has_value = False
        for key in EXTRACT_FIELDS:
            value = result.get(key, [])
            if isinstance(value, list) and value:
                has_value = True
                preview = "、".join(str(item) for item in value[:3])
                suffix = "..." if len(value) > 3 else ""
                lines.append(f"  {key}: {preview}{suffix}")
            elif isinstance(value, list):
                lines.append(f"  {key}: (空)")
        if not has_value:
            lines.append("  (空)")
        return lines

    if task == "match":
        return [
            f"模型: is_match = {_format_value(result.get('is_match'))}",
            f"       score = {result.get('score')}",
        ]

    return [f"模型: {json.dumps(result, ensure_ascii=False)}"]


def format_summary_value(task: str, item: dict[str, Any]) -> str:
    expected = item.get("expected")
    result = item.get("result")

    if task == "classify":
        standard = expected.get("category", "(无)") if expected else "(无)"
        actual = result.get("category", "(无)") if result else "(无)"
        return f"标准={standard} | 模型={actual}"

    if task == "match":
        standard = _format_value(expected.get("is_match")) if expected else "(无)"
        actual = _format_value(result.get("is_match")) if result else "(无)"
        return f"标准={standard} | 模型={actual}"

    if task == "extract":
        label = format_match_label(item.get("is_correct"))
        return label

    return "(已返回)"


def print_results(
    task: str,
    results: list[dict[str, Any]],
    *,
    output_mode: str,
    text_preview_length: int,
    show_raw_output: bool,
    output_path: str | None = None,
) -> None:
    if output_mode == "json":
        print(json.dumps(results, ensure_ascii=False, indent=2))
        if output_path:
            print(f"\n完整 JSON 已保存到: {output_path}")
        return

    if output_mode == "quiet":
        success_count = sum(1 for item in results if item.get("status") == "success")
        failed_count = len(results) - success_count
        correct_count = sum(1 for item in results if item.get("is_correct") is True)
        compared_count = sum(
            1 for item in results if item.get("is_correct") is not None
        )
        print(
            f"任务 {task} 完成:成功 {success_count} 条,失败 {failed_count} 条,"
            f"正确 {correct_count}/{compared_count} 条。"
        )
        if output_path:
            print(f"完整 JSON 已保存到: {output_path}")
        return

    task_label = TASK_LABELS.get(task, task)
    print("=" * 60)
    print(f"金融文本打标结果 | 任务: {task_label} | 共 {len(results)} 条")
    print("=" * 60)
    print()

    for index, item in enumerate(results, start=1):
        sample_id = item.get("id", f"sample_{index}")
        difficulty = DIFFICULTY_LABELS.get(
            item.get("difficulty", ""),
            item.get("difficulty", "未知"),
        )
        status = "成功" if item.get("status") == "success" else "失败"

        print(f"[{index}/{len(results)}] {sample_id} | 难度: {difficulty}")
        print(format_input_text(task, item.get("input", {}), text_preview_length))
        print()

        for line in format_expected_lines(task, item.get("expected")):
            print(line)
        for line in format_result_lines(task, item.get("result")):
            print(line)

        if item.get("is_correct") is not None:
            print(f"对比: {format_match_label(item.get('is_correct'))}")

        print(f"状态: {status}")

        if item.get("status") != "success":
            print(f"错误: {item.get('error', '未知错误')}")
            if show_raw_output and item.get("raw_output"):
                print(f"原始返回: {item.get('raw_output')}")

        if show_raw_output and item.get("status") == "success" and item.get("raw_output"):
            print(f"原始返回: {item.get('raw_output')}")

        print()

    print("-" * 60)
    print("汇总")
    print("-" * 60)
    for item in results:
        sample_id = item.get("id", "unknown")
        difficulty = DIFFICULTY_LABELS.get(
            item.get("difficulty", ""),
            item.get("difficulty", "未知"),
        )
        status = "成功" if item.get("status") == "success" else "失败"
        compare = format_match_label(item.get("is_correct"))
        summary = format_summary_value(task, item)
        print(f"{sample_id:<12} {difficulty:<4} {compare:<6} {status:<4} {summary}")

    if output_path:
        print()
        print(f"完整 JSON 已保存到: {output_path}")