Skip to content

Gemini-Balance :突破 Gemini API 限制的代理服务 ​

一、项目简介 ​

Gemini-Balance 是一个轻量级的 Gemini API 轮询代理服务。它的核心目标是帮助开发者突破 Gemini 免费 API 的速率限制,并通过在国内可访问的服务器进行中转,实现稳定、高效的 API 调用。

核心功能:

  • API Key 轮询:通过配置多个 Gemini API Key,将请求轮流分发到不同的 Key上,从而将免费额度(默认为 5 RPM)提升 N 倍。
  • OpenAI 格式兼容:将 Gemini 的 API 请求和响应格式转换为 OpenAI 的格式,使大量现有的 AI 客户端和工具(如 LobeChat, Continue, NextChat 等)可以无缝接入。
  • 流式响应支持:完整支持 Gemini API 的流式输出,保证了打字机效果的流畅体验。
  • 安全认证:支持设置访问令牌(Auth Token),保护你的代理服务不被滥用。
  • 多模态支持:支持 gemini-pro-vision 模型,可以处理图像和文本的多模态输入。
  • 部署简单:基于 FastAPI 和 Docker,提供了极其简单的部署方案。

二、准备工作 ​

在开始部署之前,请确保你已准备好以下内容:

  1. 至少一个 Gemini API Key:

    • 访问 Google AI Studio 获取。
    • 强烈建议:准备多个 Google 账户以获取多个 API Key,这是实现额度翻倍的基础。
  2. 一个可以访问外网的环境:

  3. 安装 Docker 和 Docker Compose (如果你选择方案 A):

三、服务配置 ​

Gemini-Balance 的所有配置都通过环境变量完成。如果你使用 Docker Compose,则可以直接创建一个 .env 文件。

克隆项目:

bash
git clone https://github.com/snailyp/gemini-balance.git
cd gemini-balance

创建你的配置文件:

bash
cp .env.example .env

使用编辑器(如 vim 或 nano)打开并编辑 .env 文件:

bash
vim .env

关键配置项说明:

配置项说明默认值
数据库配置
DATABASE_TYPE可选,数据库类型,支持 mysql 或 sqlitemysql
SQLITE_DATABASE可选,当使用 sqlite 时必填,SQLite 数据库文件路径default_db
MYSQL_HOST当使用 mysql 时必填,MySQL 数据库主机地址localhost
MYSQL_SOCKET可选,MySQL 数据库 socket 地址/var/run/mysqld/mysqld.sock
MYSQL_PORT当使用 mysql 时必填,MySQL 数据库端口3306
MYSQL_USER当使用 mysql 时必填,MySQL 数据库用户名your_db_user
MYSQL_PASSWORD当使用 mysql 时必填,MySQL 数据库密码your_db_password
MYSQL_DATABASE当使用 mysql 时必填,MySQL 数据库名称defaultdb
API 相关配置
API_KEYS必填,Gemini API 密钥列表,用于负载均衡["your-gemini-api-key-1", "your-gemini-api-key-2"]
ALLOWED_TOKENS必填,允许访问的 Token 列表["your-access-token-1", "your-access-token-2"]
AUTH_TOKEN可选,超级管理员token,具有所有权限,不填默认使用 ALLOWED_TOKENS 的第一个sk-123456

四、部署方案 ​

方案一:使用 Docker Compose 在服务器上部署 (推荐) ​

这是最稳定、最推荐的部署方式。

  1. 准备文件:确保你已经按照上面的步骤,在服务器的某个目录(例如 /opt/gemini-balance)下创建并配置好了 .env 文件。同时,确保该目录下有项目自带的 docker-compose.yml 文件。

  2. 启动服务:在该目录下,执行以下命令:

    bash
    docker-compose up -d

    -d 参数表示在后台运行。

  3. 验证服务:

    • 查看容器是否正在运行:
      bash
      docker ps
      你应该能看到一个名为 gemini-balance 的容器正在运行,并且端口 8000 已被映射。
    • 使用 curl 命令测试服务是否正常工作(请将 your_server_ip 和 your_auth_token 替换为你的实际值):
      bash
      curl http://your_server_ip:8000/v1/models \
        -H "Authorization: Bearer your_auth_token"
      如果配置正确,它将返回一个类似 OpenAI 格式的模型列表,其中包含 gemini-pro 和 gemini-pro-vision。

管理面板 http://your_server_ip:8000

面板

方案二:使用免费云平台部署 ​

参考官方文档 从零部署 Gemini Balance 手册之更新篇 | Gemini Balance

五、如何使用你的代理服务 ​

部署成功后,你的代理服务地址为 http://<你的IP或域名>:8000 (如果使用 Docker Compose) 。

