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 属地四川