学习笔记:利用OpenAI实现阅卷智能体

时间:2025-03-10 09:13:06

https://zhuanlan.zhihu.com/p/18047953492

### 学习笔记:利用OpenAI实现阅卷智能体

#### 一、背景与需求

在各类考试中,选择题、判断题、填空题的阅卷相对简单,只需对比答案与作答是否一致。然而,简答题的阅卷较为复杂,需要对比考生作答的意思是否符合题目要求,通常需要人工阅读作答内容。随着大模型技术的发展,我们可以借助大模型来辅助阅卷,为简答题生成评分和评价。

#### 二、环境搭建与API配置

1. **加载环境变量**:使用`dotenv`库加载环境变量,从`.env`文件中读取`api_key`。

2. **配置API参数**:设置`base_url`和`chat_model`。本教程使用的是自塾提供的大模型API服务,`api_key`和`base_url`已在`.env`文件中配置。在生产环境中,建议使用大厂的大模型API服务,如智谱、零一万物、月之暗面、deepseek等,只需提供`api_key`、`base_url`和`chat_model`即可。

```python

import os

from dotenv import load_dotenv

load_dotenv()

api_key = os.getenv('ZISHU_API_KEY')

base_url = "http://43.200.7.56:8008/v1"

chat_model = "glm-4-flash"

```

#### 三、构造Client

使用`OpenAI`库构造客户端,需要提供`api_key`和`base_url`。

```python

from openai import OpenAI

client = OpenAI(

api_key=api_key,

base_url=base_url

)

```

#### 四、辅助函数与类定义

1. **提取JSON内容**:定义`extract_json_content`函数,用于提取大模型输出中的JSON部分,并删除换行符和首位空白符。

2. **JSON解析器**:定义`JsonOutputParser`类,用于将JSON字符串解析成Python对象。当前实现性能较差,有优化空间。

3. **阅卷类**:定义`GradingOpenAI`类,用于生成评分和评语。类中包含模板字符串,用于生成提示信息,并通过`create_prompt`方法生成具体的提示内容。`grade_answer`方法用于调用大模型生成评分和评语,并通过`output_parser`解析结果。`run`方法用于处理输入数据,生成评分和评语。

```python

import json

import re

def extract_json_content(text):

text = text.replace("\n", "")

pattern = r"```json(.*?)```"

matches = re.findall(pattern, text, re.DOTALL)

if matches:

return matches[0].strip()

return text

class JsonOutputParser:

def parse(self, result):

try:

result = extract_json_content(result)

parsed_result = json.loads(result)

return parsed_result

except json.JSONDecodeError as e:

raise Exception(f"Invalid json output: {result}") from e

class GradingOpenAI:

def __init__(self):

self.model = "glm-4-flash"

self.output_parser = JsonOutputParser()

self.template = """你是一位中国专利代理师考试阅卷专家,

擅长根据给定的题目和答案为考生生成符合要求的评分和中文评语,

并按照特定的格式输出。

你的任务是,根据我输入的考题和答案,针对考生的作答生成评分和中文的评语,并以JSON格式返回。

阅卷标准适当宽松一些,只要考生回答出基本的意思就应当给分。

答案如果有数字标注,含义是考生如果答出这个知识点,这道题就会得到几分。

生成的中文评语需要能够被json.loads()这个函数正确解析。

生成的整个中文评语需要用英文的双引号包裹,在被包裹的字符串内部,请用中文的双引号。

中文评语中不可以出现换行符、转义字符等等。

输出格式为JSON:

{{

"llmgetscore": 0,

"llmcomments": "中文评语"

}}

比较学生的回答与正确答案,

并给出满分为10分的评分和中文评语。

题目:{ques_title}

答案:{answer}

学生的回复:{reply}"""

def create_prompt(self, ques_title, answer, reply):

return self.template.format(

ques_title=ques_title,

answer=answer,

reply=reply

)

def grade_answer(self, ques_title, answer, reply):

success = False

while not success:

try:

response = client.chat.completions.create(

model=self.model,

messages=[

{"role": "system", "content": "你是一位专业的考试阅卷专家。"},

{"role": "user", "content": self.create_prompt(ques_title, answer, reply)}

],

temperature=0.7

)

result = self.output_parser.parse(response.choices[0].message.content)

success = True

except Exception as e:

print(f"Error occurred: {e}")

continue

return result['llmgetscore'], result['llmcomments']

def run(self, input_data):

output = []

for item in input_data:

score, comment = self.grade_answer(

item['ques_title'],

item['answer'],

item['reply']

)

item['llmgetscore'] = score

item['llmcomments'] = comment

output.append(item)

return output

grading_openai = GradingOpenAI()

```

