从零开始做一个课程资料 RAG Agent 问答系统(一)项目搭建

从零开始做一个 Java Web 课程资料 RAG Agent 问答系统

本文是一份面向初学者的手把手开发教程,基于当前仓库里的后端 MVP 项目和本轮对话整理而成。

项目目标:做一个面向高校单门 Java Web 开发课程的资料问答系统。教师上传课程 PPT、教材 PDF、实验指导书、示例代码后,学生可以围绕课程资料提问:

  • 这章重点是什么?
  • 实验怎么做?
  • 这段代码是什么意思?
  • 考试可能怎么出题?
  • 报错应该怎么排查?

当前版本是后端 MVP。它已经具备文件上传、资料解析、文本切块、本地检索、问答接口和引用来源返回能力,但还没有前端页面,也还没有接真实大模型 API。


1. 项目定位

这个项目的核心不是训练一个大模型,而是把大模型能力接入真实教学业务场景。

完整目标流程如下:

text 复制代码
教师上传课程资料
-> 系统解析资料
-> 系统把资料切成小片段
-> 学生提出问题
-> 系统先从资料里找相关内容
-> 再基于找到的资料生成回答
-> 返回答案和出处

这就是 RAG 的基本流程。

RAG 是 Retrieval-Augmented Generation,中文常译为检索增强生成。简单说,就是先检索资料,再生成回答。

普通大模型问答:

text 复制代码
学生提问
-> 大模型凭自己的知识回答

RAG 问答:

text 复制代码
学生提问
-> 系统从课程资料里找相关片段
-> 把相关片段交给大模型
-> 大模型基于这些资料回答
-> 返回答案和出处

RAG 的价值是让回答有依据,减少幻觉。


2. Agent、RAG、LLM 的关系

2.1 LLM 是什么

LLM 是 Large Language Model,大语言模型。

常见例子包括 GPT、Claude、Gemini、通义千问、DeepSeek、Kimi 等。

LLM 负责理解和生成自然语言。但是 LLM 不一定知道你的课程资料、你的实验指导书、你的课堂要求,也可能编造内容。

2.2 RAG 是什么

RAG 让大模型先看你的资料,再回答问题。

在教育场景里,它解决的问题是:

  • 学生问的问题必须基于课程资料回答。
  • 回答需要附带出处。
  • 资料不足时不能乱编。
  • 教师可以控制知识来源。

2.3 Agent 是什么

Agent 比普通问答更进一步。

普通问答系统主要是:

text 复制代码
你问一句,它答一句。

Agent 更像是:

text 复制代码
你给一个任务,它会拆步骤、调工具、执行流程。

例如以后可以让系统做:

text 复制代码
帮我分析本章课程资料,生成 10 道选择题、5 道简答题,并整理成 Word。

一个 Agent 可能会执行:

text 复制代码
理解任务
-> 检索课程资料
-> 调用大模型生成题目
-> 调用文档工具生成 Word
-> 返回下载链接

当前项目还不是完整 Agent。当前项目是 RAG 后端 MVP,是后续 Agent 化的基础。


3. 当前项目技术栈

当前后端使用 Python 技术栈:

text 复制代码
Python
FastAPI
Uvicorn
SQLAlchemy
SQLite
Swagger UI
本地文件存储 uploads

3.1 Python

Python 是项目的主要编程语言。

注意:课程内容是 Java Web,但系统本身用 Python 写。

也就是说:

text 复制代码
系统服务对象:Java Web 课程
系统开发语言:Python

3.2 FastAPI

FastAPI 是 Python Web API 框架。

它负责定义接口,例如:

text 复制代码
GET /api/health
POST /api/documents
GET /api/documents
DELETE /api/documents/{document_id}
POST /api/chat/ask

类比 Java:

text 复制代码
FastAPI 类似 Spring MVC / Spring Boot Web

3.3 Uvicorn

Uvicorn 是 ASGI Web 服务器。

它负责把 FastAPI 应用跑起来,监听浏览器或客户端发来的 HTTP 请求。

