File size: 6,513 Bytes
38d8dc2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import os
import openai
from openai import APIError
from typing import Dict, List, Union

# 自定义异常
class InsufficientBalanceError(Exception):
    pass

class EvaluationError(Exception):
    pass

# 系统提示词 - 更详细的评分标准
SYS_PROMPT = """你是一个专业的文本质量评估专家。请根据以下标准对文本进行评分(满分10分):

1. 创意性(权重25%): 内容的原创性和新颖性

2. 文采(权重25%): 语言表达的优美程度和修辞手法

3. 格式(权重25%): 结构清晰度、可读性和符合要求的格式

4. 长度(权重25%): 内容长度是否适中(50-300字为佳)

5. 总分(根据四个维度进行加权计算)



评分要求:

- 使用表格形式输出,得到得分表格.

- 每项评分保留1位小数

- 最后简要对目标文本的评价,而不是让你自己再写一个,切记

"""

def evaluate_text_quality(

    text: str,

    api_key: str = None,

    model: str = "deepseek-chat",

    temperature: float = 0.3,

    max_tokens: int = 300

) -> Dict[str, Union[float, str]]:
    # 获取API密钥
    api_key = api_key or os.getenv("you_api_key")
    if not api_key:
        raise ValueError("DeepSeek API密钥未提供")
    
    # 创建客户端
    client = openai.OpenAI(
        api_key=api_key,
        base_url="https://api.deepseek.com/v1"
    )
    
    try:
        # 调用API
        response = client.chat.completions.create(
            model=model,
            messages=[
                {"role": "system", "content": SYS_PROMPT},
                {"role": "user", "content": text}
            ],
            temperature=temperature,
            max_tokens=max_tokens,
            stream=False
        )
        
        # 解析结果
        output = response.choices[0].message.content.strip()
        
        # 从API响应中提取评分
        return parse_evaluation_result(output)
        
    except APIError as e:
        if e.status_code == 402:  # 假设402为余额不足状态码
            raise InsufficientBalanceError("API余额不足,请充值") from e
        else:
            raise EvaluationError(f"API错误[{e.status_code}]: {e.message}") from e
    except Exception as e:
        raise EvaluationError(f"评估失败: {str(e)}") from e

def parse_evaluation_result(output: str) -> Dict[str, Union[float, str]]:
    """

    改进后的评估结果解析函数,能更好处理中文评分表格

    """
    result = {
        "scores": {
            "creativity": 0.0,
            "language": 0.0,
            "format": 0.0,
            "length": 0.0,
            "total": 0.0
        },
        "evaluation": output  # 默认保留全部输出
    }
    
    # 改进的表格解析逻辑
    lines = [line.strip() for line in output.split('\n') if line.strip()]
    
    for line in lines:
        # 处理创意性评分
        if "创意性" in line:
            result["scores"]["creativity"] = extract_score_from_line(line)
        # 处理文采评分
        elif any(key in line for key in ["文采", "语言表达"]):
            result["scores"]["language"] = extract_score_from_line(line)
        # 处理格式评分
        elif "格式" in line:
            result["scores"]["format"] = extract_score_from_line(line)
        # 处理长度评分
        elif "长度" in line:
            result["scores"]["length"] = extract_score_from_line(line)
        # 处理总分
        elif any(key in line for key in ["总分", "总计", "平均"]):
            result["scores"]["total"] = extract_score_from_line(line)
    
    # 提取评价部分(从"评价:"之后的内容)
    evaluation_lines = []
    found_evaluation = False
    for line in lines:
        if any(prefix in line for prefix in ["评价:", "评语:", "总结:"]):
            found_evaluation = True
            line = line.split(":", 1)[-1].strip()
        if found_evaluation and line:
            evaluation_lines.append(line)
    
    if evaluation_lines:
        result["evaluation"] = "\n".join(evaluation_lines)
    
    return result

def extract_score_from_line(line: str) -> float:
    """

    改进的分数提取函数,能处理多种表格格式

    """
    try:
        # 处理 | 创意性 | 8.5 | 这种格式
        if "|" in line:
            parts = [p.strip() for p in line.split("|") if p.strip()]
            for part in parts:
                if part.replace('.', '').isdigit():
                    return float(part)
        
        # 处理 "创意性: 8.5" 这种格式
        if ":" in line or ":" in line:
            parts = line.split(":", 1) if ":" in line else line.split(":", 1)
            num_part = parts[-1].strip()
            for s in num_part.split():
                s = s.replace('/', '').replace('分', '')
                if s.replace('.', '').isdigit():
                    return float(s)
        
        # 直接搜索数字
        for word in line.split():
            word = word.replace('分', '').replace('/', '')
            if word.replace('.', '').isdigit():
                return float(word)
                
    except (ValueError, IndexError):
        pass
    
    return 0.0

    
def print_evaluation_result(

    evaluation: Dict[str, Union[float, str]],

    show_details: bool = True,

    score_only: bool = False

) -> None:
    """

    打印评估结果

    

    参数:

        evaluation: evaluate_text_quality返回的评估结果字典

        show_details: 是否显示详细评价

        score_only: 是否仅显示分数(优先级高于show_details)

    """
    if not evaluation:
        print("无有效评估结果")
        return
    
    scores = evaluation.get("scores", {})
    evaluation_text = evaluation.get("evaluation", "")
    
    # 打印分数摘要
    print("\n=== 文本质量评估 ===")
    print(f"[创意性] {scores.get('creativity', 0.0):.1f}/10")
    print(f"[文采]    {scores.get('language', 0.0):.1f}/10")
    print(f"[格式]    {scores.get('format', 0.0):.1f}/10")
    print(f"[长度]    {scores.get('length', 0.0):.1f}/10")
    print("-" * 25)
    print(f"[总分]    {scores.get('total', 0.0):.1f}/10")
    
    # 根据参数决定是否显示详细评价
    if not score_only and show_details and evaluation_text:
        print("\n=== 详细评价 ===")
        print(evaluation_text)