学伴(KnowAI)项目开发实战:从零构建一个AI驱动的在线教育平台

前言:我为什么要做这个项目?

作为一名开发者,我一直对“AI如何改变教育”这个话题感兴趣。市面上不缺课程——B站有海量免费视频、慕课有几千门名校课程。但有两个问题始终没解决:

  1. 用户看完视频,不知道学没学会。没有反馈,没有验证。
  2. 用户不知道下一步学什么。碎片化学习,东一榔头西一棒子。

所以我想做一个平台:让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 数据流向

  1. 用户请求 → Nginx → FastAPI
  2. 读操作 → 优先Redis缓存 → 缓存未命中则查MySQL/ES
  3. 写操作 → MySQL → 异步同步到ES/Redis/MongoDB
  4. AI请求 → FastAPI → LangGraph工作流 → 检索ChromaDB → 调用DeepSeek → 返回结果
  5. 秒杀请求 → Redis预扣库存 → RabbitMQ排队 → 异步Worker下单

四、核心功能实现

4.1 用户认证(JWT + Redis黑名单)

认证系统的核心逻辑:

  1. 用户登录成功后,后端生成JWT并存入Redis(key: token:{user_id}:{jti}
  2. 每次请求,验证JWT签名 + 检查Redis中是否存在该token
  3. 用户退出时,从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)后,系统自动构建向量知识库:

  1. 文档加载:使用LangChain的文档加载器读取各类格式
  2. 文本分块:按500 token分块,重叠50 token,保持语义完整性
  3. 向量化:使用BGE嵌入模型将文本转为向量
  4. 存储:存入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工作流分析:

  1. 意图解析Agent:提取关键词(Python、机器学习、数据科学家)
  2. 课程检索Agent:从MySQL搜索匹配课程 + 从知识库检索相关内容
  3. 推荐排序Agent:综合课程销量、评分、匹配度排序,生成推荐理由

输出示例

根据你的目标“成为数据科学家”,推荐以下课程:

  1. Python基础入门(匹配度92%)- 数据科学必备语言
  2. 机器学习实战(匹配度88%)- 核心技能
  3. 数据分析与可视化(匹配度85%)- 日常工作必备
4.3.4 AI对话助手

用户在任何页面都可以打开AI助手对话框,用自然语言提问。系统按以下顺序处理:

  1. 知识库检索:从课程知识库中搜索相关内容(RAG)
  2. 联网搜索:如果知识库找不到,使用DuckDuckGo联网搜索
  3. 大模型兜底:以上都没有,用DeepSeek生成回答

特点是:回答会标注来源(知识库/联网/大模型),让用户知道信息的可靠性。

用户真实使用场景

用户在学习《Python基础》时,问AI:“列表和元组有什么区别?”
AI从课程知识库中找到对应内容,回答:“根据课程第二章第3节的讲解,列表是可变的(可变序列),元组是不可变的(不可变序列)…”

4.4 秒杀崩溃恢复机制

这是系统稳定性的关键设计。线上环境可能因各种原因导致秒杀处理失败,需要一套保障机制:

问题场景

  • Worker进程崩溃,正在处理的秒杀消息丢失
  • 网络抖动导致消息处理超时
  • 数据库连接断开导致事务回滚

解决方案

  1. 每个秒杀消息处理时,设置Redis锁(TTL 30秒)
  2. 独立的Recovery Worker每60秒扫描一次,检查是否有消息被遗忘
  3. 如果发现消息的锁已过期,自动将其重新入队
# 崩溃恢复逻辑
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 短期优化

  1. 视频直接上传:目前视频上传依赖讲师提供外部链接,后续可支持直接上传MP4并转码
  2. 学习路径自动规划:用户输入目标,AI自动生成完整学习计划
  3. 课程证书系统:学完课程生成NFT证书

8.2 长期扩展

  1. 直播教学:集成实时音视频,支持直播互动
  2. 移动端APP:用Flutter或React Native开发独立APP
  3. 学习成就系统:通过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:建议先看一遍需求文档,然后按以下顺序搭建:

  1. 先跑通后端(FastAPI + 注册登录)
  2. 再加课程管理
  3. 再加购物车和订单
  4. 再加搜索(ES)
  5. 最后加AI功能(先简单接API,再考虑LangGraph)

写在最后

从零开始做一个完整的全栈项目,确实不容易。中间踩过无数坑,但也学到了很多。如果你也在做类似的项目,希望这篇文章能给你一些参考。

几个建议

  1. 代码要能跑:功能再多,跑不起来都是零
  2. AI是工具,不是答案:能用AI提高效率,但别让它替你思考
  3. 坚持到底:做到最后你会发现,最难的其实是“坚持做下去”

项目还在不断完善中,欢迎交流讨论。如果对部署有兴趣,可以关注后续的部署实战文章。


项目地址:https://github.com/lcm-git/zhixue-ai (私有仓库,可联系获取访问权限)

在线演示:https://knowai.你的域名.com (部署中)

如果你在开发过程中遇到类似的问题,欢迎在评论区交流。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