Gemini API 最佳使用方式
本文最后更新于107 天前,其中的信息可能已经过时,如有错误请发送邮件到[email protected]

GPT-LOAD

必须安装

多个KEY需要使用工具来进行统一管理轮询。GPT-Load是一个高性能、企业级的 AI 接口透明代理服务。

安装步骤,根据文档进行安装。

如果你的服务器可以直接访问Google并且必须是能够使用Gemini的地区那么到这里就已经可以直接用{当前地址}/proxy/gemini代替https://generativelanguage.googleapis.com进行测试了,不出意外的话直接能够访问通。

代理

VPN

如果你有可用的VPN可以通过我这篇文章来配置,直达链接。然后在GPT-LOAD的配置文件中加上下面的配置,然后进行测试。

HTTP_PROXY=http://127.0.0.1:10808
HTTPS_PROXY=http://127.0.0.1:10808

动态IP

如果存在大量的KEY,使用同一个IP可能会被Google封锁,所以需要通过下面方法让出口IP都不一样

Supabase 的Edge Functions 可以实现免代理访问 Gemini-API,注册后创建一个项目,地区选择美国,然后创建Edge Functions,填入下面代码,并且JWT必须关闭!!!

import { serve } from "https://deno.land/[email protected]/http/server.ts";
// 1. API 代理映射表
const proxies = {
  discord: "discord.com/api",
  telegram: "api.telegram.org",
  httpbin: "httpbin.org",
  openai: "api.openai.com",
  claude: "api.anthropic.com",
  gemini: "generativelanguage.googleapis.com",
  gemininothink: "generativelanguage.googleapis.com",
  meta: "www.meta.ai/api",
  groq: "api.groq.com/openai",
  xai: "api.x.ai",
  cohere: "api.cohere.ai",
  huggingface: "api-inference.huggingface.co",
  together: "api.together.xyz",
  novita: "api.novita.ai",
  portkey: "api.portkey.ai",
  fireworks: "api.fireworks.ai",
  targon: "api.targon.com",
  openrouter: "openrouter.ai/api",
  siliconflow: "api.siliconflow.cn",
  modelscope: "api-inference.modelscope.cn",
  gmi: "api.gmi-serving.com",
  azureinference: "models.inference.ai.azure.com",
  githubai: "models.github.ai/inference",
  dmxcom: "www.dmxapi.com",
  dmxcn: "www.dmxapi.cn"
};
// 2. 增强的 Header 黑名单
const BlacklistedHeaders = new Set([
  "cf-connecting-ip",
  "cf-ipcountry",
  "cf-ray",
  "cf-visitor",
  "cf-worker",
  "cdn-loop",
  "cf-ew-via",
  "baggage",
  "sb-request-id",
  "x-amzn-trace-id",
  "x-forwarded-for",
  "x-forwarded-host",
  "x-forwarded-proto",
  "x-forwarded-server",
  "x-real-ip",
  "x-original-host",
  "forwarded",
  "via",
  "referer",
  "x-request-id",
  "x-correlation-id",
  "x-trace-id"
]);
// 3. 日志记录辅助函数
function logRequest(method, pathname, targetUrl, status) {
  const timestamp = new Date().toISOString();
  const statusInfo = status ? ` [${status}]` : '';
  const target = targetUrl ? ` -> ${targetUrl}` : '';
  console.log(`[${timestamp}] ${method} ${pathname}${target}${statusInfo}`);
}
// 4. 错误类型识别函数
function categorizeError(error) {
  const errorMessage = error.message.toLowerCase();
  if (error.name === 'AbortError' || errorMessage.includes('timeout')) {
    return {
      type: 'TIMEOUT',
      message: 'Request timeout - the target service took too long to respond',
      status: 504
    };
  }
  if (errorMessage.includes('network') || errorMessage.includes('fetch')) {
    return {
      type: 'NETWORK',
      message: 'Network error - unable to reach the target service',
      status: 502
    };
  }
  if (errorMessage.includes('dns') || errorMessage.includes('name resolution')) {
    return {
      type: 'DNS',
      message: 'DNS resolution failed - unable to resolve target hostname',
      status: 502
    };
  }
  if (errorMessage.includes('connection refused') || errorMessage.includes('connect')) {
    return {
      type: 'CONNECTION',
      message: 'Connection refused - target service is not accepting connections',
      status: 503
    };
  }
  if (errorMessage.includes('ssl') || errorMessage.includes('tls') || errorMessage.includes('certificate')) {
    return {
      type: 'SSL',
      message: 'SSL/TLS error - certificate or encryption issue',
      status: 502
    };
  }
  return {
    type: 'UNKNOWN',
    message: `Unexpected error: ${error.message}`,
    status: 500
  };
}
// 5. 创建标准错误响应
function createErrorResponse(message, status, details) {
  const errorBody = JSON.stringify({
    error: message,
    status,
    timestamp: new Date().toISOString(),
    ...details && {
      details
    }
  });
  return new Response(errorBody, {
    status,
    headers: {
      "Content-Type": "application/json; charset=utf-8",
      "Access-Control-Allow-Origin": "*"
    }
  });
}
// 6. 主服务函数
serve(async (req)=>{
  const url = new URL(req.url);
  const { pathname, search } = url;
  logRequest(req.method, pathname);
  // OPTIONS 请求处理
  if (req.method === "OPTIONS") {
    return new Response(null, {
      status: 204,
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH",
        "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With, anthropic-version, x-api-key"
      }
    });
  }
  // 恢复到第一版的路径解析逻辑
  const pathParts = pathname.split("/");
  // 验证路径格式(适配第一版逻辑)
  // 假设格式为 /<base_path>/<service_alias>/...  (e.g., /api/openai/...)
  // pathParts will be ['', <base_path>, <service_alias>, ...]
  if (pathParts.length < 3) {
    return createErrorResponse("Invalid path format. Expected format like: /api/{service}/{path}", 400, `Available services: ${Object.keys(proxies).join(', ')}`);
  }
  const targetAlias = pathParts[2]; // 获取服务别名
  const targetHost = proxies[targetAlias];
  console.log(`服务别名: ${targetAlias}, 目标主机: ${targetHost}`);
  // 验证服务映射
  if (!targetHost) {
    console.error(`服务映射未找到: 客户端尝试访问别名 '${targetAlias}'`);
    return createErrorResponse(`Service alias '${targetAlias}' not found`, 404, `Available services: ${Object.keys(proxies).join(', ')}`);
  }
  // 构建目标路径和URL
  const targetPath = pathParts.slice(3).join("/");
  const targetUrl = `https://${targetHost}/${targetPath}${search}`;
  console.log(`目标路径: ${targetPath}`);
  console.log(`最终目标URL: ${targetUrl}`);
  try {
    // 处理请求头
    const forwardedHeaders = new Headers();
    for (const [key, value] of req.headers.entries()){
      const lowerKey = key.toLowerCase();
      if (!BlacklistedHeaders.has(lowerKey) && !lowerKey.startsWith("sec-ch-ua")) {
        forwardedHeaders.set(key, value);
      }
    }
    // 设置必要的headers
    forwardedHeaders.set("Host", targetHost);
    forwardedHeaders.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");
    // Claude API 特殊处理
    if (targetAlias === "claude" && !forwardedHeaders.has("anthropic-version")) {
      forwardedHeaders.set("anthropic-version", "2023-06-01");
    }
    // 处理请求体
    let requestBody = null;
    if (req.method !== "GET" && req.method !== "HEAD") {
      // Gemini NoThink 特殊处理
      if (targetAlias === "gemininothink" && req.method === "POST" && req.headers.get("content-type")?.includes("application/json")) {
        try {
          const bodyText = await req.text();
          const bodyJson = JSON.parse(bodyText);
          bodyJson.generationConfig = {
            ...bodyJson.generationConfig || {},
            thinkingConfig: {
              thinkingBudget: 0
            }
          };
          requestBody = JSON.stringify(bodyJson);
          forwardedHeaders.set("content-type", "application/json");
        } catch (e) {
          console.error(`修改gemininothink请求体失败: ${e.message}`);
          return createErrorResponse("Invalid JSON format in request body", 400);
        }
      } else {
        requestBody = req.body;
      }
    }
    console.log(`发起请求到: ${targetUrl}`);
    // 发起代理请求
    const apiResponse = await fetch(targetUrl, {
      method: req.method,
      headers: forwardedHeaders,
      body: requestBody,
      redirect: "manual"
    });
    console.log(`API响应状态: ${apiResponse.status}`);
    logRequest(req.method, pathname, targetUrl, apiResponse.status);
    // 设置CORS响应头
    const responseHeaders = new Headers(apiResponse.headers);
    responseHeaders.set("Access-Control-Allow-Origin", "*");
    responseHeaders.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH");
    responseHeaders.set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, anthropic-version, x-api-key");
    return new Response(apiResponse.body, {
      status: apiResponse.status,
      headers: responseHeaders
    });
  } catch (error) {
    // 详细的错误分类和日志记录
    const errorInfo = categorizeError(error);
    console.error(`[${errorInfo.type}] API代理请求失败:`);
    console.error(`  目标URL: ${targetUrl}`);
    console.error(`  错误详情: ${error.message}`);
    console.error(`  错误堆栈: ${error.stack}`);
    logRequest(req.method, pathname, targetUrl, errorInfo.status);
    return createErrorResponse(errorInfo.message, errorInfo.status, `Error type: ${errorInfo.type}`);
  }
});
console.log("🚀 API代理服务器已启动");
console.log(`📋 支持的服务: ${Object.keys(proxies).join(', ')}`);
console.log("📖 使用方法: /<base_path>/{service}/{path} (例如: /api/openai/v1/chat/completions)");

