Skip to content

【外滩大会2026】慧考 AI · 证券从业资格考试智能题库 #134

Description

@wanhe-hash

参赛项目名称

慧考 AI · 证券从业资格考试智能题库

团队 / 作者

第一作者
wanhe-hash https://github.com/wanhe-hash
第二作者
Dawn https://github.com/huit2

我做了什么

基于阿里云百炼 CLI( bl )和 DeepSeek LLM,构建了一个完整的证券从业资格考试智能题库系统「慧考 AI」。核心亮点:

  1. 真题导入 :编写 PDF 解析脚本( tools/parse_real_exam.py ),使用 pdfplumber 从中证协真题 PDF 中提取了 336 道真题 ,自动识别题号、选项、答案、解析,并按关键词分类到 10 个章节
  2. Few-shot AI 扩题 :改进 AI 扩题模块,每次生成新题时自动从数据库随机抽取同章节 3 道真题作为 few-shot 示例,让 AI 模仿真题风格和难度,生成题目质量显著提升
  3. 自动错题本 :答题时答错自动收录到数据库,支持按章节筛选、展开查看解析、单道移除、一键清空
  4. AI 模型设置 :前端多厂商模型选择弹窗(国内/国外双 Tab),当前使用 DeepSeek-V3
  5. 全栈应用 :C++ 核心模块 + FastAPI 后端 + Vue 3 前端,支持在线答题、章节练习、随机抽题、AI 扩题、错题复习等功能
  6. 题库规模 :从 235 道扩充到 584 道 (真题 336 + AI 生成 248),覆盖 10 个章节

使用的工具

  • OpenWork / 百炼 CLI : bl v1.14.2 (已安装 5 个 Skills:bailian-cli、bailian-finetune、bailian-gen、bailian-managed-agent、bailian-protocol)
  • 百炼能力 / 模型 :DASHSCOPE_API_KEY(阿里云百炼 MaaS API)、DeepSeek LLM(deepseek-chat / deepseek-reasoner)
  • Skill 名称 :bailian-cli(核心 CLI,应用调用/知识库/配额管理)、bailian-protocol(鉴权协议)
  • 其他 :Node.js v22.12.0、C++17 / CMake、Python 3.12 / FastAPI / Uvicorn、Vue 3 / Vite / TypeScript / Axios、SQLite3、pdfplumber

效果展示

AI 生成模块 (C++ / DeepSeek LLM)

后端 API (FastAPI / Python 3.12)
├── 题库查询 / 判分 / 随机抽题
├── AI 扩题(subprocess 调 C++ chat_demo)
├── 自动错题本(SQLite wrong_answers 表)
└── AI 模型设置(多厂商选择)

前端界面 (Vue 3 / Vite)
├── 主页:Hero + 章节网格 + AI 扩题按钮
├── 答题页:进度条 + 答题卡 + 快捷键 1-4
├── 结果页:正确率统计 + 错题回顾
└── 错题本:章节筛选 + 解析展开 + 移除/清空

questions.db (SQLite)
← 真题导入 ← PDF 解析脚本 (pdfplumber)
← AI 扩题 ← C++ chat_demo expand
题库分布:

  • 法律法规:78 题 | 金融基础:86 题 | 证券分析师:40 题 | 投资顾问:132 题
  • 覆盖 10 个章节:股票种类与标识、沪深北交易所、股票交易规则、债券基础、基金类型、金融衍生品、技术分析、基本面分析、证券公司业务、证券从业法规
Image Image Image Image Image Image Image

项目链接(可选)

踩坑记录(可选)

1. LLM / API 相关 1.1 DeepSeek 第三方 gateway 401 错误

  • 现象 :扩题时报 API key invalid: governor ,所有请求失败
  • 原因 :早期用的第三方 gateway 限流,不是 key 本身的问题
  • 解决 :切换到 DeepSeek 官方 API 端点 https://api.deepseek.com/v1 ,问题消失
  • 教训 :AI 项目要预留"换 LLM 厂商"的能力,配置全走环境变量 1.2 json_mode=true 要求 prompt 含 "json" 字样
  • 现象 :第二步 LLM 出题用 json_mode=true ,报 400 Prompt must contain the word 'json'
  • 原因 :DeepSeek 的强制 JSON 模式要求 prompt 中包含 "json" 关键字
  • 解决 :第一步 meta-prompt(出题策略)改用 json_mode=false 输出自由文本,第二步生成题目才用 json_mode=true
  • 代码 : expander.cpp 中 cfg_text.json_mode = false; 1.3 LLM 返回 JSON 缺括号
  • 现象 :LLM 返回 {"choices":[{"message":{"content":"..."]}} — 末尾少 }
  • 原因 : deepseek-v4-flash 模型自身偶尔的输出 bug
  • 解决 :编写 parseOuterWithRepair 函数绕开外层 JSON 解析,直接提取 content 字段,实现自愈不依赖外层结构合法性
  • 教训 :永远不要相信 LLM 一定会返回合法 JSON 1.4 AI 扩题重复率高
  • 现象 :连续扩 10 道题,3-4 道重复("下列关于股票..." 反复出现)
  • 原因 :LLM 没有"已知题目"信息,纯靠训练知识出题
  • 解决 :
    1. meta-prompt 中把现有题目列表喂给 LLM
    2. 出题后用最长公共子串相似度去重(>30% 算重复)
    3. 升级方向:embedding 语义去重(DeepSeek text-embedding-v2)

2. PDF 解析 2.1 【答案】:C 格式正则没匹配

  • 现象 :第一版正则 r"答案[::]" 漏掉大部分题目
  • 原因 :PDF 实际格式是 【答案】:C (带【】,全角冒号)
  • 解决 :正则改为 r"【?答案】?[::]\s*([A-D])" ,兼容多种格式 2.2 解析里的列表项被误识别为新题号
  • 现象 :解析里 "1、具有中华人民共和国国籍;2、品行良好..." 被当成新题
  • 原因 :按"题号"切分时被解析里的数字误导
  • 解决 :改用"答案"作为切分锚点(题干 100% 必含答案),向前找最近的"数字+顿号"作为题号
  • 效果 :解析率从 37% 提升到 97.5% 2.3 题干切分漏开头
  • 现象 :题 1 stem 只剩 () ,题干开头被砍
  • 原因 :用 () 做锚点 + 往前找最近句末符号,遇到题 1(无上题解析)会把整段题干砍掉
  • 解决 :用 () + 题号("数字+顿号")双锚点,先找题号再找结束 2.4 选项里混进页码
  • 现象 :题 3 的 C 选项是 200\n1 / 26\n233网校...
  • 原因 :PDF 抽文本时把页脚跟选项文本混到一行
  • 解决 :用 re.sub(r'\d+\s*/\s*\d+', '', full) 删页码;删 233 网校广告行 2.5 多选题被当单选解析
  • 现象 :分析师 PDF 里的多选题,答案 "ABD" 只取 A,选项 "正确" 残留
  • 原因 :解析脚本只支持单选
  • 解决(待做) :检测题号后"多选题"标识,答案允许多字符 2.6 选项被截断(PDF 排版跨页)
  • 现象 :法规 PDF 里题 1 实际有 4 个选项(A 50人 / B 30人 / C 200人 / D 100人),解析只出 3 个
  • 原因 :D 选项排版到下一页,正则只切到当前页
  • 解决(待做) :合并跨页文本后再切分 2.7 PowerShell 把中文 regex 编码损坏
  • 现象 : re.sub(r'233网校...', ...) 报 unterminated character set
  • 原因 :PowerShell Out-File 把 "网校" 转成 GBK 字节,Python 读 UTF-8 时乱码
  • 解决 :用 Unicode 转义 \u7f51\u6821 代替直接写中文,跨平台兼容

