学伴(KnowAI)项目开发实战:从零构建一个AI驱动的在线教育平台
学伴(KnowAI)项目开发实战:从零构建一个AI驱动的在线教育平台
前言:我为什么要做这个项目?
作为一名开发者,我一直对“AI如何改变教育”这个话题感兴趣。市面上不缺课程——B站有海量免费视频、慕课有几千门名校课程。但有两个问题始终没解决:
- 用户看完视频,不知道学没学会。没有反馈,没有验证。
- 用户不知道下一步学什么。碎片化学习,东一榔头西一棒子。
所以我想做一个平台:让AI像学伴一样,全程陪伴学习、验证效果、规划路径。这就是“学伴(KnowAI)”的由来。
学伴的核心价值不是“提供内容”,而是“提供学会的保障”。
经过2个星期的开发,项目已经基本完成,部署在阿里云ECS上。这篇文章将完整记录开发过程、技术选型、踩坑经验和最终成果。
当前进度:项目已完整开发完成,目前正在部署上线阶段,服务器已购买,待完成Docker部署和域名配置即可公网访问。
一、项目全景:学伴是什么?
1.1 一句话定位
学伴是一个AI驱动的个性化学习平台——让每个学习者拥有专属的AI学伴。
1.2 解决的三个核心问题
| 问题 | 学伴的解决方案 |
|---|---|
| 学而不练 | AI智能出题,学完章节自动生成测验 |
| 学而不伴 | 24小时AI对话助手,随时解答疑问 |
| 学而不精 | 基于学习历史的个性化课程推荐 |
1.3 用户角色
- 学员:购买课程、看视频、做测验、问AI、记笔记
- 讲师:发布课程、管理章节、上传知识库、看销售数据
- 管理员:审核课程、管理用户、配置秒杀
1.4 一个完整的学习流程
注册 → 浏览课程 → 加入购物车 → 下单支付 → 学习课程 → AI出题验证 → 获得反馈 → 推荐下一门课
二、技术栈全览
这个项目最大的特点就是全栈——从最前端的Vue界面到最底层的向量数据库,都是我自己写的。
2.1 技术栈表格
| 层级 | 技术 | 用途 |
|---|---|---|
| 前端框架 | Vue 3.4 + TypeScript + Vite | 响应式UI |
| UI组件 | Element Plus + Vant + ECharts | 后台管理+移动端+图表 |
| 后端框架 | FastAPI + SQLAlchemy 2.0(异步) | RESTful API + ORM |
| 主数据库 | MySQL 8.0 | 用户、课程、订单、库存 |
| 文档数据库 | MongoDB 6 | 聊天记录、学习笔记 |
| 缓存 | Redis 7 | 会话、购物车、秒杀、首页缓存 |
| 搜索引擎 | Elasticsearch 8.10 | 课程全文搜索 |
| 消息队列 | RabbitMQ | 秒杀订单异步处理 |
| AI框架 | LangChain + LangGraph + ChromaDB | RAG知识库、多Agent工作流 |
| AI模型 | DeepSeek API + SiliconFlow BGE | 大语言模型 + 向量嵌入 |
| 容器化 | Docker Compose | 一键部署所有服务 |
2.2 为什么这样选型?
为什么用FastAPI而不是Django?
- 原生支持异步,在调用AI API、操作Redis/ES时性能更好
- 自动生成OpenAPI文档,前后端联调省时间
- 类型提示友好,Pydantic校验让代码更健壮
为什么用LangGraph而不是直接调LLM?
- 多Agent协作:一个Agent负责理解用户意图,一个负责检索知识库,一个负责生成回答
- 状态管理:LangGraph的状态图让每个Agent能看到之前的处理结果
- 可观测性:每一步都有记录,方便调试
为什么用MongoDB存聊天记录?
- 对话数据是非结构化的,MongoDB的文档模型很自然
- 支持嵌套结构(一条聊天记录包含多轮对话)
- TTL索引可以自动清理过期数据
三、架构设计
3.1 系统架构图

