# myopia **Repository Path**: lowkey110/myopia ## Basic Information - **Project Name**: myopia - **Description**: No description available - **Primary Language**: Rust - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-07-08 - **Last Updated**: 2026-07-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Opia — API Aggregation Proxy > 一个 Rust 编写的单二进制 API 聚合代理,支持 OpenAI / Anthropic 多后端,提供统一 OpenAI 兼容接口、Web 管理面板和完整的请求管理。 [![Build](https://gitee.com/lowkey110/myopia/workflows/Build%20%26%20Test/badge.svg)](https://gitee.com/lowkey110/myopia/actions) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Rust](https://img.shields.io/badge/rust-1.75+-orange.svg)](https://www.rust-lang.org) [![Version](https://img.shields.io/badge/version-0.1.0-green.svg)]() ## 功能特性 | 特性 | 说明 | |------|------| | **OpenAI 兼容** | 所有 OpenAI 标准端点,支持 `/v1/models`、`/v1/chat/completions`、`/v1/embeddings`、`/v1/audio/`、`/v1/images/` 等 | | **多后端** | 同时支持 OpenAI、Anthropic 等多个 API 提供商 | | **智能路由** | 模型别名 → 多个 Provider,支持轮询/回退策略 | | **密钥加密** | AES-256-GCM 加密存储 Provider API Key | | **请求日志** | 自动记录每次请求的 Token 消耗、延迟、状态码 | | **用量统计** | 按天聚合的用量统计 | | **Web 管理** | 基于 WASM + Leptos 的响应式管理面板 | | **扫描发现** | 一键扫描 Provider API 自动发现可用模型 | | **多语言** | 内置中英文 (EN/ZH) 切换 | | **单二进制** | 所有依赖打包进一个可执行文件,开箱即用 | ## 架构概览 ``` ┌─────────────────────────────────────────────────────────────┐ │ 客户端 (LLM 应用) │ └───────────────────────────┬─────────────────────────────────┘ │ OpenAI 兼容 HTTP 请求 │ (Bearer sk-xxx) ▼ ┌─────────────────────────────────────────────────────────────┐ │ Opia Proxy (Port 9999) │ │ ┌───────────┐ ┌─────────────┐ ┌───────────────────────┐ │ │ │ API Key │ │ Router │ │ Translator │ │ │ │ Auth │→ │ Alias→Model │ │ Format 转换 │ │ │ └───────────┘ └─────────────┘ └───────────────────────┘ │ │ │ │ │ ┌────┴────┐ │ │ │ SQLite │ providers / api_keys / │ │ │ │ model_mappings / logs │ │ └─────────┘ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Web UI (WASM) — http://localhost:9999/ │ │ │ │ Provider 管理 / 密钥管理 / 模型映射 / 路由规则 / 日志 │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ┌─────────────┼─────────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ OpenAI │ │ Anthropic│ │ 自定义 │ │ Provider │ │ Provider │ │ Provider│ └──────────┘ └──────────┘ └──────────┘ ``` ## 快速开始 ### 环境要求 - **Rust**: 1.75+ (`rustup install stable`) - **WASM 目标** (仅构建 Web UI): `rustup target add wasm32-unknown-unknown` ### 构建 ```bash # 1. 克隆仓库 git clone https://gitee.com/lowkey110/myopia.git cd myopia # 2. 安装 WASM 编译目标(构建 Web UI) rustup target add wasm32-unknown-unknown # 3. 构建 cargo build --release --workspace # 输出: target/release/api-proxy ``` ### 运行 ```bash # 默认配置 (端口 9999, 当前目录 ./data/app.db) ./target/release/api-proxy # 自定义端口和数据库路径 ./target/release/api-proxy \ --listen 0.0.0.0:8080 \ --database /path/to/data.db # 更多选项 ./target/release/api-proxy --help ``` ### 访问 | 地址 | 说明 | |------|------| | http://localhost:9999/ | Web 管理面板 | | http://localhost:9999/v1/chat/completions | OpenAI 聊天补全 | | http://localhost:9999/v1/models | OpenAI 模型列表(官方规范) | | http://localhost:9999/v1/embeddings | OpenAI 嵌入向量生成 | ## 配置说明 ### 命令行参数 | 参数 | 短参数 | 环境变量 | 默认值 | 说明 | |------|--------|----------|--------|------| | `--listen` | `-l` | — | `0.0.0.0:9999` | 监听地址 | | `--database` | `-d` | `APP_DATABASE` | `./data/app.db` | SQLite 数据库路径 | | `--master-key` | — | `APP_MASTER_KEY` | `./data/master.key` | 加密主密钥文件 | | `--static-dir` | — | — | 嵌入 | 前端资源目录路径 | | `--log-level` | — | `APP_LOG_LEVEL` | `info` | 日志级别 (debug/info/warn/error) | ### 环境变量 ```bash # 开发环境: 显示 debug 日志 export APP_LOG_LEVEL=debug # 自定义数据库路径 export APP_DATABASE=/var/lib/opia/data.db # CORS 设置 export APP_CORS=http://localhost:3000,https://example.com ``` ### 数据库迁移 首次运行时自动执行迁移并创建所有表。迁移文件位于 `migrations/` 目录。 ## 使用方法 ### 1. 添加 Provider (提供商) **方法 A: Web 管理面板(推荐)** 1. 打开 http://localhost:9999/ 2. 左侧菜单进入 **Providers** 页面 3. 点击 **Scan** 标签 4. 填写 Provider 信息: - **类型**: 选择 OpenAI 或 Anthropic - **Base URL**: 如 `https://api.openai.com` - **API Key**: 你的 API 密钥 5. 点击 **Scan** 自动拉取可用模型列表 6. 勾选需要的模型,点击 **Create** 一键创建 **方法 B: API 调用** ```bash # 扫描可用模型 curl -X POST http://localhost:9999/api/admin/providers/scan \ -H "Content-Type: application/json" \ -d '{ "provider_type": "openai", "base_url": "https://api.openai.com", "api_key": "sk-xxx" }' # 一键创建 Provider + 模型映射 curl -X POST http://localhost:9999/api/admin/providers/create-with-models \ -H "Content-Type: application/json" \ -d '{ "provider_type": "openai", "name": "my-openai", "base_url": "https://api.openai.com", "api_key": "sk-xxx", "models": ["gpt-4o", "gpt-3.5-turbo"] }' ``` ### 2. 创建 API Key (客户端密钥) ```bash # Web 面板: Keys 页面 → 输入名称创建 # API curl -X POST http://localhost:9999/api/admin/keys \ -H "Content-Type: application/json" \ -d '{"name": "my-app"}' # 返回结果中包含 API Key,请妥善保存 ``` ### 3. 调用 OpenAI 兼容 API 用创建的 API Key 调用代理端点: **聊天补全** ```bash curl http://localhost:9999/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-your-api-key" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "Hello!"}], "max_tokens": 1024 }' ``` **列出可用模型** ```bash curl http://localhost:9999/v1/models ``` **查询单个模型** ```bash curl http://localhost:9999/v1/models/gpt-4o ``` **嵌入向量生成** ```bash curl -X POST http://localhost:9999/v1/embeddings \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-your-api-key" \ -d '{ "model": "text-embedding-ada-002", "input": "hello world" }' ``` **音频转录** ```bash curl -X POST http://localhost:9999/v1/audio/transcriptions \ -H "Authorization: Bearer sk-your-api-key" ``` **图像生成** ```bash curl -X POST http://localhost:9999/v1/images/generations \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-your-api-key" \ -d '{"prompt": "a beautiful sunset over the mountains"}' ``` ### 4. 管理模型路由 ```bash # 查看模型映射 curl http://localhost:9999/api/admin/mappings # 创建自定义映射 (alias → target) curl -X POST http://localhost:9999/api/admin/mappings \ -H "Content-Type: application/json" \ -d '{ "provider_id": "provider-uuid", "alias": "my-alias", "target": "gpt-4o" }' # 查看路由规则 curl http://localhost:9999/api/admin/routing-rules ``` ### 5. 查看日志和统计 ```bash # 请求日志 curl http://localhost:9999/api/admin/logs # 用量统计 curl http://localhost:9999/api/admin/stats ``` ### 6. Web 面板导航 | 页面 | 功能 | |------|------| | **Dashboard** | 概览: 请求总数、Token 用量、Provider 数量 | | **Providers** | 管理后端 API 提供商 (增删查) | | **Scan** | 扫描 Provider API 发现模型 (推荐) | | **Keys** | 管理客户端 API 密钥 (创建/吊销) | | **Mappings** | 模型别名映射 (alias → target) | | **Routing Rules** | 路由规则 (轮询/回退) | | **Logs** | 请求日志 | | **Stats** | 用量统计 | ## API 文档 ### Admin API | Method | 路径 | 说明 | |--------|------|------| | GET | `/api/admin/providers` | 列出所有 Provider | | POST | `/api/admin/providers` | 创建 Provider | | GET | `/api/admin/providers/{id}` | 获取 Provider 详情 | | PUT | `/api/admin/providers/{id}` | 更新 Provider | | DELETE | `/api/admin/providers/{id}` | 删除 Provider | | POST | `/api/admin/providers/scan` | 扫描 Provider 可用模型 | | POST | `/api/admin/providers/create-with-models` | 一键创建 Provider + 模型 | | GET | `/api/admin/keys` | 列出 API 密钥 | | POST | `/api/admin/keys` | 创建 API 密钥 | | DELETE | `/api/admin/keys/{id}` | 吊销 API 密钥 | | GET | `/api/admin/mappings` | 列出模型映射 | | POST | `/api/admin/mappings` | 创建模型映射 | | DELETE | `/api/admin/mappings/{id}` | 删除映射 | | GET | `/api/admin/routing-rules` | 列出路由规则 | | POST | `/api/admin/routing-rules` | 创建路由规则 | | DELETE | `/api/admin/routing-rules/{id}` | 删除规则 | | GET | `/api/admin/stats` | 获取用量统计 | | GET | `/api/admin/logs` | 获取请求日志 | ### OpenAI 兼容 Proxy API | Method | 路径 | 说明 | |--------|------|------| | POST | `/v1/chat/completions` | 聊天补全 (OpenAI 兼容) | | GET | `/v1/models` | 列出所有可用模型 | | GET | `/v1/models/{model}` | 查询单个模型 | | POST | `/v1/embeddings` | 生成文本嵌入向量 | | POST | `/v1/audio/transcriptions` | 语音转文本 | | POST | `/v1/audio/speech` | 文本转语音 (TTS) | | POST | `/v1/audio/translations` | 语音翻译 | | POST | `/v1/images/generations` | 图像生成 | | POST | `/v1/images/variations` | 图像变体 | ## CI/CD 项目配置了 Gitee Pages 自动构建。 - 推送代码到 `master` / `main` 分支会自动触发构建 - 构建产物包含 release 二进制 + Web UI - 访问 https://.gitee.io/myopia/ 使用在线版 ## 项目结构 ``` myopia/ ├── Cargo.toml # Workspace 配置 ├── migrations/ │ └── 20260707000000_initial.sql # 数据库迁移 ├── .gitee/workflows/ │ └── build.yml # CI/CD 流水线 ├── crates/ │ ├── shared/ # 共享库 (模型定义、加解密) │ │ └── src/lib.rs │ ├── server/ # 服务端 (Axum) │ │ └── src/ │ │ ├── main.rs # 入口 + 路由 │ │ ├── config.rs # CLI 配置 │ │ ├── db.rs # 数据库初始化 │ │ ├── static_files.rs # 静态文件服务 │ │ ├── proxy/ # 代理引擎 │ │ │ ├── router.rs │ │ │ ├── translator.rs │ │ │ ├── stats.rs │ │ │ ├── logger.rs │ │ │ └── providers/ │ │ └── routes/ # HTTP 路由处理 │ └── frontend/ # Web UI (Leptos WASM) │ ├── index.html # 页面入口 + 样式 │ ├── Trunk.toml # Trunk 构建配置 │ └── src/ │ ├── main.rs # Leptos 入口 │ ├── app.rs # 组件 + 路由 │ ├── api.rs # API 客户端 │ └── i18n.rs # 国际化 (EN/ZH) └── README.md ``` ## 技术栈 | 层级 | 技术 | |------|------| | 语言 | Rust 🦀 | | Web 框架 | Axum 0.8 | | 前端 | Leptos 0.7 (WASM) + Trunk | | 数据库 | SQLite (sqlx) | | 加密 | ring (AES-256-GCM) | | 日志 | tracing + tracing-subscriber | | CLI | clap | ## 安全 - Provider API Key 使用 **AES-256-GCM** 加密后存储 - 客户端 API Key 仅存储 hash (SHA-256) - 主密钥文件 (master.key) 默认生成在项目 data 目录 - 生产环境建议设置 `APP_MASTER_KEY` 环境变量 ## 开发 ```bash # 开发时实时监控并构建 cd crates/frontend && trunk watch # 仅构建服务端 cargo build --release -p server # 运行服务端 (自动加载 dist) cargo run -p server --release -- --static-dir crates/frontend/dist # 测试 cargo test --workspace ``` ## 许可 MIT ## 贡献 欢迎提交 Issue 和 Pull Request。