Reference:Datawhale wow agent day11
实现内容#
本节课我们将通过 Zigent 框架实现一个出题智能体,其主要功能是根据指定的 Markdown 文件内容自动生成考卷。该智能体支持单选题、多选题和填空题三种题型,并能将生成的考卷保存为 Markdown 文件。
设计思路#
出题智能体的核心功能包括:
- 从指定目录加载 Markdown 文件作为知识来源
- 根据用户指定的受众群体和考察目的生成考卷
- 支持多种题型(单选题、多选题、填空题)
- 自动保存生成的考卷并返回结果路径
代码实现#
定义出题 Action#
定义 QuizGenerationAction 类,负责生成考卷题目:
class QuizGenerationAction(BaseAction):
"""Generate quiz questions from markdown content"""
def __init__(self, llm: LLM) -> None:
action_name = "GenerateQuiz"
action_desc = "Generate quiz questions from markdown content"
params_doc = {
"content": "(Type: string): The markdown content to generate questions from",
"question_types": "(Type: list): List of question types to generate",
"audience": "(Type: string): Target audience for the quiz",
"purpose": "(Type: string): Purpose of the quiz"
}
super().__init__(action_name, action_desc, params_doc)
self.llm = llm
def __call__(self, **kwargs):
content = kwargs.get("content", "")
question_types = kwargs.get("question_types", [])
audience = kwargs.get("audience", "")
purpose = kwargs.get("purpose", "")
prompt = f"""
你是一个辅助设计考卷的机器人,全程使用中文。
你的任务是帮助用户快速创建、设计考卷,考卷以markdown格式给出。
要求:
1. 受众群体:{audience}
2. 考察目的:{purpose}
3. 需要包含以下题型:{", ".join(question_types)}
4. 考卷格式要求:
"""
prompt += """
# 问卷标题
---
1. 这是判断题的题干?
- (x) True
- ( ) False
# (x)为正确答案
2. 这是单选题的题干
- (x) 这是正确选项
- ( ) 这是错误选项
# (x)为正确答案
3. 这是多选题的题干?
- [x] 这是正确选项1
- [x] 这是正确选项2
- [ ] 这是错误选项1
- [ ] 这是错误选项2
# [x]为正确答案
4. 这是填空题的题干?
- R:= 填空题答案
#填空题正确答案格式
"""
prompt += f"\n请根据以下内容生成考卷:\n{content}"
quiz_content = self.llm.run(prompt)
return {
"quiz_content": quiz_content,
"audience": audience,
"purpose": purpose,
"question_types": question_types
}
定义保存 Action#
定义 SaveQuizAction 类,负责保存生成的考卷:
class SaveQuizAction(BaseAction):
"""Save quiz to file and return URL"""
def __init__(self) -> None:
action_name = "SaveQuiz"
action_desc = "Save quiz content to file and return URL"
params_doc = {
"quiz_content": "(Type: string): The quiz content to save",
"quiz_title": "(Type: string): Title of the quiz"
}
super().__init__(action_name, action_desc, params_doc)
def __call__(self, **kwargs):
quiz_content = kwargs.get("quiz_content", "")
quiz_title = kwargs.get("quiz_title", "quiz")
output_dir = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
os.makedirs(output_dir, exist_ok=True)
output_file = os.path.join(output_dir, f"{quiz_title}.md")
with open(output_file, 'w', encoding='utf-8') as f:
f.write(quiz_content)
return {
"file_path": output_file,
"quiz_url": f"/{output_file}"
}
定义出题智能体#
定义 QuizGeneratorAgent 类,管理整个出题流程:
class QuizGeneratorAgent(BaseAgent):
"""Quiz generation agent that manages quiz creation process"""
def __init__(
self,
llm: LLM,
markdown_dir: str
):
name = "QuizGeneratorAgent"
role = """你是一个专业的考卷生成助手。你可以根据提供的Markdown内容生成结构良好、
内容全面的考卷。你擅长根据受众群体和考察目的设计合适的题目。"""
super().__init__(
name=name,
role=role,
llm=llm,
)
self.markdown_dir = markdown_dir
self.quiz_action = QuizGenerationAction(llm)
self.save_action = SaveQuizAction()
self._add_quiz_example()
def _load_markdown_content(self) -> str:
"""Load all markdown files from directory"""
content = []
for root, _, files in os.walk(self.markdown_dir):
for file in files:
if file.endswith(".md"):
with open(os.path.join(root, file), 'r', encoding='utf-8') as f:
content.append(f.read())
return "\n".join(content)
def __call__(self, task: TaskPackage):
"""Process the quiz generation task"""
# Parse task parameters
params = json.loads(task.instruction)
audience = params.get("audience", "")
purpose = params.get("purpose", "")
question_types = params.get("question_types", [])
# Load markdown content
content = self._load_markdown_content()
# Generate quiz
quiz_result = self.quiz_action(
content=content,
question_types=question_types,
audience=audience,
purpose=purpose
)
# Save quiz
save_result = self.save_action(
quiz_content=quiz_result["quiz_content"],
quiz_title="generated_quiz"
)
task.answer = {
"quiz_content": quiz_result["quiz_content"],
"quiz_url": save_result["quiz_url"]
}
task.completion = "completed"
return task
使用#
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 = "deepseek-chat"
llm = LLM(api_key=api_key, base_url=base_url, model_name=chat_model)
# 创建出题智能体
markdown_dir = "docs" # 指定包含Markdown文件的目录
agent = QuizGeneratorAgent(llm=llm, markdown_dir=markdown_dir)
# 定义考卷参数
quiz_params = {
"audience": "高水平", # 受众群体
"purpose": "测试知识掌握情况", # 考察目的
"question_types": ["单选题"] # 需要包含的题型
}
# 生成考卷
task = TaskPackage(instruction=json.dumps(quiz_params))
result = agent(task)
print("生成的考卷内容:")
print(result.answer["quiz_content"])
print(f"考卷路径: {result.answer['quiz_url']}")
结果:
高水平知识掌握情况测试
-
量子力学中,普朗克常数 (h) 的单位是什么?
- (x) 焦耳・秒 (J・s)
- () 牛顿・米 (N・m)
- () 瓦特・秒 (W・s)
- () 库仑・秒 (C・s)
-
在生物化学中,DNA 的双螺旋结构是由哪两位科学家在 1953 年提出的?
- (x) 詹姆斯・沃森和弗朗西斯・克里克
- ( ) 鲁道夫・维尔茨和阿尔伯特・萨克斯
- ( ) 罗伯特・胡克尔和弗朗西斯・克里克
- ( ) 乔治・比德尔和爱德华・塔特姆
-
请列举出以下元素中,属于碱金属元素的是哪一个?
- (x) 钠 (Na)
- () 氯 (Cl)
- () 氧 (O)
- () 硅 (Si)
-
在经典力学中,描述物体在空间中运动状态的基本方程是:
- (x) 牛顿第二定律 ( F = ma )
... - () 氧 (O)
- () 氢 (H)
- () 氯 (Cl)
- (x) 牛顿第二定律 ( F = ma )