类比 Java:

text 复制代码
Uvicorn 类似 Tomcat / Netty
FastAPI 类似 Spring MVC

启动命令:

bash 复制代码
uvicorn app.main:app --reload

这条命令的含义:

text 复制代码
uvicorn        启动 Uvicorn 服务器
app.main       找 backend/app/main.py 这个模块
:app           使用 main.py 里的 app 变量
--reload       开发模式,代码改了自动重启

3.4 Swagger UI

浏览器打开:

text 复制代码
http://127.0.0.1:8000/docs

这个页面就是 Swagger UI。

它是后端接口文档和接口测试页面。它能让你不用写前端,也不用 Postman,就能直接测试接口。

3.5 SQLite

SQLite 是本地轻量级数据库。

它不需要单独启动数据库服务,也不需要像 MySQL 那样安装服务端。Python 标准库自带 SQLite 支持,所以当前项目可以直接使用。

当前项目里:

text 复制代码
原始上传文件 -> 保存到 backend/uploads 目录
文档元数据 -> 保存到 SQLite
解析后的文本切块 -> 保存到 SQLite
问答历史 -> 保存到 SQLite

所以,上传的文件本体不是直接塞进 SQLite。SQLite 主要保存文件信息、解析文本、切块和问答记录。


4. 项目目录结构

项目根目录:

text 复制代码
E:\CodeX\agent

主要目录:

text 复制代码
agent/
  backend/
    app/
      api/
      core/
      models/
      schemas/
      services/
      main.py
    tests/
    pyproject.toml
    README.md
    .env.example
  docs/
    superpowers/
    tutorials/
  .gitignore

4.1 backend

backend 是后端项目目录,包含 FastAPI 应用代码、数据库模型、业务服务、API 路由、测试代码和 Python 依赖配置。

4.2 app/main.py

入口文件:

text 复制代码
backend/app/main.py

核心作用:

  • 创建 FastAPI 应用。
  • 注册健康检查接口。
  • 注册文档接口。
  • 注册问答接口。

示例结构:

python 复制代码
from fastapi import FastAPI

from app.api.chat import router as chat_router
from app.api.documents import router as documents_router


def create_app() -> FastAPI:
    app = FastAPI(title="Java Web RAG Assistant", version="0.1.0")

    @app.get("/api/health")
    def health() -> dict[str, str]:
        return {"status": "ok", "service": "java-web-rag-assistant"}

    app.include_router(documents_router)
    app.include_router(chat_router)
    return app


app = create_app()

这里的 def create_app() -> FastAPI: 表示定义一个函数,返回 FastAPI 类型的对象。

类比 Java:

java 复制代码
public static FastAPI createApp() {
    ...
}

Python 里的 -> FastAPI 是返回值类型标注,不是 lambda。

4.3 app/api

负责定义 HTTP 接口。

当前主要文件:

text 复制代码
documents.py    文档上传、文档列表、删除文档
chat.py         学生提问接口

4.4 app/core

负责基础配置。

当前主要文件:

text 复制代码
config.py       读取配置,例如数据库地址、上传目录
database.py     创建数据库连接、初始化表

4.5 app/models

负责数据库表模型。

当前主要文件:

text 复制代码
document.py     上传文档表
chunk.py        文本切块表
chat.py         会话和消息表
user.py         用户表,当前 MVP 先预留

4.6 app/schemas

负责接口请求和响应结构。Swagger 页面底部的 Schemas 就来自这里。

例如:

text 复制代码
ChatAskRequest      提问请求结构
ChatAskResponse     提问响应结构
DocumentRead        文档返回结构

你可以把它理解成 Java 里的 DTO。

4.7 app/services

负责业务逻辑。

当前主要文件:

text 复制代码
storage.py      保存上传文件
parsers.py      解析 PDF、DOCX、PPTX、Markdown、代码等
chunking.py     文本切块
ingestion.py    文档入库流程
retrieval.py    本地检索
prompt.py       Prompt 构造
chat.py         问答服务