系统要求:实现一个只需要使用语言即可使用的选课系统,不包含任何GUI。被调用的函数可以使用copilot生成,不需要使用数据库,只需要能够模拟对应功能。

基础功能

  • 查询:带有筛选的查询,可以筛选必修或选修
  • 选课:选择需要的课程,智能返回结果,成功返回选课结果,未成功返回错误
  • 删除:删除选择的课程,智能返回结果

进阶功能

  • 查询增强,根据描述返回用户最为感兴趣的课程。例如:用户喜欢体育,羽毛球等放在前面
  • 选择增强:当用户在选课和删除时提供的课程不准确时,智能提供可能用户想提的课程

环境搭建
python库:https://github.com/QwenLM/Qwen-Agent
调用模型的设置可以参考如下:

'model' : 'Qwen2.5-14B',
'model_server' : 'http://10.58.0.2:8000/v1', ;
'api_key' : 'None',

程序代码

import pprint
import urllib.parse
import json5
from qwen_agent.agents import Assistant
from qwen_agent.tools.base import BaseTool, register_tool


# 步骤 1:添加自定义工具用于选课系统相关操作
# 自定义查询课程工具
@register_tool('query_courses_tool')
class QueryCoursesTool(BaseTool):
description = '用于查询课程信息,可根据课程类别(如基础课、专业课、拓展课、体育课、艺术课)或必修选修属性来筛选课程。'
parameters = [
{
'name': 'category',
'type': 'string',
'description': '课程类别(可选值:基础课、专业课、拓展课、体育课、艺术课),若不指定则查询所有课程',
'required': False
},
{
'name': 'is_required',
'type': 'boolean',
'description': '是否必修(True表示必修,False表示选修),若不指定则不区分必修选修进行查询',
'required': False
}
]

def call(self, params: str, **kwargs) -> str:
params_dict = json5.loads(params)
category = params_dict.get('category')
is_required = params_dict.get('is_required')

result = []
for course_name, course_info in courses.items():
if (category is None or course_info["category"] == category) and \
(is_required is None or course_info["is_required"] == is_required):
result.append(course_name)
# 按照类别排序课程(可按需调整排序逻辑)
result.sort(key=lambda x: courses[x]["category"])
return json5.dumps(result, ensure_ascii=False)


# 自定义选课工具
@register_tool('select_course_tool')
class SelectCourseTool(BaseTool):
description = '用于选择指定的课程,若课程存在则添加到已选课程列表中。'
parameters = [
{
'name': 'course_name',
'type': 'string',
'description': '要选择的课程名称',
'required': True
}
]

def call(self, params: str, **kwargs) -> str:
course_name = json5.loads(params)['course_name']
if course_name in courses:
selected_courses.append(course_name)
return json5.dumps(f"成功选择课程:{course_name}", ensure_ascii=False)
else:
# 构造提示语,明确要求智能体返回课程名列表形式的相似课程
similar_courses_prompt = f"如果课程库中不存在课程 '{course_name}',请根据课程名的相似性,从以下课程中找出与之相似的课程,并以列表形式返回:{', '.join(courses.keys())}"
similar_courses_result = bot.run([{"role": "user", "content": similar_courses_prompt}])
similar_courses = []
for res in similar_courses_result:
try:
content = json5.loads(res['content'])
if isinstance(content, list):
similar_courses = content
except:
continue
if similar_courses:
return json5.dumps(f"未找到课程 {course_name},你可能想选的课程有:{', '.join(similar_courses)}", ensure_ascii=False)
return json5.dumps(f"课程 {course_name} 不存在,无法选课", ensure_ascii=False)


# 自定义删除课程工具
@register_tool('delete_course_tool')
class DeleteCourseTool(BaseTool):
description = '用于删除已选的指定课程,若课程在已选课程列表中则进行删除操作。'
parameters = [
{
'name': 'course_name',
'type': 'string',
'description': '要删除的课程名称',
'required': True
}
]

def call(self, params: str, **kwargs) -> str:
course_name = json5.loads(params)['course_name']
global selected_courses
if course_name in selected_courses:
selected_courses.remove(course_name)
return json5.dumps(f"成功删除课程:{course_name}", ensure_ascii=False)
else:
# 构造提示语,明确要求智能体返回课程名列表形式的相似课程
similar_courses_prompt = f"如果已选课程列表中不存在课程 '{course_name}',请根据课程名的相似性,从以下已选课程中找出与之相似的课程,并以列表形式返回:{', '.join(selected_courses)}"
similar_courses_result = bot.run([{"role": "user", "content": similar_courses_prompt}])
similar_courses = []
for res in similar_courses_result:
try:
content = json5.loads(res['content'])
if isinstance(content, list):
similar_courses = content
except:
continue
if similar_courses:
return json5.dumps(f"未找到已选课程 {course_name},你可能想删的课程有:{', '.join(similar_courses)}", ensure_ascii=False)
return json5.dumps(f"课程 {course_name} 不在已选课程中,无法删除", ensure_ascii=False)


# 模拟课程数据,课程字典中键为课程名,值为包含课程类别、是否必修选修等相关信息的字典
courses = {
"高等数学": {"category": "基础课", "is_required": True},
"线性代数": {"category": "基础课", "is_required": True},
"计算机系统基础": {"category": "基础课", "is_required": True},
"大学英语": {"category": "基础课", "is_required": True},
"数据结构": {"category": "专业课", "is_required": True},
"计算机网络": {"category": "专业课", "is_required": True},
"操作系统": {"category": "专业课", "is_required": True},
"计算机组成原理": {"category": "专业课", "is_required": True},
"算法设计与分析": {"category": "专业课", "is_required": True},
"编译原理": {"category": "拓展课", "is_required": False},
"Web应用开发": {"category": "拓展课", "is_required": False},
"软件测试": {"category": "拓展课", "is_required": False},
"量子力学": {"category": "拓展课", "is_required": False},
"羽毛球": {"category": "体育课", "is_required": False},
"篮球": {"category": "体育课", "is_required": False},
"乒乓球": {"category": "体育课", "is_required": False},
"太极拳": {"category": "体育课", "is_required": False},
"游泳": {"category": "体育课", "is_required": True},
"大学美术": {"category": "艺术课", "is_required": False},
"大学音乐": {"category": "艺术课", "is_required": False},
"诗歌朗诵": {"category": "艺术课", "is_required": False}
}

# 初始化已选课程列表
selected_courses = []

# 步骤 2:配置LLM
llm_cfg = {
'model': 'qwen-max',
'model_server': 'dashscope',
'generate_cfg': {
'top_p': 0.8
}
}

# 步骤 3:创建一个智能体
system_instruction = '''你是一个选课系统助手,帮助用户进行课程查询、选课以及删除已选课程等操作。
用户会提出相关需求,你需要调用对应的工具来完成操作,并以中文回复用户告知操作结果。'''
tools = ['query_courses_tool','select_course_tool', 'delete_course_tool']
bot = Assistant(llm=llm_cfg,
system_message=system_instruction,
function_list=tools,
files=[])

# 步骤 4:作为聊天机器人运行智能体
messages = [] # 这里储存聊天历史
while True:
# 获取用户输入请求
query = input('请输入您的选课相关需求(如查询基础课、选择数据结构、删除已选的羽毛球等,输入exit退出):')
if query.lower() == "exit":
break
# 将用户请求添加到聊天历史
messages.append({'role': 'user', 'content': query})
response = []
for response in bot.run(messages=messages):
# 流式输出
print('机器人回应:')
pprint.pprint(response, indent=2)
# 将机器人的回应添加到聊天历史
messages.extend(response)