3.2 数据流向
- 用户请求 → Nginx → FastAPI
- 读操作 → 优先Redis缓存 → 缓存未命中则查MySQL/ES
- 写操作 → MySQL → 异步同步到ES/Redis/MongoDB
- AI请求 → FastAPI → LangGraph工作流 → 检索ChromaDB → 调用DeepSeek → 返回结果
- 秒杀请求 → Redis预扣库存 → RabbitMQ排队 → 异步Worker下单
四、核心功能实现
4.1 用户认证(JWT + Redis黑名单)
认证系统的核心逻辑:
- 用户登录成功后,后端生成JWT并存入Redis(key:
token:{user_id}:{jti}) - 每次请求,验证JWT签名 + 检查Redis中是否存在该token
- 用户退出时,从Redis删除该token(实现黑名单注销)
# auth.py 核心逻辑
async def get_current_user(
token: str = Depends(oauth2_scheme),
db: AsyncSession = Depends(get_db),
redis: Redis = Depends(get_redis),
) -> User:
token_data = decode_token(token)
# 检查Redis黑名单
if await redis.exists(f"token:{token_data.user_id}:{token_data.jti}") == 0:
raise HTTPException(status_code=401, detail="Token已失效")
# 查数据库获取用户
user = await db.get(User, token_data.user_id)
return user
设计要点:
- Token本身不存数据库,减少DB查询
- 注销只需删除Redis key,O(1)复杂度
- Token有效期7天,可配置
4.2 秒杀系统(防止超卖的完整方案)
秒杀是电商的经典场景,也是这个项目最复杂的功能之一。我设计了一套“四层防护”方案:
第一层:限流(令牌桶)
每分钟只允许3000个请求进入,超过的直接返回“活动太火爆”
第二层:Redis预扣库存
活动开始前5分钟,将库存加载到Redis (String类型)
抢购时执行原子DECR操作,库存为0则直接返回“已抢光”
第三层:异步排队(RabbitMQ)
抢到名额的用户ID写入RabbitMQ队列,立即返回“排队中”
不阻塞用户,提升体验
第四层:异步Worker下单
消费者从队列读取消息,真正扣减MySQL库存、生成订单
保证最终一致性
恢复机制:
如果订单超时未支付或被取消,会自动恢复Redis库存和MySQL库存,让名额回到池中。
代码结构:
# seckill.py - 抢购入口
@router.post("/{activity_id}")
async def submit_seckill(activity_id: int, current_user: User):
# 1. 限流检查
if not await allow_token_bucket(redis, key, 3000, 3000):
raise HTTPException(429, "请求过于频繁")
# 2. Redis原子扣库存
stock = await redis.decr(f"seckill:stock:{activity_id}")
if stock < 0:
raise HTTPException(400, "已抢光")
# 3. 写入队列
queue_id = uuid.uuid4().hex
await redis.rpush("seckill:queue", json.dumps({
"queue_id": queue_id,
"activity_id": activity_id,
"user_id": current_user.id
}))
return {"queue_id": queue_id, "status": "queued"}
4.3 AI学伴:LangGraph + RAG
这是项目最核心、最亮眼的功能。下面详细展开。
4.3.1 知识库构建
讲师上传课件(PDF/DOCX/TXT)后,系统自动构建向量知识库:
- 文档加载:使用LangChain的文档加载器读取各类格式
- 文本分块:按500 token分块,重叠50 token,保持语义完整性
- 向量化:使用BGE嵌入模型将文本转为向量
- 存储:存入ChromaDB持久化
# 核心流程
def build_knowledge_base(course_id: int, file_paths: list[str]):
documents = []
for path in file_paths:
docs = load_document(path) # 支持PDF/DOCX/TXT
documents.extend(docs)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = text_splitter.split_documents(documents)
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory=f"./chroma_db/course_{course_id}"
)
4.3.2 智能出题工作流
学员学完章节后,点击“生成练习题”触发LangGraph工作流:
用户请求 → 意图解析 → 检索知识库 → 生成题目 → 校验题目 → 返回
用LangGraph实现的多Agent协作:
# 状态定义
class WorkflowState(TypedDict):
messages: list[BaseMessage]
retrieved_docs: list[Document]
generated_questions: list[dict]
validation_result: dict
# 构建工作流图
workflow = StateGraph(WorkflowState)
workflow.add_node("retrieve", retrieve_relevant_docs)
workflow.add_node("generate", generate_questions)
workflow.add_node("validate", validate_questions)
workflow.add_edge("retrieve", "generate")
workflow.add_edge("generate", "validate")
效果:用户点击出题后,5-10秒内得到5道选择题,每题包含4个选项和正确答案。前端渲染后学员可以直接作答,系统自动评分。
4.3.3 智能推荐工作流
用户输入学习目标(如“我想成为一名数据科学家,需要学Python和机器学习”),系统通过多Agent工作流分析:
- 意图解析Agent:提取关键词(Python、机器学习、数据科学家)
- 课程检索Agent:从MySQL搜索匹配课程 + 从知识库检索相关内容
- 推荐排序Agent:综合课程销量、评分、匹配度排序,生成推荐理由
输出示例:
根据你的目标“成为数据科学家”,推荐以下课程:
- Python基础入门(匹配度92%)- 数据科学必备语言
- 机器学习实战(匹配度88%)- 核心技能
- 数据分析与可视化(匹配度85%)- 日常工作必备
4.3.4 AI对话助手
用户在任何页面都可以打开AI助手对话框,用自然语言提问。系统按以下顺序处理:
- 知识库检索:从课程知识库中搜索相关内容(RAG)
- 联网搜索:如果知识库找不到,使用DuckDuckGo联网搜索
- 大模型兜底:以上都没有,用DeepSeek生成回答
特点是:回答会标注来源(知识库/联网/大模型),让用户知道信息的可靠性。
用户真实使用场景:
用户在学习《Python基础》时,问AI:“列表和元组有什么区别?”
AI从课程知识库中找到对应内容,回答:“根据课程第二章第3节的讲解,列表是可变的(可变序列),元组是不可变的(不可变序列)…”
4.4 秒杀崩溃恢复机制
这是系统稳定性的关键设计。线上环境可能因各种原因导致秒杀处理失败,需要一套保障机制:
问题场景:
- Worker进程崩溃,正在处理的秒杀消息丢失
- 网络抖动导致消息处理超时
- 数据库连接断开导致事务回滚
解决方案:
- 每个秒杀消息处理时,设置Redis锁(TTL 30秒)
- 独立的Recovery Worker每60秒扫描一次,检查是否有消息被遗忘
- 如果发现消息的锁已过期,自动将其重新入队
# 崩溃恢复逻辑
async def recovery_worker():
while True:
await asyncio.sleep(60)
for worker_id in range(WORKER_COUNT):
key = f"seckill:processing:{worker_id}"
items = await redis.lrange(key, 0, -1)
for raw in items:
payload = json.loads(raw)
lock_key = f"seckill:lock:{payload['queue_id']}"
if not await redis.exists(lock_key):
# 锁已过期,重新入队
await redis.rpush("seckill:queue", raw)
await redis.lrem(key, 1, raw)
print(f"恢复: 重新入队 {payload['queue_id']}")
4.5 课程搜索(Elasticsearch)
使用ES实现课程的全文检索:
- 索引设计:包含title(text)、description(text)、category(keyword)、price_min(float)、sales(integer)
- 中文分词:使用IK分词器,搜索更精准
- 同步机制:课程数据变更时,通过RabbitMQ异步同步到ES
支持的搜索方式:
- 关键词搜索(支持分词)
- 分类筛选
- 价格区间筛选
- 排序(销量/价格/最新)
前端体验:输入关键词 → 1秒内返回匹配课程列表,高亮显示匹配片段。
4.6 订单超时自动取消
用户下单后30分钟未支付,系统自动取消并恢复库存:
实现方式:
- 后台独立协程,每30秒扫描一次数据库
- 查找
status='pending'且expire_time < now()的订单 - 逐个取消并恢复库存
async def scan_expired_orders():
while True:
await asyncio.sleep(30)
async with AsyncSessionLocal() as db:
# 查找过期订单
result = await db.execute(
select(Order).where(
Order.status == OrderStatus.pending,
Order.expire_time <= datetime.now()
)
)
for order in result.scalars():
# 恢复库存、更新状态
await cancel_order(db, order)
await db.commit()
五、踩坑与解决
5.1 Dify迁移到LangGraph
初期使用Dify工作流,但遇到定制化困难:
- 问题:Dify的节点编排灵活,但无法精细控制每一步的输入输出格式
- 解决:迁移到LangGraph + LangChain,完全代码可控,可以自定义每个Agent的逻辑
5.2 Windows上调用SSL证书错误
开发环境是Windows,调用Dify API时遇到SSL证书验证失败:
- 问题:httpx在Windows上对Cloudflare的SSL验证失败
- 解决:检测到Windows平台时自动降级为curl命令调用(
dify_client.py中实现了fallback)
5.3 DeepSeek API连接超时
偶尔出现连接超时:
- 问题:DeepSeek API不稳定
- 解决:实现重试机制(最多3次),并配置超时时间(30秒)
- 降级:如果DeepSeek完全不可用,返回模拟数据保证功能不中断
六、部署实战(正在进行中)
6.1 为什么选择阿里云?
- 国内访问速度快
- 学生优惠(一年100多块)
- 支持Docker部署
6.2 部署架构
使用Docker Compose编排7个服务:
| 服务 | 镜像 | 端口 |
|---|---|---|
| MySQL | mysql:8.0 | 3306 |
| MongoDB | mongo:6 | 27017 |
| Redis | redis:7-alpine | 6379 |
| Elasticsearch | elasticsearch:8.10 | 9200 |
| RabbitMQ | rabbitmq:3-management | 5672/15672 |
| Backend | 自定义FastAPI镜像 | 8000 |
| Frontend | Nginx托管Vue静态文件 | 80/443 |
6.3 部署步骤
1. 购买阿里云ECS(2核4G以上)
2. 安装Docker和Docker Compose
3. 将项目代码推送到服务器
4. 配置.env环境变量
5. 执行 docker-compose up -d
6. 配置Nginx反向代理和SSL证书
6.4 一键部署脚本
# 项目根目录下执行
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f backend
6.5 遇到的问题
- 内存不足:ES和MySQL同时启动占用内存较大,需要调整JVM参数
- 域名解析:需要配置域名解析到服务器IP,等待DNS生效(10-30分钟)
七、成果展示
7.1 功能清单
- 用户注册登录(手机号+密码)
- JWT认证 + Redis黑名单注销
- 课程列表、搜索、详情(ES)
- 学习计划(购物车)
- 下单支付(支付宝模拟)
- 秒杀活动(Redis+RabbitMQ)
- 订单管理
- 学习进度追踪
- AI对话助手(LangGraph+RAG)
- AI智能出题
- AI作业批改
- AI课程推荐
- 讲师后台(课程管理)
- 管理员后台
- 首页缓存(Redis)
- Docker一键部署
7.2 代码量
- 后端Python代码:约8000行
- 前端Vue代码:约6000行
- 配置文件:约500行
八、未来优化方向
8.1 短期优化
- 视频直接上传:目前视频上传依赖讲师提供外部链接,后续可支持直接上传MP4并转码
- 学习路径自动规划:用户输入目标,AI自动生成完整学习计划
- 课程证书系统:学完课程生成NFT证书
8.2 长期扩展
- 直播教学:集成实时音视频,支持直播互动
- 移动端APP:用Flutter或React Native开发独立APP
- 学习成就系统:通过ECharts生成学习数据看板
九、一些思考
9.1 关于AI辅助编程
这个项目大量使用了AI辅助编程(Copilot、ChatGPT、Cursor等)。我的感受是:
- AI能帮你写80%的模板代码,但设计决策需要你自己做
- AI生成的代码必须逐行review,否则会有隐藏bug
- 真正有价值的是你对项目的整体理解
9.2 关于全栈开发
全栈开发不是“什么都会一点”,而是:
- 能独立设计数据库表结构
- 能写干净的后端API
- 能做出能用的前端界面
- 能把项目部署到服务器上
学伴项目让我真正理解了“全栈”的含义。
9.3 技术选型的思考
- 能用的技术 ≠ 适合的技术。比如Dify虽然用起来简单,但定制化困难,最后迁移到了LangGraph。
- 先跑通再优化。很多功能我是先用简单实现跑通,再逐步优化。
- 文档是最好的朋友。LangChain、FastAPI、Vue的官方文档帮了大忙。
9.4 关于AI原生应用
这个项目让我深刻体会到:AI不是加一个聊天窗口就叫AI应用。真正的AI原生应用,是把AI能力嵌入到产品的核心流程中:
- 学完自动出题 → AI
- 学完推荐下一门 → AI
- 有疑问立即解答 → AI
AI不是外挂,而是产品的一部分。
十、常见问题
Q:部署需要什么配置的服务器?
A:最低2核4G,建议4核8G(MySQL和ES比较吃内存)。
Q:DeepSeek API免费吗?
A:注册送500万tokens,正常使用够用很久。
Q:项目做完了可以商用吗?
A:代码是个人项目,如果商用建议替换掉ES(使用费)和DeepSeek API(调用费)。
Q:我想自己做一个类似的,从哪里开始?
A:建议先看一遍需求文档,然后按以下顺序搭建:
- 先跑通后端(FastAPI + 注册登录)
- 再加课程管理
- 再加购物车和订单
- 再加搜索(ES)
- 最后加AI功能(先简单接API,再考虑LangGraph)
写在最后
从零开始做一个完整的全栈项目,确实不容易。中间踩过无数坑,但也学到了很多。如果你也在做类似的项目,希望这篇文章能给你一些参考。
几个建议:
- 代码要能跑:功能再多,跑不起来都是零
- AI是工具,不是答案:能用AI提高效率,但别让它替你思考
- 坚持到底:做到最后你会发现,最难的其实是“坚持做下去”
项目还在不断完善中,欢迎交流讨论。如果对部署有兴趣,可以关注后续的部署实战文章。
项目地址:https://github.com/lcm-git/zhixue-ai (私有仓库,可联系获取访问权限)
在线演示:https://knowai.你的域名.com (部署中)
如果你在开发过程中遇到类似的问题,欢迎在评论区交流。
更多推荐



所有评论(0)