⚠️ 警告:本文含“高危”操作,阅读前请确保你的 Gemini CLI 已经装好,并且你拥有至少两个 Google 账号(大号和小号)。
😫 崩溃瞬间:当灵感撞上 429
作为一个被 AI 惯坏的工程师,我现在写代码基本是这样的: “Gemini,帮我重构这个函数” -> “Gemini,写个单元测试” -> “Gemini,这行报错是什么鬼?”
正当我代码写得起飞,多巴胺疯狂分泌的时候,终端突然冷冰冰地甩给我一行字:
Error: 429 Quota exceeded for the current user.
那一刻,我感觉像是刚要冲刺百米终点,裤衩突然松了。绝望,太绝望了。
为了继续写代码,我不得不:
gemini auth logout(含泪登出)gemini auth login(打开浏览器,扫码,切小号,授权...)- 回来重新输入刚才断掉的命令。
这哪里是写代码?这简直是在做“账号切换耐力测试”!这种“断流”感,对于心流状态简直是毁灭性打击。
于是我怒了。DeepSeek 都在教我们怎么榨干算力,我居然还在手动切号? 必须搞个自动化的!
🧠 思路:给 CLI 装个“备胎”系统
只要稍微扒一下 Gemini CLI 的底裤(~/.gemini/ 目录),你就会发现它的鉴权机制单纯得可爱:
- 凭证文件:
~/.gemini/oauth_creds.json - 账号信息:
~/.gemini/google_accounts.json
这不就简单了吗? 我只要提前把“大号”和“小号”的这两个文件偷出来存好,等到大号欠费时,用脚本毫秒级把小号的文件覆盖回去,CLI 不就以为我是尊贵的满血会员了吗?
说干就干。我设计了一套 “主备容灾系统 (Active-Passive Failover)”。
🛠️ 第一步:造一个“身份管理器”
我们需要一个脚本来负责“物理换卡”。这相当于给你的 CLI 装了一个双卡双待的卡槽。
在 ~/Documents/AI_Common/docs/scripts/ 下创建一个 gemini_manager.sh:
#!/bin/bash
# gemini_manager.sh - 你的身份管家
# 你的配置文件仓库(建议放在 dotfiles 或文档里)
PROFILE_STORE="$HOME/Documents/AI_Common/docs/secrets/gemini_profiles"
GEMINI_DIR="$HOME/.gemini"
mkdir -p "$PROFILE_STORE"
# 💾 存档技能:把当前账号存起来
function save_profile() {
NAME=$1
TARGET="$PROFILE_STORE/$NAME"
mkdir -p "$TARGET"
# 核心动作:把凭证“偷”走备份
cp "$GEMINI_DIR/oauth_creds.json" "$TARGET/" 2>/dev/null
cp "$GEMINI_DIR/google_accounts.json" "$TARGET/" 2>/dev/null
echo "✅ 账号已存档为: '$NAME'"
}
# 🔄 读档技能:切换到指定账号
function switch_profile() {
NAME=$1
TARGET="$PROFILE_STORE/$NAME"
if [ ! -d "$TARGET" ]; then
echo "❌ 找不到账号存档 '$NAME',你是不是没存过?"
return 1
fi
echo "🔄 正在切换身份到: '$NAME'..."
# 核心动作:覆盖回去
cp "$TARGET/oauth_creds.json" "$GEMINI_DIR/" 2>/dev/null
cp "$TARGET/google_accounts.json" "$GEMINI_DIR/" 2>/dev/null
echo "🎉 切换成功!现在你是 '$NAME' 了。"
}
# 🧐 鉴定技能:我现在到底是谁?
function check_status() {
# 通过对比文件哈希值来确认身份
CURRENT_SUM=$(shasum "$GEMINI_DIR/oauth_creds.json" 2>/dev/null | awk '{print $1}')
FOUND=0
for profile in "$PROFILE_STORE"/*; do
if [ -d "$profile" ]; then
P_NAME=$(basename "$profile")
P_SUM=$(shasum "$profile/oauth_creds.json" 2>/dev/null | awk '{print $1}')
if [ "$CURRENT_SUM" == "$P_SUM" ]; then
echo "✅ 当前身份: $P_NAME"
FOUND=1
break
fi
fi
done
if [ "$FOUND" -eq 0 ]; then echo "⚠️ 未知身份 (未存档)"; fi
}
# 简单的路由
case $1 in
save) save_profile "$2" ;;
switch) switch_profile "$2" ;;
status) check_status ;;
*) echo "Usage: $0 {save|switch|status} [name]" ;;
esac
🚀 第二步:终极黑科技 "Auto-Failover Wrapper"
我要封装一个 g 命令。它平时就是普通的 Gemini,但在检测到报错时,它会光速切号并自动重试。
创建 g.sh:
#!/bin/bash
# g.sh - 永不欠费的 Gemini 包装器
MANAGER="$HOME/Documents/AI_Common/docs/scripts/gemini_manager.sh"
# 1. 显性化:告诉自己现在在用哪个号
CURRENT_PROFILE=$($MANAGER status | grep "当前身份" | awk '{print $NF}')
echo -e "\033[1;34m[Gemini CLI]\033[0m Account: \033[1;32m${CURRENT_PROFILE:-UNKNOWN}\033[0m"
# 2. 核心逻辑:拦截报错
if [[ "$*" == *"-p"* ]] || [[ "$*" == *"--prompt"* ]]; then
TMP_LOG=$(mktemp)
gemini "$@" 2>&1 | tee "$TMP_LOG"
if grep -iqE "Quota exceeded|429|Too Many Requests" "$TMP_LOG"; then
echo -e "\n\033[1;33m⚠️ 检测到额度耗尽!启动自动故障转移...\033[0m"
if [ "$CURRENT_PROFILE" == "primary" ]; then
$MANAGER switch secondary
else
$MANAGER switch primary
fi
echo -e "\033[1;32m🔄 已重试...\033[0m\n"
gemini "$@"
fi
rm "$TMP_LOG"
else
gemini "$@"
fi
🎉 最终效果:爽到飞起
把这个脚本 alias g='.../g.sh' 后,我的开发体验发生了质变。
全程无人工干预! 我甚至不用把手从键盘上拿开。
这才是 AI 时代该有的工作流啊兄弟们!把重复的劳动交给脚本,把脑子留给架构。
写在最后: 觉得有用的话,点赞、收藏、转发三连,别让你的 Gemini 饿着!🚀