触发条件

  • Antigravity CLI(agy,Google 的 Gemini 编码代理)以任何模式(交互/--print 无头)发起会话。
  • 出口流量经代理,且代理出口落在 Gemini API 不支持的地区(中国大陆全境,以及部分被拉黑的机场 IP 段)。
  • 相关 API 端点:daily-cloudcode-pa.googleapis.com(cloudcode-pa.googleapis.com)。

症状与报错特征

  • CLI 前台只给一句含糊的:Error: Agent execution terminated due to error.
  • 必须加 --log-file=/tmp/agy.log 才能看到真错:
    FAILED_PRECONDITION (code 400): User location is not supported for the API use.
  • 特征:1-2 秒内立即失败(0 tokens),不是超时——超时是代理/节点层问题,秒拒才是 Google 侧主动拒绝。
  • 登录态完好(keyring 认证正常),与登录无关。

排查步骤

  1. 确认出口 IP 与地区: curl -x http://127.0.0.1:<port> https://www.cloudflare.com/cdn-cgi/trace 看 loc=。
  2. 对照测试: 同一命令换已知可用出口(如 7890 的 SG 节点)跑 agy --print=... --output-format json,能成功就坐实地区问题。
  3. 逐节点扫描: 换一个出口 → curl 验证 loc= → 跑 agy --print 测试,记录哪个地区可用。

根因

  • Gemini API 按 Google 可见出口 IP 的地区判定,而按 2026-08 实测(机场 moeshark/dy.moeazusa.app):

    • 香港 (HK) 直接拒绝。
    • 机场节点即使 loc 显示 US/JP/TW,机房 IP 段仍可能被 Google 拉黑(该机场 AS215355 Alice Network 的美国段、日本段、台湾段全被拒)。
    • 新加坡 (SG) 段可用,且 app anytls 与普通 anytls 的 SG 节点出口是同一 IP(188.253.5.73),agy 都能过。
  • 所以"换节点"不保证可用,每个节点都要实测,loc= 只是必要条件不是充分条件。
  • 判断"被 Google 拉黑"vs"节点本身坏了":节点能正常出网(curl cloudflare trace 通、google.com 302)但唯独 Gemini API 拒 → IP 段被 Google 风控。

解决

  • 把代理出口切到实测可用的节点(本机:Vortex 7897 → app anytls 新加坡 1)。
  • fallback:agyy 临时改走 7890(Clash Verge,SG 出口)。

下次如何识别

  • agy 秒失败(1-2s, 0 tokens)+ 前台报错模糊 → 直接 --log-file 拿真错。
  • 看到 User location is not supported → 查代理出口 loc=,但别信 loc,要实测。
  • 同一机场不同地区可用性不同;同一地区不同机房可用性也不同。

复现记录:2026-09-21(tx 服务器 AstrBot 链路)

同一根因经由另一条链路再次出现,排查路径值得记住。

  • 症状:AstrBot 回复用户时报 LLM 响应错误: BadRequestError: Error code: 400 - {'message': 'User location is not supported for the API use.'}。
  • 链路:AstrBot → new-api(127.0.0.1:3000)渠道 CPA-agy → cli-proxy-api(127.0.0.1:8317)→ 经 HTTP_PROXY=127.0.0.1:7890 的 mihomo → daily-cloudcode-pa.googleapis.com。
  • 定位手段:

    1. 用行内日志拿到真实报错:sudo journalctl -u astrbot.service 与 new-api 的 logs/*.log 均记录 channel error (channel #2, status code: 400)。
    2. 查 new-api 渠道表定位上游:sqlite3 projects/newapi/data/one-api.db → select id,name,base_url from channels。
    3. 确认代理确在链路上:curl http://127.0.0.1:9090/connections 看 chains 含 PROXY;ss -tnp 看到 cli-proxy-api 连着 127.0.0.1:7890。
  • 关键反证:loadCodeAssist 走台湾出口能成功,只有 generateContent 被拒 → 不是 IP 被封,而是 Gemini 对生成接口单独做地区判定。
  • 实测矩阵(同一 token、同一接口,只换出口):

    出口IP结果
    anytls 台湾 1–4103.127.218.42–45400
    anytls 美国 131.22.111.60400
    anytls 日本 1161.248.62.4400
    anytls 新加坡 1–4188.253.4.9 / 188.253.5.x200
  • 解决:curl -X PUT http://127.0.0.1:9090/proxies/PROXY -d '{"name":"anytls 新加坡 1"}',链路立即恢复。
  • 教训:mihomo 的 PROXY selector 是手动固定值,不会自己漂移;tg 排查时应先读 GET /proxies 的 now 字段确认当前出口,再对照上表判断——不要凭印象猜是哪个节点。

相关概念


本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps