AI药典助手 - 项目体系全面分析报告
Pharmacopoeia AI Agent 项目架构、功能实现与缺陷诊断
一、项目概览
AI药典助手(Pharmacopoeia AI)是一个面向药店从业人员(药师、营业员、医生)的智能问答系统,基于《中华人民共和国药典》构建 RAG(检索增强生成) 知识库,通过通义千问(Qwen)大模型提供专业药学问答服务。同时规划了执业药师考试辅导模块。
2
后端语言(Java + Python)
9
数据库表
40+
API 端点
3
前端形态(Web + 小程序 + 静态)
项目阶段进度
当前状态
项目处于 Phase 1-2 过渡期:骨架已搭建完成,RAG 链路已打通(pgvector + DashScope Embedding + Qwen LLM),Java 后端为 主力运行环境,Python 后端为辅助开发方向。核心瓶颈在于数据采集(药典 PDF 解析、NMPA 爬虫)尚未完成。
二、技术架构
整体架构图
flowchart TB
subgraph 客户端层
MP[微信小程序
uni-app / Vue]
WEB[Web 前端
HTML + JS]
STATIC[静态演示页
Mock 数据]
end
subgraph 网关层
NG[Nginx
反向代理 + SSL + SSE + 限流]
end
subgraph 后端层
JAVA[Java 后端 - Spring Boot 3.3
主力运行 | 端口 9000]
PY[Python 后端 - FastAPI
辅助开发 | 端口 8000]
end
subgraph AI 服务
QWEN[通义千问 Qwen API
文本/视觉/Embedding]
RERANK[Reranker
启发式重排序]
end
subgraph 存储层
PG[(PostgreSQL 16
+ pgvector 向量检索)]
RD[(Redis
限流 / 缓存)]
end
subgraph 数据管道
CRAWL[爬虫模块
维基/NMPA/药典PDF]
PROC[处理模块
切片/清洗/Embedding]
end
MP --> NG
WEB --> NG
NG --> JAVA
NG --> PY
JAVA --> QWEN
JAVA --> RERANK
JAVA --> PG
JAVA --> RD
PY --> QWEN
PY --> PG
CRAWL --> PROC
PROC --> PG
技术栈总览
| 层次 | 技术 | 说明 |
|---|---|---|
| Java 后端 | Spring Boot 3.3 + Java 21 | Servlet 容器 + WebFlux(SSE/WebClient) |
| Python 后端 | FastAPI + asyncpg + SQLAlchemy | 异步框架,辅助开发方向 |
| 数据库 | PostgreSQL 16 + pgvector | 向量维度 1024,IVFFlat 索引 |
| 缓存 | Redis | 限流(已配置,部分未启用) |
| LLM | 通义千问 Qwen(DashScope) | qwen3.7-max(对话)/ qwen3.6-flash(视觉)/ text-embedding-v3 |
| 小程序 | uni-app + Vue | 微信小程序,SSE 流式对话 |
| Web 前端 | 原生 HTML + JS + Fetch | 内嵌于 Spring Boot 静态资源 |
| 部署 | Docker Compose + Nginx + Supervisor | 两套配置共存(Java/Python) |
三、Java 后端(主力运行)
3.1 项目结构
| 包 | 职责 | 关键类 |
|---|---|---|
| config | 配置类 | JwtProperties, QwenProperties, WechatProperties, RateLimitProperties, JsonbConverter, GlobalExceptionHandler |
| controller | API 控制器(10 个) | ChatController, DrugController, AuthController, AdminController, AdminKnowledgeController, ExamChapterController, ExamPracticeController, ExamProgressController, ExamQaController, HealthController |
| dto | 数据传输对象(16 个) | ChatRequest, DrugSearchRequest, LoginRequest, MultimodalChatRequest 等 |
| entity | JPA 实体(9 个) | Drug, DrugChunk, User, Conversation, Message, KnowledgePoint, Question, AnswerRecord, UserProgress |
| repository | 数据访问层(10 个) | 继承 JpaRepository,含自定义查询 |
| security | 安全框架 | JwtAuthFilter, JwtUtil, RateLimitFilter, SecurityConfig |
| service | 业务逻辑(8 个) | LLMService, RetrieverService, RerankerService, PromptService, DrugService, ChatPersistenceService, AuthService, AdminKnowledgeService |
3.2 核心 RAG 对话流程
核心数据流
用户提问 → 意图分类(关键词匹配,5 种意图)→ 药品名提取(精确/前缀/模糊匹配)→ pgvector 向量检索(top 20)→ 启发式重排序(阈值过滤 + 关键词加权 + Jaccard 去重,top 5)→ Prompt 构建(6 套意图模板 + 合规规则)→ Qwen LLM 生成 → 来源拼接 → 持久化 → SSE/同步返回
3.3 API 端点清单
| 控制器 | 路径前缀 | 端点数 | 状态 |
|---|---|---|---|
| ChatController | /api/v1/chat | 12 | 完整实现 |
| DrugController | /api/v1/drug | 3 | 完整实现 |
| AuthController | /api/v1/auth | 2 | 完整实现 |
| AdminController | /api/v1/admin | 3 | 部分占位 |
| AdminKnowledgeController | /api/v1/admin/knowledge | 18 | CRUD 完整 / 导入占位 |
| ExamChapterController | /api/v1/exam/chapter | 2 | 空壳/硬编码 |
| ExamPracticeController | /api/v1/exam/practice | 3 | 空壳 |
| ExamProgressController | /api/v1/exam/progress | 2 | 空壳 |
| ExamQaController | /api/v1/exam/qa | 2 | 空壳 |
| HealthController | /health | 1 | 完整实现 |
3.4 已完成的功能
- 多模态对话:支持纯文本、图片(OCR)、视频、混合输入,同步 + SSE 流式双模式
- 意图分类:5 种意图(药品查询、用药指导、法规条款、症状建议、考试辅导)+ 否定语义检测
- 向量检索:pgvector 余弦距离,先精确匹配药品名再向量检索
- 启发式重排序:阈值过滤 + 关键词覆盖率加权 + Section 相关性 + 版本优先级 + Jaccard 去重
- Prompt 工程:6 套意图模板,含合规规则(来源标注、AI 免责声明、不编造)
- 药品管理 CRUD:搜索、详情、分类树、创建、更新、软删除
- 知识点/题库 CRUD:完整增删改查 + 批量审核
- 对话持久化:会话管理、消息记录、反馈收集
- 微信登录:jscode2session + 游客登录降级
- JWT 鉴权:HS256 签名,24 小时有效期
- IP 限流:内存滑动窗口,每分钟 60 次 / 每小时 1000 次
- 知识库统计:药品数、向量覆盖率、知识点数、题目数
3.5 Java 后端存在的问题
严重问题
- JWT 密钥硬编码:application.yml 中 64 位十六进制密钥明文存储,任何有代码权限的人可伪造任意用户 Token
- 安全配置形同虚设:SecurityConfig 中所有路径
permitAll(),包括/api/v1/admin/**,管理员接口完全无保护 - CORS 完全开放:
setAllowedOriginPatterns("*")+setAllowCredentials(true),允许任何域名带凭证跨域访问 - 数据库默认弱密码:默认密码
pharma2025
性能问题
- 对话历史全量加载:
ChatPersistenceService.getHistory()使用findAll()全量加载所有对话到内存再排序分页,数据量大时将 OOM - 无 Embedding 缓存:每次检索都调用远程 API 生成向量,相同 query 重复调用浪费时间和费用
- LLM 同步阻塞:
.block()阻塞调用,高并发下 Servlet 线程池可能耗尽
代码质量问题
- ChatController 职责过重:770 行代码,包含 RAG 管线、来源构建、药品名提取等多个职责
- SECTION_DISPLAY 重复定义:ChatController 和 PromptService 各自定义了一份映射,存在不一致风险
- 异常处理吞掉错误:LLMService 中多处
catch (Exception e) { return ""; },无法区分模型返回空和调用失败 - Conversation.userId 硬编码为 0:未关联实际用户
- 死代码:
buildDirectAnswer()定义但从未调用
四、Python 后端(辅助开发)
Python 后端基于 FastAPI 构建,是项目的辅助开发方向。API 端点与 Java 后端基本对齐,但在实现深度上存在差异。
4.1 与 Java 后端的差异
| 维度 | Java 后端 | Python 后端 |
|---|---|---|
| 运行状态 | 主力运行 | 辅助开发 |
| ORM 使用 | JPA 全量使用 | 大部分用原生 SQL,ORM 形同虚设 |
| 数据库连接 | 连接池自动管理 | chat.py 每次请求创建新引擎(严重性能问题) |
| 权限控制 | SecurityConfig(虽无效但有框架) | 无任何权限校验 |
| 管理接口 | CRUD 完整实现 | 大部分返回硬编码空数据 |
| 限流 | 内存滑动窗口(已启用) | Redis 限流类已定义但未调用 |
| 对话上下文 | 无多轮历史 | 无多轮历史 |
4.2 Python 后端特有问题
- 数据库连接未复用:chat.py 中
_save_message和_ensure_user每次都create_async_engine,高并发下会耗尽数据库连接 - 对话历史不按用户过滤:返回所有用户的对话,存在数据泄露风险
- ORM 模型与实际使用脱节:大部分路由用原生
text()SQL,ORM 定义基本只在 drug.py 使用 - drug.py 硬编码数据库连接字符串:未使用 config.py 的配置
- Base 重复定义:
base.py和user.py各定义了一个DeclarativeBase() - RateLimiter 未被使用:定义了类但在任何 API 路由中都没有调用
- get_current_user 返回 payload dict:而非 User 对象,路由拿到的 user 只有 sub(openid)
- 默认 secret_key="change-me":生产环境严重安全隐患
五、前端与小程序
5.1 前端形态对比
| 前端 | 路径 | 类型 | API 连接 | 状态 |
|---|---|---|---|---|
| 生产级 Web | backend-java/.../static/index.html | 内嵌 Spring Boot | 真实 API(非流式) | 可用 |
| 演示 Web | frontend-web/index.html | 独立 HTML | Mock 数据 | 演示用 |
| 静态副本 | static/index.html | 独立 HTML | Mock 数据 | 冗余文件 |
| API 测试 | frontend-web/test.html | 独立 HTML | SSE(Token 已过期) | 不可用 |
| 小程序页面 | miniprogram/pages/ai-yaodian/ | uni-app Vue | 真实 SSE API | 可用 |
| 小程序组件 | miniprogram/components/ai-chat/ | 浮动面板组件 | 真实 SSE API | 可用 |
5.2 前端已完成功能
- 生产级 Web:JWT 鉴权、对话历史侧边栏、消息队列可视化、反馈功能(👍👎)、药品库分页搜索、健康检查
- 小程序页面:SSE 流式对话、消息队列(排队发送)、停止功能、多媒体上传、快捷标签、来源展示、意图标签
- 小程序浮动组件:可嵌入任意页面的 AI 对话面板,支持 drugName prop 自动填入
- 演示页:完整的 UI 交互演示,含药品库浏览、媒体上传预览、打字机效果
5.3 前端存在的问题
关键缺陷
- 生产级 Web 未使用 SSE:调用非流式
/chat/ask,浪费了后端已实现的/chat/streamSSE 能力 - Markdown 渲染逻辑三处重复:frontend-web、ai-yaodian 页面、ai-chat 组件各自独立实现,维护成本极高
- SSE 工具类未被使用:
utils/sse.js提供了通用 SSE 能力,但api/ai.js内联了几乎相同的逻辑 - 运算符优先级 Bug:frontend-web/index.html 三元表达式嵌套错误,导致媒体类型显示为 true/false
- 小程序 BASE_URL 占位符:
https://your-api-domain.com未配置 - 文件冗余:
static/index.html与frontend-web/index.html完全相同 - scrollToBottom 不可靠:固定大值方式在部分场景下失效
- XSS 风险:药品详情页 sections 内容直接 innerHTML 输出未转义
六、数据管道
6.1 爬虫模块状态
| 爬虫 | 文件 | 状态 | 说明 |
|---|---|---|---|
| 维基百科采集 | wiki_spider.py | 已实现 | BeautifulSoup 解析,匹配药典相关栏目 |
| 批量维基采集 | batch_collect.py | 已实现 | 限量 50 个/轮 |
| 药典 PDF 目录提取 | extract_catalog.py | 已实现 | PyMuPDF + 动态阈值 |
| 多源探测 | probe.py | 已实现 | 数据可用性检测工具 |
| 基础框架 | spider.py | 框架存在 | Scrapy BasePharmSpider,引用了不存在的 middleware |
| NMPA 爬虫 | nmpa_spider.py | 空壳 Phase 2 | 需要 Selenium/Playwright |
| 药典 PDF 解析 | pharmacopoeia.py | 空壳 Phase 2 | PyMuPDF,核心数据源未实现 |
| 考试大纲采集 | exam_outline.py | 空壳 Phase 2 | 待实现 |
6.2 处理模块状态
| 处理器 | 文件 | 状态 | 说明 |
|---|---|---|---|
| 智能切片器 | chunker.py | 已实现 | 三种模式(药品/法规/考试),但未被 ingest.py 使用 |
| 文本清洗 | cleaner.py | 已实现 | OCR 纠错字典,但未被 ingest.py 调用 |
| 远程 Embedding | ingest.py | 已实现 | DashScope text-embedding-v3,批量 10 条 |
| 本地 Embedding | embedder.py | 空壳 | BGE-M3 返回全零向量 |
| 知识点切片 | knowledge_chunker.py | 空壳 | Phase 2 |
| 题目生成 | question_generator.py | 空壳 | Phase 2 |
核心瓶颈
药典 PDF 解析器(pharmacopoeia.py)是整个项目的最大瓶颈。当前只能依赖手动整理的 JSON 数据和维基百科采集,药典正文数据的最主要来源尚未实现。同时,已实现的 chunker.py 和 cleaner.py 被 ingest.py 绕过,数据处理质量未达到设计标准。
6.3 数据入库流程
ingest.py 数据流
JSON 文件 → 按 section 切 chunk → 拼接药品名+栏目名+来源 → 批量调用 DashScope Embedding API(每批 10 条)→ 写入 drug_chunks 表(content + embedding JSON + vec pgvector)→ 写入 drugs 表(ON CONFLICT DO UPDATE)
ingest.py 存在的问题:逐条 INSERT 无批量操作、无错误处理和断点续传、同时写 embedding(JSON) 和 vec(pgvector) 冗余存储、手动解析 .env 而非使用配置管理。
七、数据库设计
7.1 表结构总览
| 表名 | 说明 | 关键字段 | 状态 |
|---|---|---|---|
| users | 用户 | openid(UK), nickname, role | 已使用 |
| drugs | 药品主表 | drug_id(UK), name, sections(JSONB), 分类, source_version | 已使用 |
| drug_chunks | 药品文本切片 | content, vec(vector(1024)), embedding(JSON) | 已使用 |
| conversations | 对话会话 | conversation_id(UK), user_id, title | user_id 硬编码 0 |
| messages | 对话消息 | role, content, intent, sources(JSONB), feedback | 已使用 |
| knowledge_points | 考试知识点 | point_id(UK), subject, chapter, difficulty, frequency | 已建表/无数据 |
| questions | 考试题目 | question_id(UK), type(A/B/X), options(JSONB), answer | 已建表/无数据 |
| user_progress | 用户学习进度 | user_id, subject, chapter, questions_answered | 已建表/无数据 |
| answer_records | 答题记录 | user_id, question_id, is_correct | 已建表/无数据 |
7.2 索引设计
- pgvector IVFFlat 索引:
idx_drug_chunks_vec(lists=10) - GIN 索引:
ix_drugs_sections_gin(JSONB sections 列) - 唯一索引:drug_id, conversation_id, point_id, question_id, openid
- 外键:messages→conversations, answer_records→users, user_progress→users
7.3 数据库存在的问题
- IVFFlat 索引 lists=10 过小:数据量增长到数万条时检索质量严重下降,建议使用 HNSW 或增大 lists
- embedding 和 vec 冗余存储:drug_chunks 同时有 embedding(JSON) 和 vec(vector),embedding 列完全多余
- 无 tsvector 全文搜索索引:BM25 检索无法实现
- 无 created_at 索引:按时间排序的查询会全表扫描
- conversations.user_id 允许 NULL:与 messages 外键引用和实际使用(硬编码 0)设计不一致
八、部署方案
8.1 部署架构
| 组件 | 工具 | 说明 |
|---|---|---|
| 容器编排 | Docker Compose | 仅定义 PostgreSQL + Redis,后端未纳入 |
| 反向代理 | Nginx | 两套配置共存(Java 端口 9000 / Python 端口 8000) |
| 进程管理 | Supervisor | 两套配置共存(Java JAR / Python uvicorn) |
| SSL | Nginx | 证书路径为占位符,未配置 |
8.2 部署存在的问题
- 两套配置共存:nginx.conf / nginx-pharmacopoeia.conf、supervisord.conf / supervisord-java.conf,说明部署架构还在 Java/Python 过渡期
- 后端未纳入 Docker Compose:FastAPI 应用未容器化
- SSL 证书占位符:
/etc/nginx/ssl/cert.pem - supervisord.conf 引用不存在的 tasks 模块:
celery -A app.tasks worker - supervisord-java.conf 硬编码密码和 API Key
- PostgreSQL 默认密码:
POSTGRES_PASSWORD: postgres
九、缺陷清单与风险评估
9.1 严重缺陷(P0 - 必须立即修复)
| # | 缺陷 | 位置 | 影响 |
|---|---|---|---|
| 1 | JWT 密钥硬编码在配置文件中 | Java: application.yml | 任何人可伪造 Token,完全绕过认证 |
| 2 | 所有 API 路径 permitAll(),无权限控制 | Java: SecurityConfig.java | 管理员接口完全无保护,任何人可执行增删改查 |
| 3 | CORS 完全开放 + 允许凭证 | Java: SecurityConfig.java | CSRF 风险,任何网站可代用户操作 |
| 4 | 对话历史不按用户过滤 | Python: chat.py | 数据泄露,任何用户可查看所有对话 |
| 5 | Python 后端每次请求创建新数据库引擎 | Python: chat.py | 高并发下耗尽数据库连接,服务崩溃 |
9.2 高优先级缺陷(P1 - 尽快修复)
| # | 缺陷 | 位置 | 影响 |
|---|---|---|---|
| 6 | 对话历史全量加载到内存分页 | Java: ChatPersistenceService | 数据量增长后 OOM 和严重延迟 |
| 7 | 数据库默认弱密码 | Java: application.yml / Docker | 数据库安全风险 |
| 8 | Python 默认 secret_key="change-me" | Python: config.py | JWT 可被轻易伪造 |
| 9 | Conversation.userId 硬编码为 0 | Java: ChatPersistenceService | 对话无法关联到具体用户 |
| 10 | 无多轮对话上下文 | Java + Python | LLM 无法理解上下文,问答质量受限 |
| 11 | 生产级 Web 未使用 SSE 流式 | Java: static/index.html | 用户体验差,浪费后端能力 |
| 12 | 小程序 BASE_URL 为占位符 | miniprogram: api/ai.js | 小程序无法连接后端 |
9.3 中优先级缺陷(P2 - 计划修复)
| # | 缺陷 | 位置 | 影响 |
|---|---|---|---|
| 13 | 无 Embedding 缓存 | Java: RetrieverService | 重复查询浪费 API 费用和时间 |
| 14 | LLMService 同步阻塞 | Java: LLMService | 高并发下线程池耗尽 |
| 15 | BM25 检索未实现 | Java + Python | 混合检索只实现了一半,检索召回率受限 |
| 16 | BGE-Reranker 未加载 | Java + Python | 重排序使用简单启发式,精度不足 |
| 17 | Markdown 渲染逻辑三处重复 | 前端多文件 | 维护成本极高,行为不一致 |
| 18 | ChatController 职责过重(770 行) | Java: ChatController | 代码可维护性差 |
| 19 | ingest.py 未使用 chunker/cleaner | data-pipeline | 数据处理质量未达设计标准 |
| 20 | IVFFlat 索引 lists=10 过小 | database: schema.sql | 数据量增长后检索质量下降 |
| 21 | embedding 和 vec 冗余存储 | database + ingest | 存储浪费,一致性风险 |
| 22 | 异常处理吞掉错误 | Java: LLMService | 无法区分模型返回空和调用失败 |
| 23 | Python ORM 模型与实际使用脱节 | Python: models/ | 代码混乱,维护困难 |
| 24 | 部署配置两套共存 | deploy/ | 部署混乱,易出错 |
9.4 低优先级缺陷(P3 - 优化改进)
| # | 缺陷 | 位置 | 影响 |
|---|---|---|---|
| 25 | 文件冗余(static/index.html 重复) | static/ | 维护混乱 |
| 26 | 工具脚本功能重叠 | tools/ | 应合并为一个 |
| 27 | test.html Token 过期 | frontend-web/ | 测试工具不可用 |
| 28 | test_qwen_api.py .env 路径错误 | tools/ | 测试工具无法找到配置 |
| 29 | scrollToBottom 实现不可靠 | 小程序 | 部分场景滚动失效 |
| 30 | XSS 防护不一致 | 前端多文件 | 药品详情页 sections 未转义 |
| 31 | 死代码 buildDirectAnswer() | Java: ChatController | 代码整洁度 |
| 32 | SECTION_DISPLAY 重复定义 | Java: ChatController + PromptService | 不一致风险 |
| 33 | RateLimitFilter 仅内存限流 | Java | 多实例部署无法共享限流状态 |
| 34 | 缺少 @Transactional(readOnly=true) | Java: Repository | 浪费数据库资源 |
| 35 | 视频 base64 传输 | Python: llm_client.py | 50MB 视频产生 ~67MB base64,内存压力极大 |
9.5 未完成模块
| 模块 | 状态 | 影响 |
|---|---|---|
| 药典 PDF 解析器 | 空壳 | 核心数据源缺失,是最主要瓶颈 |
| NMPA 药品数据库爬虫 | 空壳 | 药品数据来源受限 |
| 考试学习模块(4 个 Controller) | 全部空壳 | 考试辅导功能完全不可用 |
| 管理后台导入/索引/AI 出题 | 占位 | 批量操作不可用 |
| Celery 异步任务 | 无 tasks 模块 | 长时间操作无法异步执行 |
| 本地 BGE-M3 Embedding | 返回全零向量 | 依赖远程 API,成本和延迟较高 |
| BM25 全文检索 | 未实现 | 混合检索只实现了一半 |
| BGE-Reranker 模型 | 空方法 | 重排序精度不足 |
十、总结与建议
10.1 项目成果总结
AI药典助手项目已经完成了基础架构搭建和核心 RAG 链路打通,具体成果包括:
- 搭建了完整的双后端体系(Java 主力 + Python 辅助),覆盖 40+ API 端点
- 实现了基于 pgvector 的向量检索 + 启发式重排序 + Qwen LLM 生成的 RAG 管线
- 支持多模态输入(文本/图片/视频),SSE 流式输出
- 完成了微信小程序和 Web 前端的 UI 交互实现
- 设计了完整的数据库结构(9 张表)和知识库管理 CRUD
- 构建了数据管道框架(爬虫 + 处理器 + 入库脚本)
- 完成了 Prompt 工程(6 套意图模板 + 合规规则)
10.2 核心问题诊断
三大核心问题
- 安全体系缺失:JWT 密钥硬编码、权限控制形同虚设、CORS 完全开放,生产环境存在严重安全风险
- 数据采集瓶颈:药典 PDF 解析器和 NMPA 爬虫未实现,知识库数据量严重不足,直接影响问答质量
- 双后端维护成本:Java/Python 两套后端共存,部署配置、ORM 使用、API 实现深度均不一致,增加维护复杂度
10.3 优先修复建议
| 优先级 | 行动项 | 预期效果 |
|---|---|---|
| P0 | 修复安全配置:JWT 密钥改用环境变量、admin 路由强制认证、限制 CORS 来源 | 消除生产环境安全风险 |
| P0 | 修复数据泄露:对话历史按 user_id 过滤、Python 后端复用数据库连接 | 防止用户数据泄露和服务崩溃 |
| P1 | 实现药典 PDF 解析器 | 突破数据采集瓶颈,充实知识库 |
| P1 | 修复对话历史分页查询、关联真实 userId | 解决 OOM 风险和用户隔离 |
| P1 | 生产级 Web 切换到 SSE 流式、小程序配置真实 BASE_URL | 提升用户体验 |
| P2 | 引入 Embedding 缓存、实现 BM25 检索、加载 BGE-Reranker | 提升检索质量和性能 |
| P2 | 统一部署配置、合并冗余文件、重构 ChatController | 降低维护成本 |
| P2 | 前端抽取共享 Markdown 渲染和 SSE 工具 | 消除代码重复 |
| P2 | 数据库升级 IVFFlat→HNSW、清理冗余 embedding 列、添加 tsvector 索引 | 提升检索性能和可扩展性 |
10.4 架构演进建议
- 明确后端策略:建议以 Java 后端为唯一生产环境,Python 后端仅用于数据管道和脚本工具,避免双后端维护负担
- 引入多轮对话:当前每次请求只发送当前问题,应携带历史消息上下文以提升问答质量
- 完善监控体系:添加请求日志、LLM 调用统计、API 用量追踪,便于运维和成本控制
- 数据质量管控:让 ingest.py 使用已实现的 chunker.py 和 cleaner.py,确保入库数据质量
- 渐进式功能交付:考试模块可先实现章节树和基础刷题,再逐步加入 AI 出题和进度跟踪