为个人打造的简单、美观、优雅的 LLM API 聚合与负载均衡服务
简体中文 | English
直接运行
docker run -d --name octopus -v /path/to/data:/app/data -p 8080:8080 bestrui/octopus
或者使用 docker compose 运行
wget https://raw.githubusercontent.com/bestruirui/octopus/refs/heads/dev/docker-compose.yml
docker compose up -d
从 Releases 下载对应平台的二进制文件,然后运行:
./octopus start
环境要求: - Go 1.24.4 - Node.js 18+ - pnpm
# 克隆项目
git clone https://github.com/bestruirui/octopus.git
cd octopus
# 构建前端
cd web && pnpm install && pnpm run build && cd ..
# 移动前端产物到 static 目录
mv web/out static/
# 启动后端服务
go run main.go start
💡 提示:前端构建产物会被嵌入到 Go 二进制文件中,所以必须先构建前端再启动后端。
开发模式
cd web && pnpm install && NEXT_PUBLIC_API_BASE_URL="http://127.0.0.1:8080" pnpm run dev
## 新建终端,启动后端服务
go run main.go start
## 访问前端地址
http://localhost:3000
首次启动后,访问 http://localhost:8080 使用以下默认账户登录管理面板:
adminadmin⚠️ 安全提示:请在首次登录后立即修改默认密码。
配置文件默认位于 data/config.json,首次启动时自动生成。
完整配置示例:
{
"server": {
"host": "0.0.0.0",
"port": 8080
},
"database": {
"type": "sqlite",
"path": "data/data.db"
},
"log": {
"level": "info"
}
}
配置项说明:
| 配置项 | 说明 | 默认值 |
|---|---|---|
server.host |
监听地址 | 0.0.0.0 |
server.port |
服务端口 | 8080 |
database.type |
数据库类型 | sqlite |
database.path |
数据库连接地址 | data/data.db |
log.level |
日志级别 | info |
数据库配置:
支持三种数据库:
| 类型 | database.type |
database.path 格式 |
|---|---|---|
| SQLite | sqlite |
data/data.db |
| MySQL | mysql |
user:password@tcp(host:port)/dbname |
| PostgreSQL | postgres |
postgresql://user:password@host:port/dbname?sslmode=disable |
MySQL 配置示例:
{
"database": {
"type": "mysql",
"path": "root:password@tcp(127.0.0.1:3306)/octopus"
}
}
PostgreSQL 配置示例:
{
"database": {
"type": "postgres",
"path": "postgresql://user:password@localhost:5432/octopus?sslmode=disable"
}
}
💡 提示:MySQL 和 PostgreSQL 需要先手动创建数据库,程序会自动创建表结构。
环境变量:
所有配置项均可通过环境变量覆盖,格式为 OCTOPUS_ + 配置路径(用 _ 连接):
| 环境变量 | 对应配置项 |
|---|---|
OCTOPUS_SERVER_PORT |
server.port |
OCTOPUS_SERVER_HOST |
server.host |
OCTOPUS_DATABASE_TYPE |
database.type |
OCTOPUS_DATABASE_PATH |
database.path |
OCTOPUS_LOG_LEVEL |
log.level |
OCTOPUS_GITHUB_PAT |
用于获取最新版本时的速率限制(可选) |
OCTOPUS_RELAY_MAX_SSE_EVENT_SIZE |
最大 SSE 事件大小(可选) |
OCTOPUS_IMAGES_BODY_MEMORY_THRESHOLD_MB |
Images 请求体内存缓存阈值,超过阈值会落盘临时文件(可选,默认 16) |
OCTOPUS_IMAGES_BODY_MAX_MB |
Images 请求体最大大小限制,超过限制将拒绝请求(可选,默认 256) |
OCTOPUS_IMAGES_BODY_TMP_DIR |
Images 请求体临时文件目录(可选,默认 ./cache) |
OCTOPUS_IMAGES_BODY_TMP_CLEANUP_HOURS |
启动时清理临时文件的时间阈值(可选,默认 24) |
| 首页 | 渠道 | 分组 |
![]() |
![]() |
![]() |
| 价格 | 日志 | 设置 |
![]() |
![]() |
![]() |
| 首页 | 渠道 | 分组 | 价格 | 日志 | 设置 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
渠道是连接 LLM 供应商的基础配置单元。
Base URL 说明:
程序会根据渠道类型自动补全 API 路径,您只需填写基础 URL 即可:
| 渠道类型 | 自动补全路径 | 填写 URL | 完整请求地址示例 |
|---|---|---|---|
| OpenAI Chat | /chat/completions |
https://api.openai.com/v1 |
https://api.openai.com/v1/chat/completions |
| OpenAI Responses | /responses |
https://api.openai.com/v1 |
https://api.openai.com/v1/responses |
| OpenAI Images | /images/generations、/images/edits、/images/variations |
https://api.openai.com/v1 |
https://api.openai.com/v1/images/generations |
| Anthropic | /messages |
https://api.anthropic.com/v1 |
https://api.anthropic.com/v1/messages |
| Gemini | /models/:model:generateContent |
https://generativelanguage.googleapis.com/v1beta |
https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent |
💡 提示:填写 Base URL 时无需包含具体的 API 端点路径,程序会自动处理。
分组用于将多个渠道聚合为一个统一的对外模型名称。
核心概念:
model 参数设置为分组名称即可负载均衡模式:
| 模式 | 说明 |
|---|---|
| 🔄 轮询 | 每次请求依次切换到下一个渠道 |
| 🎲 随机 | 每次请求随机选择一个可用渠道 |
| 🛡️ 故障转移 | 优先使用高优先级渠道,仅当其故障时才切换到低优先级渠道 |
| ⚖️ 加权分配 | 根据渠道设置的权重比例分配请求 |
💡 示例:创建分组名称为
gpt-4o,将多个供应商的 GPT-4o 渠道加入该分组,即可通过统一的model: gpt-4o访问所有渠道。
管理系统中的模型价格信息。
数据来源:
价格优先级:
| 优先级 | 来源 | 说明 |
|---|---|---|
| 🥇 高 | 本页面 | 用户在价格管理页面设置的价格 |
| 🥈 低 | models.dev | 自动同步的默认价格 |
💡 提示:如需覆盖某个模型的默认价格,只需在价格管理页面为其设置自定义价格即可。
系统全局配置项。
统计保存周期(分钟):
由于程序涉及大量统计项目,若每次请求都直接写入数据库会影响读写性能。因此程序采用以下策略:
⚠️ 重要提示:退出程序时,请使用正常的关闭方式(如
Ctrl+C或发送SIGTERM信号),以确保内存中的统计数据能正确写入数据库。请勿使用kill -9等强制终止方式,否则可能导致统计数据丢失。
from openai import OpenAI
import os
client = OpenAI(
base_url="http://127.0.0.1:8080/v1",
api_key="sk-octopus-P48ROljwJmWBYVARjwQM8Nkiezlg7WOrXXOWDYY8TI5p9Mzg",
)
completion = client.chat.completions.create(
model="octopus-openai", // 填写正确的分组名称
messages = [
{"role": "user", "content": "Hello"},
],
)
print(completion.choices[0].message.content)
编辑 ~/.claude/settings.json
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:8080",
"ANTHROPIC_AUTH_TOKEN": "sk-octopus-P48ROljwJmWBYVARjwQM8Nkiezlg7WOrXXOWDYY8TI5p9Mzg",
"API_TIMEOUT_MS": "3000000",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
"ANTHROPIC_MODEL": "octopus-sonnet-4-5",
"ANTHROPIC_SMALL_FAST_MODEL": "octopus-haiku-4-5",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "octopus-sonnet-4-5",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "octopus-sonnet-4-5",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "octopus-haiku-4-5"
}
}
编辑 ~/.codex/config.toml
model = "octopus-codex" # 填写正确的分组名称
model_provider = "octopus"
[model_providers.octopus]
name = "octopus"
base_url = "http://127.0.0.1:8080/v1"
编辑 ~/.codex/auth.json
{
"OPENAI_API_KEY": "sk-octopus-P48ROljwJmWBYVARjwQM8Nkiezlg7WOrXXOWDYY8TI5p9Mzg"
}
$ claude mcp add octopus \
-- python -m otcore.mcp_server <graph>