# net_cafe_management **Repository Path**: tanbing/net_cafe_management ## Basic Information - **Project Name**: net_cafe_management - **Description**: 网咖前台管理系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-10-21 - **Last Updated**: 2026-10-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 网咖前台管理系统 基于 **FastAPI + MySQL + 原生 HTML/CSS/JavaScript** 的网咖前台管理系统,内置 **AI 智能助手**、**本地 RAG 知识库问答**,以及基于 **Neo4j** 的**知识图谱结构化增强**能力,并配套**离线评估与模块消融实验**(检索 / 生成双维度打分)。 --- ## 功能模块 ### 1. 管理员登录 / 注册 - 管理员账号注册 - 管理员登录验证(前端基于 localStorage 记录登录态) ### 2. 数据统计(首页) - 机器总数、使用中、空闲、维修中数量 - 会员总数 - 今日收入、今日订单数 - 商品总数、低库存商品数 - 近 7 天收入趋势图 ### 3. 机器管理 - 机器列表(网格视图) - 机器状态:空闲、使用中、维修、关机(下机)、预定、挂机 - 机器增删改查 - 上机 / 下机 / 批量下机 - 机器预定 / 取消预定 - 实时费用计算(上机预扣、挂机计时) ### 4. 会员管理 - 会员注册、列表搜索 - 会员充值、余额调整 - 会员启用 / 禁用 ### 5. 商品管理 - 商品列表(分类筛选)、增删改查 - 库存管理、低库存预警 - 商品销售(会员扣款) ### 6. 订单管理 - 上机订单、商品订单 - 订单详情查看、状态筛选(今日 / 近 7 天 / 近 30 天) - 上机订单结账下机 ### 7. AI 智能助手 - 侧边栏「AI 助手」进入独立对话页,对话历史本地保存(localStorage) - 自动检索知识库并增强回答,回复下方展示「参考知识库」来源 - 同时注入知识图谱产出的【图谱事实】:来自结构化数据与计费规则的确定事实,与文档摘录冲突时以其为准 ### 8. 知识库管理(RAG) - 知识库的创建 / 列表 / 删除 - 文档上传(`.txt` / `.md` / `.markdown` / `.docx`,单文件 ≤ 10MB) - 自动解析 → 分块 → 向量化 → 建索引 - 文档列表、重建索引、删除文档 - 检索测试:查看命中片段、相似度分数,以及图谱通道产出的图谱事实与图谱上下文 ### 9. 知识图谱 - 侧边栏「知识图谱」进入可视化页(`kg.html`,基于 vis-network)展示主线图谱 - 图谱范围「窄而深」:区域 → 机器 → 费率 → 计费规则 → 机器状态流转;节点 / 关系 100% 来自业务库与计费代码语义,不做文档抽取,故无抽取误差 - 顶部统计:图谱节点数 / 关系数 / 本次命中事实数;按节点类型着色并附图例 - 节点详情:点击图中节点查看其结构化属性 - 图谱问答探针:输入一句话,实时展示识别出的实体、产出的图谱事实,以及最终送进大模型的图谱上下文 - 只读展示:图谱由后台脚本构建,前端页面只读,不影响其它模块 ### 10. 评估实验(RAG 离线评估) - 侧边栏「评估实验」进入 `eval.html`:先看**模块开关现状**(按检索前 / 检索中 / 检索后 / 生成分组展示),再看**消融矩阵**(14 组组合 × 8 项指标,含相对基线的 Δ) - **历史明细批次**:汇总 `rag-eval/` 下每次逐条评估的结果(检索六项 + 生成四项均值),可横向对比不同配置 - 页面可直接**触发一次跑批**:检索层消融(`ablation`)或逐条明细(`detail`,可选追加生成层判分),后台以子进程拉起 `scripts/eval_rag.py`,实时回显日志尾部 - 评估与实现解耦:脚本是**纯 HTTP 客户端**,只调本后端的 `/api/kb/search` 与 `/api/ai/chat`,不 import 任何 `rag` 模块,重构后无需改脚本 --- ## 技术栈 ### 后端 | 组件 | 说明 | |---|---| | FastAPI | Web 框架 | | SQLAlchemy | ORM | | **MySQL** | 业务数据库(通过 PyMySQL 驱动) | | Pydantic | 数据校验 | | httpx | 调用本地 Ollama 接口 | | **Chroma** | 向量数据库(持久化,余弦相似度) | | python-docx | 解析 `.docx` 文档 | | **Neo4j** | 图数据库(知识图谱主线,Bolt 协议) | ### AI / RAG | 组件 | 说明 | |---|---| | Ollama | 本地大模型运行时 | | **bge-m3** | 向量化模型(1024 维,无需 query 前缀) | | **qwen3:4b** | 生成模型 `gen_model`(回答生成)+ 辅助模型 `aux_model`(查询改写 / LLM 重排),默认同为 qwen3:4b | | **bge-reranker-v2-m3** | cross-encoder 精排(`rerank_mode="ce"`,默认关闭,需按 `requirements-reranker.txt` 预下载) | | **Neo4j** | 知识图谱存储(区域 → 机器 → 费率 → 计费规则 → 机器状态) | | **qwen3:0.6b** | 评估判分模型(`eval_rag.py --judge-model` 默认值,temperature=0),只用于离线评估打分,**不参与线上问答** | ### 前端 - 原生 HTML / CSS / JavaScript - **vis-network**:知识图谱可视化(本地引入 `js/vis-network.min.js`,无 CDN 依赖) - 响应式设计,无构建步骤 --- ## 项目结构 ``` net_cafe_manage/ ├── backend/ # 后端 │ ├── main.py # 应用入口(注册路由、挂载静态资源、启动定时扣费) │ ├── database.py # 数据库连接与会话 │ ├── models.py # SQLAlchemy 数据模型 │ ├── schemas.py # Pydantic 模型 │ ├── billing.py # 计费逻辑 + 后台定时扣费任务 │ ├── init_data.py # 初始化测试数据 │ ├── ai_service.py # 大模型调用(系统提示词 + RAG 上下文注入) │ ├── rag/ # RAG 模块(Advanced RAG 模块化实现) │ │ ├── config.py # 全局可调参数(按三阶段组织) │ │ ├── loader.py # 文档加载(txt/md/docx) │ │ ├── splitter.py # 文档分块(检索前) │ │ ├── embedder.py # 向量化(bge-m3) │ │ ├── store.py # 向量库封装(Chroma)+ 语料缓存 │ │ ├── indexer.py # 建 / 删索引 │ │ ├── query_processor.py # 查询改写 / 扩展 / 子查询分解(检索前) │ │ ├── retriever.py # 稠密 + BM25 多路召回 + RRF 融合(检索中) │ │ ├── reranker.py # 重排序(检索中) │ │ ├── postprocessor.py # 过滤 / 去重 / 压缩(检索后) │ │ ├── pipeline.py # 三阶段串联 │ │ ├── llm.py # RAG 内部 LLM 调用 │ │ └── text_utils.py # 分词 / 相似度工具 │ ├── kg/ # 知识图谱模块(窄而深主线) │ │ ├── graph_schema.py # 图谱 Schema(五类节点与关系定义) │ │ ├── graph_store.py # Neo4j 连接 / 写入 / 清空封装 │ │ ├── builder_mysql.py # 从 MySQL 与计费语义构建主线图谱 │ │ └── graph_query.py # 查询通道:实体识别 → 子图查询 → 事实文本化 │ ├── .env # 本地环境变量(Neo4j 口令等,已 gitignore) │ ├── .env.example # 环境变量样例 │ ├── requirements.txt # Python 依赖 │ ├── requirements-reranker.txt # cross-encoder 精排的可选依赖(torch / transformers) │ ├── migrate_*.py # 历史迁移脚本(idcard / machines / sqlite→mysql) │ ├── scripts/ │ │ ├── ingest_knowledge.py # 批量把 knowledge/ 下的文档导入知识库 │ │ ├── build_kg.py # 构建知识图谱到 Neo4j(`--reset` 先清空再重建) │ │ ├── check_kg_query.py # 图谱查询通道离线自测(含「应为空」用例) │ │ ├── eval_rag.py # RAG 离线评估脚本(检索 / 生成指标 + 消融,纯 HTTP 客户端) │ │ └── eval_set.csv # 评估集(80 条,含 gold 标注) │ ├── knowledge/ # 示例知识文档 │ │ ├── 计费规则.md │ │ ├── 会员制度.md │ │ ├── 机器管理.md │ │ ├── 电脑操作指南.md │ │ ├── 外设调试指南.md │ │ ├── 网管问题处理.md │ │ └── 常见问题补充.md │ ├── uploads/ # 上传的原始文档(运行时生成,已 gitignore) │ ├── chroma_db/ # 向量库持久化目录(运行时生成,已 gitignore) │ └── routers/ # API 路由 │ ├── auth.py # 管理员认证 │ ├── members.py # 会员管理 │ ├── machines.py # 机器管理 │ ├── products.py # 商品管理 │ ├── orders.py # 订单管理 │ ├── stats.py # 数据统计 │ ├── ai.py # AI 对话(含 RAG 检索增强) │ ├── knowledge.py # 知识库管理 │ ├── graph.py # 知识图谱只读接口(/api/kg) │ └── eval.py # 评估实验接口(/api/eval:overview / run / run_status) ├── frontend/ # 前端 │ ├── css/style.css # 全局样式 │ ├── js/common.js # 通用工具 + 侧边栏/顶栏渲染 │ ├── js/ai-page.js # AI 助手对话页逻辑(检索增强、来源展示) │ ├── js/vis-network.min.js # 图谱可视化库(本地引入,无 CDN 依赖) │ ├── login.html # 登录页 │ ├── register.html # 注册页 │ ├── home.html # 功能预览 │ ├── index.html # 数据统计 │ ├── machines.html # 机器管理 │ ├── members.html # 会员管理 │ ├── products.html # 商品管理 │ ├── orders.html # 订单管理 │ ├── knowledge.html # 知识库管理 │ ├── ai.html # AI 助手 │ ├── kg.html # 知识图谱 │ └── eval.html # 评估实验(开关现状 / 消融矩阵 / 历史批次 / 跑批) ├── rag-eval/ # 评估报告与存档(HTML 报告 + 评估明细 CSV) ├── start.bat # Windows 启动脚本 ├── .gitignore └── README.md ``` --- ## RAG 知识库架构 采用 **Advanced RAG** 三阶段流水线,组件全部在 `backend/rag/` 下按职责拆分,可单独替换: ``` 检索前 检索中 检索后 QueryProcessor → HybridRetriever → Reranker → PostProcessor 查询改写/扩展/分解 稠密 + 稀疏 + 图谱三路召回 + 加权 RRF 重排序 过滤/去重/压缩 ``` ### 数据流:入库(写) ``` 上传文件 → 落盘 uploads/{uuid}.{ext} → 建 KnowledgeFile 记录(status=pending) → rag.loader.load_text() 按扩展名解析(txt/md 多编码;docx 走 python-docx,含表格) → rag.splitter.split_text() Markdown 按标题层级切章节,章节内段落聚合 + 长段按句切 + 50 字重叠 → rag.embedder.embed() 调 Ollama /api/embed(bge-m3,批大小 16) → rag.indexer.delete_file_index() 按 file_id 清旧切片(保证幂等) → Chroma.add() 写入向量 + 文本 + metadata(含 heading) → 回写 chunk_count、status=ready ``` > 知识图谱不走这条上传链路:它由 `scripts/build_kg.py` 从 MySQL 与计费语义**离线构建**到 Neo4j,与文档入库互不影响。 ### 数据流:问答(读) ``` POST /api/ai/chat {message, history, kb_id, overrides?} → rag.get_pipeline(overrides).retrieve() # overrides 为请求级覆盖,仅当次请求生效 ① 检索前 QueryProcessor · 查询改写(rule 去口语词;llm 可选) · 查询扩展(网咖领域同义词,喂给 BM25) · 子查询分解(「和 / 以及 / 还有」多问题拆分) ② 检索中 HybridRetriever · 稠密召回:查询向量化 → Chroma 余弦 top-15(每个子查询一路) · 稀疏召回:BM25(纯 Python,中文按字符二元组)top-15 · 图谱通道:实体识别 → Neo4j 子图查询 → 事实文本化(由 `kg_*` 开关控制) · 加权 RRF 融合多路 → 候选 top-20 · 统一用「查询-候选余弦」作为 score(阈值口径一致) ③ 检索中 Reranker · heuristic:余弦 + BM25 + 关键词覆盖率 + 标题命中 + 图谱证据分(`rerank_weight_graph`) · llm:辅助模型 `aux_model` listwise 打分(可选) · ce:bge-reranker-v2-m3 精排(可选,需预下载模型,未就绪时自动回退 heuristic) ④ 检索后 PostProcessor · 相关性过滤(score ≥ 0.4,`filter_enabled`) · 去重(Jaccard ≥ 0.85 视为近似重复,`dedup_enabled`) · 上下文压缩(只保留与问题最相关的句子,≤ 420 字,`compress`) · 截断到 top-3(`postprocess_enabled` 为整段总开关) → rag.build_context() 拼成「[资料i](来源:文件名 · 小节)」注入 system 消息; 图谱事实单独成块(【图谱事实】),不占向量切片名额 → ai_service.chat() 调 Ollama /api/chat(生成模型 `gen_model`) → 返回 {reply, sources, used_kb} ``` ### 关键参数 | 参数 | 取值 | 位置 | |---|---|---| | 分块长度 / 重叠 | 450 / 50 | `rag/config.py` | | 相似度阈值 | 0.4 | `rag/config.py` | | 稠密 / 稀疏 / 融合候选 | 15 / 15 / 20 | `rag/config.py` | | 重排模式 | `heuristic`(可切 `llm` / `ce` / `off`) | `rag/config.py` | | 去重阈值 | 0.85(Jaccard) | `rag/config.py` | | 上下文压缩上限 | 420 字 | `rag/config.py` | | 注入条数 | 3 | `rag/config.py` | | 查询改写模式 | `rule`(可切 `llm` / `off`) | `rag/config.py` | | 向量维度 | 1024(bge-m3) | `rag/embedder.py` | | 向量库 | Chroma,一库一 collection(`kb_{id}`),`hnsw:space=cosine` | `rag/store.py` | | 图谱开关 | `kg_enabled = True` | `rag/config.py` | | 图谱融合权重 | `kg_weight = 0.5`(与「一路」对齐) | `rag/config.py` | | 图谱回捞 / 事实上限 | `kg_expand_top_k = 5` / `kg_max_facts = 8` | `rag/config.py` | | 图谱证据分权重 | `rerank_weight_graph = 0.2` | `rag/config.py` | | 模块开关 | `dense_enabled` / `sparse_enabled` / `postprocess_enabled` / `filter_enabled` / `dedup_enabled`,默认均 `True` | `rag/config.py` | | 请求级覆盖 | `/api/kb/search`、`/api/ai/chat` 支持 `overrides`(白名单见 `OVERRIDE_FIELDS`),仅对当次请求生效,不写回全局配置 | `rag/config.py` | | 消融实验 | `python scripts/eval_rag.py --ablation`(leave-one-out,检索层,零模型开销) | `scripts/eval_rag.py` | | 评估集 / 消融组 | 80 条 / 14 组(1 组 baseline + 12 组 leave-one-out + 1 组换档对照 `rerank=ce`) | `scripts/eval_set.csv`、`scripts/eval_rag.py` | | 判分模型 | `qwen3:0.6b`(`--judge-model` 默认值,temperature=0) | `scripts/eval_rag.py` | | 评估口径 | `n` = 有 gold 的样本数(排序指标口径);`n_ctx` = 上下文预算样本数(含拒答样本) | `scripts/eval_rag.py` | | 生成模型超时 | 180s(首次冷启动需加载模型) | `ai_service.py` | ### 设计要点 - **模块化**:三阶段各是一个组件类,`pipeline.py` 只负责串联;替换检索器 / 重排器不影响其它环节。 - **检索失败不影响对话**:`_retrieve()` 内 try/except 兜底,返回空上下文继续回答。 - **阈值门控**:全部命中低于 0.4 时不注入资料,`used_kb` 返回 `false`。 - **零额外依赖**:BM25 与中文分词均为纯 Python 实现,不引入 jieba / rank_bm25。 - **重排与查询改写默认走轻量模式**(heuristic / rule),LLM 版本作为可选开关,更准但更慢。 - **图谱降级安全**:Neo4j 未启动或未配置口令时,图谱通道降级为空结果并只提示一次,问答链路不受影响。 - **图谱「窄而深」**:只覆盖结构化主线(计费 / 费率 / 区域 / 机器状态),文档类问题主动沉默,因节点来自业务库而非文档抽取,故无抽取误差。 ### 模块开关与消融(请求级 `overrides`) 所有检索 / 后处理开关都集中在 `rag/config.py`,并开放为**请求级覆盖**:`POST /api/kb/search`、`POST /api/ai/chat` 都可带 `overrides`,后端用 `normalize_overrides` 收敛(白名单 + 类型 + 取值校验),再用 `apply_overrides` 以 `dataclasses.replace` 生成一份配置副本交给该次请求的流水线;**不写回全局 config**,因此线上默认行为不受影响。`get_pipeline(overrides)` 按覆盖组合缓存 `RAGPipeline`,同一组合反复调用不重复构建。 `OVERRIDE_FIELDS` 白名单(12 个字段): | 分类 | 字段 | 取值 | |---|---|---| | 三态 | `query_rewrite_mode` | `off` / `rule` / `llm` | | 三态 | `rerank_mode` | `off` / `heuristic` / `llm` / `ce` | | 布尔 | `query_expand`、`subquery_decompose`、`dense_enabled`、`sparse_enabled`、`kg_enabled` | `true` / `false` | | 布尔 | `postprocess_enabled`、`filter_enabled`、`dedup_enabled`、`compress` | `true` / `false` | | 数值 | `rerank_weight_graph` | `0 ~ 1` | 请求示例(临时关闭重排与图谱,仅本次生效): ```bash curl -X POST http://localhost:8000/api/kb/search \ -H "Content-Type: application/json" \ -d '{"query": "挂机怎么收费", "top_k": 5, "overrides": {"rerank_mode": "off", "kg_enabled": false}}' ``` ### 离线评估(`scripts/eval_rag.py`) 评估脚本是**纯 HTTP 客户端**:只调本后端的 `/api/kb/search`(inspect 路径,保留阈值以下的候选,排序质量才可测)与 `/api/ai/chat`(真实线上路径),**不 import 任何 `rag` 模块**,因此重构 RAG 后无需改脚本。 - **检索层六项**:Hit@1 / Hit@3、Precision@5、Recall@5、NDCG@10、MRR,外加**上下文成本**(`context_chunks` / `context_chars`)——零模型开销、可反复跑。 - **生成层四项**:忠实度 `faithful`、答案相关性 `relevancy`、答案正确率 `correctness`、拒答正确率 `abstained`,由本地判分模型打分(`--with-llm`)。 - **消融矩阵**:`--ablation` 跑 14 组(1 组 baseline + 12 组 leave-one-out + 1 组 `rerank=ce` 换档),输出各组合指标与相对 baseline 的 Δ。 ```bash cd backend python scripts/eval_rag.py # 仅检索层六项 python scripts/eval_rag.py --with-llm # 追加生成层四项(调用 Ollama 判分) python scripts/eval_rag.py --ablation --out ablation.csv # leave-one-out 消融矩阵 ``` **真实消融结论**(评估集 80 条,有 gold 的 68 条,明细见 `rag-eval/ablation_*.csv` 最新一批): | 组合 | Hit@1 | Recall@5 | 上下文切片 | 上下文字符 | 结论 | |---|---|---|---|---|---| | baseline | 0.6471 | 0.8407 | 18.58 | 3295.8 | — | | −rerank_mode | 0.6029 | 0.7941 | 18.58 | 3295.8 | **重排序贡献最大**(Hit@1 −0.044、MRR −0.025) | | −postprocess_enabled | 0.6471 | 0.8407 | 19.85 | 3577.3 | 后处理**只省上下文**(−281 字符),排序不变 | | −kg_enabled | 0.6324 | 0.8627 | 18.53 | 3291.5 | 图谱提升**首位命中**(Hit@1 −0.015),代价是 Recall 略降 | | −dense_enabled | 0.6471 | 0.8407 | 14.10 | 2455.0 | 稠密对排序无增益,但占约 1/4 上下文预算 | | rerank=ce | 0.6471 | 0.8505 | 18.58 | 3295.9 | CE 档 Hit@3 0.9118 → 0.9265,小幅提升 | > 判分模型说明:本地判定模型为带思维链的 Qwen3,提示词越啰嗦思考越久(同一判定长提示词 122s、短提示词 2s),且业界常见的 `think=false` 在 Ollama 上无效。因此判分提示词写得**极短 + 各带一条 few-shot**(否则 0.6b 小模型会把错答判满分),默认判分模型改为 `qwen3:0.6b`(≈2s/次);如需更高质量可 `--judge-model qwen3:4b`,但慢约 25 倍。 --- ## 快速开始 ### 0. 环境前置 1. **MySQL 已启动**,并存在 `net_cafe` 数据库(连接串见 `backend/database.py`)。 2. **Ollama 已启动**,且已拉取所需模型: ```bash ollama serve ollama pull bge-m3 ollama pull qwen3:4b ``` 3. **Neo4j 已启动**(知识图谱用,可选;不启动则图谱通道自动降级为空结果,其它功能不受影响): - 复制 `backend/.env.example` 为 `backend/.env`,填好 `NEO4J_PASSWORD`(该文件已 gitignore,不入库); - 之后执行一次「构建知识图谱」把主线写入 Neo4j。 ### 1. 安装依赖 ```bash cd backend pip install -r requirements.txt ``` ### 2. 初始化数据(可选) ```bash cd backend python init_data.py ``` ### 3. 构建知识图谱(可选) 需 Neo4j 已启动且 `backend/.env` 已配置口令: ```bash cd backend python scripts/build_kg.py --reset # 构建主线图谱(--reset 先清空再重建) python scripts/check_kg_query.py # 离线自测图谱查询通道 ``` ### 4. 启动服务 **推荐(Windows 双击):** ```bash start.bat ``` **手动启动:** ```bash cd backend python -m uvicorn main:app --host 0.0.0.0 --port 8000 ``` > 注意:不要加 `--reload`,会与后台定时扣费任务冲突导致进程异常。 ### 5. 访问系统 - 登录页:http://localhost:8000/static/login.html - API 文档:http://localhost:8000/docs - 健康检查:http://localhost:8000/api/health ### 6. 体验 RAG 与知识图谱 1. 登录后进入侧边栏「**知识库管理**」; 2. 上传 `backend/knowledge/` 下的文档(也可在 `backend/` 下执行 `python scripts/ingest_knowledge.py` 批量入库); 3. 在「检索测试」输入问题,查看三阶段流水线的改写结果、候选数与重排分数; 4. 进入侧边栏「**AI 助手**」提问,回复下方会显示引用的知识库来源; 5. 进入侧边栏「**知识图谱**」:查看 53 节点 / 108 关系的主线图谱,点击节点看详情;在「图谱问答探针」输入如「挂机怎么收费」,可看到命中的实体与 4 条图谱事实; 6. 进入侧边栏「**评估实验**」:查看模块开关现状与消融矩阵;点「跑批」可选检索层消融(`ablation`)或逐条明细(`detail`,勾选生成层则调 Ollama 判分),后台实时回显日志。 > 也可不进页面、直接在命令行跑评估,命令见上文「[离线评估](#离线评估scriptseval_ragpy)」小节。 --- ## 默认账号 | 角色 | 用户名 | 密码 | 备注 | |---|---|---|---| | 管理员 | `admin` | `123456` | | | 测试会员 | `member001` | `123456` | 余额 ¥100 | --- ## API 概览 ### 认证 `/api/auth` | 方法 | 路径 | 说明 | |---|---|---| | POST | `/api/auth/register` | 管理员注册 | | POST | `/api/auth/login` | 管理员登录 | ### 机器 `/api/machines` | 方法 | 路径 | 说明 | |---|---|---| | GET / POST | `/api/machines` | 列表 / 新增 | | GET / PUT / DELETE | `/api/machines/{id}` | 详情 / 修改 / 删除 | | POST | `/api/machines/{id}/start` | 上机 | | POST | `/api/machines/{id}/stop` | 下机 | | POST | `/api/machines/{id}/idle-machine` | 挂机 | | POST | `/api/machines/{id}/reserve` | 预定 | | POST | `/api/machines/batch-stop` | 批量下机 | | PUT | `/api/machines/batch-rate/update` | 批量改价 | | GET | `/api/machines/{id}/cost` | 实时费用 | | GET | `/api/machines/{id}/member-info` | 当前上机会员信息 | ### 会员 `/api/members` | 方法 | 路径 | 说明 | |---|---|---| | GET | `/api/members` | 会员列表 | | POST | `/api/members/register` | 会员注册 | | POST | `/api/members/login` | 会员登录 | | POST | `/api/members/recharge` | 充值 | | PUT | `/api/members/{id}/toggle` | 启用 / 禁用 | | PUT | `/api/members/{id}/balance` | 调整余额 | | DELETE | `/api/members/{id}` | 删除 | ### 商品 `/api/products` | 方法 | 路径 | 说明 | |---|---|---| | GET / POST | `/api/products` | 列表 / 新增 | | GET / PUT / DELETE | `/api/products/{id}` | 详情 / 修改 / 删除 | | GET | `/api/products/categories/list` | 分类列表 | ### 订单 `/api/orders` | 方法 | 路径 | 说明 | |---|---|---| | GET | `/api/orders` | 订单列表(支持类型、日期筛选) | | GET | `/api/orders/{id}` | 订单详情 | | POST | `/api/orders/machine` | 创建上机订单 | | POST | `/api/orders/product` | 创建商品订单 | | POST | `/api/orders/{id}/complete` | 结账完成 | ### 统计 `/api/stats` | 方法 | 路径 | 说明 | |---|---|---| | GET | `/api/stats` | 首页汇总数据 | | GET | `/api/stats/weekly` | 近 7 天收入 | | GET | `/api/stats/daily` | 按日统计 | ### 知识库 `/api/kb` | 方法 | 路径 | 传参 | 说明 | |---|---|---|---| | GET | `/api/kb/list` | — | 知识库列表(含文件数、切片数) | | POST | `/api/kb` | JSON `{name, description}` | 新建知识库 | | DELETE | `/api/kb/{kb_id}` | 路径 `kb_id` | 删除知识库(级联删文件与向量) | | GET | `/api/kb/{kb_id}/files` | 路径 `kb_id` | 文档列表 | | POST | `/api/kb/{kb_id}/upload` | 路径 `kb_id` + form 字段 `file` | 上传并建索引 | | DELETE | `/api/kb/file/{file_id}` | 路径 `file_id` | 删除文档及其切片 | | POST | `/api/kb/file/{file_id}/rebuild` | 路径 `file_id` | 重建索引 | | POST | `/api/kb/search` | JSON `{query, kb_id?, top_k=5}` | 检索测试,返回命中片段 + 流水线信息(改写 / 子查询 / 候选数) | ### AI `/api/ai` | 方法 | 路径 | 传参 | 说明 | |---|---|---|---| | POST | `/api/ai/chat` | JSON `{message, history?, kb_id?}` | 对话(自动检索增强),返回 `{reply, sources, used_kb}` | ### 知识图谱 `/api/kg`(只读) | 方法 | 路径 | 传参 | 说明 | |---|---|---|---| | GET | `/api/kg/graph` | — | 全量主线子图(节点 + 关系),供前端一次性渲染 | | POST | `/api/kg/explain` | JSON `{question}` | 输入提问,返回命中实体、图谱事实、需高亮的节点 | > 图谱不可用(Neo4j 未启动 / 未配置口令)时返回 `503` 并带上原因,前端据此给出提示,不影响其它模块。 ### 评估实验 `/api/eval` | 方法 | 路径 | 传参 | 说明 | |---|---|---|---| | GET | `/api/eval/overview` | — | 一次性返回:模块开关现状(按三阶段分组)+ 最新消融矩阵(含 Δ)+ 历史明细批次 + 当前任务状态 | | POST | `/api/eval/run` | JSON `{mode: "ablation"\|"detail", with_llm?, overrides?, label?}` | 后台子进程拉起 `eval_rag.py` 跑批;同一时间只允许一个任务,重复触发返回 `409`;`ablation` 为纯检索,不支持 `with_llm` | | GET | `/api/eval/run/status` | — | 查询后台任务进度、退出码与日志尾部(供页面实时回显) | > 跑批输出落在 `rag-eval/`:`ablation_*.csv`(消融矩阵)与 `detail_*.csv`(逐条明细);页面「历史明细批次」即从该目录汇总。 --- ## 数据表 | 表名 | 说明 | |---|---| | `admins` | 管理员 | | `members` | 会员(以身份证号唯一标识) | | `machines` | 机器 | | `products` | 商品 | | `orders` | 订单 | | `order_items` | 订单明细 | | `recharge_records` | 充值记录 | | `knowledge_bases` | 知识库 | | `knowledge_files` | 知识库文档 | > 知识图谱不使用 MySQL 表:五类节点(区域 / 机器 / 费率 / 计费规则 / 机器状态)与关系存放在 **Neo4j** 中,由 `scripts/build_kg.py` 构建。 --- ## 常见问题 **Q:启动报 `Can't connect to MySQL server on 'localhost:3306'`?** MySQL 服务未启动,先启动 MySQL 再运行后端。 **Q:AI 对话报 503「AI 服务未连接」?** Ollama 未启动,执行 `ollama serve`。 **Q:首次对话很慢或超时?** qwen3:4b 首次调用需加载约 2.5GB 模型,冷启动可能超过 1 分钟,已把超时放宽到 180s。 **Q:上传文档报「建索引失败」?** 检查 Ollama 是否可用、`bge-m3` 是否已拉取;`.docx` 需安装 `python-docx`。 **Q:能直接用 Navicat 改数据库吗?** 不建议。后端每 60 秒执行一次定时扣费并写库,直连改数据会绕过业务校验与联动,容易造成数据不一致;操作前请先停服务。 **Q:知识库检索不到内容?** 确认文档已上传且状态为 `ready`,并在「检索测试」里观察相似度是否低于 0.4 阈值。 **Q:知识图谱页报「知识图谱不可用」或接口返回 503?** Neo4j 未启动,或 `backend/.env` 里 `NEO4J_PASSWORD` 未配置。启动 Neo4j 并确认口令后重试;此状态下 AI 问答仍可正常使用(图谱通道自动降级)。 **Q:图谱页显示 0 个节点?** 尚未构建图谱。Neo4j 启动后,在 `backend/` 下执行 `python scripts/build_kg.py --reset`。 **Q:评估页跑批很慢 / 判分超时?** 判分模型默认 `qwen3:0.6b`,单次约 2s;`detail` + 生成层需逐条调生成与判分,样本多时耗时较长。检索层消融(`ablation`)完全不调用模型,最快。若换 `qwen3:4b` 判分,质量更高但慢约 25 倍。 **Q:为什么消融矩阵的 `n` 是 68,而评估集有 80 条?** `n` 是「有 gold 标注」的样本数——排序指标只在有 gold 时才计算命中;`n_ctx` 是实际返回了上下文预算的样本数(含拒答类样本)。两个口径不同,属于正常现象。