在GPT-LOAD中的上游地址里需要修改成https://xxx.supabase.co/functions/v1/funcname/gemini进行测试,如果配置正确会收到测试成功的消息。

实现隐藏IP

GPT-LOAD中提供了一种 AI Gateway 的方式去反代这个也能免提子+动态IP,工作流程简述如下。

但是这里我想说的是有风险,这里我通过测试一个OpenAI的代理服务地址来说明一下,返回如下。

{
    "body": "",
    "headers": {
        "Accept": [
            "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
        ],
        "Accept-Encoding": [
            "gzip, br"
        ],
        "Accept-Language": [
            "zh-CN,zh;q=0.9,en;q=0.8"
        ],
        "Cdn-Loop": [
            "cloudflare; loops=1; subreqs=1"
        ],
        "Cf-Connecting-Ip": [
            "35.212.171.151"
        ],
        "Cf-Ew-Via": [
            "15"
        ],
        "Cf-Ipcountry": [
            "US"
        ],
        "Cf-Ray": [
            "9759edc645e608e7-SEA"
        ],
        "Cf-Visitor": [
            "{\"scheme\":\"https\"}"
        ],
        "Cf-Worker": [
            "oaipro.com"
        ],
        "Cookie": [
            "cf_clearance=YcM9OPOpS2j1PzZJEynjvKhXVqoLji23PO2zJDhLetI-1750843660-1.2.1.1-y1zHXVyYvfxKwpAtFAHsPYCbrVzFFsaDGGEnEN8QJCMTZ2kxxCZC4BJatQKmuojFl06Ofb8nYYec7EineidF2BdOHjGYQ5OX_sYMuA08doFMPcu7288PUbrSUIfyBVEv3rBgE6zaUZaHpVAVjkufqs6vJ2fkgUvfuhLaS5idu4VqiTsJfkehPZfuMkCFbbW1Xq_zJ8hrcf7gne897t7_zZer_nPzJiSLAFaUc5SreMvMA3NPOOLHgGetyHHT75BNzwJCStN6NR.5W8ABmPCWArCdbT1xq_ibw22dMqQltRhOSFSCOJW_GNWj6dEXUEG6YTS3JvAoyCeEpxdufNYjXcqFngHfgUS73UAyJvX8eV7SHjm.4lTW3pzvxxp5pVfa; cfz_google-analytics_v4=%7B%22nTmD_engagementDuration%22%3A%7B%22v%22%3A%220%22%2C%22e%22%3A1786672467616%7D%2C%22nTmD_engagementStart%22%3A%7B%22v%22%3A%221755136467616%22%2C%22e%22%3A1786672467616%7D%2C%22nTmD_counter%22%3A%7B%22v%22%3A%2239%22%2C%22e%22%3A1786672467616%7D%2C%22nTmD_session_counter%22%3A%7B%22v%22%3A%224%22%2C%22e%22%3A1786672467616%7D%2C%22nTmD_ga4%22%3A%7B%22v%22%3A%221795d006-0a60-40c5-84c5-4601bcc8a270%22%2C%22e%22%3A1786672467616%7D%2C%22nTmD_let%22%3A%7B%22v%22%3A%221755136467616%22%2C%22e%22%3A1786672467616%7D%2C%22nTmD_ga4sid%22%3A%7B%22v%22%3A%22848806308%22%2C%22e%22%3A1755138267616%7D%7D"
        ],
        "Priority": [
            "u=0, i"
        ],
        "Referer": [
            "https://linux.do/"
        ],
        "Sec-Ch-Ua": [
            "\"Not;A=Brand\";v=\"99\", \"Google Chrome\";v=\"139\", \"Chromium\";v=\"139\""
        ],
        "Sec-Ch-Ua-Mobile": [
            "?0"
        ],
        "Sec-Ch-Ua-Platform": [
            "\"Windows\""
        ],
        "Sec-Fetch-Dest": [
            "document"
        ],
        "Sec-Fetch-Mode": [
            "navigate"
        ],
        "Sec-Fetch-Site": [
            "cross-site"
        ],
        "Sec-Fetch-User": [
            "?1"
        ],
        "Upgrade-Insecure-Requests": [
            "1"
        ],
        "User-Agent": [
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
        ],
        "X-Forwarded-For": [
            "35.212.171.151, 35.212.171.151"
        ],
        "X-Forwarded-Proto": [
            "https"
        ],
        "X-Real-Ip": [
            "35.212.171.151"
        ]
    },
    "method": "GET",
    "queries": {}
}

这里很明显发现CF把你"卖了",他将的你的真实地址毫无保留的告诉了OpenAI,OpenAI就像看猴戏一样。

  • cf-connecting-ip: 暴露用户的真实 IP 地址。
  • cf-ipcountry: 国家/地区代码。
  • cf-worker: 暴露 Worker 代理的主机名。

所以我们需要搭建一个能够隐藏这些关键信息的Worker,SpectreProxy是一个非常好的选择,根据教程搭建好并且配置AUTH_TOKEN后修改配置

  1. Supabase的代码中添加

    const proxies = {
     cfproxy: "xxx.xxxx.workers.dev"
    };
  2. 修改GPT-LOAD的上游地址https://xxx.supabase.co/functions/v1/funcname/gemini/cfproxy/{AUTH_TOKEN}/gemini

进行测试,如果配置没问题则会显示测试成功。

欢迎来到我的 ChatGPT 中转站,极具性价比,为付费不方便的朋友提供便利,有需求的可以添加左侧 QQ 二维码,另外,邀请新用户能获取余额哦!最后说一句,那啥:请自觉遵守《生成式人工智能服务管理暂行办法》。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