366 lines
16 KiB
Markdown
366 lines
16 KiB
Markdown
# 系统架构
|
||
|
||
<cite>
|
||
**本文档引用的文件**
|
||
- [docker-compose.yml](file://docker-compose.yml)
|
||
- [backend/Dockerfile](file://backend/Dockerfile)
|
||
- [frontend/Dockerfile](file://frontend/Dockerfile)
|
||
- [backend/app/main.py](file://backend/app/main.py)
|
||
- [backend/app/api/queries.py](file://backend/app/api/queries.py)
|
||
- [backend/app/services/query.py](file://backend/app/services/query.py)
|
||
- [backend/app/models/query.py](file://backend/app/models/query.py)
|
||
- [backend/app/workers/citation_engine.py](file://backend/app/workers/citation_engine.py)
|
||
- [backend/app/workers/platforms/base.py](file://backend/app/workers/platforms/base.py)
|
||
- [backend/app/workers/platforms/kimi.py](file://backend/app/workers/platforms/kimi.py)
|
||
- [backend/app/workers/platforms/wenxin.py](file://backend/app/workers/platforms/wenxin.py)
|
||
- [frontend/lib/api.ts](file://frontend/lib/api.ts)
|
||
- [frontend/components/providers.tsx](file://frontend/components/providers.tsx)
|
||
- [frontend/app/layout.tsx](file://frontend/app/layout.tsx)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖分析](#依赖分析)
|
||
7. [性能考虑](#性能考虑)
|
||
8. [故障排查指南](#故障排查指南)
|
||
9. [结论](#结论)
|
||
10. [附录](#附录)
|
||
|
||
## 简介
|
||
本系统是一个学术查询与引用管理平台,采用前后端分离架构:前端使用 Next.js 构建用户界面,后端基于 FastAPI 提供 REST API,并通过 SQLAlchemy ORM 访问 PostgreSQL 数据库;AI 平台查询由后端工作器通过适配器模式对接不同平台(Kimi、文心一言),并通过 Redis 缓存与队列进行异步调度。系统通过 Docker Compose 将数据库、缓存、后端与前端容器化编排,便于开发与部署。
|
||
|
||
## 项目结构
|
||
系统分为四层:
|
||
- 表现层(前端 Next.js):负责用户界面渲染与 API 调用
|
||
- 业务逻辑层(后端 FastAPI):提供 REST 接口、业务服务与调度
|
||
- 数据访问层(SQLAlchemy ORM):模型定义与数据库交互
|
||
- 基础设施层(Docker 容器):PostgreSQL、Redis、后端与前端容器
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "表现层前端 Next.js"
|
||
FE_APP["Next.js 应用<br/>路由与页面"]
|
||
FE_LIB_API["API 客户端<br/>frontend/lib/api.ts"]
|
||
FE_PROVIDERS["会话提供者<br/>frontend/components/providers.tsx"]
|
||
end
|
||
subgraph "业务逻辑层后端 FastAPI"
|
||
BE_MAIN["应用入口<br/>backend/app/main.py"]
|
||
BE_ROUTERS["API 路由<br/>backend/app/api/*"]
|
||
BE_SERVICES["业务服务<br/>backend/app/services/*"]
|
||
BE_WORKERS["工作器与适配器<br/>backend/app/workers/*"]
|
||
end
|
||
subgraph "数据访问层SQLAlchemy ORM"
|
||
BE_MODELS["ORM 模型<br/>backend/app/models/*"]
|
||
end
|
||
subgraph "基础设施层Docker 容器"
|
||
DC_DB["PostgreSQL 容器"]
|
||
DC_REDIS["Redis 容器"]
|
||
DC_BE["后端容器"]
|
||
DC_FE["前端容器"]
|
||
end
|
||
FE_APP --> FE_LIB_API
|
||
FE_LIB_API --> BE_MAIN
|
||
BE_MAIN --> BE_ROUTERS
|
||
BE_ROUTERS --> BE_SERVICES
|
||
BE_SERVICES --> BE_MODELS
|
||
BE_WORKERS --> BE_MODELS
|
||
BE_MAIN --> DC_BE
|
||
BE_MODELS --> DC_DB
|
||
BE_WORKERS --> DC_REDIS
|
||
FE_APP --> DC_FE
|
||
```
|
||
|
||
图表来源
|
||
- [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71)
|
||
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
|
||
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
|
||
- [backend/app/services/query.py:1-130](file://backend/app/services/query.py#L1-L130)
|
||
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
- [frontend/components/providers.tsx:1-9](file://frontend/components/providers.tsx#L1-L9)
|
||
|
||
章节来源
|
||
- [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71)
|
||
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
|
||
- [frontend/app/layout.tsx:1-37](file://frontend/app/layout.tsx#L1-L37)
|
||
|
||
## 核心组件
|
||
- 前端 Next.js:提供登录注册、查询管理、引用统计与报告导出等功能页面,通过统一 API 客户端发起请求。
|
||
- 后端 FastAPI:提供认证、查询词、引用数据、报告导出等接口;启动时初始化调度器并挂载 CORS 中间件。
|
||
- 工作器与适配器:以适配器模式封装不同 AI 平台(Kimi、文心一言)的查询行为,统一对外接口。
|
||
- ORM 模型:定义查询词、引用记录、任务等实体及索引,支撑业务数据持久化。
|
||
- 基础设施:PostgreSQL 存储业务数据,Redis 支持缓存与队列,Docker Compose 统一编排。
|
||
|
||
章节来源
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
|
||
- [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71)
|
||
|
||
## 架构总览
|
||
系统采用分层解耦与容器化部署,前端通过 REST API 与后端交互,后端通过工作器调用 AI 平台,数据库与缓存分别承担数据持久化与临时状态管理。下图展示从用户请求到 AI 平台查询再到结果返回的完整链路。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as "用户"
|
||
participant FE as "前端 Next.js"
|
||
participant API as "后端 API 路由"
|
||
participant SVC as "业务服务"
|
||
participant ENG as "引用检测引擎"
|
||
participant ADP as "AI 平台适配器"
|
||
participant DB as "PostgreSQL"
|
||
U->>FE : "提交查询/触发查询"
|
||
FE->>API : "HTTP 请求带鉴权"
|
||
API->>SVC : "调用业务方法"
|
||
SVC->>ENG : "执行引用检测"
|
||
loop "遍历平台"
|
||
ENG->>ADP : "query(keyword)"
|
||
ADP-->>ENG : "返回平台响应文本"
|
||
end
|
||
ENG->>DB : "写入引用记录/更新任务状态"
|
||
DB-->>ENG : "确认写入"
|
||
ENG-->>SVC : "返回检测结果"
|
||
SVC-->>API : "组装响应"
|
||
API-->>FE : "返回结果"
|
||
FE-->>U : "展示引用统计/报告"
|
||
```
|
||
|
||
图表来源
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
|
||
- [backend/app/services/query.py:1-130](file://backend/app/services/query.py#L1-L130)
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
- [backend/app/workers/platforms/kimi.py:1-206](file://backend/app/workers/platforms/kimi.py#L1-L206)
|
||
- [backend/app/workers/platforms/wenxin.py:1-205](file://backend/app/workers/platforms/wenxin.py#L1-L205)
|
||
|
||
## 详细组件分析
|
||
|
||
### 前端组件分析
|
||
- API 客户端:集中封装鉴权头、错误处理与基础路径,统一暴露认证、查询、引用、报告等接口。
|
||
- 会话提供者:为 NextAuth 集成提供会话上下文,保障页面与 API 调用的鉴权一致性。
|
||
- 布局与字体:全局样式与字体配置,保证一致的视觉体验。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["页面发起请求"]) --> BuildHeaders["构建请求头<br/>含 Authorization"]
|
||
BuildHeaders --> FetchAPI["调用 fetchWithAuth"]
|
||
FetchAPI --> RespOK{"响应成功?"}
|
||
RespOK --> |是| ParseJSON["解析 JSON 响应"]
|
||
RespOK --> |否| HandleError["抛出错误包含 HTTP 状态"]
|
||
ParseJSON --> ReturnData["返回数据给页面"]
|
||
HandleError --> ThrowErr["上抛错误供 UI 处理"]
|
||
```
|
||
|
||
图表来源
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
|
||
章节来源
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
- [frontend/components/providers.tsx:1-9](file://frontend/components/providers.tsx#L1-L9)
|
||
- [frontend/app/layout.tsx:1-37](file://frontend/app/layout.tsx#L1-L37)
|
||
|
||
### 后端组件分析
|
||
- 应用入口:注册路由、启用 CORS、启动/关闭调度器生命周期钩子。
|
||
- API 路由:提供认证、查询词、引用数据、报告导出等接口,统一前缀与标签。
|
||
- 业务服务:封装查询词的增删改查与配额校验、频率与下次查询时间计算。
|
||
- ORM 模型:定义查询词实体及其索引,关联用户、引用记录与任务。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class Query {
|
||
+UUID id
|
||
+UUID user_id
|
||
+string keyword
|
||
+string target_brand
|
||
+list brand_aliases
|
||
+list platforms
|
||
+string frequency
|
||
+string status
|
||
+datetime last_queried_at
|
||
+datetime next_query_at
|
||
+datetime created_at
|
||
+datetime updated_at
|
||
}
|
||
class User {
|
||
+UUID id
|
||
+string name
|
||
+string email
|
||
+int max_queries
|
||
}
|
||
class CitationRecord {
|
||
+UUID id
|
||
+UUID query_id
|
||
+string platform
|
||
+bool cited
|
||
+int citation_position
|
||
+string citation_text
|
||
+list competitor_brands
|
||
+string raw_response
|
||
}
|
||
class QueryTask {
|
||
+UUID id
|
||
+UUID query_id
|
||
+string platform
|
||
+string status
|
||
+datetime started_at
|
||
+datetime completed_at
|
||
+string error_message
|
||
}
|
||
User "1" --> "many" Query : "拥有"
|
||
Query "1" --> "many" CitationRecord : "生成"
|
||
Query "1" --> "many" QueryTask : "驱动"
|
||
```
|
||
|
||
图表来源
|
||
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
|
||
|
||
章节来源
|
||
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
|
||
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
|
||
- [backend/app/services/query.py:1-130](file://backend/app/services/query.py#L1-L130)
|
||
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
|
||
|
||
### 工作器与适配器分析
|
||
- 引用检测引擎:根据查询词与目标品牌,遍历平台列表,调用对应适配器获取响应,执行品牌匹配与竞争品牌检测,生成引用记录并更新任务状态与查询时间。
|
||
- 适配器基类:定义平台名称、URL 与抽象查询方法,统一资源清理接口。
|
||
- Kimi 适配器:通过 Playwright 自动化模拟用户输入与提交,等待回复稳定后提取文本。
|
||
- 文心一言适配器:同 Kimi,但针对文心一言页面结构进行适配。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class BasePlatformAdapter {
|
||
<<abstract>>
|
||
+string platform_name
|
||
+string platform_url
|
||
+query(keyword) str
|
||
+close()
|
||
}
|
||
class KimiAdapter {
|
||
+platform_name = "kimi"
|
||
+platform_url = "https : //kimi.moonshot.cn"
|
||
+query(keyword) str
|
||
+close()
|
||
}
|
||
class WenxinAdapter {
|
||
+platform_name = "wenxin"
|
||
+platform_url = "https : //yiyan.baidu.com"
|
||
+query(keyword) str
|
||
+close()
|
||
}
|
||
class CitationEngine {
|
||
+execute_query(query, db) CitationRecord[]
|
||
+execute_single_platform(keyword, platform, target_brand, brand_aliases) dict
|
||
+close()
|
||
}
|
||
BasePlatformAdapter <|-- KimiAdapter
|
||
BasePlatformAdapter <|-- WenxinAdapter
|
||
CitationEngine --> BasePlatformAdapter : "使用"
|
||
```
|
||
|
||
图表来源
|
||
- [backend/app/workers/platforms/base.py:1-18](file://backend/app/workers/platforms/base.py#L1-L18)
|
||
- [backend/app/workers/platforms/kimi.py:1-206](file://backend/app/workers/platforms/kimi.py#L1-L206)
|
||
- [backend/app/workers/platforms/wenxin.py:1-205](file://backend/app/workers/platforms/wenxin.py#L1-L205)
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
|
||
章节来源
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
- [backend/app/workers/platforms/base.py:1-18](file://backend/app/workers/platforms/base.py#L1-L18)
|
||
- [backend/app/workers/platforms/kimi.py:1-206](file://backend/app/workers/platforms/kimi.py#L1-L206)
|
||
- [backend/app/workers/platforms/wenxin.py:1-205](file://backend/app/workers/platforms/wenxin.py#L1-L205)
|
||
|
||
### 数据流与处理流程
|
||
- 用户在前端提交查询或手动触发查询。
|
||
- 前端通过 API 客户端调用后端接口,携带鉴权信息。
|
||
- 后端路由将请求委派给业务服务,服务层执行权限与配额检查、频率计算等逻辑。
|
||
- 引用检测引擎根据平台列表逐个调用适配器,等待回复稳定后进行品牌匹配与竞争品牌检测。
|
||
- 结果写入数据库并更新任务状态,前端轮询或接收通知后刷新页面。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["用户提交查询"] --> B["前端 API 客户端"]
|
||
B --> C["后端 API 路由"]
|
||
C --> D["业务服务权限/配额/频率"]
|
||
D --> E["引用检测引擎"]
|
||
E --> F["Kimi 适配器"]
|
||
E --> G["文心一言适配器"]
|
||
F --> H["品牌匹配/竞争品牌检测"]
|
||
G --> H
|
||
H --> I["写入引用记录/更新任务状态"]
|
||
I --> J["返回结果给前端"]
|
||
J --> K["展示统计/报告"]
|
||
```
|
||
|
||
图表来源
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
|
||
- [backend/app/services/query.py:1-130](file://backend/app/services/query.py#L1-L130)
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
- [backend/app/workers/platforms/kimi.py:1-206](file://backend/app/workers/platforms/kimi.py#L1-L206)
|
||
- [backend/app/workers/platforms/wenxin.py:1-205](file://backend/app/workers/platforms/wenxin.py#L1-L205)
|
||
|
||
## 依赖分析
|
||
- 组件内聚与耦合:后端 API 路由仅负责参数解析与委派,业务服务与模型解耦良好;工作器通过适配器模式与具体平台解耦。
|
||
- 外部依赖:后端依赖 PostgreSQL 与 Redis;前端依赖 Next.js 生态与 NextAuth;工作器依赖 Playwright 浏览器自动化。
|
||
- 容器编排:Compose 文件定义数据库、缓存、后端与前端服务,设置健康检查与端口映射,后端依赖数据库与缓存健康。
|
||
|
||
```mermaid
|
||
graph TB
|
||
FE["前端"] --> BE["后端"]
|
||
BE --> DB["PostgreSQL"]
|
||
BE --> RD["Redis"]
|
||
BE --> PW["Playwright 浏览器"]
|
||
DC["Docker Compose"] --> DB
|
||
DC --> RD
|
||
DC --> BE
|
||
DC --> FE
|
||
```
|
||
|
||
图表来源
|
||
- [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71)
|
||
- [backend/Dockerfile:1-41](file://backend/Dockerfile#L1-L41)
|
||
- [frontend/Dockerfile:1-15](file://frontend/Dockerfile#L1-L15)
|
||
|
||
章节来源
|
||
- [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71)
|
||
- [backend/Dockerfile:1-41](file://backend/Dockerfile#L1-L41)
|
||
- [frontend/Dockerfile:1-15](file://frontend/Dockerfile#L1-L15)
|
||
|
||
## 性能考虑
|
||
- 异步与并发:后端使用异步数据库会话与异步适配器调用,提升 I/O 密集场景下的吞吐。
|
||
- 重试与指数退避:适配器对平台请求进行多轮重试与指数退避,降低偶发网络波动影响。
|
||
- 回复稳定性检测:等待 AI 回复文本稳定后再提取,减少因动态渲染导致的截断误差。
|
||
- 索引优化:查询词模型建立多字段索引,加速分页与过滤查询。
|
||
- 缓存与队列:建议结合 Redis 实现任务队列与结果缓存,进一步降低重复查询成本。
|
||
|
||
## 故障排查指南
|
||
- 健康检查:Compose 为数据库与缓存配置健康检查,若服务未就绪,前端将无法连接后端。
|
||
- Playwright 依赖:适配器需使用 Playwright 安装 Chromium,若启动失败请先安装浏览器依赖。
|
||
- CORS 限制:后端仅允许本地前端域名访问,跨域请求需调整中间件配置。
|
||
- 错误处理:前端客户端对非 2xx 响应抛出错误,后端路由对未找到与权限问题返回明确状态码。
|
||
|
||
章节来源
|
||
- [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71)
|
||
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
|
||
- [backend/app/workers/platforms/kimi.py:1-206](file://backend/app/workers/platforms/kimi.py#L1-L206)
|
||
- [backend/app/workers/platforms/wenxin.py:1-205](file://backend/app/workers/platforms/wenxin.py#L1-L205)
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
|
||
## 结论
|
||
该系统通过清晰的分层架构与容器化部署,实现了从前端到后端、再到 AI 平台与数据库的完整闭环。适配器模式有效隔离平台差异,业务服务与 ORM 模型保障可维护性与扩展性。建议后续引入任务队列与缓存策略以进一步提升性能与用户体验。
|
||
|
||
## 附录
|
||
- 开发环境启动:使用 Compose 启动数据库、缓存、后端与前端服务,分别暴露 5432、6379、8000、3000 端口。
|
||
- 后端镜像:基于 Python slim 镜像,预装 Playwright 与系统依赖,暴露 8000 端口。
|
||
- 前端镜像:基于 Node Alpine 镜像,安装依赖后暴露 3000 端口。
|
||
|
||
章节来源
|
||
- [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71)
|
||
- [backend/Dockerfile:1-41](file://backend/Dockerfile#L1-L41)
|
||
- [frontend/Dockerfile:1-15](file://frontend/Dockerfile#L1-L15) |