310 lines
12 KiB
Markdown
310 lines
12 KiB
Markdown
# Atlas
|
||
|
||
Atlas 是面向 AI 能力的统一接入与使用平台。Go + Vue 单体部署:用户端提供对话、文生图、图生图与历史记录;管理端配置上游 Provider 与模型、查看请求日志;内部 Gateway 兼容 OpenAI / Replicate 协议,统一编排、日志与路由。
|
||
|
||
## 特性
|
||
|
||
- **单体部署**:API 与 SPA 同进程、同端口,生产环境无需 Node.js
|
||
- **多协议 Gateway**:`/v1/*` 透传 OpenAI(Chat、Embeddings 等)与 Replicate(Predictions)
|
||
- **统一 invoke 编排**:同步/异步调用、任务队列、上游轮询 + 前端 SSE 进度推送
|
||
- **Provider 管理**:管理端配置上游地址与密钥;模型优先从上游 `/v1/models` 同步,也可手动维护
|
||
- **请求日志**:Gateway 与用户 invoke 全链路记录,管理端可检索
|
||
- **用户会话隔离**:Cookie 会话区分用户数据;管理端独立 Bearer 鉴权
|
||
- **纯 Go 编译**:SQLite 使用 `glebarez/go-sqlite`(`CGO_ENABLED=0`);Docker 构建对齐 Luminary(BuildKit 缓存、`npm ci`、阿里云 apk 源)
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 开发模式(两个终端)
|
||
make run # 后端 :8080
|
||
make dev-web # 前端 :5173,/api 代理到 8080
|
||
|
||
# 生产构建
|
||
make build
|
||
./dist/app
|
||
|
||
# Docker
|
||
docker compose up -d
|
||
```
|
||
|
||
启动后访问:
|
||
|
||
| 入口 | 地址 | 说明 |
|
||
|------|------|------|
|
||
| 用户端 | `http://localhost:8080/chat` | 对话、生图、历史(无需登录) |
|
||
| 管理端 | `http://localhost:8080/admin` | Provider、日志、设置(需登录) |
|
||
| Gateway | `http://localhost:8080/v1/*` | OpenAI / Replicate 兼容 API |
|
||
| 健康检查 | `GET /health` | `{ "status": "ok" }` |
|
||
|
||
默认管理员密码:`admin`(可在管理端设置页修改)。
|
||
|
||
---
|
||
|
||
## 架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ 单一 Go 进程 │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────┐ │
|
||
│ │ /api/v1/* │ │ /v1/* │ │ /health │ │ /* SPA │ │
|
||
│ │ 用户 + 管理 │ │ Gateway │ │ │ │ embed │ │
|
||
│ └──────┬──────┘ └──────┬──────┘ └──────────────┘ └──────────┘ │
|
||
│ │ │ │
|
||
│ ┌──────▼────────────────▼──────────────────────────────────────┐ │
|
||
│ │ api → service (invoke / chat / reqlog / taskevents) → store │ │
|
||
│ └──────────────────────────┬───────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────────▼───────────────────────────────────┐ │
|
||
│ │ provider (Router / ModelsService / ProxyStream) → 上游 API │ │
|
||
│ └────────────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌──────────────────────────▼───────────────────────────────────┐ │
|
||
│ │ SQLite WAL {data}/app.db │ │
|
||
│ └────────────────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 调用链路
|
||
|
||
**对话(Chat)**
|
||
|
||
```
|
||
浏览器 → POST /api/v1/user/conversations/:id/messages
|
||
→ chat.Service → provider.ProxyStream → 上游 SSE 真流式回传
|
||
```
|
||
|
||
**生图(异步任务)**
|
||
|
||
```
|
||
浏览器 → POST /api/v1/user/generate
|
||
→ invoke.Service 创建 task → async_worker 轮询上游
|
||
→ GET /api/v1/user/tasks/:id/events (SSE) 推送进度
|
||
```
|
||
|
||
**Gateway 直连**
|
||
|
||
```
|
||
客户端 → /v1/chat/completions | /v1/predictions ...
|
||
→ provider.Router 按模型路由 → 上游 + request_logs
|
||
```
|
||
|
||
### 分层约定
|
||
|
||
| 层 | 路径 | 职责 |
|
||
|----|------|------|
|
||
| 入口 | `cmd/app/` | 参数解析、依赖初始化、HTTP 服务、优雅关闭 |
|
||
| HTTP | `internal/api/` | 路由、中间件、用户/管理/Gateway Handler、SPA |
|
||
| 编排 | `internal/service/` | invoke、chat、reqlog、taskevents、asset |
|
||
| 上游 | `internal/provider/` | HTTP 代理、模型列表、流式转发、Provider 路由 |
|
||
| 领域 | `internal/domain/` | 服务类型、invoke 请求/响应模型 |
|
||
| 持久化 | `internal/store/` | SQLite、goose 迁移、仓储与 HotCache |
|
||
| 配置 | `internal/settings/` | KV 配置键、默认值、脱敏 |
|
||
| 前端 | `web/` | Vue SPA,构建产物嵌入 `internal/api/static/` |
|
||
|
||
---
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
.
|
||
├── cmd/app/ # 进程入口
|
||
├── internal/
|
||
│ ├── api/
|
||
│ │ ├── handlers.go # 基础路由、鉴权、设置
|
||
│ │ ├── user_handlers.go # 用户端 API
|
||
│ │ ├── admin_handlers.go # 管理端 API
|
||
│ │ ├── gateway*.go # /v1 Gateway
|
||
│ │ ├── task_sse.go # 任务 SSE
|
||
│ │ └── static/ # 前端 embed 产物
|
||
│ ├── service/
|
||
│ │ ├── invoke/ # 同步/异步 invoke + worker
|
||
│ │ ├── chat/ # 对话编排
|
||
│ │ ├── reqlog/ # 请求日志
|
||
│ │ └── taskevents/ # 任务事件广播
|
||
│ ├── provider/ # 上游 HTTP 代理与路由
|
||
│ ├── domain/
|
||
│ ├── store/migrations/ # goose SQL(002_atlas, 003_provider_models)
|
||
│ └── settings/
|
||
├── web/src/
|
||
│ ├── views/ # Chat、生图、History、Admin 页面
|
||
│ ├── layouts/ # UserLayout / AdminLayout
|
||
│ ├── composables/ # useInvoke (SSE)、useUserMeta 等
|
||
│ └── styles/global.css # 设计规范落地样式
|
||
├── docs/UI-DESIGN-SYSTEM.md # UI 设计规范
|
||
├── Makefile
|
||
├── Dockerfile
|
||
└── docker-compose.yml
|
||
```
|
||
|
||
---
|
||
|
||
## 技术栈
|
||
|
||
| 层级 | 选型 |
|
||
|------|------|
|
||
| 后端 | Go 1.25 + Gin |
|
||
| 数据库 | SQLite (glebarez/go-sqlite) |
|
||
| 迁移 | goose v3 (embed SQL) |
|
||
| 前端 | Vue 3 + Vite + TypeScript |
|
||
| UI | Element Plus |
|
||
| 状态 | Pinia |
|
||
| HTTP | axios(管理端)/ fetch + EventSource(用户端 SSE) |
|
||
|
||
---
|
||
|
||
## 功能模块
|
||
|
||
### 用户端(`/chat`、`/image/*`、`/history`)
|
||
|
||
- 多轮对话,SSE 流式输出
|
||
- 文生图、图生图(异步任务 + SSE 进度)
|
||
- 生成历史、参数预设
|
||
- 基于 `Atlas-Session` Cookie 的会话隔离
|
||
|
||
### 管理端(`/admin/*`)
|
||
|
||
- Provider CRUD(OpenAI / Replicate 协议、base_url、api_key)
|
||
- 模型列表:上游 sync 或手动添加
|
||
- 请求日志检索、仪表盘统计
|
||
- 系统设置(应用名、鉴权、语言等)
|
||
|
||
### Gateway(`/v1/*`)
|
||
|
||
| 协议 | 路由示例 |
|
||
|------|----------|
|
||
| OpenAI | `GET /v1/models`、`POST /v1/chat/completions`、`POST /v1/embeddings` … |
|
||
| Replicate | `POST /v1/predictions`、`GET /v1/predictions/:id`、`GET /v1/predictions/:id/stream` … |
|
||
|
||
Gateway 使用与用户端相同的 Cookie 会话,按模型名路由到已配置的 Provider。
|
||
|
||
---
|
||
|
||
## API 概览
|
||
|
||
**前缀:** `/api/v1`
|
||
|
||
### 鉴权(管理端)
|
||
|
||
| 接口 | 说明 |
|
||
|------|------|
|
||
| `POST /api/v1/auth/login` | 登录,返回 `{ "token": "..." }` |
|
||
| `GET /api/v1/auth/status` | `{ "enabled": true \| false }` |
|
||
| 受保护路由 | Header: `Authorization: Bearer <token>` |
|
||
|
||
当 `auth_enabled` 不为 `"true"` 时,管理端路由跳过鉴权(便于本地调试)。用户端路由始终公开,通过 Cookie 区分会话。
|
||
|
||
### 用户端(节选)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/user/session` | 初始化会话 |
|
||
| GET | `/user/meta` | 可用模型与服务元信息 |
|
||
| * | `/user/conversations/*` | 对话 CRUD 与消息 |
|
||
| POST | `/user/generate` | 文生图 / 图生图 |
|
||
| POST | `/user/upload` | 上传参考图 |
|
||
| GET | `/user/tasks/:id/events` | 任务进度 SSE |
|
||
| * | `/user/generations/*`、`/user/presets/*` | 历史与预设 |
|
||
|
||
### 管理端(节选)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| * | `/admin/providers/*` | Provider 与模型管理 |
|
||
| POST | `/admin/providers/:id/models/sync` | 从上游同步模型 |
|
||
| GET | `/admin/logs` | 请求日志 |
|
||
| GET | `/admin/dashboard/stats` | 统计 |
|
||
|
||
### 响应格式
|
||
|
||
```json
|
||
{ "ok": true }
|
||
{ "items": [...], "total": 42 }
|
||
{ "error": "human readable message" }
|
||
```
|
||
|
||
列表接口支持 `?limit=`(默认 50,最大 500)与 `?offset=`。
|
||
|
||
---
|
||
|
||
## 配置
|
||
|
||
### 启动参数与环境变量
|
||
|
||
| 来源 | 名称 | 默认 | 说明 |
|
||
|------|------|------|------|
|
||
| CLI | `-data` | `./data` | 数据目录(SQLite、上传文件等) |
|
||
| CLI | `-addr` | `:8080` | HTTP 监听地址 |
|
||
| Env | `APP_DATA` | — | 覆盖 `-data` |
|
||
| Env | `APP_ADDR` | — | 覆盖 `-addr` |
|
||
|
||
### 运行时配置(SQLite KV)
|
||
|
||
| 键 | 说明 |
|
||
|----|------|
|
||
| `app_name` | 应用名称(默认 `Atlas`) |
|
||
| `admin_password` | 管理员密码 |
|
||
| `auth_enabled` | 是否启用管理端认证 |
|
||
| `ui_locale` | 界面语言(`zh-CN` / `en`) |
|
||
| `file_sign_secret` | 文件访问签名密钥 |
|
||
|
||
可通过管理端设置页修改,无需重启。
|
||
|
||
---
|
||
|
||
## 开发工作流
|
||
|
||
```bash
|
||
# 终端 1 — 后端
|
||
make run
|
||
|
||
# 终端 2 — 前端热更新
|
||
make dev-web
|
||
# 浏览器 http://localhost:5173
|
||
```
|
||
|
||
| 命令 | 作用 |
|
||
|------|------|
|
||
| `make run` | 运行后端 |
|
||
| `make dev-web` | Vite 开发服务器 |
|
||
| `make build` | 构建含 embed 前端的完整二进制 |
|
||
| `make build-go` | 仅编译后端(跳过前端) |
|
||
| `make test` | Go 测试 |
|
||
| `make tidy` | `go mod tidy` |
|
||
| `make clean` | 清理构建产物 |
|
||
|
||
---
|
||
|
||
## Docker 部署
|
||
|
||
```bash
|
||
make docker-build # Docker 内完整构建(含 BuildKit 缓存)
|
||
make docker-push-prebuilt # 本地编译 Go + 轻量 runtime 镜像(最快,推荐)
|
||
docker run -d -p 8080:8080 -v atlas-data:/data atlas:latest
|
||
```
|
||
|
||
或:
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
镜像多阶段构建(Node 编译前端 → Go 编译 → Alpine 运行),非 root 用户,数据持久化至 `/data`。
|
||
|
||
---
|
||
|
||
## CI
|
||
|
||
仓库包含 `.gitea/workflows/ci.yml`:push 到 `main` 或打 `v*` tag 时运行测试并构建 Docker 镜像。详见 [.gitea/README.md](.gitea/README.md)。
|
||
|
||
---
|
||
|
||
## UI 设计
|
||
|
||
前端样式与布局规范见 [docs/UI-DESIGN-SYSTEM.md](docs/UI-DESIGN-SYSTEM.md)。页面统一使用 `PageHeader`、`AppCard`、`StatCard` 等壳层组件,品牌色与间距 Token 定义在 `web/src/styles/global.css`。
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
MIT — 见 [LICENSE](./LICENSE)
|