由于该代理兼容 OpenAI API 格式,你可以在任何支持自定义 OpenAI 接口的客户端中使用它。

通用配置:

  • API Base URL / 接口地址:http://<你的IP或域名>:8000
  • API Key / 密钥:填入你设置的 AUTH_TOKEN (不是 Gemini API Key!)
  • 模型名称 (Model Name):gemini-2.5-pro 等

示例:在 cherrystudio 中配置

  1. 打开 cherrystudio 设置 -> 模型服务。
  2. 在 OpenAI/Gemini 模块下,填写以下信息:
    • 接口地址:http://your_server_ip:8000
    • API Key:a_very_secret_and_strong_token (你设置的 AUTH_TOKEN)
    • 模型列表:点击“管理”或手动添加 gemini-2.5-pro。
  3. 保存后即可在 cherrystudio 中选择并使用 gemini-2.5-pro 模型进行对话。

cherryStudio

示例:在 python 中调用

python

#!/bin/env python3
# -*- coding: utf-8 -*-
import httpx
import asyncio

# ==============================================================================
#  方法一:使用 Google Gemini 原生 API 格式调用
# ==============================================================================
class GeminiNativeTester:
    def __init__(self):

        self.base_url = 'http://ip:port/gemini/v1beta/'

        self.api_key = 'sk-xxxxxxxx'  # 实际的authtoken

    async def chat(self, prompt: str, model: str = "gemini-1.5-flash") -> str:
        
        url = f"{self.base_url}models/{model}:generateContent"

        # Gemini 原生格式的 headers
        headers = {
            'Content-Type': 'application/json',
            'x-goog-api-key': self.api_key
        }

        # Gemini 原生格式的 payload
        payload = {
            "contents": [
                {
                    "parts": [{"text": prompt}]
                }
            ]
        }

        async with httpx.AsyncClient() as client:
            response = await client.post(url, headers=headers, json=payload, timeout=60)
          
            if response.status_code == 200:
                result = response.json()
                # 解析 Gemini 原生格式的响应
                if 'candidates' in result and result['candidates']:
                    return result['candidates'][0]['content']['parts'][0]['text']
                else:
                    return f"未能从响应中解析出回答: {result}"
            else:
                raise Exception(f"请求失败: {response.status_code}, {response.text}")


# ==============================================================================
#  方法二:使用 OpenAI 兼容 API 格式调用
# ==============================================================================
class OpenAICompatibleTester:
    def __init__(self):

        self.base_url = 'http://ip:port/openai/v1'
      
        self.api_key = 'sk-xxxxxxxxh'  # 实际的authtoken

    async def chat(self, prompt: str, model: str = "gemini-1.5-flash") -> str:

        url = f"{self.base_url}/chat/completions"

        # OpenAI 格式的 headers,使用 Bearer Token 进行认证
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {self.api_key}'
        }

        # OpenAI 格式的 payload
        payload = {
            "model": model,
            "messages": [
                {"role": "user", "content": prompt}
            ],
            "stream": False
        }

        async with httpx.AsyncClient() as client:
            try:
                response = await client.post(url, headers=headers, json=payload, timeout=60)
                response.raise_for_status() 

                result = response.json()
              
                # 解析 OpenAI 格式的响应
                if 'choices' in result and len(result['choices']) > 0:
                    return result['choices'][0]['message']['content']
                else:
                    return f"未能从响应中解析出回答: {result}"
            except httpx.HTTPStatusError as e:
                raise Exception(f"请求失败,状态码: {e.response.status_code}, 响应: {e.response.text}")
            except Exception as e:
                raise Exception(f"发生未知错误: {e}")

# ==============================================================================
#  测试主程序
# ==============================================================================
if __name__ == "__main__":
    async def main():
        prompt = '你好,请用中文简单介绍一下你自己。'

        # --- 测试方法一:Gemini 原生格式 ---
        print("\n" + "="*20 + " Gemini 原生格式调用测试 " + "="*20)
        try:
            native_tester = GeminiNativeTester()
            result = await native_tester.chat(prompt, model="gemini-1.5-flash")
            print("Gemini (原生) 回复:")
            print(result)
        except Exception as e:
            print("原生格式调用出错:", e)

        print("\n" + "-"*60 + "\n")

        # --- 测试方法二:OpenAI 兼容格式 ---
        print("="*20 + " OpenAI 兼容格式调用测试 " + "="*20)
        try:
            openai_tester = OpenAICompatibleTester()
            # gemini-balance 代理将模型映射为 "gemini-pro"
            result = await openai_tester.chat(prompt, model="gemini-1.5-flash")
            print("Gemini (OpenAI格式) 回复:")
            print(result)
        except Exception as e:
            print("OpenAI 格式调用出错:", e)

    asyncio.run(main())