#### 五、示例测试

1. **输入数据**:定义两个简答题的输入数据,包括题目、答案、分值和考生作答。

2. **运行阅卷**:调用`run`方法,传入输入数据,生成评分和评语。

3. **输出结果**:打印生成的评分和评语。

```python

# 示例输入数据

input_data = [

{

'ques_title': '请解释共有技术特征、区别技术特征、附加技术特征、必要技术特征的含义',

'answer': '共有技术特征:与最接近的现有技术共有的技术特征(2.5分); 区别技术特征:区别于最接近的现有技术的技术特征(2.5分); 附加技术特征:对所引用的技术特征进一步限定的技术特征,增加的技术特征(2.5分); 必要技术特征:为解决其技术问题所不可缺少的技术特征(2.5分)。',

'fullscore': 10,

'reply': '共有技术特征:与所对比的技术方案相同的技术特征\n区别技术特征:与所对比的技术方案相区别的技术特征\n附加技术特征:对引用的技术特征进一步限定的技术特征\n必要技术特征:解决技术问题必须可少的技术特征'

},

{

'ques_title': '请解释前序部分、特征部分、引用部分、限定部分',

'answer': '前序部分:独权中,主题+与最接近的现有技术共有的技术特征,在其特征在于之前(2.5分); 特征部分:独权中,与区别于最接近的现有技术的技术特征,在其特征在于之后(2.5分);引用部分:从权中引用的权利要求编号及主题 (2.5分);限定部分:从权中附加技术特征(2.5分)。',

'fullscore': 10,

'reply': '前序部分:独立权利要求中与现有技术相同的技术特征\n特征部分:独立权利要求中区别于现有技术的技术特征\n引用部分:从属权利要求中引用其他权利要求的部分\n限定部分:对所引用的权利要求进一步限定的技术特征'

}

]

# 运行Chain

graded_data = grading_openai.run(input_data)

print(graded_data)

```

#### 六、输出结果

大模型给出的阅卷结果如下:

```json

[

{

'ques_title': '请解释共有技术特征、区别技术特征、附加技术特征、必要技术特征的含义',

'answer': '共有技术特征:与最接近的现有技术共有的技术特征(2.5分); 区别技术特征:区别于最接近的现有技术的技术特征(2.5分); 附加技术特征:对所引用的技术特征进一步限定的技术特征,增加的技术特征(2.5分); 必要技术特征:为解决其技术问题所不可缺少的技术特征(2.5分)。',

'fullscore': 10,

'reply': '共有技术特征:与所对比的技术方案相同的技术特征\n区别技术特征:与所对比的技术方案相区别的技术特征\n附加技术特征:对引用的技术特征进一步限定的技术特征\n必要技术特征:解决技术问题必须可少的技术特征',

'llmgetscore': 10,

'llmcomments': '考生对共有技术特征、区别技术特征、附加技术特征和必要技术特征的解释基本正确,能够准确描述其含义,故给予满分10分。'

},

{

'ques_title': '请解释前序部分、特征部分、引用部分、限定部分',

'answer

发布于 2025-01-13 15:54・IP 属地四川