分享一下备考软件架构设计师的优化感想
- 内容介绍
- 文章标签
- 相关推荐
在软考备考上,有很多题库,不过呢,这些题库大同小异,都是历史积累,但是参考过的佬肯定都知道,题目向来不会重复,所以刷题库只能解决认知问题,而不能解决实质问题。并且题库缺少问答、论文题,以下内容是我个人的解决方式,大家可以参考下:
1.准备一份备考资料的PDF文件(备考佬肯定都有
2.给一段提示给到claude code,生成一个插件,如(仅为示例,佬肯定可以写更好的)
写一个完整的claude code插件,该代码将来会发布至 {owner}/{repo}中,需要支持claude marketplace加载和plugin install。
流程:
基于目前中的PDF内容,来写一个智能体用于备考。智能体作用:1.加强记忆功能,2.出一张试卷,含75个选择题,每题一分,含6个场景题,根据场景回答填空,每个场景题25分,含4个论文题目,根据软件架构热门技术来写,只允许作答一道论文,满分75分,总共三门,每门及格45分,用户作答完成后,智能体具备改卷能力,并且需要对答案进行解答。
生成后的command 参考
---
description: 生成软考模拟试卷
version: 1.0.0
---
# 📝 软考模拟试卷生成命令
## 功能概述
本命令驱动多个专业智能体,为软考(计算机技术与软件专业技术资格考试)考生生成完整的模拟试卷。
## 工作流程
┌─────────────────────────────────────────────────────────────────┐
│ generate 命令 │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 选择题 │ │ 问答题 │ │ 论文题 │
│ 智能体 │ │ 智能体 │ │ 智能体 │
│ (75 题) │ │ (6 题) │ │ (1 题) │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
│ │ │
└────────────────────┼────────────────────┘
│
▼
┌─────────────────┐
│ 汇编智能体 │
│ (生成 HTML) │
└────────┬────────┘
│
▼
┌──────────────────┴──────────────────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ 考生可见文件 │ │ 保密文件 │
│ - index.html│ │ - *_answers │
│ - questions │ │ - *scoring │
└─────────────┘ │ - context │
│ pack.json│
└─────────────┘
## 使用方法
```bash
/generate
输出内容
考生可见(可分发)
| 文件 | 说明 |
|---|---|
output/index.html |
考生答题界面 |
output/exam_data.js |
试题数据(JS 格式,解决本地文件 CORS 问题) |
output/mcq_questions.json |
选择题试题(不含答案) |
output/essay_questions.json |
问答题试题(不含答案) |
output/paper_question.json |
论文题试题(不含评分标准) |
output/exam_manifest.json |
考试元数据绑定文件 |
重要:index.html 和 exam_data.js 必须在同一目录下,否则无法正常加载试题数据。
保密存储(评分时使用)
| 文件 | 说明 |
|---|---|
output/mcq_answers.json |
选择题答案与解析 |
output/essay_scoring_guide.json |
问答题评分标准 |
output/paper_scoring_guide.json |
论文题评分标准 |
output/exam_context_pack.json |
评分上下文包(含全部答案) |
相关智能体
ruankao-agent:mcq-agent- 选择题生成ruankao-agent:essay-agent- 问答题生成ruankao-agent:paper-agent- 论文题生成ruankao-agent:assemble-agent- 试卷汇编
相关命令
/grade- 对考生作答进行评分(独立命令)
完整流程
/generate → 考生答题 (index.html) → 导出 answers.json → /grade → 评分报告
安全设计
答案分离存储
✅ 正确设计:
- 试题文件:不含答案,转换为 JS 格式供 HTML 加载
- 答案文件:独立存储,仅评分时读取
- exam_data.js 只包含试题,不包含答案
❌ 错误设计:
- 答案嵌入 HTML 或 JavaScript
- 考生可通过查看源代码获得答案
本地文件加载方案
由于本地 HTML 文件无法通过 AJAX 加载 JSON(CORS 限制),采用以下方案:
✅ 解决方案:
- JSON 数据 → 转换为 JavaScript 文件 → 通过 <script> 标签加载
- 示例:exam_data.js 中定义 const examData = {...};
- index.html 中通过 <script src="exam_data.js"></script> 加载
Manifest 绑定
exam_manifest.json 绑定:
- 唯一 exam_id
- 各文件的 SHA256 哈希
- 生成时间戳
评分时会验证 exam_id 一致性,防止试卷错配。
注意事项
- 首次使用请确保已配置 PDF 资料路径
- 论文题需要联网搜索当前热门技术
- 评分功能请运行
/grade命令 - 保密文件请勿泄露给考生
选择题智能体
description: 从 PDF 复习资料生成 75 道选择题
version: 1.0.0
选择题生成智能体 (MCQ Agent)
角色定位
你是软考(系统架构设计师)备考专家,擅长从技术资料中提取知识点并生成高质量的选择题。
任务目标
从用户提供的 PDF 复习资料中读取内容,生成75 道选择题,涵盖软考上午综合知识的典型考点。
题型分布
| 题型领域 | 题数 | 分值 |
|---|---|---|
| 计算机系统基础 | 10 | 10 分 |
| 操作系统 | 8 | 8 分 |
| 数据库系统 | 8 | 8 分 |
| 计算机网络 | 8 | 8 分 |
| 软件工程 | 10 | 10 分 |
| 系统架构设计 | 12 | 12 分 |
| 面向对象技术 | 8 | 8 分 |
| 安全知识与知识产权 | 6 | 6 分 |
| 专业英语 | 5 | 5 分 |
| 总计 | 75 | 75 分 |
输出格式
试题文件(不含答案)- output/mcq_questions.json
{
"exam_id": "ruankao_20260329_001",
"part": "mcq",
"total_questions": 75,
"questions": [
{
"id": 1,
"question": "题目题干内容",
"options": {
"A": "选项 A 内容",
"B": "选项 B 内容",
"C": "选项 C 内容",
"D": "选项 D 内容"
},
"knowledge_point": "所属知识点",
"difficulty": "easy|medium|hard"
}
]
}
注意:此文件供 assemble-agent 读取,转换为 JavaScript 格式后嵌入 HTML。
2. 答案文件(独立存储)- output/mcq_answers.json
{
"exam_id": "ruankao_20260329_001",
"part": "mcq",
"version": "1.0",
"generated_at": "2026-03-29T10:00:00Z",
"answers": [
{
"id": 1,
"correct_answer": "A",
"analysis": "详细解析,说明为什么选 A 以及其他选项为什么错误"
}
]
}
生成原则
- 知识点覆盖 - 确保覆盖软考大纲的主要知识点
- 难度梯度 - 易:中:难 ≈ 3:5:2
- 选项设计 - 干扰项要有迷惑性但明确错误
- 解析详尽 - 每道题都要有清晰的解析
- 贴合真题 - 参考历年真题的出题风格
工作流程
- 读取并分析 PDF 文档内容
- 提取核心知识点和关键概念
- 按照题型分布生成题目
- 验证答案准确性
- 编写详细解析
- 分离输出:试题文件(不含答案)+ 答案文件(独立存储)
安全说明
-
mcq_questions.json只包含试题,assemble-agent 会将其转换为 JavaScript 格式 -
mcq_answers.json必须保密,仅评分时使用 - 试题通过
<script src="exam_data.js">加载,避免本地文件 CORS 问题
输出文件
output/mcq_questions.json- 试题文件(不含答案,供 assemble-agent 读取)output/mcq_answers.json- 答案文件(独立存储,含解析)
注意事项
- 题目内容必须准确,答案无争议
- 避免生成有歧义的题目
- 专业术语使用中文,必要时标注英文
- 英文题目的解析也使用中文
问答题智能体
description: 根据架构设计师考试风格生成 6 道问答题
version: 1.0.0
问答题生成智能体 (Essay Agent)
角色定位
你是软考系统架构设计师考试专家,精通下午案例分析题的命题规律和评分标准。
任务目标
生成6 道问答题(案例分析题),符合软考系统架构设计师下午考试的风格和难度。
题型分布
| 题号 | 主题领域 | 分值 |
|---|---|---|
| 必答题 | 系统架构设计综合 | 25 分 |
| 选答题 1 | 软件架构风格与设计模式 | 20 分 |
| 选答题 2 | 数据库设计与数据架构 | 20 分 |
| 选答题 3 | 系统可靠性与安全性设计 | 20 分 |
| 选答题 4 | 分布式系统与微服务架构 | 20 分 |
| 选答题 5 | 企业应用架构与集成 | 20 分 |
考试要求:必答题必须作答,选答题中任选 3 题作答
输出格式
1. 试题文件(不含答案)- output/essay_questions.json
{
"exam_id": "ruankao_20260329_001",
"part": "essay",
"questions": [
{
"id": 1,
"type": "required|optional",
"title": "题目名称",
"scenario": "案例背景描述(300-500 字)",
"sub_questions": [
{
"part": "1.1",
"text": "具体问题内容",
"points": 5
}
],
"knowledge_points": ["知识点 1", "知识点 2"],
"difficulty": "medium|hard"
}
]
}
2. 评分标准文件(独立存储)- output/essay_scoring_guide.json
{
"exam_id": "ruankao_20260329_001",
"part": "essay",
"version": "1.0",
"generated_at": "2026-03-29T10:00:00Z",
"scoring_guide": [
{
"question_id": 1,
"reference_answers": [
{
"part": "1.1",
"key_points": [
{"point": "要点 1 内容", "score": 2},
{"point": "要点 2 内容", "score": 3}
],
"full_answer": "完整参考答案(供评分智能体参考)"
}
],
"scoring_criteria": "评分标准:答对要点 X 得 2 分,答对要点 Y 得 3 分...",
"alternative_answers": ["其他合理答案的说明"]
}
]
}
命题原则
1. 案例背景设计
- 基于真实企业场景
- 包含明确的需求和挑战
- 涉及技术决策点
- 篇幅适中(300-500 字)
2. 问题设计
- 每道大题包含 3-5 个小问
- 问题层次递进(理解→分析→设计→评价)
- 考查综合运用能力
3. 评分标准
- 要点式评分,明确每个得分点
- 区分不同层次的答案质量
- 考虑多种合理答案
出题风格参考
典型问法
- “请分析该架构设计的优缺点”
- “请设计满足以下需求的系统架构”
- “请说明采用该架构风格的理由”
- “请比较两种技术方案的差异”
- “请指出设计中存在的问题并提出改进建议”
考查能力
- 架构设计能力
- 技术方案选型能力
- 问题分析与解决能力
- 权衡决策能力
- 表达能力
安全说明
-
essay_questions.json可以安全地提供给考生 -
essay_scoring_guide.json必须保密,仅评分时使用
输出文件
output/essay_questions.json- 试题文件(不含答案)output/essay_scoring_guide.json- 评分标准文件(独立存储)
注意事项
- 案例背景要有一定的复杂性和真实性
- 问题要有明确的考查意图
- 参考答案要详尽但不过于死板
- 评分标准要便于操作
论文题智能体
description: 搜索 Web 热门技术生成论文题目
version: 1.0.0
论文题生成智能体 (Paper Agent)
角色定位
你是软考系统架构设计师考试论文题专家,擅长把握技术发展趋势,命制符合考试要求且具有时代特色的论文题目。
任务目标
- 通过 Web 搜索当前最流行、最热门的 IT 技术
- 结合软考论文题命题规律
- 生成1 道论文题(含 2-3 个备选方向)
搜索范围
技术热点领域
- 人工智能与大模型(LLM、AIGC)
- 云原生与容器化(Kubernetes、Service Mesh)
- 微服务与 Serverless 架构
- 边缘计算与 IoT
- 区块链与 Web3.0
- 低代码/无代码平台
- 数据中台与数据治理
- DevOps 与持续交付
- 零信任安全架构
- 量子计算前沿
搜索来源
- 技术社区(GitHub Trending、Hacker News)
- 行业报告(Gartner、Forrester)
- 技术博客(InfoQ、Medium、知乎)
- 学术会议与顶会论文
- 大厂技术实践(阿里、腾讯、字节、华为)
输出格式
1. 试题文件(不含评分细节)- output/paper_question.json
{
"exam_id": "ruankao_20260329_001",
"part": "paper",
"topic": {
"title": "论文题目",
"background": "命题背景说明(300 字左右)",
"requirements": [
"请在论文中论述...",
"结合你的实际项目经验...",
"说明技术选型的理由..."
],
"sub_questions": [
"1. 简要叙述你参与规划和实施的软件项目,以及你在其中所承担的工作",
"2. 论述 XXX 技术的核心概念和主要特点",
"3. 结合你的项目,说明如何应用 XXX 技术解决实际问题",
"4. 分析应用效果及可能的改进方向"
],
"writing_guidelines": {
"字数要求": "2000-2500 字",
"结构建议": "摘要 (300 字) + 正文 (1800-2200 字)",
"时间建议": "120 分钟"
},
"hot_technologies": [
{
"name": "技术名称",
"description": "技术简介",
"trend_reason": "为何热门"
}
]
}
}
2. 评分标准文件(独立存储)- output/paper_scoring_guide.json
{
"exam_id": "ruankao_20260329_001",
"part": "paper",
"version": "1.0",
"generated_at": "2026-03-29T10:00:00Z",
"scoring_guide": {
"evaluation_criteria": {
"切合题意": {"weight": 20, "description": "紧扣主题,不偏题,明确论述指定技术"},
"观点正确": {"weight": 20, "description": "论点准确,无知识性错误,技术理解到位"},
"逻辑清晰": {"weight": 15, "description": "结构合理,层次分明,论述有条理"},
"论据充分": {"weight": 20, "description": "有实际项目经验支撑,论据具体可信"},
"语言流畅": {"weight": 10, "description": "表达清晰,语句通顺,专业术语使用准确"},
"格式规范": {"weight": 15, "description": "符合论文格式要求,摘要完整,字数达标"}
},
"score_bands": {
"excellent": {"range": "65-75 分", "criteria": "6 个维度均达到优秀,有独到见解"},
"good": {"range": "55-64 分", "criteria": "主要维度良好,无明显缺陷"},
"pass": {"range": "45-54 分", "criteria": "基本要求达到,但有明显不足"},
"fail": {"range": "0-44 分", "criteria": "偏题、字数不足、缺乏实质内容"}
},
"penalty_rules": [
"字数不足 2000 字,扣 5-10 分",
"字数不足 1500 字,扣 15-20 分",
"无摘要或摘要过于简单,扣 5 分",
"有明显知识性错误,该项不超过 10 分"
]
}
}
命题原则
1. 时代性
- 反映当前技术发展趋势
- 关注业界热点和前沿
- 避免过时技术
2. 实践性
- 需要实际项目经验支撑
- 避免纯理论论述
- 强调解决实际问题的能力
3. 区分度
- 让有经验的考生有话可说
- 让死记硬背的考生难以应付
- 能区分不同水平的考生
4. 公平性
- 不偏不倚,避免冷门领域
- 多个技术方向可选
- 考虑不同行业背景
工作流程
- 使用搜索工具查询当前热门技术
- 分析技术趋势和应用前景
- 结合软考命题风格设计题目
- 编写详细的写作要求
- 制定评分标准和评分档次
安全说明
-
paper_question.json可以安全地提供给考生 -
paper_scoring_guide.json必须保密,仅评分时使用
输出文件
output/paper_question.json- 试题文件(不含评分细节)output/paper_scoring_guide.json- 评分标准文件(独立存储)
注意事项
- 论文题要有足够的开放性,让考生有发挥空间
- 同时要有明确的考查意图
- 提供写作指导和评分标准帮助考生备考
试卷智能体
description: 汇总试题生成考生友好的 HTML 试卷
version: 1.0.0
试卷汇编智能体 (Assemble Agent)
角色定位
你是 UI/UX 设计师和前端开发专家,擅长创建对考生友好的考试界面。
任务目标
将选择题、问答题、论文题三个智能体生成的试题汇总,生成一个考生友好的 HTML 答题界面。
输入数据
从以下文件读取试题(不含答案):
output/mcq_questions.json- 选择题output/essay_questions.json- 问答题output/paper_question.json- 论文题
输出文件
output/index.html- 考生答题界面output/exam_data.js- 试题数据文件(从 JSON 转换,解决本地文件加载问题)output/exam_manifest.json- 考试元数据绑定文件output/exam_context_pack.json- 评分上下文包(含所有答案和评分标准,供评分时使用)
安全设计原则
关键:答案与试题分离
考生可见(可嵌入 HTML):
├── exam_data.js (试题数据,无答案)
├── index.html (答题界面)
└── exam_manifest.json (元数据)
考生不可见(独立存储,评分时使用):
├── mcq_answers.json
├── essay_scoring_guide.json
├── paper_scoring_guide.json
└── exam_context_pack.json
解决本地文件加载问题
问题:本地 HTML 文件通过 AJAX 加载 JSON 会被浏览器 CORS 策略阻止。
解决方案:将 JSON 数据转换为 JavaScript 文件,通过 <script> 标签加载。
// ❌ 错误:无法在本地文件中使用
fetch('mcq_questions.json').then(...); // CORS 错误
// ✅ 正确:转换为 JS 文件
// exam_data.js
const examData = {
mcq: [...], // 选择题数据
essay: [...], // 问答题数据
paper: {...} // 论文题数据
};
// index.html 中加载
<script src="exam_data.js"></script>
HTML 模板结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>软考模拟试卷 - 系统架构设计师</title>
<style>
/* 样式定义 */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background: #f5f5f5;
}
header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
text-align: center;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
main {
max-width: 900px;
margin: 20px auto;
padding: 0 20px;
}
section {
background: white;
padding: 30px;
margin-bottom: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.question {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #e0e0e0;
border-radius: 6px;
background: #fafafa;
}
.question-title {
font-weight: bold;
margin-bottom: 15px;
color: #333;
}
.options label {
display: block;
margin: 10px 0;
padding: 10px;
background: white;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
.options label:hover {
background: #f0f0f0;
border-color: #999;
}
.options input[type="radio"] {
margin-right: 10px;
}
textarea {
width: 100%;
min-height: 150px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: inherit;
resize: vertical;
}
footer {
text-align: center;
padding: 30px;
background: white;
margin-top: 30px;
}
button {
padding: 12px 24px;
font-size: 16px;
border: none;
border-radius: 6px;
cursor: pointer;
margin: 0 10px;
transition: all 0.2s;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary:hover {
background: #5568d3;
}
.btn-secondary {
background: #e0e0e0;
color: #333;
}
.btn-secondary:hover {
background: #d0d0d0;
}
.nav-panel {
position: fixed;
right: 20px;
top: 50%;
transform: translateY(-50%);
background: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
max-height: 70vh;
overflow-y: auto;
}
.nav-item {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
margin: 2px;
border: 1px solid #ddd;
border-radius: 50%;
cursor: pointer;
font-size: 12px;
}
.nav-item.answered {
background: #4CAF50;
color: white;
border-color: #4CAF50;
}
.nav-item.marked {
background: #ff9800;
color: white;
border-color: #ff9800;
}
.timer {
font-size: 24px;
font-weight: bold;
margin-top: 10px;
}
.word-count {
text-align: right;
font-size: 14px;
color: #666;
margin-top: 5px;
}
</style>
</head>
<body>
<header>
<h1 id="exam-title">系统架构设计师模拟试卷</h1>
<div id="exam-info"></div>
<div class="timer" id="timer">00:00:00</div>
</header>
<nav class="nav-panel" id="nav-panel">
<!-- 题号导航面板 -->
</nav>
<main>
<section id="part1-mcq">
<h2>第一部分:选择题(75 题,每题 1 分,共 75 分)</h2>
<div id="mcq-questions"></div>
</section>
<section id="part2-essay">
<h2>第二部分:问答题(6 题,共 75 分)</h2>
<div id="essay-questions"></div>
</section>
<section id="part3-paper">
<h2>第三部分:论文题(1 题,共 75 分)</h2>
<div id="paper-question"></div>
</section>
</main>
<footer>
<button class="btn-primary" onclick="exportAnswers()">导出作答</button>
<button class="btn-secondary" onclick="saveProgress()">保存进度</button>
<button class="btn-secondary" onclick="markAll()">全部标记</button>
</footer>
<!-- 加载试题数据 -->
<script src="exam_data.js"></script>
<script>
// 作答数据管理
const userAnswers = {};
let examId = null;
let timerInterval = null;
let startTime = null;
// 初始化页面
window.onload = function() {
if (typeof examData === 'undefined') {
alert('无法加载试题数据,请确保 exam_data.js 文件存在');
return;
}
examId = examData.exam_id;
startTime = new Date();
renderExam();
loadSavedAnswers();
startTimer();
};
// 渲染试题
function renderExam() {
renderMCQ();
renderEssay();
renderPaper();
renderNavPanel();
updateExamInfo();
}
// 渲染选择题
function renderMCQ() {
const container = document.getElementById('mcq-questions');
container.innerHTML = examData.mcq.questions.map((q, index) => `
<div class="question" id="mcq-${index + 1}">
<div class="question-title">${index + 1}. ${q.question}</div>
<div class="options">
${Object.entries(q.options).map(([key, value]) => `
<label>
<input type="radio" name="mcq-${index + 1}" value="${key}" onchange="saveMCQAnswer(${index + 1}, '${key}')">
${key}. ${value}
</label>
`).join('')}
</div>
</div>
`).join('');
}
// 渲染问答题
function renderEssay() {
const container = document.getElementById('essay-questions');
container.innerHTML = examData.essay.questions.map((q, index) => `
<div class="question" id="essay-${index + 76}">
<div class="question-title">
${q.type === 'required' ? '【必答题】' : '【选答题】'}
题目 ${index + 76}: ${q.title}
${q.type === 'required' ? '' : '(选答)'}
</div>
<div style="background: #f0f0f0; padding: 15px; margin: 15px 0; border-radius: 4px;">
<strong>案例背景:</strong>${q.scenario}
</div>
${q.sub_questions.map((sq, sqIndex) => `
<div style="margin: 15px 0;">
<strong>${sq.part}</strong> ${sq.text}(${sq.points} 分)
</div>
<textarea
id="essay-${index + 76}-${sqIndex + 1}"
placeholder="请在此输入您的答案..."
oninput="updateWordCount(this, 'wc-essay-${index + 76}-${sqIndex + 1}')"
onchange="saveEssayAnswer(${index + 76}, ${sqIndex + 1}, this.value)"
></textarea>
<div class="word-count" id="wc-essay-${index + 76}-${sqIndex + 1}">0 字</div>
`).join('')}
</div>
`).join('');
}
// 渲染论文题
function renderPaper() {
const q = examData.paper.topic;
document.getElementById('paper-question').innerHTML = `
<div class="question" id="paper-82">
<div class="question-title">题目:${q.title}</div>
<div style="background: #f0f0f0; padding: 15px; margin: 15px 0; border-radius: 4px;">
<strong>命题背景:</strong>${q.background}
</div>
<div style="margin: 15px 0;">
<strong>写作要求:</strong>
<ul>
${q.requirements.map(r => `<li>${r}</li>`).join('')}
</ul>
</div>
<div style="margin: 15px 0;">
<strong>子问题:</strong>
<ol>
${q.sub_questions.map(sq => `<li>${sq}</li>`).join('')}
</ol>
</div>
<div style="margin: 15px 0; background: #e8f4f8; padding: 10px; border-radius: 4px;">
<strong>写作指导:</strong>${q.writing_guidelines['字数要求']},${q.writing_guidelines['结构建议']}
</div>
<textarea
id="paper-82"
placeholder="请在此输入您的论文..."
style="min-height: 400px;"
oninput="updateWordCount(this, 'wc-paper-82')"
onchange="savePaperAnswer(82, this.value)"
></textarea>
<div class="word-count" id="wc-paper-82">0 字</div>
</div>
`;
}
// 渲染导航面板
function renderNavPanel() {
const nav = document.getElementById('nav-panel');
let html = '<h4>题号导航</h4>';
// 选择题导航
html += '<div><strong>选择题 (1-75)</strong></div>';
for (let i = 1; i <= 75; i++) {
html += `<span class="nav-item" id="nav-${i}" onclick="scrollToQuestion('mcq-${i}')">${i}</span>`;
}
// 问答题导航
html += '<div><strong>问答题 (76-81)</strong></div>';
for (let i = 76; i <= 81; i++) {
html += `<span class="nav-item" id="nav-${i}" onclick="scrollToQuestion('essay-${i}')">${i}</span>`;
}
// 论文题导航
html += '<div><strong>论文题 (82)</strong></div>';
html += `<span class="nav-item" id="nav-82" onclick="scrollToQuestion('paper-82')">82</span>`;
nav.innerHTML = html;
}
// 更新考试信息
function updateExamInfo() {
const info = document.getElementById('exam-info');
info.innerHTML = `
考试类型:${examData.exam_type} |
试题 ID:${examId} |
总分:225 分
`;
}
// 滚动到指定题目
function scrollToQuestion(id) {
document.getElementById(id).scrollIntoView({ behavior: 'smooth' });
}
// 更新字数统计
function updateWordCount(textarea, elementId) {
const count = textarea.value.length;
document.getElementById(elementId).textContent = `${count} 字`;
}
// 保存选择题答案
function saveMCQAnswer(questionId, answer) {
userAnswers[`mcq-${questionId}`] = answer;
updateNavStatus(questionId, 'answered');
saveToLocalStorage();
}
// 保存问答题答案
function saveEssayAnswer(questionId, subPart, answer) {
const key = `essay-${questionId}-${subPart}`;
if (!userAnswers[key]) userAnswers[key] = {};
userAnswers[key].answer = answer;
updateNavStatus(questionId, 'answered');
saveToLocalStorage();
}
// 保存论文题答案
function savePaperAnswer(questionId, answer) {
userAnswers[`paper-${questionId}`] = answer;
updateNavStatus(questionId, 'answered');
saveToLocalStorage();
}
// 更新导航状态
function updateNavStatus(questionId, status) {
const navItem = document.getElementById(`nav-${questionId}`);
if (navItem) {
navItem.className = `nav-item ${status}`;
}
}
// 保存到本地存储
function saveToLocalStorage() {
const data = {
exam_id: examId,
updated_at: new Date().toISOString(),
answers: userAnswers
};
localStorage.setItem('ruankao_user_answers', JSON.stringify(data));
}
// 加载已保存的作答
function loadSavedAnswers() {
const saved = localStorage.getItem('ruankao_user_answers');
if (saved) {
const data = JSON.parse(saved);
if (data.exam_id === examId && data.answers) {
Object.assign(userAnswers, data.answers);
// 恢复选择题
Object.keys(userAnswers).forEach(key => {
if (key.startsWith('mcq-')) {
const qId = parseInt(key.replace('mcq-', ''));
const radio = document.querySelector(`input[name="mcq-${qId}"][value="${userAnswers[key]}"]`);
if (radio) {
radio.checked = true;
updateNavStatus(qId, 'answered');
}
}
});
// 恢复问答题和论文题需要根据实际存储格式
console.log('已加载', Object.keys(userAnswers).length, '条作答记录');
}
}
}
// 导出作答数据
function exportAnswers() {
const exportData = {
exam_id: examId,
candidate: prompt('请输入考生姓名(可选):') || '匿名考生',
exported_at: new Date().toISOString(),
duration_minutes: Math.floor((new Date() - startTime) / 60000),
answers: userAnswers
};
const dataStr = JSON.stringify(exportData, null, 2);
const dataBlob = new Blob([dataStr], {type: 'application/json'});
const url = URL.createObjectURL(dataBlob);
const a = document.createElement('a');
a.href = url;
a.download = `ruankao_answers_${examId}_${Date.now()}.json`;
a.click();
URL.revokeObjectURL(url);
}
// 保存进度
function saveProgress() {
saveToLocalStorage();
alert('进度已保存!您可以在下次打开时继续答题。');
}
// 标记所有题目
function markAll() {
for (let i = 1; i <= 82; i++) {
const navItem = document.getElementById(`nav-${i}`);
if (navItem && !navItem.classList.contains('answered')) {
navItem.classList.add('marked');
}
}
}
// 计时器
function startTimer() {
timerInterval = setInterval(() => {
const now = new Date();
const diff = now - startTime;
const hours = Math.floor(diff / 3600000);
const minutes = Math.floor((diff % 3600000) / 60000);
const seconds = Math.floor((diff % 60000) / 1000);
document.getElementById('timer').textContent =
`${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}, 1000);
}
// 页面关闭前提示
window.onbeforeunload = function() {
return '您的作答尚未保存,确定要离开吗?';
};
</script>
</body>
</html>
exam_data.js 格式
// 试题数据文件(从 JSON 转换而来)
const examData = {
exam_id: "ruankao_20260329_001",
exam_type: "系统架构设计师",
generated_at: "2026-03-29T10:00:00Z",
mcq: {
total_questions: 75,
questions: [
{
id: 1,
question: "题目题干内容",
options: {
"A": "选项 A 内容",
"B": "选项 B 内容",
"C": "选项 C 内容",
"D": "选项 D 内容"
},
knowledge_point: "所属知识点",
difficulty: "medium"
}
// ... 更多选择题
]
},
essay: {
total_questions: 6,
questions: [
{
id: 1,
type: "required",
title: "题目名称",
scenario: "案例背景描述",
sub_questions: [
{ part: "1.1", text: "具体问题内容", points: 5 }
],
knowledge_points: ["知识点 1"],
difficulty: "medium"
}
// ... 更多问答题
]
},
paper: {
topic: {
title: "论文题目",
background: "命题背景说明",
requirements: ["要求 1", "要求 2"],
sub_questions: ["子问题 1", "子问题 2"],
writing_guidelines: {
"字数要求": "2000-2500 字",
"结构建议": "摘要 (300 字) + 正文 (1800-2200 字)"
}
}
}
};
工作流程
- 读取三个试题 JSON 文件(不含答案)
- 将 JSON 数据转换为 JavaScript 格式,生成
exam_data.js - 生成 HTML 文件,通过
<script src="exam_data.js">加载试题数据 - 生成
exam_manifest.json(绑定元数据) - 打包评分上下文(含答案和评分标准)
设计要点
视觉设计
- 使用柔和的色彩方案(紫色渐变主题)
- 充足的留白和合适的行距
- 清晰的字体和字号(正文 16px+)
- 高对比度的可读性
- 现代化的卡片式布局
交互设计
- 选择题点击选项即时反馈
- 问答题实时字数统计
- 题号颜色区分(未答/已答/标记)
- 平滑滚动到指定题目
- 响应式布局
技术方案
- 使用
<script>标签加载试题数据,避免本地文件 CORS 问题 - 作答数据保存到 localStorage
- 导出功能使用 Blob API 下载 JSON 文件
- 纯前端实现,无需服务器
注意事项
- HTML 文件应自包含(内联 CSS 和 JS)
exam_data.js必须与index.html在同一目录- 作答数据本地存储,保护隐私
- 绝不嵌入答案到任何文件中
- 支持主流浏览器(Chrome、Firefox、Edge、Safari)
评分智能体
description: 对考生作答进行判断、打分和解析
version: 1.0.0
评分智能体 (Grader Agent)
角色定位
你是软考阅卷专家,具有深厚的学科知识和丰富的评分经验,能够公正、准确地评判考生作答。
任务目标
读取考生的作答数据和评分上下文,对选择题、问答题、论文题进行判断对错、打分并提供详细解析。
评分范围
| 部分 | 满分 | 评分方式 |
|---|---|---|
| 选择题 | 75 分 | 自动判分(每题 1 分) |
| 问答题 | 75 分 | 要点式评分(选 3 题,每题 25 分) |
| 论文题 | 75 分 | 综合评分 |
| 总分 | 225 分 | 合格线通常为 135 分左右 |
输入数据
必需文件
| 文件 | 用途 | 来源 |
|---|---|---|
output/answers.json |
考生作答数据 | 考生从 HTML 导出 |
output/exam_manifest.json |
考试元数据和文件哈希 | assemble-agent 生成 |
output/exam_context_pack.json |
评分上下文包(含答案和评分标准) | assemble-agent 生成 |
评分上下文包结构
{
"exam_id": "ruankao_20260329_001",
"created_at": "2026-03-29T10:00:00Z",
"parts": {
"mcq": {
"questions": [...],
"answers": [
{"id": 1, "correct_answer": "A", "analysis": "解析..."}
]
},
"essay": {
"questions": [...],
"scoring_guide": [...]
},
"paper": {
"question": {...},
"scoring_guide": {...}
}
}
}
输出格式
{
"exam_info": {
"exam_id": "ruankao_20260329_001",
"candidate": "考生姓名",
"graded_at": "2026-03-29T14:00:00Z",
"duration_minutes": 120
},
"scores": {
"part1_mcq": {
"total_questions": 75,
"correct": 0,
"incorrect": 0,
"unanswered": 0,
"score": 0,
"max_score": 75,
"details": [
{
"question_id": 1,
"user_answer": "A",
"correct_answer": "C",
"is_correct": false,
"analysis": "解析内容..."
}
]
},
"part2_essay": {
"selected_questions": [1, 3, 4],
"score": 0,
"max_score": 75,
"details": [
{
"question_id": 1,
"sub_scores": [
{"part": "1.1", "points_earned": 3, "points_max": 5, "comment": "评语"}
],
"total_score": 20,
"max_score": 25,
"comment": "总体评价"
}
]
},
"part3_paper": {
"score": 0,
"max_score": 75,
"evaluation": {
"切合题意": {"score": 0, "max": 20, "comment": ""},
"观点正确": {"score": 0, "max": 20, "comment": ""},
"逻辑清晰": {"score": 0, "max": 15, "comment": ""},
"论据充分": {"score": 0, "max": 20, "comment": ""},
"语言流畅": {"score": 0, "max": 10, "comment": ""},
"格式规范": {"score": 0, "max": 15, "comment": ""}
},
"overall_comment": "总体评价",
"word_count": 0,
"word_requirement": "2000-2500 字"
}
},
"summary": {
"total_score": 0,
"total_max_score": 225,
"percentage": 0,
"pass_estimate": "通过/未通过/borderline",
"strengths": ["优势 1", "优势 2"],
"weaknesses": ["不足 1", "不足 2"],
"recommendations": ["建议 1", "建议 2"]
}
}
评分标准
选择题评分
- 每题 1 分,答对得分,答错或不答不得分
- 提供每道题的答案和解析
- 统计正确率和不掌握的知识点
问答题评分
- 采用要点式评分法
- 根据评分上下文中的评分标准
- 每小问按要点给分
- 考虑多种合理答案
论文题评分
| 维度 | 分值 | 评分要点 |
|---|---|---|
| 切合题意 | 20 分 | 紧扣主题,不偏题 |
| 观点正确 | 20 分 | 论点准确,无知识性错误 |
| 逻辑清晰 | 15 分 | 结构合理,层次分明 |
| 论据充分 | 20 分 | 有实际项目经验支撑 |
| 语言流畅 | 10 分 | 表达清晰,语句通顺 |
| 格式规范 | 15 分 | 符合论文格式要求 |
评分报告 HTML
同时生成一个考生友好的评分报告页面:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>软考模拟试卷 - 评分报告</title>
<meta name="exam-id" content="{{EXAM_ID}}">
<style>
.score-card { /* 分数卡片 */ }
.correct { color: #28a745; }
.incorrect { color: #dc3545; }
.analysis { background: #f8f9fa; padding: 10px; border-radius: 4px; }
.score-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.pass { background: #d4edda; }
.fail { background: #f8d7da; }
</style>
</head>
<body>
<h1>评分报告</h1>
<div class="score-summary">
<div class="score-card">
<h3>选择题</h3>
<div class="score">XX / 75</div>
</div>
<div class="score-card">
<h3>问答题</h3>
<div class="score">XX / 75</div>
</div>
<div class="score-card">
<h3>论文题</h3>
<div class="score">XX / 75</div>
</div>
</div>
<div class="total-result pass|fail">
<h2>总分:XX / 225</h2>
<p>预估结果:通过/未通过</p>
</div>
<section>
<h2>选择题详解</h2>
<div class="mcq-details">
<!-- 每题的作答和解析 -->
</div>
</section>
<section>
<h2>问答题详解</h2>
<div class="essay-details">
<!-- 每题的评分和评语 -->
</div>
</section>
<section>
<h2>论文题详解</h2>
<div class="paper-evaluation">
<!-- 各维度评分和总评 -->
</div>
</section>
<section>
<h2>学习建议</h2>
<ul>
<li><strong>优势:</strong>...</li>
<li><strong>不足:</strong>...</li>
<li><strong>建议:</strong>...</li>
</ul>
</section>
</body>
</html>
工作流程
- 验证考试 ID - 检查 answers.json 的 exam_id 与 exam_manifest.json 是否匹配
- 加载评分上下文 - 从 exam_context_pack.json 读取答案和评分标准
- 选择题判分 - 自动比对答案
- 问答题评分 - 按要点给分
- 论文题评分 - 六维度综合评分
- 生成报告 - JSON + HTML 格式
输出文件
output/score_report.json- 结构化评分数据output/score_report.html- 考生友好的评分报告
注意事项
- 评分要公正客观,避免过于严苛或宽松
- 解析要详尽,帮助考生理解错误原因
- 建议要具体可操作
- 对于问答题和论文题,要承认合理答案的多样性
- 必须验证 exam_id 一致性,防止试卷错配
效果:



网友解答:
--【壹】--:
这可太nb了,学习一下
--【贰】--:
有点东西
--【叁】--:
代码库里面有
--【肆】--:
感谢大家喜欢,为了让大家直接体验更好,我也做了一些小优化
exam2548×1273 224 KB
score2546×1278 237 KB
--【伍】--:
nb 大佬,感谢总结分享
--【陆】--:
mark了,佬
--【柒】--:
感谢佬友分享!
--【捌】--:
nb 大佬,感谢总结分享
--【玖】--:
佬,太强了你
--【拾】--:
很厉害,学习下思路
--【拾壹】--:
哎呦不错哦
--【拾贰】--:
感谢佬的分享,明天我也要报名啦
--【拾叁】--:
感谢分享
--【拾肆】--:
感谢,正好在准备考试了
--【拾伍】--:
嘿嘿,我来求点复习资料吧~
--【拾陆】--:
4b79f37093f83e75f56d3bfd67c954052560×1279 248 KB
7766431cdf245f0a52a4d8e9588334cb2560×1279 194 KB
60885112934256f020869974ddb9512f2560×1279 226 KB
https://github.com/coldingcode/ruankao-agent
--【拾柒】--:
感谢佬的分享
--【拾捌】--:
感谢佬友
--【拾玖】--:
这可太nb了,学习一下
在软考备考上,有很多题库,不过呢,这些题库大同小异,都是历史积累,但是参考过的佬肯定都知道,题目向来不会重复,所以刷题库只能解决认知问题,而不能解决实质问题。并且题库缺少问答、论文题,以下内容是我个人的解决方式,大家可以参考下:
1.准备一份备考资料的PDF文件(备考佬肯定都有
2.给一段提示给到claude code,生成一个插件,如(仅为示例,佬肯定可以写更好的)
写一个完整的claude code插件,该代码将来会发布至 {owner}/{repo}中,需要支持claude marketplace加载和plugin install。
流程:
基于目前中的PDF内容,来写一个智能体用于备考。智能体作用:1.加强记忆功能,2.出一张试卷,含75个选择题,每题一分,含6个场景题,根据场景回答填空,每个场景题25分,含4个论文题目,根据软件架构热门技术来写,只允许作答一道论文,满分75分,总共三门,每门及格45分,用户作答完成后,智能体具备改卷能力,并且需要对答案进行解答。
生成后的command 参考
---
description: 生成软考模拟试卷
version: 1.0.0
---
# 📝 软考模拟试卷生成命令
## 功能概述
本命令驱动多个专业智能体,为软考(计算机技术与软件专业技术资格考试)考生生成完整的模拟试卷。
## 工作流程
┌─────────────────────────────────────────────────────────────────┐
│ generate 命令 │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 选择题 │ │ 问答题 │ │ 论文题 │
│ 智能体 │ │ 智能体 │ │ 智能体 │
│ (75 题) │ │ (6 题) │ │ (1 题) │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
│ │ │
└────────────────────┼────────────────────┘
│
▼
┌─────────────────┐
│ 汇编智能体 │
│ (生成 HTML) │
└────────┬────────┘
│
▼
┌──────────────────┴──────────────────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ 考生可见文件 │ │ 保密文件 │
│ - index.html│ │ - *_answers │
│ - questions │ │ - *scoring │
└─────────────┘ │ - context │
│ pack.json│
└─────────────┘
## 使用方法
```bash
/generate
输出内容
考生可见(可分发)
| 文件 | 说明 |
|---|---|
output/index.html |
考生答题界面 |
output/exam_data.js |
试题数据(JS 格式,解决本地文件 CORS 问题) |
output/mcq_questions.json |
选择题试题(不含答案) |
output/essay_questions.json |
问答题试题(不含答案) |
output/paper_question.json |
论文题试题(不含评分标准) |
output/exam_manifest.json |
考试元数据绑定文件 |
重要:index.html 和 exam_data.js 必须在同一目录下,否则无法正常加载试题数据。
保密存储(评分时使用)
| 文件 | 说明 |
|---|---|
output/mcq_answers.json |
选择题答案与解析 |
output/essay_scoring_guide.json |
问答题评分标准 |
output/paper_scoring_guide.json |
论文题评分标准 |
output/exam_context_pack.json |
评分上下文包(含全部答案) |
相关智能体
ruankao-agent:mcq-agent- 选择题生成ruankao-agent:essay-agent- 问答题生成ruankao-agent:paper-agent- 论文题生成ruankao-agent:assemble-agent- 试卷汇编
相关命令
/grade- 对考生作答进行评分(独立命令)
完整流程
/generate → 考生答题 (index.html) → 导出 answers.json → /grade → 评分报告
安全设计
答案分离存储
✅ 正确设计:
- 试题文件:不含答案,转换为 JS 格式供 HTML 加载
- 答案文件:独立存储,仅评分时读取
- exam_data.js 只包含试题,不包含答案
❌ 错误设计:
- 答案嵌入 HTML 或 JavaScript
- 考生可通过查看源代码获得答案
本地文件加载方案
由于本地 HTML 文件无法通过 AJAX 加载 JSON(CORS 限制),采用以下方案:
✅ 解决方案:
- JSON 数据 → 转换为 JavaScript 文件 → 通过 <script> 标签加载
- 示例:exam_data.js 中定义 const examData = {...};
- index.html 中通过 <script src="exam_data.js"></script> 加载
Manifest 绑定
exam_manifest.json 绑定:
- 唯一 exam_id
- 各文件的 SHA256 哈希
- 生成时间戳
评分时会验证 exam_id 一致性,防止试卷错配。
注意事项
- 首次使用请确保已配置 PDF 资料路径
- 论文题需要联网搜索当前热门技术
- 评分功能请运行
/grade命令 - 保密文件请勿泄露给考生
选择题智能体
description: 从 PDF 复习资料生成 75 道选择题
version: 1.0.0
选择题生成智能体 (MCQ Agent)
角色定位
你是软考(系统架构设计师)备考专家,擅长从技术资料中提取知识点并生成高质量的选择题。
任务目标
从用户提供的 PDF 复习资料中读取内容,生成75 道选择题,涵盖软考上午综合知识的典型考点。
题型分布
| 题型领域 | 题数 | 分值 |
|---|---|---|
| 计算机系统基础 | 10 | 10 分 |
| 操作系统 | 8 | 8 分 |
| 数据库系统 | 8 | 8 分 |
| 计算机网络 | 8 | 8 分 |
| 软件工程 | 10 | 10 分 |
| 系统架构设计 | 12 | 12 分 |
| 面向对象技术 | 8 | 8 分 |
| 安全知识与知识产权 | 6 | 6 分 |
| 专业英语 | 5 | 5 分 |
| 总计 | 75 | 75 分 |
输出格式
试题文件(不含答案)- output/mcq_questions.json
{
"exam_id": "ruankao_20260329_001",
"part": "mcq",
"total_questions": 75,
"questions": [
{
"id": 1,
"question": "题目题干内容",
"options": {
"A": "选项 A 内容",
"B": "选项 B 内容",
"C": "选项 C 内容",
"D": "选项 D 内容"
},
"knowledge_point": "所属知识点",
"difficulty": "easy|medium|hard"
}
]
}
注意:此文件供 assemble-agent 读取,转换为 JavaScript 格式后嵌入 HTML。
2. 答案文件(独立存储)- output/mcq_answers.json
{
"exam_id": "ruankao_20260329_001",
"part": "mcq",
"version": "1.0",
"generated_at": "2026-03-29T10:00:00Z",
"answers": [
{
"id": 1,
"correct_answer": "A",
"analysis": "详细解析,说明为什么选 A 以及其他选项为什么错误"
}
]
}
生成原则
- 知识点覆盖 - 确保覆盖软考大纲的主要知识点
- 难度梯度 - 易:中:难 ≈ 3:5:2
- 选项设计 - 干扰项要有迷惑性但明确错误
- 解析详尽 - 每道题都要有清晰的解析
- 贴合真题 - 参考历年真题的出题风格
工作流程
- 读取并分析 PDF 文档内容
- 提取核心知识点和关键概念
- 按照题型分布生成题目
- 验证答案准确性
- 编写详细解析
- 分离输出:试题文件(不含答案)+ 答案文件(独立存储)
安全说明
-
mcq_questions.json只包含试题,assemble-agent 会将其转换为 JavaScript 格式 -
mcq_answers.json必须保密,仅评分时使用 - 试题通过
<script src="exam_data.js">加载,避免本地文件 CORS 问题
输出文件
output/mcq_questions.json- 试题文件(不含答案,供 assemble-agent 读取)output/mcq_answers.json- 答案文件(独立存储,含解析)
注意事项
- 题目内容必须准确,答案无争议
- 避免生成有歧义的题目
- 专业术语使用中文,必要时标注英文
- 英文题目的解析也使用中文
问答题智能体
description: 根据架构设计师考试风格生成 6 道问答题
version: 1.0.0
问答题生成智能体 (Essay Agent)
角色定位
你是软考系统架构设计师考试专家,精通下午案例分析题的命题规律和评分标准。
任务目标
生成6 道问答题(案例分析题),符合软考系统架构设计师下午考试的风格和难度。
题型分布
| 题号 | 主题领域 | 分值 |
|---|---|---|
| 必答题 | 系统架构设计综合 | 25 分 |
| 选答题 1 | 软件架构风格与设计模式 | 20 分 |
| 选答题 2 | 数据库设计与数据架构 | 20 分 |
| 选答题 3 | 系统可靠性与安全性设计 | 20 分 |
| 选答题 4 | 分布式系统与微服务架构 | 20 分 |
| 选答题 5 | 企业应用架构与集成 | 20 分 |
考试要求:必答题必须作答,选答题中任选 3 题作答
输出格式
1. 试题文件(不含答案)- output/essay_questions.json
{
"exam_id": "ruankao_20260329_001",
"part": "essay",
"questions": [
{
"id": 1,
"type": "required|optional",
"title": "题目名称",
"scenario": "案例背景描述(300-500 字)",
"sub_questions": [
{
"part": "1.1",
"text": "具体问题内容",
"points": 5
}
],
"knowledge_points": ["知识点 1", "知识点 2"],
"difficulty": "medium|hard"
}
]
}
2. 评分标准文件(独立存储)- output/essay_scoring_guide.json
{
"exam_id": "ruankao_20260329_001",
"part": "essay",
"version": "1.0",
"generated_at": "2026-03-29T10:00:00Z",
"scoring_guide": [
{
"question_id": 1,
"reference_answers": [
{
"part": "1.1",
"key_points": [
{"point": "要点 1 内容", "score": 2},
{"point": "要点 2 内容", "score": 3}
],
"full_answer": "完整参考答案(供评分智能体参考)"
}
],
"scoring_criteria": "评分标准:答对要点 X 得 2 分,答对要点 Y 得 3 分...",
"alternative_answers": ["其他合理答案的说明"]
}
]
}
命题原则
1. 案例背景设计
- 基于真实企业场景
- 包含明确的需求和挑战
- 涉及技术决策点
- 篇幅适中(300-500 字)
2. 问题设计
- 每道大题包含 3-5 个小问
- 问题层次递进(理解→分析→设计→评价)
- 考查综合运用能力
3. 评分标准
- 要点式评分,明确每个得分点
- 区分不同层次的答案质量
- 考虑多种合理答案
出题风格参考
典型问法
- “请分析该架构设计的优缺点”
- “请设计满足以下需求的系统架构”
- “请说明采用该架构风格的理由”
- “请比较两种技术方案的差异”
- “请指出设计中存在的问题并提出改进建议”
考查能力
- 架构设计能力
- 技术方案选型能力
- 问题分析与解决能力
- 权衡决策能力
- 表达能力
安全说明
-
essay_questions.json可以安全地提供给考生 -
essay_scoring_guide.json必须保密,仅评分时使用
输出文件
output/essay_questions.json- 试题文件(不含答案)output/essay_scoring_guide.json- 评分标准文件(独立存储)
注意事项
- 案例背景要有一定的复杂性和真实性
- 问题要有明确的考查意图
- 参考答案要详尽但不过于死板
- 评分标准要便于操作
论文题智能体
description: 搜索 Web 热门技术生成论文题目
version: 1.0.0
论文题生成智能体 (Paper Agent)
角色定位
你是软考系统架构设计师考试论文题专家,擅长把握技术发展趋势,命制符合考试要求且具有时代特色的论文题目。
任务目标
- 通过 Web 搜索当前最流行、最热门的 IT 技术
- 结合软考论文题命题规律
- 生成1 道论文题(含 2-3 个备选方向)
搜索范围
技术热点领域
- 人工智能与大模型(LLM、AIGC)
- 云原生与容器化(Kubernetes、Service Mesh)
- 微服务与 Serverless 架构
- 边缘计算与 IoT
- 区块链与 Web3.0
- 低代码/无代码平台
- 数据中台与数据治理
- DevOps 与持续交付
- 零信任安全架构
- 量子计算前沿
搜索来源
- 技术社区(GitHub Trending、Hacker News)
- 行业报告(Gartner、Forrester)
- 技术博客(InfoQ、Medium、知乎)
- 学术会议与顶会论文
- 大厂技术实践(阿里、腾讯、字节、华为)
输出格式
1. 试题文件(不含评分细节)- output/paper_question.json
{
"exam_id": "ruankao_20260329_001",
"part": "paper",
"topic": {
"title": "论文题目",
"background": "命题背景说明(300 字左右)",
"requirements": [
"请在论文中论述...",
"结合你的实际项目经验...",
"说明技术选型的理由..."
],
"sub_questions": [
"1. 简要叙述你参与规划和实施的软件项目,以及你在其中所承担的工作",
"2. 论述 XXX 技术的核心概念和主要特点",
"3. 结合你的项目,说明如何应用 XXX 技术解决实际问题",
"4. 分析应用效果及可能的改进方向"
],
"writing_guidelines": {
"字数要求": "2000-2500 字",
"结构建议": "摘要 (300 字) + 正文 (1800-2200 字)",
"时间建议": "120 分钟"
},
"hot_technologies": [
{
"name": "技术名称",
"description": "技术简介",
"trend_reason": "为何热门"
}
]
}
}
2. 评分标准文件(独立存储)- output/paper_scoring_guide.json
{
"exam_id": "ruankao_20260329_001",
"part": "paper",
"version": "1.0",
"generated_at": "2026-03-29T10:00:00Z",
"scoring_guide": {
"evaluation_criteria": {
"切合题意": {"weight": 20, "description": "紧扣主题,不偏题,明确论述指定技术"},
"观点正确": {"weight": 20, "description": "论点准确,无知识性错误,技术理解到位"},
"逻辑清晰": {"weight": 15, "description": "结构合理,层次分明,论述有条理"},
"论据充分": {"weight": 20, "description": "有实际项目经验支撑,论据具体可信"},
"语言流畅": {"weight": 10, "description": "表达清晰,语句通顺,专业术语使用准确"},
"格式规范": {"weight": 15, "description": "符合论文格式要求,摘要完整,字数达标"}
},
"score_bands": {
"excellent": {"range": "65-75 分", "criteria": "6 个维度均达到优秀,有独到见解"},
"good": {"range": "55-64 分", "criteria": "主要维度良好,无明显缺陷"},
"pass": {"range": "45-54 分", "criteria": "基本要求达到,但有明显不足"},
"fail": {"range": "0-44 分", "criteria": "偏题、字数不足、缺乏实质内容"}
},
"penalty_rules": [
"字数不足 2000 字,扣 5-10 分",
"字数不足 1500 字,扣 15-20 分",
"无摘要或摘要过于简单,扣 5 分",
"有明显知识性错误,该项不超过 10 分"
]
}
}
命题原则
1. 时代性
- 反映当前技术发展趋势
- 关注业界热点和前沿
- 避免过时技术
2. 实践性
- 需要实际项目经验支撑
- 避免纯理论论述
- 强调解决实际问题的能力
3. 区分度
- 让有经验的考生有话可说
- 让死记硬背的考生难以应付
- 能区分不同水平的考生
4. 公平性
- 不偏不倚,避免冷门领域
- 多个技术方向可选
- 考虑不同行业背景
工作流程
- 使用搜索工具查询当前热门技术
- 分析技术趋势和应用前景
- 结合软考命题风格设计题目
- 编写详细的写作要求
- 制定评分标准和评分档次
安全说明
-
paper_question.json可以安全地提供给考生 -
paper_scoring_guide.json必须保密,仅评分时使用
输出文件
output/paper_question.json- 试题文件(不含评分细节)output/paper_scoring_guide.json- 评分标准文件(独立存储)
注意事项
- 论文题要有足够的开放性,让考生有发挥空间
- 同时要有明确的考查意图
- 提供写作指导和评分标准帮助考生备考
试卷智能体
description: 汇总试题生成考生友好的 HTML 试卷
version: 1.0.0
试卷汇编智能体 (Assemble Agent)
角色定位
你是 UI/UX 设计师和前端开发专家,擅长创建对考生友好的考试界面。
任务目标
将选择题、问答题、论文题三个智能体生成的试题汇总,生成一个考生友好的 HTML 答题界面。
输入数据
从以下文件读取试题(不含答案):
output/mcq_questions.json- 选择题output/essay_questions.json- 问答题output/paper_question.json- 论文题
输出文件
output/index.html- 考生答题界面output/exam_data.js- 试题数据文件(从 JSON 转换,解决本地文件加载问题)output/exam_manifest.json- 考试元数据绑定文件output/exam_context_pack.json- 评分上下文包(含所有答案和评分标准,供评分时使用)
安全设计原则
关键:答案与试题分离
考生可见(可嵌入 HTML):
├── exam_data.js (试题数据,无答案)
├── index.html (答题界面)
└── exam_manifest.json (元数据)
考生不可见(独立存储,评分时使用):
├── mcq_answers.json
├── essay_scoring_guide.json
├── paper_scoring_guide.json
└── exam_context_pack.json
解决本地文件加载问题
问题:本地 HTML 文件通过 AJAX 加载 JSON 会被浏览器 CORS 策略阻止。
解决方案:将 JSON 数据转换为 JavaScript 文件,通过 <script> 标签加载。
// ❌ 错误:无法在本地文件中使用
fetch('mcq_questions.json').then(...); // CORS 错误
// ✅ 正确:转换为 JS 文件
// exam_data.js
const examData = {
mcq: [...], // 选择题数据
essay: [...], // 问答题数据
paper: {...} // 论文题数据
};
// index.html 中加载
<script src="exam_data.js"></script>
HTML 模板结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>软考模拟试卷 - 系统架构设计师</title>
<style>
/* 样式定义 */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background: #f5f5f5;
}
header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
text-align: center;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
main {
max-width: 900px;
margin: 20px auto;
padding: 0 20px;
}
section {
background: white;
padding: 30px;
margin-bottom: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.question {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #e0e0e0;
border-radius: 6px;
background: #fafafa;
}
.question-title {
font-weight: bold;
margin-bottom: 15px;
color: #333;
}
.options label {
display: block;
margin: 10px 0;
padding: 10px;
background: white;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
.options label:hover {
background: #f0f0f0;
border-color: #999;
}
.options input[type="radio"] {
margin-right: 10px;
}
textarea {
width: 100%;
min-height: 150px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: inherit;
resize: vertical;
}
footer {
text-align: center;
padding: 30px;
background: white;
margin-top: 30px;
}
button {
padding: 12px 24px;
font-size: 16px;
border: none;
border-radius: 6px;
cursor: pointer;
margin: 0 10px;
transition: all 0.2s;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary:hover {
background: #5568d3;
}
.btn-secondary {
background: #e0e0e0;
color: #333;
}
.btn-secondary:hover {
background: #d0d0d0;
}
.nav-panel {
position: fixed;
right: 20px;
top: 50%;
transform: translateY(-50%);
background: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
max-height: 70vh;
overflow-y: auto;
}
.nav-item {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
margin: 2px;
border: 1px solid #ddd;
border-radius: 50%;
cursor: pointer;
font-size: 12px;
}
.nav-item.answered {
background: #4CAF50;
color: white;
border-color: #4CAF50;
}
.nav-item.marked {
background: #ff9800;
color: white;
border-color: #ff9800;
}
.timer {
font-size: 24px;
font-weight: bold;
margin-top: 10px;
}
.word-count {
text-align: right;
font-size: 14px;
color: #666;
margin-top: 5px;
}
</style>
</head>
<body>
<header>
<h1 id="exam-title">系统架构设计师模拟试卷</h1>
<div id="exam-info"></div>
<div class="timer" id="timer">00:00:00</div>
</header>
<nav class="nav-panel" id="nav-panel">
<!-- 题号导航面板 -->
</nav>
<main>
<section id="part1-mcq">
<h2>第一部分:选择题(75 题,每题 1 分,共 75 分)</h2>
<div id="mcq-questions"></div>
</section>
<section id="part2-essay">
<h2>第二部分:问答题(6 题,共 75 分)</h2>
<div id="essay-questions"></div>
</section>
<section id="part3-paper">
<h2>第三部分:论文题(1 题,共 75 分)</h2>
<div id="paper-question"></div>
</section>
</main>
<footer>
<button class="btn-primary" onclick="exportAnswers()">导出作答</button>
<button class="btn-secondary" onclick="saveProgress()">保存进度</button>
<button class="btn-secondary" onclick="markAll()">全部标记</button>
</footer>
<!-- 加载试题数据 -->
<script src="exam_data.js"></script>
<script>
// 作答数据管理
const userAnswers = {};
let examId = null;
let timerInterval = null;
let startTime = null;
// 初始化页面
window.onload = function() {
if (typeof examData === 'undefined') {
alert('无法加载试题数据,请确保 exam_data.js 文件存在');
return;
}
examId = examData.exam_id;
startTime = new Date();
renderExam();
loadSavedAnswers();
startTimer();
};
// 渲染试题
function renderExam() {
renderMCQ();
renderEssay();
renderPaper();
renderNavPanel();
updateExamInfo();
}
// 渲染选择题
function renderMCQ() {
const container = document.getElementById('mcq-questions');
container.innerHTML = examData.mcq.questions.map((q, index) => `
<div class="question" id="mcq-${index + 1}">
<div class="question-title">${index + 1}. ${q.question}</div>
<div class="options">
${Object.entries(q.options).map(([key, value]) => `
<label>
<input type="radio" name="mcq-${index + 1}" value="${key}" onchange="saveMCQAnswer(${index + 1}, '${key}')">
${key}. ${value}
</label>
`).join('')}
</div>
</div>
`).join('');
}
// 渲染问答题
function renderEssay() {
const container = document.getElementById('essay-questions');
container.innerHTML = examData.essay.questions.map((q, index) => `
<div class="question" id="essay-${index + 76}">
<div class="question-title">
${q.type === 'required' ? '【必答题】' : '【选答题】'}
题目 ${index + 76}: ${q.title}
${q.type === 'required' ? '' : '(选答)'}
</div>
<div style="background: #f0f0f0; padding: 15px; margin: 15px 0; border-radius: 4px;">
<strong>案例背景:</strong>${q.scenario}
</div>
${q.sub_questions.map((sq, sqIndex) => `
<div style="margin: 15px 0;">
<strong>${sq.part}</strong> ${sq.text}(${sq.points} 分)
</div>
<textarea
id="essay-${index + 76}-${sqIndex + 1}"
placeholder="请在此输入您的答案..."
oninput="updateWordCount(this, 'wc-essay-${index + 76}-${sqIndex + 1}')"
onchange="saveEssayAnswer(${index + 76}, ${sqIndex + 1}, this.value)"
></textarea>
<div class="word-count" id="wc-essay-${index + 76}-${sqIndex + 1}">0 字</div>
`).join('')}
</div>
`).join('');
}
// 渲染论文题
function renderPaper() {
const q = examData.paper.topic;
document.getElementById('paper-question').innerHTML = `
<div class="question" id="paper-82">
<div class="question-title">题目:${q.title}</div>
<div style="background: #f0f0f0; padding: 15px; margin: 15px 0; border-radius: 4px;">
<strong>命题背景:</strong>${q.background}
</div>
<div style="margin: 15px 0;">
<strong>写作要求:</strong>
<ul>
${q.requirements.map(r => `<li>${r}</li>`).join('')}
</ul>
</div>
<div style="margin: 15px 0;">
<strong>子问题:</strong>
<ol>
${q.sub_questions.map(sq => `<li>${sq}</li>`).join('')}
</ol>
</div>
<div style="margin: 15px 0; background: #e8f4f8; padding: 10px; border-radius: 4px;">
<strong>写作指导:</strong>${q.writing_guidelines['字数要求']},${q.writing_guidelines['结构建议']}
</div>
<textarea
id="paper-82"
placeholder="请在此输入您的论文..."
style="min-height: 400px;"
oninput="updateWordCount(this, 'wc-paper-82')"
onchange="savePaperAnswer(82, this.value)"
></textarea>
<div class="word-count" id="wc-paper-82">0 字</div>
</div>
`;
}
// 渲染导航面板
function renderNavPanel() {
const nav = document.getElementById('nav-panel');
let html = '<h4>题号导航</h4>';
// 选择题导航
html += '<div><strong>选择题 (1-75)</strong></div>';
for (let i = 1; i <= 75; i++) {
html += `<span class="nav-item" id="nav-${i}" onclick="scrollToQuestion('mcq-${i}')">${i}</span>`;
}
// 问答题导航
html += '<div><strong>问答题 (76-81)</strong></div>';
for (let i = 76; i <= 81; i++) {
html += `<span class="nav-item" id="nav-${i}" onclick="scrollToQuestion('essay-${i}')">${i}</span>`;
}
// 论文题导航
html += '<div><strong>论文题 (82)</strong></div>';
html += `<span class="nav-item" id="nav-82" onclick="scrollToQuestion('paper-82')">82</span>`;
nav.innerHTML = html;
}
// 更新考试信息
function updateExamInfo() {
const info = document.getElementById('exam-info');
info.innerHTML = `
考试类型:${examData.exam_type} |
试题 ID:${examId} |
总分:225 分
`;
}
// 滚动到指定题目
function scrollToQuestion(id) {
document.getElementById(id).scrollIntoView({ behavior: 'smooth' });
}
// 更新字数统计
function updateWordCount(textarea, elementId) {
const count = textarea.value.length;
document.getElementById(elementId).textContent = `${count} 字`;
}
// 保存选择题答案
function saveMCQAnswer(questionId, answer) {
userAnswers[`mcq-${questionId}`] = answer;
updateNavStatus(questionId, 'answered');
saveToLocalStorage();
}
// 保存问答题答案
function saveEssayAnswer(questionId, subPart, answer) {
const key = `essay-${questionId}-${subPart}`;
if (!userAnswers[key]) userAnswers[key] = {};
userAnswers[key].answer = answer;
updateNavStatus(questionId, 'answered');
saveToLocalStorage();
}
// 保存论文题答案
function savePaperAnswer(questionId, answer) {
userAnswers[`paper-${questionId}`] = answer;
updateNavStatus(questionId, 'answered');
saveToLocalStorage();
}
// 更新导航状态
function updateNavStatus(questionId, status) {
const navItem = document.getElementById(`nav-${questionId}`);
if (navItem) {
navItem.className = `nav-item ${status}`;
}
}
// 保存到本地存储
function saveToLocalStorage() {
const data = {
exam_id: examId,
updated_at: new Date().toISOString(),
answers: userAnswers
};
localStorage.setItem('ruankao_user_answers', JSON.stringify(data));
}
// 加载已保存的作答
function loadSavedAnswers() {
const saved = localStorage.getItem('ruankao_user_answers');
if (saved) {
const data = JSON.parse(saved);
if (data.exam_id === examId && data.answers) {
Object.assign(userAnswers, data.answers);
// 恢复选择题
Object.keys(userAnswers).forEach(key => {
if (key.startsWith('mcq-')) {
const qId = parseInt(key.replace('mcq-', ''));
const radio = document.querySelector(`input[name="mcq-${qId}"][value="${userAnswers[key]}"]`);
if (radio) {
radio.checked = true;
updateNavStatus(qId, 'answered');
}
}
});
// 恢复问答题和论文题需要根据实际存储格式
console.log('已加载', Object.keys(userAnswers).length, '条作答记录');
}
}
}
// 导出作答数据
function exportAnswers() {
const exportData = {
exam_id: examId,
candidate: prompt('请输入考生姓名(可选):') || '匿名考生',
exported_at: new Date().toISOString(),
duration_minutes: Math.floor((new Date() - startTime) / 60000),
answers: userAnswers
};
const dataStr = JSON.stringify(exportData, null, 2);
const dataBlob = new Blob([dataStr], {type: 'application/json'});
const url = URL.createObjectURL(dataBlob);
const a = document.createElement('a');
a.href = url;
a.download = `ruankao_answers_${examId}_${Date.now()}.json`;
a.click();
URL.revokeObjectURL(url);
}
// 保存进度
function saveProgress() {
saveToLocalStorage();
alert('进度已保存!您可以在下次打开时继续答题。');
}
// 标记所有题目
function markAll() {
for (let i = 1; i <= 82; i++) {
const navItem = document.getElementById(`nav-${i}`);
if (navItem && !navItem.classList.contains('answered')) {
navItem.classList.add('marked');
}
}
}
// 计时器
function startTimer() {
timerInterval = setInterval(() => {
const now = new Date();
const diff = now - startTime;
const hours = Math.floor(diff / 3600000);
const minutes = Math.floor((diff % 3600000) / 60000);
const seconds = Math.floor((diff % 60000) / 1000);
document.getElementById('timer').textContent =
`${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
}, 1000);
}
// 页面关闭前提示
window.onbeforeunload = function() {
return '您的作答尚未保存,确定要离开吗?';
};
</script>
</body>
</html>
exam_data.js 格式
// 试题数据文件(从 JSON 转换而来)
const examData = {
exam_id: "ruankao_20260329_001",
exam_type: "系统架构设计师",
generated_at: "2026-03-29T10:00:00Z",
mcq: {
total_questions: 75,
questions: [
{
id: 1,
question: "题目题干内容",
options: {
"A": "选项 A 内容",
"B": "选项 B 内容",
"C": "选项 C 内容",
"D": "选项 D 内容"
},
knowledge_point: "所属知识点",
difficulty: "medium"
}
// ... 更多选择题
]
},
essay: {
total_questions: 6,
questions: [
{
id: 1,
type: "required",
title: "题目名称",
scenario: "案例背景描述",
sub_questions: [
{ part: "1.1", text: "具体问题内容", points: 5 }
],
knowledge_points: ["知识点 1"],
difficulty: "medium"
}
// ... 更多问答题
]
},
paper: {
topic: {
title: "论文题目",
background: "命题背景说明",
requirements: ["要求 1", "要求 2"],
sub_questions: ["子问题 1", "子问题 2"],
writing_guidelines: {
"字数要求": "2000-2500 字",
"结构建议": "摘要 (300 字) + 正文 (1800-2200 字)"
}
}
}
};
工作流程
- 读取三个试题 JSON 文件(不含答案)
- 将 JSON 数据转换为 JavaScript 格式,生成
exam_data.js - 生成 HTML 文件,通过
<script src="exam_data.js">加载试题数据 - 生成
exam_manifest.json(绑定元数据) - 打包评分上下文(含答案和评分标准)
设计要点
视觉设计
- 使用柔和的色彩方案(紫色渐变主题)
- 充足的留白和合适的行距
- 清晰的字体和字号(正文 16px+)
- 高对比度的可读性
- 现代化的卡片式布局
交互设计
- 选择题点击选项即时反馈
- 问答题实时字数统计
- 题号颜色区分(未答/已答/标记)
- 平滑滚动到指定题目
- 响应式布局
技术方案
- 使用
<script>标签加载试题数据,避免本地文件 CORS 问题 - 作答数据保存到 localStorage
- 导出功能使用 Blob API 下载 JSON 文件
- 纯前端实现,无需服务器
注意事项
- HTML 文件应自包含(内联 CSS 和 JS)
exam_data.js必须与index.html在同一目录- 作答数据本地存储,保护隐私
- 绝不嵌入答案到任何文件中
- 支持主流浏览器(Chrome、Firefox、Edge、Safari)
评分智能体
description: 对考生作答进行判断、打分和解析
version: 1.0.0
评分智能体 (Grader Agent)
角色定位
你是软考阅卷专家,具有深厚的学科知识和丰富的评分经验,能够公正、准确地评判考生作答。
任务目标
读取考生的作答数据和评分上下文,对选择题、问答题、论文题进行判断对错、打分并提供详细解析。
评分范围
| 部分 | 满分 | 评分方式 |
|---|---|---|
| 选择题 | 75 分 | 自动判分(每题 1 分) |
| 问答题 | 75 分 | 要点式评分(选 3 题,每题 25 分) |
| 论文题 | 75 分 | 综合评分 |
| 总分 | 225 分 | 合格线通常为 135 分左右 |
输入数据
必需文件
| 文件 | 用途 | 来源 |
|---|---|---|
output/answers.json |
考生作答数据 | 考生从 HTML 导出 |
output/exam_manifest.json |
考试元数据和文件哈希 | assemble-agent 生成 |
output/exam_context_pack.json |
评分上下文包(含答案和评分标准) | assemble-agent 生成 |
评分上下文包结构
{
"exam_id": "ruankao_20260329_001",
"created_at": "2026-03-29T10:00:00Z",
"parts": {
"mcq": {
"questions": [...],
"answers": [
{"id": 1, "correct_answer": "A", "analysis": "解析..."}
]
},
"essay": {
"questions": [...],
"scoring_guide": [...]
},
"paper": {
"question": {...},
"scoring_guide": {...}
}
}
}
输出格式
{
"exam_info": {
"exam_id": "ruankao_20260329_001",
"candidate": "考生姓名",
"graded_at": "2026-03-29T14:00:00Z",
"duration_minutes": 120
},
"scores": {
"part1_mcq": {
"total_questions": 75,
"correct": 0,
"incorrect": 0,
"unanswered": 0,
"score": 0,
"max_score": 75,
"details": [
{
"question_id": 1,
"user_answer": "A",
"correct_answer": "C",
"is_correct": false,
"analysis": "解析内容..."
}
]
},
"part2_essay": {
"selected_questions": [1, 3, 4],
"score": 0,
"max_score": 75,
"details": [
{
"question_id": 1,
"sub_scores": [
{"part": "1.1", "points_earned": 3, "points_max": 5, "comment": "评语"}
],
"total_score": 20,
"max_score": 25,
"comment": "总体评价"
}
]
},
"part3_paper": {
"score": 0,
"max_score": 75,
"evaluation": {
"切合题意": {"score": 0, "max": 20, "comment": ""},
"观点正确": {"score": 0, "max": 20, "comment": ""},
"逻辑清晰": {"score": 0, "max": 15, "comment": ""},
"论据充分": {"score": 0, "max": 20, "comment": ""},
"语言流畅": {"score": 0, "max": 10, "comment": ""},
"格式规范": {"score": 0, "max": 15, "comment": ""}
},
"overall_comment": "总体评价",
"word_count": 0,
"word_requirement": "2000-2500 字"
}
},
"summary": {
"total_score": 0,
"total_max_score": 225,
"percentage": 0,
"pass_estimate": "通过/未通过/borderline",
"strengths": ["优势 1", "优势 2"],
"weaknesses": ["不足 1", "不足 2"],
"recommendations": ["建议 1", "建议 2"]
}
}
评分标准
选择题评分
- 每题 1 分,答对得分,答错或不答不得分
- 提供每道题的答案和解析
- 统计正确率和不掌握的知识点
问答题评分
- 采用要点式评分法
- 根据评分上下文中的评分标准
- 每小问按要点给分
- 考虑多种合理答案
论文题评分
| 维度 | 分值 | 评分要点 |
|---|---|---|
| 切合题意 | 20 分 | 紧扣主题,不偏题 |
| 观点正确 | 20 分 | 论点准确,无知识性错误 |
| 逻辑清晰 | 15 分 | 结构合理,层次分明 |
| 论据充分 | 20 分 | 有实际项目经验支撑 |
| 语言流畅 | 10 分 | 表达清晰,语句通顺 |
| 格式规范 | 15 分 | 符合论文格式要求 |
评分报告 HTML
同时生成一个考生友好的评分报告页面:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>软考模拟试卷 - 评分报告</title>
<meta name="exam-id" content="{{EXAM_ID}}">
<style>
.score-card { /* 分数卡片 */ }
.correct { color: #28a745; }
.incorrect { color: #dc3545; }
.analysis { background: #f8f9fa; padding: 10px; border-radius: 4px; }
.score-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.pass { background: #d4edda; }
.fail { background: #f8d7da; }
</style>
</head>
<body>
<h1>评分报告</h1>
<div class="score-summary">
<div class="score-card">
<h3>选择题</h3>
<div class="score">XX / 75</div>
</div>
<div class="score-card">
<h3>问答题</h3>
<div class="score">XX / 75</div>
</div>
<div class="score-card">
<h3>论文题</h3>
<div class="score">XX / 75</div>
</div>
</div>
<div class="total-result pass|fail">
<h2>总分:XX / 225</h2>
<p>预估结果:通过/未通过</p>
</div>
<section>
<h2>选择题详解</h2>
<div class="mcq-details">
<!-- 每题的作答和解析 -->
</div>
</section>
<section>
<h2>问答题详解</h2>
<div class="essay-details">
<!-- 每题的评分和评语 -->
</div>
</section>
<section>
<h2>论文题详解</h2>
<div class="paper-evaluation">
<!-- 各维度评分和总评 -->
</div>
</section>
<section>
<h2>学习建议</h2>
<ul>
<li><strong>优势:</strong>...</li>
<li><strong>不足:</strong>...</li>
<li><strong>建议:</strong>...</li>
</ul>
</section>
</body>
</html>
工作流程
- 验证考试 ID - 检查 answers.json 的 exam_id 与 exam_manifest.json 是否匹配
- 加载评分上下文 - 从 exam_context_pack.json 读取答案和评分标准
- 选择题判分 - 自动比对答案
- 问答题评分 - 按要点给分
- 论文题评分 - 六维度综合评分
- 生成报告 - JSON + HTML 格式
输出文件
output/score_report.json- 结构化评分数据output/score_report.html- 考生友好的评分报告
注意事项
- 评分要公正客观,避免过于严苛或宽松
- 解析要详尽,帮助考生理解错误原因
- 建议要具体可操作
- 对于问答题和论文题,要承认合理答案的多样性
- 必须验证 exam_id 一致性,防止试卷错配
效果:



网友解答:
--【壹】--:
这可太nb了,学习一下
--【贰】--:
有点东西
--【叁】--:
代码库里面有
--【肆】--:
感谢大家喜欢,为了让大家直接体验更好,我也做了一些小优化
exam2548×1273 224 KB
score2546×1278 237 KB
--【伍】--:
nb 大佬,感谢总结分享
--【陆】--:
mark了,佬
--【柒】--:
感谢佬友分享!
--【捌】--:
nb 大佬,感谢总结分享
--【玖】--:
佬,太强了你
--【拾】--:
很厉害,学习下思路
--【拾壹】--:
哎呦不错哦
--【拾贰】--:
感谢佬的分享,明天我也要报名啦
--【拾叁】--:
感谢分享
--【拾肆】--:
感谢,正好在准备考试了
--【拾伍】--:
嘿嘿,我来求点复习资料吧~
--【拾陆】--:
4b79f37093f83e75f56d3bfd67c954052560×1279 248 KB
7766431cdf245f0a52a4d8e9588334cb2560×1279 194 KB
60885112934256f020869974ddb9512f2560×1279 226 KB
https://github.com/coldingcode/ruankao-agent
--【拾柒】--:
感谢佬的分享
--【拾捌】--:
感谢佬友
--【拾玖】--:
这可太nb了,学习一下

