Commit 6a87f73b authored by uuo00_n's avatar uuo00_n

docs: 更新项目文档结构和内容

- 重构 ACCOUNTS.md 文件,补充初始化脚本来源和详细账号信息
- 删除过时的 ARCHITECTURE_REDESIGN.md 文件
- 优化 DEVELOPMENT.md 文件结构,简化启动说明
- 重写 README.md,完善模块说明和架构细节
- 更新技术白皮书内容,调整架构描述和数据存储策略
parent 15c33bcb
# 默认初始化账号清单
以下账号已在数据库中初始化完成,可直接用于测试。所有账号的默认密码均为:**`password123`**
以下账号会在初始化脚本执行后写入 PostgreSQL,可直接用于测试。所有账号的默认密码均为:**`password123`**
初始化来源:
- 用户账号:`scripts/init_postgres.sql`
- 教务演示数据(班级/人员/绑定/课表/考勤/操行/通知):`scripts/init_edu_postgres.py`
- LLM 侧演示数据(敏感词等):`scripts/init_mongo.py`
## 🎓 教育版 (Edu Edition)
......@@ -10,17 +15,17 @@
| 角色 | 账号 | 角色等级 | 姓名 | 班级 | 说明 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **学生** | `student_101` | 1 (User) | 张一 | 高一(1)班 | 理科创新班 |
| **学生** | `student_102` | 1 (User) | 李二 | 高一(2)班 | 理科普通班 |
| **学生** | `student_103` | 1 (User) | 王三 | 高一(3)班 | 文科普通班 |
| **学生** | `student_101` | 1 (User) | 张一 | 软件2301班 | 绑定学号:S20230101 |
| **学生** | `student_102` | 1 (User) | 李二 | 软件2302班 | 绑定学号:S20230102 |
| **学生** | `student_103` | 1 (User) | 王三 | 网络2301班 | 绑定学号:S20230103 |
### 教师账号 (Teachers)
| 角色 | 账号 | 角色等级 | 姓名 | 职务 | 说明 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **班主任** | `teacher_101` | 2 (Manager) | 赵老师 | 班主任 | 负责高一(1)班 |
| **班主任** | `teacher_102` | 2 (Manager) | 钱老师 | 班主任 | 负责高一(2)班 |
| **班主任** | `teacher_103` | 2 (Manager) | 孙老师 | 班主任 | 负责高一(3)班 |
| **班主任** | `teacher_101` | 2 (Manager) | 赵老师 | 班主任 | 软件2301班 |
| **班主任** | `teacher_102` | 2 (Manager) | 钱老师 | 班主任 | 软件2302班 |
| **班主任** | `teacher_103` | 2 (Manager) | 孙老师 | 班主任 | 网络2301班 |
### 管理层账号 (Administration)
......@@ -44,14 +49,17 @@
系统初始化了以下核心业务数据:
- **班级**: 3个高一年级班级 (1班、2班、3班),包含不同的文理科方向
- **班级**: 3 个班级(软件2301、软件2302、网络2301)
- **人员**: 覆盖了学生、班主任、教务主任、年级组长、校长等多种角色。
- **课表**: 为每个班级生成了一周的完整课表,包含主科(语数英)和副科,且配置了对应的授课老师
- **考勤与操行**: 生成了当天的考勤记录和操行评分示例
- **通知公告**: 生成了校级、年级级、部门级的多层级通知数据
- **课表**: 为每个班级生成工作日课表(示例课程包含 Java/前端/网络等)
- **考勤与操行**: 生成当天考勤与操行示例数据
- **通知公告**: 生成校园/部门/年级等层级的通知示例
## ⚠️ 注意事项
1. **密码安全**: 上述密码仅用于开发测试环境,**切勿在生产环境使用**
2. **数据重置**: 运行 `scripts/init_mongo.py` 会清空 MongoDB 中的相关集合,请谨慎操作。
3. **ID 关联**: MongoDB 中的 `account_id` 字段严格对应 PostgreSQL 中生成的自增 ID。若重新初始化数据库,请确保两边脚本配套执行。
2. **数据重置**:
- `scripts/init_postgres.sql` 会清空并重建(TRUNCATE)PostgreSQL 中的核心表,且会重置自增 ID。
- `scripts/init_edu_postgres.py` 会清理并重新写入教务演示数据(依赖 `init_postgres.sql` 生成的用户 ID)。
- `scripts/init_mongo.py` 会清空 MongoDB 中 LLM 相关集合并写入演示敏感词。
3. **跨服务用户标识**: JWT 的 `sub` 字段对应 PostgreSQL `users.id`,LLM 服务在 MongoDB 中的对话/审计数据使用该用户 ID 作为关联键。
# 微服务架构重构方案
## 1. 现状分析
当前项目是一个基于 Python FastAPI 的单体应用,主要包含以下业务领域:
- **认证与用户管理**:用户注册、登录、角色权限。
- **教育教务管理**:学生、教师、班级、课表、人员档案、绑定关系。
- **LLM 对话与过滤**:对话管理、敏感词过滤、对接 Ollama。
- **数据统计**:仪表盘。
**痛点(为什么感觉乱):**
1. **控制层与数据层耦合**:API 路由函数中直接包含大量 MongoDB 查询逻辑(如 `app/api/v1/auth.py`),缺乏独立的 Service 层封装。
2. **业务边界模糊**`bindings`(绑定关系)逻辑穿插在 Auth 和各个实体模块中。
3. **单体膨胀风险**:教务逻辑(复杂的实体关系)与 AI 逻辑(无状态、流式、计算密集)混在一起,扩展性受限。
## 2. 拆分建议
建议将项目拆分为三个独立微服务,根据业务特性选择最适合的语言:
### 服务 A: 身份认证中心 (Identity Service)
- **职责**:用户注册、登录、JWT 签发与验证、权限管理 (RBAC)、绑定关系管理。
- **建议语言****Go** (Golang)
- **数据库****PostgreSQL**
- **理由**:用户账户、角色权限是典型的结构化数据,关系型数据库能提供更好的事务支持和数据一致性保障。
- **接管路由**`/auth`, `/admin` (部分用户管理), `/bindings`
### 服务 B: 教务核心服务 (Edu Core Service)
- **职责**:学生、教师、班级、课表、人员档案的 CRUD 与业务逻辑。
- **建议语言****Java (Spring Boot)**
- **数据库****PostgreSQL**
- **理由**:教务数据之间存在复杂的关联关系(如班级-学生、课程-教师),使用外键约束能有效维护数据完整性。Spring Data JPA 提供了强大的 ORM 支持。
- **接管路由**`/students`, `/teachers`, `/classes`, `/schedules`, `/persons`
### 服务 C: LLM 智能服务 (LLM Filter Service)
- **职责**:LLM 对话管理、敏感词过滤算法、Ollama 接口对接。
- **建议语言****Python** (保持现状)
- **数据库****PostgreSQL (JSONB)****MongoDB**
- **理由**:对话记录虽然是非结构化的,但 PostgreSQL 的 JSONB 性能非常强劲,且便于与用户表做关联查询。为了简化运维,推荐全栈统一使用 PostgreSQL。
- **接管路由**`/conversations`, `/admin` (敏感词管理)
### 服务 D: 聚合层 / 网关 (API Gateway / BFF)
- **职责**:统一入口,路由转发,或者聚合 Dashboard 数据。
- **实现**:Nginx, Kong, 或一个轻量级的 Node.js/Go 服务。
## 3. 架构图示
```mermaid
graph TD
Client[前端应用] --> Gateway[API 网关]
Gateway -->|/auth, /bindings| AuthSvc[身份认证服务 (Go)]
Gateway -->|/students, /classes| EduSvc[教务核心服务 (Go/Java)]
Gateway -->|/conversations| LLMSvc[LLM 智能服务 (Python)]
AuthSvc --> DB_PG[(PostgreSQL: AuthDB)]
EduSvc --> DB_PG[(PostgreSQL: EduDB)]
LLMSvc --> DB_PG[(PostgreSQL: LLMDB)]
LLMSvc --> Ollama[Ollama LLM]
```
## 4. 迁移路线 (Strangler Fig Pattern)
1. **第一步:提取公共依赖**
- 确定服务间通信协议(推荐 RESTful HTTP 或 gRPC)。
- 统一数据库设计(目前是共享 Mongo,微服务建议分库或分 Collection)。
2. **第二步:剥离身份认证 (Auth Service)**
- 优先用 Go 重写 `/auth` 模块。
- 网关将 `/auth` 流量转发至新服务。
- Python 单体保留 JWT 验证逻辑(作为中间件),信任 Go 服务签发的 Token。
3. **第三步:剥离教务业务**
-`/students` 等模块迁移至新服务。
4. **第四步:瘦身 Python 服务**
- 最后 Python 服务仅保留 LLM 相关核心业务,成为纯粹的 AI 服务。
## 5. 示例:用 Go 重构 Auth 服务
我们可以先尝试用 Go 重写 `register``login` 接口,展示微服务的结构。
# 🚀 LLM Filter 项目开发与启动指南
# LLM Filter 项目启动与开发指南
本文档旨在帮助开发人员快速搭建环境、启动服务并参与开发。本项目采用微服务架构,包含 Auth (Go), Edu (Java), LLM (Python) 三大核心服务
本文档旨在帮助开发人员快速搭建环境、启动服务并参与开发。本项目采用微服务架构,包含 Gateway (Nginx), Auth (Go), Edu (Java), LLM (Python) 四个服务组件
---
## 🏗️ 架构概览
| 服务名称 | 端口 | 技术栈 | 职责 | 目录 |
| :--- | :--- | :--- | :--- | :--- |
| **Auth Service** | **8081** | Go (Gin) | 用户认证、JWT、绑定管理 | `microservices/auth-service` |
| **Edu Service** | **8082** | Java (Spring Boot) | 学生、教师、课表、教务数据 | `microservices/edu-service` |
| **LLM Service** | **8000** | Python (FastAPI) | AI 对话、RAG、敏感词过滤 | `microservices/llm-service` |
| **Postgres** | 5433 | PostgreSQL 15 | 存储 Auth 和 Edu 数据 | (Docker) |
| **Mongo** | 27017 | MongoDB | 存储对话历史、敏感词库 | (Docker) |
---
## ⚡ 快速启动 (Docker 模式)
这是最简单的启动方式,适合预览或部署。
## 快速启动(Docker)
### 前置要求
- Docker & Docker Compose
- 根目录下已配置 `.env` 文件
- 可选:根目录 `.env`(建议生产/团队环境使用,避免把密钥写进配置文件)
### 启动命令
在项目根目录执行:
......@@ -36,13 +22,20 @@ docker-compose logs -f
```
### 访问服务
- **Swagger 文档 (LLM)**: [http://localhost:8000/docs](http://localhost:8000/docs)
- **Auth API**: [http://localhost:8081/api/v1/auth/health](http://localhost:8081/api/v1/auth/health)
- **Edu API**: [http://localhost:8082/api/v1/edu/health](http://localhost:8082/api/v1/edu/health)
- **统一入口(网关)**: [http://localhost:8080](http://localhost:8080)
- **LLM Swagger(通过网关)**: [http://localhost:8080/docs](http://localhost:8080/docs)
- **Edu Swagger(通过网关)**: [http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html)
- **Auth Swagger(直连)**: [http://localhost:8081/swagger/index.html](http://localhost:8081/swagger/index.html)
端口约定:
- Gateway: 8080
- Auth Service: 8081
- Edu Service: 8082
- LLM Service: 8000
---
## 🛠️ 本地开发指南 (Local Development)
## 本地开发指南
如果你需要修改代码,建议在本地分别启动服务。
......@@ -94,13 +87,13 @@ source venv/bin/activate # macOS/Linux
# 安装依赖
pip install -r requirements.txt
# 运行服务 (会自动向上查找根目录的 .env)
python main.py
# 运行服务
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
---
## 🧪 接口测试流程
## 接口测试流程
### 1. 注册与登录 (Auth Service)
所有操作都需要 Token。
......@@ -127,22 +120,28 @@ curl http://localhost:8082/api/v1/classes \
```
### 3. AI 对话 (LLM Service)
LLM Service 会自动调用 Auth Service 验证 Token
LLM Service 会在本地校验 JWT(要求 `SECRET_KEY` 与 Auth Service 的 `JWT_SECRET` 保持一致)
```bash
# 发起对话
curl -X POST http://localhost:8000/api/v1/conversations/chat \
# 1) 创建对话,拿到 conversation_id
curl -X POST http://localhost:8000/api/v1/conversations \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json"
# 2) 向对话发送消息
curl -X POST http://localhost:8000/api/v1/conversations/<CONVERSATION_ID>/messages \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{"message": "你好,请介绍一下你自己"}'
-d '{"content": "你好,请介绍一下你自己"}'
```
---
## 📂 目录结构说明
## 目录结构说明
```text
/llm-filter
├── gateway/ # Nginx 网关配置
├── docker-compose.yml # 容器编排文件
├── .env # 全局环境变量 (数据库密码、密钥等)
└── microservices/ # 微服务源码目录
......@@ -151,8 +150,8 @@ curl -X POST http://localhost:8000/api/v1/conversations/chat \
└── llm-service/ # [Python] LLM 核心服务
```
## ⚠️ 常见问题
## 常见问题
1. **端口冲突**:如果 `5432` 被本地 Postgres 占用,Docker 会映射到 `5433`。代码中已默认适配 `5433`,如需修改请检查 `.env` 和各服务的配置文件。
2. **Maven 下载慢**:请使用项目提供的 `microservices/edu-service/settings.xml`,已配置阿里云镜像。
3. **Python 找不到 .env**`config.py` 已内置自动向上查找逻辑,确保在 `microservices/llm-service` 目录下运行即可
3. **LLM 无法鉴权**:请确保 `SECRET_KEY` 与 Auth Service 的 `JWT_SECRET` 一致,否则会出现 401
......@@ -14,9 +14,9 @@
* 1.3 法规遵从性分析:《生成式人工智能服务管理暂行办法》
* 1.4 项目愿景:构建“本地化、可控、可审计”的 AI 基础设施
2. **第二章:系统架构设计哲学**
* 2.1 总体架构设计:Clean Architecture(整洁架构)的实践
* 2.1 总体架构设计:服务内整洁架构 + 系统级微服务边界
* 2.2 后端核心:基于 Python AsyncIO 的高并发异步模型
* 2.3 数据持久层:Schema-less 设计与 MongoDB 的选型逻辑
* 2.3 数据持久层:PostgreSQL + MongoDB 的混合存储策略
* 2.4 推理计算层:边缘计算与 Edge AI 的本地化部署策略
3. **第三章:核心算法与实现细节**
* 3.1 确定性有限自动机(DFA)在敏感词过滤中的应用
......@@ -28,9 +28,8 @@
* 4.2 内容风控体系:从 Prompt Injection 防御到输出阻断
* 4.3 数据主权与物理隔离:Air-Gapped 环境下的可用性保障
5. **第五章:工程化实践与性能评估**
* 5.1 容器化部署(Docker)与微服务拆分潜力
* 5.2 性能基准测试(Benchmark):并发吞吐量与延迟分析
* 5.3 CI/CD 流水线与代码质量控制
* 5.1 性能基准测试(Benchmark):并发吞吐量与延迟分析
* 5.2 CI/CD 流水线与代码质量控制
6. **第六章:总结与未来展望**
* 6.1 项目创新点总结
* 6.2 局限性讨论
......@@ -80,19 +79,39 @@ LLM-Filter 不仅仅是一个“过滤器”,它被定义为**AI 时代的防
# 第二章:系统架构设计哲学
## 2.1 总体架构设计:Clean Architecture(整洁架构)的实践
## 2.1 总体架构设计:服务内整洁架构 + 系统级微服务边界
在软件工程中,架构的质量决定了系统的生命周期。LLM-Filter 采用了 Robert C. Martin 提出的 **Clean Architecture(整洁架构)** 思想,强调“关注点分离”(Separation of Concerns)和“依赖倒置”(Dependency Inversion)。
系统从逻辑上划分为四层同心圆结构:
LLM-Filter 的架构可以拆成两层理解:
1) **系统级(Microservices)**:通过网关对外暴露统一入口,内部按领域拆成 Auth(认证/绑定)、Edu(教务/看板)、LLM(对话/过滤/审计)。
2) **服务内(Clean Architecture)**:以 LLM Service 为例,服务内部再使用整洁架构分层,保证可测试性与可替换性。
系统级拓扑如下:
```mermaid
graph TD
Client[Client] --> Gateway[Gateway (Nginx)]
Gateway --> AuthSvc[Auth Service (Go/Gin)]
Gateway --> EduSvc[Edu Service (Java/Spring Boot)]
Gateway --> LLMSvc[LLM Service (Python/FastAPI)]
AuthSvc --> PG[(PostgreSQL)]
EduSvc --> PG
LLMSvc --> Mongo[(MongoDB)]
LLMSvc --> LLM[Ollama / Dify]
```
服务内从逻辑上划分为四层同心圆结构:
1. **实体层(Entities / Domain Layer)**:这是系统的核心,定义了最基础的业务对象,如 `User`(用户)、`Conversation`(对话)、`SensitiveWord`(敏感词)。这些对象不依赖于任何外部框架(如数据库、Web 框架),仅包含纯粹的 Python 数据类(Pydantic Models)。
* *代码体现*`app/models/` 目录下的定义。
* *代码体现*`microservices/llm-service/app/models/` 目录下的定义。
2. **用例层(Use Cases / Service Layer)**:定义了具体的业务逻辑,如“创建对话”、“检测敏感词”、“调用 LLM 生成回复”。这一层协调实体与外部接口,但依然不依赖具体的 HTTP 协议。
* *代码体现*`app/services/` 目录下的业务逻辑函数。
* *代码体现*`microservices/llm-service/app/services/` 目录下的业务逻辑函数。
3. **接口适配层(Interface Adapters / API Layer)**:负责将外部的 HTTP 请求转换为用例层能理解的数据结构,并将处理结果转换为 JSON 格式返回。这一层处理路由分发、参数校验、状态码控制。
* *代码体现*`app/api/` 目录下的 FastAPI 路由定义。
* *代码体现*`microservices/llm-service/app/api/` 目录下的 FastAPI 路由定义。
4. **基础设施层(Frameworks & Drivers / Infrastructure Layer)**:包含具体的数据库驱动(Motor/MongoDB)、外部 API 客户端(Httpx/Ollama)、日志系统等。
* *代码体现*`app/db/`, `app/core/` 等配置与驱动。
* *代码体现*`microservices/llm-service/app/db/`, `microservices/llm-service/app/core/` 等配置与驱动。
这种分层架构的最大优势在于**可测试性****可替换性**。例如,如果未来我们需要将 MongoDB 替换为 PostgreSQL,或者将 Ollama 替换为 vLLM,我们只需要修改基础设施层的代码,而核心的业务逻辑层(Service)和实体层(Model)完全不需要变动。
......@@ -106,25 +125,26 @@ LLM-Filter 不仅仅是一个“过滤器”,它被定义为**AI 时代的防
### 2.2.1 事件循环(Event Loop)与协程(Coroutine)
Python 的 `async/await` 语法允许我们在应用层显式地控制控制权的切换。当代码执行到 `await generate_response(...)` 时,当前的协程会挂起(Suspend),将控制权交还给事件循环(Event Loop)。事件循环可以立即调度其他就绪的任务(如处理另一个用户的登录请求或读取数据库)。只有当 GPU 完成推理并返回数据时,原来的协程才会被唤醒(Resume)。
`app/services/ollama.py` 中,我们使用了 `httpx.AsyncClient` 来发起非阻塞的 HTTP 请求:
`microservices/llm-service/app/services/ollama.py` 中,我们使用了 `httpx.AsyncClient` 来发起非阻塞的 HTTP 请求:
```python
async with httpx.AsyncClient() as client:
response = await client.post(...)
```
这一行代码的改变,使得单核 CPU 的并发吞吐量从几十 QPS 提升到了数千 QPS(仅针对 I/O 等待场景)。这对于资源受限的边缘服务器(Edge Server)至关重要。
## 2.3 数据持久层:Schema-less 设计与 MongoDB 的选型逻辑
## 2.3 数据持久层:PostgreSQL + MongoDB 的混合存储策略
在落地实现中,我们采用了 **混合存储**
在数据库选型上,我们放弃了传统的关系型数据库(RDBMS, 如 MySQL),选择了文档型数据库 **MongoDB**。这一决策基于以下考量:
1. **PostgreSQL(强一致 + 结构化)**
* 适用:用户账户、RBAC、绑定关系、教务核心实体与看板统计。
* 优势:外键/事务保障、便于做复杂查询与报表。
1. **数据的非结构化特征**
* 对话历史(Conversation History)是高度动态的。一条消息可能包含纯文本,未来可能包含图片 URL、引用链接、代码块等。使用 JSON 文档存储可以自然地映射这些嵌套结构,避免了 MySQL 中复杂的关联表(JOIN)查询。
2. **写密集型场景(Write-Intensive)**
* LLM-Filter 需要记录详细的审计日志(Audit Logs)。在高并发场景下,大量的日志写入会对数据库造成压力。MongoDB 的 WiredTiger 存储引擎在处理高并发写入方面表现优异,且支持分片(Sharding)扩展。
3. **敏捷迭代需求**
* 项目处于快速发展期,数据模型变化频繁。MongoDB 的 Schema-less 特性允许我们在不进行繁琐的数据库迁移(Migration)的情况下,动态添加字段(如为 Message 添加 `latency` 字段)。
2. **MongoDB(高写入 + 半结构化)**
* 适用:对话历史、敏感词库、过滤命中记录、审计轨迹等。
* 优势:天然承载嵌套结构(messages 数组、元数据扩展),对迭代友好。
我们在 `app/models/user.py` 中结合 **Pydantic** 实现了应用层的 Schema 验证,既享受了 NoSQL 的灵活性,又通过代码层面的约束保证了数据的完整性
这种组合让系统既能在“身份/教务”上获得关系模型的完整性,又能在“对话/审计”上保持 Schema 的弹性。对于 LLM Service,我们仍然使用 Pydantic 做应用层校验,避免 Schema-less 带来的数据漂移
## 2.4 推理计算层:边缘计算与 Edge AI 的本地化部署策略
......@@ -159,7 +179,7 @@ LLM-Filter 放弃了基于正则表达式(Regex)或简单的字符串包含
### 3.2.1 数据结构定义
Trie 树的根节点为空,每个节点包含一个哈希映射(HashMap),存储指向子节点的指针。
在 Python 实现中(`app/utils/sensitive_word_filter.py`),我们优化了节点结构:
在 Python 实现中(`microservices/llm-service/app/utils/sensitive_word_filter.py`),我们优化了节点结构:
```python
class TrieNode:
def __init__(self):
......@@ -183,7 +203,7 @@ Trie 树的一个缺点是空间复杂度较高。为了优化内存,我们采
大模型的一个显著限制是 **Context Window(上下文窗口)**(如 Llama 2 通常为 4096 tokens)。如果直接将所有历史对话发给模型,很快就会超出限制导致报错或遗忘。
LLM-Filter 在 `app/services/conversation.py` 中实现了智能的**滑动窗口(Sliding Window)**算法:
LLM-Filter 在 `microservices/llm-service/app/services/conversation.py` 中实现了智能的**滑动窗口(Sliding Window)**算法:
1. **截断策略**:每次请求只携带最近的 $K$ 轮对话(默认 $K=10$)。
2. **系统提示词保留**:无论窗口如何滑动,最初的 `System Prompt`(包含角色设定和安全指令)始终被保留在 Prompt 的头部。
3. **Token 计算**:虽然目前使用简单的条数限制,但架构预留了 Tokenizer 接口,未来可升级为基于精确 Token 计数的截断策略。
......@@ -194,7 +214,7 @@ LLM-Filter 在 `app/services/conversation.py` 中实现了智能的**滑动窗
以下是 Trie 树核心匹配算法的真实代码实现。它展示了为什么我们能做到毫秒级响应:没有复杂的回溯,就是一个简单的双重循环。
```python
# app/utils/sensitive_word_filter.py
# microservices/llm-service/app/utils/sensitive_word_filter.py
# 遍历文本的每个字符作为起点
for i in range(len(text_lower)):
......@@ -227,7 +247,7 @@ def delete_conversation(user):
```
这种写法违反了单一职责原则。LLM-Filter 利用 FastAPI 强大的 **Dependency Injection System**,将权限逻辑彻底抽离。
`app/api/deps.py` 中,我们定义了高阶依赖工厂函数:
`microservices/llm-service/app/api/deps.py` 中,我们定义了高阶依赖工厂函数:
```python
def require_role(min_level: int):
async def _checker(current_user: dict = Depends(get_current_active_user)):
......@@ -259,30 +279,26 @@ LLM-Filter 采用了 **Stateless(无状态)** 的 JWT 机制。
### 4.1.3 关键接口实现:Login
为了实现高效的无状态鉴权,我们在登录接口中直接将用户的核心权限信息注入 Token。
```python
# app/api/v1/auth.py
@router.post("/login", response_model=Token, ...)
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
"""用户登录"""
# 1. 验证用户名密码
user = await authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(...) # 401 Unauthorized
# 2. 生成 JWT Token
access_token = create_access_token(
data={
"sub": str(user["_id"]),
"role": user.get("role", "user"),
"role_level": user.get("role_level", 1),
"edition": user.get("edition", "edu"),
# 关键设计:在 Token 里直接植入了 'person_id' 绑定信息
# 这样后续请求就不需要反复查库,实现了无状态鉴权
**({...} if (b := await db.db.bindings.find_one(...)) else {})
},
expires_delta=access_token_expires
)
当前实现中,登录由 **Auth Service(Go/Gin)** 负责:
1. 校验用户名/密码(bcrypt)。
2. 查询用户主绑定(bindings)。
3. 生成 JWT:Payload 中包含 `sub`(用户 ID)、`name``role``role_level``edition`、以及绑定信息字段。
4. 其他服务(LLM/Edu)在本地使用同一密钥验签并解析 Token,从而实现“无状态鉴权”。
接口返回示意:
```json
{
"token": "<JWT>",
"user": {
"id": 1,
"username": "student_101",
"role": "user",
"role_level": 1,
"edition": "edu"
}
}
```
## 4.2 内容风控体系:从 Prompt Injection 防御到输出阻断
......@@ -299,7 +315,7 @@ LLM-Filter 采取了双重防御:
在对话服务中,我们采用了 **Pipeline(管道)模式**,将用户输入、敏感词过滤和大模型推理串联起来。
```python
# app/services/conversation.py
# microservices/llm-service/app/services/conversation.py
async def add_message(conversation_id: str, user_id: str, content: str) -> Dict[str, Any]:
"""
......@@ -340,7 +356,7 @@ async def add_message(conversation_id: str, user_id: str, content: str) -> Dict[
为了满足企业级应用的需求,我们提供了高效的批量数据处理接口。
```python
# app/api/v1/admin.py
# microservices/llm-service/app/api/v1/admin.py
@router.post("/sensitive-words/import", ...)
async def import_sensitive_words_from_file(
......
# LLM-Filter 智能对话过滤系统 (Microservices)
# LLM-Filter 智能对话过滤系统
一个面向教育与企业双场景的智能对话过滤系统,基于 **微服务架构** 重构,集成了高效敏感词过滤、严格的角色与版别控制、以及完善的教务/企业数据管理。
系统采用 **Go (认证)** + **Java (教务)** + **Python (LLM)** 的混合技术栈,充分发挥各语言优势,通过 **Docker Compose** 统一编排部署。
## 🏗 系统架构
## 系统架构
本项目包含以下核心服务,通过 **Gateway (Nginx)** 统一对外暴露:
......@@ -12,15 +12,15 @@
| :--- | :--- | :--- | :--- |
| **Gateway** | Nginx | 8080 | 统一 API 网关,负责请求路由转发与跨域处理 |
| **Auth Service** | Go (Gin) | 8081 | 用户注册、登录、JWT 签发、绑定管理 |
| **Edu Service** | Java (Spring Boot) | 8082 | 教务/业务核心服务(学生、教师、班级、课表等) |
| **LLM Service** | Python (FastAPI) | 8000 | 智能对话、敏感词过滤、审计日志、数据看板 |
| **Edu Service** | Java (Spring Boot) | 8082 | 教务/业务核心服务(班级、人员、教师、课表、看板等) |
| **LLM Service** | Python (FastAPI) | 8000 | 智能对话、敏感词过滤、审计日志、敏感词管理 |
### 基础设施
- **PostgreSQL**: 存储用户账户、角色信息及教务核心结构化数据。
- **MongoDB**: 存储非结构化数据,如对话历史、敏感词库、审计日志、部分教务冗余数据。
- **Ollama**: 本地大模型推理引擎(需单独部署或配置)。
## ✨ 功能亮点
## 功能概览
- **微服务设计**: 各模块职责单一,支持独立部署与扩展,降低耦合。
- **多语言融合**:
......@@ -31,97 +31,98 @@
- **安全过滤**: 内置高效 Trie 树敏感词过滤,支持实时热更新,保障合规。
- **角色权限**: 精细化的 RBAC 权限控制(学生/教师/管理员等)及版别控制(教育版/企业版)。
## 🚀 快速开始
### 1. 前置要求
- **Docker** & **Docker Compose**
- **Ollama** (建议在本机安装并运行,默认端口 11434)
### 2. 配置环境
在项目根目录创建 `.env` 文件(可参考以下模板):
```bash
# === 数据库配置 ===
POSTGRES_USER=admin
POSTGRES_PASSWORD=password
POSTGRES_DB=llm_filter_db
MONGODB_URL=mongodb://mongo:27017
# === JWT 安全配置 ===
# 必须生成强随机密钥(建议 32 字节以上)
JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
# Auth Service 使用 JWT_SECRET, LLM Service 使用 SECRET_KEY (需保持一致)
SECRET_KEY=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
# === Ollama 配置 ===
# Docker 容器访问宿主机 Ollama 服务
OLLAMA_BASE_URL=http://host.docker.internal:11434
OLLAMA_MODEL=deepseek-r1:14b
# === 应用模式 ===
# edu (教育版) / biz (企业版)
APP_MODE=edu
```
### 3. 启动服务
使用 Docker Compose 一键构建并启动所有服务:
```bash
docker-compose up -d --build
```
等待几分钟,直到所有容器启动完成。
### 4. 访问服务
系统统一入口为 **http://localhost:8080**
#### 📝 API 文档 (Swagger/OpenAPI)
各微服务均提供了在线文档,可通过网关直接访问:
- **Auth Service 文档**: [http://localhost:8080/swagger/index.html](http://localhost:8080/swagger/index.html)
- **Edu Service 文档**: [http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html)
- **LLM Service 文档**: [http://localhost:8080/docs](http://localhost:8080/docs)
#### 🔌 主要 API 路由
- **认证相关**: `/api/v1/auth/*` (登录、注册)
- **绑定管理**: `/api/v1/bindings/*` (用户-实体绑定)
- **教务管理**:
- `/api/v1/edu/*` (综合业务)
- `/api/v1/classes/*` (班级)
- `/api/v1/persons/*` (人员档案)
- `/api/v1/teachers/*` (教师管理)
- `/api/v1/schedules/*` (课表)
- **对话与看板**:
- `/api/v1/conversations/*` (AI 对话)
- `/api/v1/dashboard/*` (数据看板)
- `/api/v1/admin/*` (敏感词管理)
## 🛠 开发指南
### 目录结构
```
llm-filter/
├── gateway/ # Nginx 网关配置
├── microservices/
│ ├── auth-service/ # [Go] 认证服务
│ │ ├── internal/ # 业务逻辑
│ │ └── main.go # 入口文件
│ ├── edu-service/ # [Java] 教务服务
│ │ └── src/main/java/ # Spring Boot 源码
│ └── llm-service/ # [Python] LLM与过滤服务
│ └── app/ # FastAPI 源码
├── docker-compose.yml # 容器编排文件
└── README.md # 项目文档
```
### 本地独立开发
若需单独开发某个微服务,请参考各子目录下的 README 或直接运行:
- **Auth Service**: 进入 `microservices/auth-service`,运行 `go run main.go`
- **Edu Service**: 进入 `microservices/edu-service`,运行 `mvn spring-boot:run`
- **LLM Service**: 进入 `microservices/llm-service`,运行 `uvicorn app.main:app --reload`
*注意:本地独立运行时需确保依赖的数据库(Postgres/Mongo)已启动并配置正确的连接地址。*
## 📄 许可证
## 模块详解
### Gateway(Nginx)
- **统一入口**:对外只暴露一个入口,由网关按路径将请求转发到各后端服务。
- **路由转发**
- 认证服务:`/api/v1/auth/*``/api/v1/bindings/*`
- 教务服务:`/api/v1/classes/*``/api/v1/persons/*``/api/v1/teachers/*``/api/v1/schedules/*``/api/v1/dashboard/*``/api/v1/edu/*`
- LLM 服务:其余路径默认转发(包含 `/docs``/api/v1/*` 等)
- **跨域与压缩**:统一设置 CORS 响应头与 gzip,减少前端对接成本。
### Auth Service(Go / Gin)
- **注册登录**
- `POST /api/v1/auth/register`:注册用户(默认 `role=user``edition=edu`
- `POST /api/v1/auth/login`:登录并签发 JWT,响应包含 `token``user`
- **账号与安全**
- 密码使用 bcrypt 加密存储
- JWT 使用 HS256 对称签名(由 `JWT_SECRET` 控制密钥)
- **身份绑定(Binding)**:用于将“账号”绑定到具体业务身份(如学生/教师):
- `POST /api/v1/bindings`:创建绑定
- `GET /api/v1/bindings/me`:获取当前用户主绑定
- `DELETE /api/v1/bindings/{person_id}`:解绑
- **JWT 载荷(Claims)**:服务在签发 Token 时会携带下列字段,供下游服务直接做本地鉴权:
- `sub`(用户ID)、`name`(用户名)、`role``role_level``edition``person_id``person_type`
### Edu Service(Java / Spring Boot)
- **基础数据管理**
- 班级与班主任:`GET /api/v1/classes``PUT /api/v1/classes/{classId}/head-teacher`
- 人员信息:`POST /api/v1/persons/bulk``GET /api/v1/persons`
- 教师信息:`POST /api/v1/teachers/bulk``GET /api/v1/teachers`
- 课表与任课教师:`GET /api/v1/schedules``PUT /api/v1/schedules/assign-teacher`
- **看板能力(按角色输出不同视图)**
- 学生:`/api/v1/dashboard/student/today``/api/v1/dashboard/student/week`
- 教师:`/api/v1/dashboard/teacher/week`
- 班主任:`/api/v1/dashboard/homeroom/current`
- 部门负责人:`/api/v1/dashboard/department/overview`
- 校级管理:`/api/v1/dashboard/campus/overview`
- **JWT 本地解析**:通过 `JwtAuthenticationFilter` 解析 `Authorization: Bearer <token>`,将用户信息写入 `UserContext`,业务层可直接读取当前用户身份。
### LLM Service(Python / FastAPI)
- **对话管理**
- `POST /api/v1/conversations`:创建会话
- `GET /api/v1/conversations`:获取会话列表(列表场景仅返回最近一条消息以降低负载)
- `GET /api/v1/conversations/{conversation_id}`:获取会话详情
- `DELETE /api/v1/conversations/{conversation_id}`:删除会话
- **对话发送与过滤链路**`POST /api/v1/conversations/{conversation_id}/messages`
- 本地 Trie 过滤:使用内存 Trie 对用户输入做敏感词匹配
- 智能体二次过滤(可选):本地过滤通过后,可调用 Dify 智能体做内容安全复核
- 审计留痕:命中敏感内容会写入 `sensitive_records`,并在会话消息中记录命中详情
- 生成回复:未命中敏感内容时调用 Ollama 生成回复
- **敏感词与审计管理(管理员)**
- 敏感词:新增/删除/查询、批量导入(JSON/CSV)
- 命中记录:按用户、会话、时间范围、分类、严重程度筛选
- 分类管理:提供默认分类配置并支持扩展
## 角色等级与权限控制
系统使用“角色等级(role_level)”统一描述权限强弱,数字越大权限越高:
| 角色 | 等级 | 典型含义 |
| :--- | :---: | :--- |
| user | 1 | 学生/员工 |
| manager | 2 | 班主任/组长/二级部门管理员 |
| leader | 3 | 中层干部/部门负责人/一级部门管理员 |
| master | 4 | 校长/集团高管/业务最高负责人 |
| administrator / admin | 5 | 系统管理员/运维超管(系统最高) |
亮点与落地方式:
- **跨服务一致性**:Auth 在签发 JWT 时写入 `role`/`role_level`,下游服务本地解析后即可做鉴权,不依赖回源查询。
- **最小权限校验**:LLM 服务提供 `require_role(min_level)` 依赖工厂,用“最小等级”表达权限门槛,避免到处硬编码角色字符串。
- **管理员能力隔离**:LLM 管理类接口统一走管理员校验(兼容 `admin``administrator` 两种命名)。
## 版别控制(教育版 / 企业版)
- **版别字段**:用户与 Token 可携带 `edition``edu``biz`)。
- **运行模式开关**:LLM 服务通过 `APP_MODE` 限制接口仅允许对应版别用户访问(在路由层统一挂载依赖,减少遗漏风险)。
## 数据存储与审计
- **PostgreSQL(结构化)**:用户账号、角色/版别、教务核心实体(班级/人员/教师/课表等)。
- **MongoDB(非结构化)**
- `conversations`:对话会话与消息历史
- `sensitive_words`:敏感词库(含分类、子类、严重程度)
- `sensitive_records`:敏感命中审计记录(按用户/会话/时间/严重程度可检索)
## 文档
- 启动与本地开发:见 [DEVELOPMENT.md](file:///Users/uu/Desktop/dles_prj/llm-filter/DEVELOPMENT.md)
- 默认账号与初始化数据:见 [ACCOUNTS.md](file:///Users/uu/Desktop/dles_prj/llm-filter/ACCOUNTS.md)
## 许可证
MIT License
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment