当前默认运行面向上线前联调,提供的核心用户能力是:
- 登录后的文本 AI 问答;
- 基于 Neo4j 数据的知识图谱可视化。
项目后端基于 FastAPI、Tortoise ORM、MySQL、Redis、Neo4j 和 LangChain/LangGraph 构建;文本问答调用 Qwen 兼容接口。默认编排不启动 语音、群聊、视频、教师生成工具、后台管理或语义缓存服务。
本项目由桂林电子科技大学三名研究生制作完成:2028 届韦草原、杨文军,2026 届洪基恒。
| 页面 | 路由 | 说明 |
|---|---|---|
| 登录/注册 | /login, /register |
用户认证与学生注册入口 |
| 文本问答 | /chat |
基于 Qwen 的文本问答;实时进度与答案通过 SSE 推送 |
| 知识图谱 | /graph |
通过后端认证接口读取 Neo4j 图数据并可视化 |
浏览器端不应配置或持有模型供应商密钥。认证、问答和图谱接口都由默认后端提供。
问答链路除基础对话外,还包含以下能力:
- 上下文压缩:超出 token 预算的较早轮次会被压缩成 rolling summary,并写回
qa_threads.conversation_summary。 - 长期记忆治理:在
QA_MEMORY_ENABLED=1且启用可选 PostgreSQL 后,回答完成会异步生成待确认候选;确认后的记忆才会进入后续回答上下文。 - 学习画像:用于调节讲解方式、难度和节奏,不作为事实记忆来源。
- 个人文档 RAG:支持上传 PDF/TXT,只检索当前用户自己的文档片段。
- 联网搜索:默认关闭;开启后可使用 Qwen 内置联网或 Tavily。
- 回答交互:已完成回答可重新生成、简化或发起出题练习。
- 线程管理:支持查看会话、隐藏会话,以及编辑当前线程的上下文摘要和问答轮次。
- 图谱检索:保留 GraphRAG 图谱问答与可视化入口。
docker-compose.yml 当前仅启动:
| 服务 | 用途 |
|---|---|
frontend |
Vue 主入口及 Nginx 同源代理 |
backend |
认证、文本问答 API、图谱 API、SSE 事件流与 WebSocket 兼容 |
worker |
文本问答后台任务 |
db_mysql |
账号与问答记录 |
db_neo4j |
知识图谱数据 |
redis |
任务队列与问答消息转发 |
graphrag-visualizer |
图谱可视化前端 |
以下目录或模块源码仍保留在仓库中,但不由默认 Compose 启动,也不在默认 前后端入口暴露:
ChatVRM-main/、ChatTTS-main/、vosk-main/;- 群聊/Mattermost;
- TTS 与语音播放;
- 视频与 OSS/MediaCMS 相关能力;
- 教师内容生成、备课和 PPT 工具;
manage-system/管理端;- Qdrant 语义缓存。
关闭默认启动不会删除既有 Docker volumes 或源代码。以后重新启用可选模块时, 需要单独进行凭据、权限、并发和资源消耗审查。
这次提交把 QA 模块整理成了一个更完整的产品面:
- 后端拆出了统一的
qa_platform路由层,集中承载记忆、画像、文档和交互接口。 - 新增了学习画像、个人文档、线程上下文管理、线程软隐藏等 API。
- 问答 worker 增加了画像注入、个人文档检索、联网搜索和记忆治理流程。
- 前端聊天页、登录页和注册页同步更新,支持新的问答交互与状态展示。
- 新增了 PostgreSQL checkpoint / memory 迁移、MySQL 文档与画像迁移,以及配套测试。
.
├── app/ # FastAPI 后端与 Vue 默认前端
├── graphrag-visualizer-main/ # 默认启用的图谱前端
├── teacher/ # 保留的教师工具源码,默认关闭
├── manage-system/ # 保留的管理端源码,默认关闭
├── ChatVRM-main/ # 保留的虚拟人源码,默认关闭
├── ChatTTS-main/ # 保留的 TTS 实验源码,默认关闭
├── vosk-main/ # 保留的语音识别源码,默认关闭
├── docker-compose.yml # 上线前联调默认编排
└── .env.example # 默认运行链路配置示例
当前编排用于上线前开发和轻量联调,不是最终 Ubuntu 生产编排。正式公开 部署前仍需要 TLS、端口收口、备份、监控、限流与容量验证。
cp .env.example .env
docker compose up -d --build
docker compose ps启动前填写核心凭据和文本问答模型密钥:
MYSQL_ROOT_PASSWORD=替换为数据库密码
DATABASE_URL=mysql://root:替换为数据库密码@db_mysql:3306/my_database?charset=utf8mb4
NEO4J_PASSWORD=替换为图数据库密码
SECRET_KEY=替换为足够长的随机JWT签名密钥
QWEN_API_KEY=你的Qwen兼容APIKey真实密钥只放在本地 .env,不要提交到仓库,也不要打进 Docker 镜像上下文。
仓库保留的 .env.example 只用于示例和初始化。
如果 mysql_data 已由旧配置初始化,MYSQL_ROOT_PASSWORD 和
DATABASE_URL 中的密码必须与已有数据卷一致。本次默认裁剪不会重置数据库
密码,也不会删除数据卷。
启动完成后可访问:
| 服务 | 地址 | 说明 |
|---|---|---|
| 主页面 | http://localhost |
登录、文本问答与知识图谱入口 |
| 后端文档 | http://localhost:8000/docs |
FastAPI API 文档 |
| 知识图谱 | http://localhost/graph |
经 Nginx 同源访问 |
| Neo4j Browser | http://localhost:7474 |
仅用于本地联调管理 |
默认问答链路(上线前联调):
Vue ChatPage
-> POST /api/v1/questions # 创建 run,返回 run_id
-> GET /api/v1/runs/{id}/events # SSE 主通道:阶段进度 + 最终答案
-> GET /api/v1/threads/{id}/turns # 刷新/重进页面时 hydrate 历史轮次
-> POST /api/v1/messages/{id}/actions # 重新生成 / 简化 / 出题练习的新 run
-> ARQ worker -> qa_agent # 后台生成,事件写入 Redis 缓冲
- SSE 主通道:
GET /api/v1/runs/{run_id}/events推送 run 生命周期事件(阶段、答案、错误)。Nginx 对该路径关闭缓冲;客户端重连会携带Last-Event-ID做短断线回放,并保留cursor兼容入口。 - WebSocket 兼容通道:仅用于旧客户端降级路径;当部署设置
QA_WS_QA_ENABLED=0且前端构建设置VUE_APP_QA_WS_QA_ENABLED=false时,问答事件仅经 SSE 传输。 - Turns hydrate:线程列表只存
run_id元数据。打开或刷新会话时,前端优先用本地缓存;若无缓存则按run_id回放 SSE 事件,或调用GET /api/v1/threads/{thread_id}/turns拉取已完成问答对。 - 上下文压缩:worker 组装 agent 输入时,对超出 token 预算的较早轮次生成 rolling summary,持久化在
qa_threads.conversation_summary(JSON)。可选QA_SUMMARY_LLM=flash|qwen走轻量模型摘要,失败或未配置时回退规则引擎。 - 长期记忆治理:设置
QA_MEMORY_ENABLED=1并启用可选 PostgreSQL 后,回答完成会异步产生待确认候选(纠正/个人规则/背景);学习目标与讲解偏好由学习画像自动维护。确认后的记忆在相关回答中注入,并通过context.memory_used披露。详见Docs/README.md。 - 用户画像:问答完成后根据用户问题记录轻量画像信号,按时间间隔或信号数量低频合并;回答前注入画像摘要,只用于调整解释方式和难度,不作为事实来源。
- 个人文档 RAG:用户可上传 PDF/TXT,后端解析为私有文本片段;回答时只检索当前用户文档,并以文件名和页码作为引用来源。
- 联网搜索:默认关闭;启用后默认使用通义千问内置联网(复用
QWEN_API_KEY,enable_search+ 搜索来源)。可选QA_WEB_SEARCH_PROVIDER=tavily走 Tavily。auto模式在问题含「联网/最新/今天」等词时触发,来源以网页标题与 URL 展示。 - 回答交互:已完成回答提供重新生成、简化与出题练习按钮,调用
POST /api/v1/messages/{run_id}/actions创建新 run,并沿用前台并发限制与 SSE 返回链路。
长期记忆上线观察可使用离线脚本,不读取或输出记忆正文:
python -m app.scripts.summarize_qa_memory_metrics /path/to/backend-worker.jsonl
python -m app.scripts.summarize_qa_memory_metrics --eval-cases全新 mysql_data 卷由 Tortoise 自动建表,无需手工 SQL。若沿用旧数据卷且缺少新列,见 app/db/migrations/README.md。长期记忆与 checkpoint 共用可选 PostgreSQL 连接;同时设置 QA_CHECKPOINT_PG=1 和 QA_MEMORY_ENABLED=1 后,backend/worker 自动应用 006_qa_user_memories.sql。
docker compose exec -T db_mysql mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" my_database \
< app/db/migrations/001_add_qa_thread_conversation_summary.sql仓库包含 app/datasource/ 示例 GraphRAG 数据。Neo4j 启动后可导入:
docker compose exec backend python app/scripts/import_graphrag_to_neo4j.pyNeo4j Browser 是本地管理工具,不应直接作为云服务器面向普通用户的入口。
| 变量 | 是否必填 | 作用 |
|---|---|---|
MYSQL_ROOT_PASSWORD |
启动必填 | MySQL 初始化或已有数据卷认证密码 |
DATABASE_URL |
启动必填 | 后端与 worker 的 MySQL 连接串 |
NEO4J_PASSWORD |
启动必填 | Neo4j 认证密码 |
SECRET_KEY |
启动必填 | JWT 签名密钥 |
CORS_ALLOWED_ORIGINS |
部署必填 | 可调用 API 的浏览器来源列表 |
QWEN_API_KEY |
问答必填 | 文本问答模型访问密钥 |
QWEN_FLASH_MODEL_NAME |
可选 | 意图识别和摘要使用的低延迟模型,默认 qwen-flash |
QWEN_PLUS_MODEL_NAME |
可选 | 普通问答模型,默认 qwen-plus |
QWEN_TURBO_MODEL_NAME |
可选 | 默认 qwen-turbo |
QWEN_MAX_MODEL_NAME |
可选 | 默认 qwen-max |
QWEN_BASE_URL |
可选 | Qwen 兼容接口地址 |
QA_MODEL_ROUTING_ENABLED |
可选 | 启用 Flash/Plus/Max 按任务路由,默认 true |
QA_SUMMARY_LLM |
可选 | 对话摘要后端:off(默认,规则引擎)、flash、qwen |
QA_SUMMARY_FLASH_MODEL |
可选 | QA_SUMMARY_LLM=flash 时模型名,默认 qwen-flash |
QA_SUMMARY_QWEN_MODEL |
可选 | QA_SUMMARY_LLM=qwen 时模型名,默认 QWEN_TURBO_MODEL_NAME |
QA_WS_QA_ENABLED |
可选 | 是否向旧 WebSocket 问答通道投递事件,默认 true |
QA_CHECKPOINT_PG |
可选 | 启用 PostgreSQL checkpoint 存储,默认 false |
QA_MEMORY_ENABLED |
可选 | 启用受控长期记忆;还需要 QA_CHECKPOINT_PG=1,默认 false |
QA_DOCUMENT_MAX_UPLOAD_BYTES |
可选 | 个人问答文档上传大小上限,默认 10485760 |
QA_DOCUMENT_STORAGE_DIR |
可选 | 个人问答文档原文件存储目录,默认 /code/data/qa_documents |
QA_QUESTION_MAX_CHARS |
可选 | 单次提问最大字符数,默认 6000 |
QA_RUN_EVENT_BUFFER_MAX |
可选 | 单个 run 的事件缓冲上限,默认 128 |
QA_WEB_SEARCH_ENABLED |
可选 | 是否启用联网搜索,默认 false |
QA_WEB_SEARCH_PROVIDER |
可选 | 联网供应商:qwen(默认,复用 QWEN_API_KEY)或 tavily |
QA_WEB_SEARCH_QWEN_MODEL |
可选 | Qwen 联网所用模型,默认 qwen-plus |
QA_WEB_SEARCH_API_KEY |
tavily 时必填 |
Tavily API Key;qwen 模式不需要 |
QA_WEB_SEARCH_TOP_K |
可选 | 每次联网搜索最多来源数,默认 3 |
GRAPH_PUBLIC_URL |
可选 | 图谱静态资源前缀,默认 /graph |
VUE_APP_API_BASE_URL |
可选 | 留空表示前端使用同源代理 |
VUE_APP_WS_URL |
可选 | 留空表示前端使用同源 WebSocket |
VUE_APP_QA_WS_QA_ENABLED |
可选 | 是否允许前端 SSE 多次失败后降级 WebSocket,默认 true |
VUE_APP_GRAPH_URL |
可选 | 默认 /graph |
检查 .env 中 QWEN_API_KEY 是否有效,并查看任务日志:
docker compose logs -f backend worker确认 Neo4j 已启动,然后执行图谱导入命令:
docker compose exec backend python app/scripts/import_graphrag_to_neo4j.py这些模块当前只保留源码,不属于默认启动与对外暴露范围。该边界用于降低 CPU-only 单机联调阶段的外部凭据依赖、额外服务开销和并发故障面。
本项目采用 Apache License 2.0,详见 LICENSE。