3. 部署 / SSH 3.1 本地 WSL 安装失败

  • 现象 : wsl --install 报 Wsl/InstallDistro/WININET_E_TIMEOUT
  • 原因 :从 GitHub 下载 Ubuntu 镜像超时(网络代理问题)
  • 解决 :放弃 WSL,改用远程 Ubuntu 云服务器 3.2 SSH 端口非默认
  • 现象 :用 ssh user@host 连不上, connection refused
  • 原因 :服务器用了非标准端口 23456
  • 解决 :用 ssh -p 23456 ... ,或在 ~/.ssh/config 里配 Host 别名 + Port 3.3 首次连接受 fingerprint 阻塞
  • 现象 :SSH 命令挂起,等用户输 yes
  • 解决 :加 -o StrictHostKeyChecking=accept-new 自动接受 3.4 known_hosts 不匹配
  • 现象 : Host key verification failed
  • 原因 :服务器重装后公钥换了,旧条目冲突
  • 解决 : ssh-keygen -R "[host]:port" 删旧条目 3.5 公钥私钥分不清
  • 现象 :用户把公钥( id_ed25519.pub )发给我,想登录服务器
  • 解决 :明确告知 id_ed25519 (无后缀)= 私钥, .pub = 公钥。永远不要发私钥 3.6 WSL 路径 \wsl$\Ubuntu... 不通
  • 现象 : Copy-Item 报"找不到路径"
  • 原因 :WSL 没装 distro(之前下载失败)
  • 解决 :项目在远程服务器,用 scp 直接传

4. 前端 / API 设计 4.1 第一版 UI 风格不匹配

  • 现象 :紫色调、扁平化卡片,不像金融专业产品
  • 解决 :重做成深海军蓝 #0a2540 + 金色 #d4a574 + 米色背景,加 Georgia 衬线斜体编号
  • 效果 :从"产品 demo"变成"专业平台" 4.2 VITE_API_BASE 默认是 localhost
  • 现象 :部署到服务器后,前端 axios 调 http://localhost:8001 ,跨域失败
  • 解决 :用 Vite proxy 将 /api/ → 127.0.0.1:8001 ,前端 VITE_API_BASE=/api 4.3 公共 API 暴露了内部 kp_id
  • 现象 :原本 /questions?kp_id=1 ,前端硬编码章节 ID
  • 解决 :API 改用 chapter 名(人类可读),后端做映射( chapter_to_kp_id 函数)
  • 设计原则 :公共 API 只暴露人类能懂的标识,内部 ID 不外泄

5. 数据库 5.1 Question struct 加字段引发连锁修改

  • 现象 :想给题目加 id 默认值,发现要改 4 个地方
  • 解决 :用默认值( int id = 0; )而不是构造函数,调用方少改一半代码 5.2 schema 预留 source 字段
  • 发现 : db.h 里 Question struct 已经有 std::string source; 字段
  • 意义 :RAG 功能不用改 schema,直接在 INSERT 时填 source 字符串即可
  • 教训 :好的 schema 设计能省未来 50% 的工作 5.3 安全策略拦截文件删除
  • 现象 : Remove-Item 被安全策略拒绝
  • 解决 :换文件名( questions_v2.db )或者 DELETE FROM 清表

6. 工具使用 6.1 pip 在 PowerShell 被拦截

  • 现象 : pip install 报 No pyvenv.cfg file
  • 原因 :PowerShell 把 pip 当成了别名
  • 解决 :用 python -m pip install ... 6.2 git clone 报 SSL 错误
  • 现象 : fatal: unable to access ... TLS connect error
  • 原因 :网络代理问题
  • 解决 :改用 GitHub API( /git/trees/... )拿文件树 + raw URL 读单文件,或用 ghfast.top 代理镜像

7. C++ 工程 7.1 parseOuterWithRepair 重复造轮子

  • 现象 : test.cpp 和 expander.cpp 都需要 parseOuterWithRepair 函数
  • 原因 : provider.cpp 没暴露,外面复制了一份
  • 教训 :AI 项目常出现工具函数被多个模块复制,应该提取到 util.h 7.2 匿名 namespace 关闭顺序
  • 现象 :编译报 return 1 parse 错误
  • 原因 : } // namespace 注释忘加,或在 int main 之后
  • 解决 :所有匿名 namespace 在 main 之前用 } // namespace 关闭 7.3 跨平台编译
  • 现象 :C++ 代码在 Windows MSVC 编译失败
  • 原因 :用了 localtime_r (POSIX),MSVC 是 localtime_s
  • 解决(待做) :编译期 #ifdef _WIN32 分支

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions