Агенттер каскады: терминал қазір жұмыс істейтінін өзі таңдайды
Claude ішінара істен шығып, кейбір модельдер жауап бермей қалғанда Gemini-ге ауысып көрдім — сонда қосалқы нұсқам әлдеқашан бұзылғанын байқадым. Міне, шынымен төтеп беретінін қалай құру керек.
TL;DR
agent деп аталатын bash іске қосқышы, ол іске қосылмас бұрын ең жақсы жұмыс істейтін AI CLI-ды таңдайды. Ол екі ось бойынша төмендейді: алдымен модель (Opus → Sonnet, Anthropic ішінде қалып), сосын транспорт, тек содан кейін провайдер. Әрбір зонд нақты API шақыруын жасайды, өйткені модель тізімдері өтірік айтады. Күзетші төменгі сатыларды екі сағат сайын тексеріп, Telegram арқылы хабарлайды.
$ agent --status
OK claude / claude-opus-5 api.anthropic.com reachable, claude-opus-5 answered
OK claude / claude-sonnet-5 api.anthropic.com reachable, claude-sonnet-5 answered
OK claude-proxy / claude-opus-5 claude-opus-5 answered
OK claude-proxy / claude-sonnet-5 claude-sonnet-5 answered
OK agy antigravity answered on Gemini 3.6 Flash (Low)
OK gemini localhost:8317 answered for gemini-3.1-pro-lowМәселе
Claude қолжетімсіз болғанда, терминалымның жұмысын жалғастырғанын қалаймын. Аңғал нұсқасы — «Claude құласа, Gemini іске қос», мен дәл солай бапталған деп ойладым. Бірақ қызықты ақаулар — үзілістер емес. Ең жиісі: Opus лимитін таусады, ал Sonnet жақсы жауап береді. Мұнда басқа провайдерге секіру мағынасыз.
Демек, нағыз сақтық нұсқа провайдер бойынша төмендеуден бұрын модель бойынша төмендеуі керек. Әрі ол қай сатының шынымен тірі екенін білуі тиіс — ең қиыны осы болды.
Бес айлық өтірік
Бірдеңе жазбас бұрын бұрыннан барын тексердім. Прокси авторизация каталогы бүкіл оқиғаны екі уақыт белгісімен айтып берді:
claude-newiqa@gmail.com.json — бүгін жаңартылған, 06:41 · gemini-newiqa@gmail.com-….json — соңғы рет 27 наурызда
Claude токені күн сайын жаңарып тұрды. Gemini токені бес ай қозғалмады. Менің тексеруім тек claude-*.json-ға қарайтын, сондықтан ешкім байқамады. Сақтық нұсқа көктемнен бері әшекей болатын — бос бөлменің үстіндегі жасыл шам. Ешкім шынымен шақырмайтын сақтық нұсқа — сақтық нұсқа емес.
Неге gateway мұны шешпейді
Айқын қадам — жергілікті LLM gateway (Bifrost, LiteLLM) конфигурацияда провайдер ауыстыруымен. Менде біреуі жұмыс істеп тұр (CLIProxyAPI), екіншісі тек тағы бір демон қосар еді.
Маңыздысы: gateway нақты міндетті орындай алмайды. API деңгейіндегі ауысу сол клиенттің астындағы модельді алмастыруды білдіреді. Claude Code-қа аударма қабаты арқылы Gemini жауабын берсеңіз, ол tool-use пен ағындық шығаруда сынады. Сақтық нұсқа CLI-ды ауыстыруы керек, оның артындағы модельді емес.
Алты саты, екі ось
Провайдер мен модель тәуелсіз істен шығады, сондықтан баспалдақ оларды кезектестіреді. Әр саты нақты бірдеңе береді, ал төмен түсу бағасы анық жазылған:
| Rung | What it survives | Cost of getting there |
|---|---|---|
| claude + opus | nothing — this is the happy path | — |
| claude + sonnet | Opus capped or overloaded | weaker model, same session shape |
| claude-proxy + opus | stale local login, broken CLI auth | separate OAuth token |
| claude-proxy + sonnet | both of the above at once | weaker model via proxy |
| agy | Anthropic outage / exhausted plan | different vendor, different CLI |
| gemini | agy itself broken | different CLI again, shares agy's quota |
Кодта саты — үштік: бекенд, зондтауға арналған модель, іске қосуға арналған модель. Жоғарғы сатыдағы бос модель көрінгеннен маңыздырақ: --model жібермеу профильдегі opus[1m] мен оның 1M контекстін сақтайды.
# Each rung: backend | model to probe | model to run with
# An empty run-model means "let the CLI use its configured default", which keeps
# the profile's opus[1m] (and its 1M context) instead of downgrading it to plain
# opus just to name it explicitly.
RUNGS=(
"claude|$AGENT_OPUS_MODEL|"
"claude|$AGENT_SONNET_MODEL|sonnet"
"claude-proxy|$AGENT_OPUS_MODEL|$AGENT_OPUS_MODEL"
"claude-proxy|$AGENT_SONNET_MODEL|$AGENT_SONNET_MODEL"
"agy||"
"gemini||"
)Жоғарғы саты қолжетімсіз болғанда, төмендеу үнсіз емес, жарияланып жасалады — төмендетілген сессияны қалыпты сессиямен шатастыруға болмайды:
$ agent -p "explain this bug"
[agent] Claude Code (claude-opus-5) unavailable — claude-opus-5 unavailable: {"error":...}
[agent] using Claude Code (claude-sonnet-5)
# ...the session continues on Sonnet, inside Anthropic, with no vendor switch.Модель тізімдері өтірік айтады
Бірінші түйсік — арзан зондтау: gateway-ден /v1/models сұрап, модельдің бар-жоғын тексеру. Бұл түкке тұрмайды. Менің проксиім әр шақыру auth_unavailable қайтарып тұрған бүкіл уақытта gemini-* тізімін көрсетіп тұрды.
Модель күйі де солай. Ешбір тізім эндпойнті Opus дәл қазір лимитте екенін айтпайды. Мұны тек нақты сұраныс көрсетеді — 429 не 529:
# Real /v1/messages call for ONE model. This is what distinguishes "Opus is
# capped" from "Anthropic is down" — no model list can tell you that.
probe_model() {
local m="$1" body
body=$(curl -sS --max-time "$PROBE_TIMEOUT" \
"$AGENT_PROXY_URL/v1/messages" \
-H "Authorization: Bearer $AGENT_PROXY_KEY" \
-H 'content-type: application/json' \
-d "{\"model\":\"$m\",\"max_tokens\":1,\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}]}")
case "$body" in
*'"type":"message"'*) REASON="$m answered"; return 0 ;;
esac
REASON="$m unavailable: $(printf '%s' "$body" | tr -d '\n' | cut -c1-140)"
return 1
}Ресми сатылардың модель қолжетімділігі проксиден алынады, ол сол Anthropic аккаунтын алдыға шығарады. Бүкіл алдын ала тексеру 7 токен және шамамен 1,3 секунд деп өлшенді.
Екі тор, біреу емес
Алдын ала зонд бәрін ұстамайды. Егер квота зонд пен іске қосу арасында бітсе, зонд дұрыс болды әрі пайдасыз қалды. Сондықтан екінші тор бар: шығу коды мен өткен уақыт.
start=$SECONDS
run_rung "$backend" "$rmodel" "$@"
rc=$?
elapsed=$(( SECONDS - start ))
# Clean exit, or the user interrupted it — either way, done.
if [ $rc -eq 0 ] || [ $rc -eq 130 ]; then
exit $rc
fi
# Survived long enough to have been genuinely used: a real error, not a rung
# that never started. Do not silently rerun the work somewhere else.
if [ $elapsed -ge $FASTFAIL_SECONDS ]; then
exit $rc
fi
warn "$(label "$backend" "$pmodel") exited $rc after ${elapsed}s — treating as unavailable"25 секундтық шек пайымды кодтайды. Бірден өлген саты шын мәнінде іске қосылмаған. Ал минуттар бойы жұмыс істеп барып құлаған саты шынымен жұмыс істеді, және сол жұмысты үнсіз басқа провайдерде қайталау қатені көрсетуден нашар болар еді.
Күзетші және оның ішіндегі тұзақ
Іске қосқыш мен оны іске қосқанда ғана жұмыс істейді, сондықтан саты сессиялар арасында шіри алады. Менің денсаулық дроидіме (launchd, екі сағат сайын, Telegram) енгізілген тексеру сол зонд кодын шақырады. Бірінші нұсқада дәл осы мақала туралы қате болды: ол бірінші жасыл сатыда сәттілік қайтарды.
# Healthy — every non-Anthropic rung answers
$ agent --check-fallback
all provider-independent fallbacks OK: agy — antigravity answered...; gemini — ...
rc=0
# One rung rotted while the other still works. This is the case that used to
# pass silently, and the whole reason the check exists.
$ GEMINI_API_KEY=broken agent --check-fallback
DEGRADED: still covered by agy — antigravity answered on Gemini 3.6 Flash (Low)
but a rung died: gemini — gemini call failed: {"error":"Invalid API key"}
rc=1Бұл қате, өйткені Anthropic емес екі саты бөлек токендерді ұстайды — Antigravity CLI өзінікін, Gemini сатысы прокси токенін. Біреуі шіриді, екіншісі мінсіз көрінеді. Сондықтан тексеру барлық сатыны зондтап, DEGRADED-ті де қате деп санайды.
Жазып алуға тұрарлық үш қате
Әрқайсысы бұзылған механизмнің үстінен жасыл сигнал берді — бір күнде үш рет қайталанған бір ақау түрі:
- Зонд мен қолданбайтын модельді тексерді. Мен
gemini-3.1-pro-previewзондтадым, ал CLIgemini-3.1-pro-low-ға бапталған еді. Олар әртүрлі провайдерге шешіледі, сондықтан мен жоқ «ескірген токенді» диагноздадым. Зонд нақты клиенттің дәл сол жолымен жүруі керек. - Үнсіз бос айнымалы. Прокси YAML кілтін
awkжәне тырнақша үшін\x27арқылы талдау BSD awk-та бос жол берді — қатесіз, ескертусіз. Тексеру бәрібір өтті.awk -v q="'"арқылы түзетілді. - Зонд өтті, ал шынайы іске қосу құлады. Gemini эндпойнтіне
curlзонды 200 қайтарды, бірақ нағызgemini -pіске қосылудан бас тартты: headless режимі сенімсіз каталогтарда бұғатталады.
Қалай қолдану
agent терсеңіз, әдеттегі Claude Code тәжірибесімен ең жақсы қолжетімді сатыны аласыз. Айқын таңдау зондтауды мүлдем аттап кетеді:
agent # auto-pick the best live rung
agent --use gemini # force a backend
agent --use claude:sonnet # force a backend AND a model
agent --use claude-proxy:opus # opus/sonnet/haiku map to full ids per backend
agent --list # backend names
agent --status # probe every rung and report
agent --check-fallback # exit 1 if a non-Anthropic rung is missing
agent -p "..." # flags pass straight through to the chosen CLIҚорытынды
Мұндағы инженерия қарапайым: bash скрипті, бірнеше curl шақыруы, реттелген массив. Күш салуды талап еткені — өз тексерулеріме сенбеу. Үш рет мен астындағысы бұзылып тұрғанда сәттілік туралы хабарлайтын нәрсе құрдым — әр жолы кінәлі сол арзан әрі жылдам зонд болды.
Төзімділік — сіз баптаған бекендтер тізімі емес. Ол тізімнің әлі де шын екенін тексеретін нәрсенің бар-жоғы. Менде қағаз жүзінде алты саты болды, ал бес ай бойы шынайысы біреу ғана.
Дереккөздер
- Claude Code Documentation — headless mode,
ANTHROPIC_BASE_URL, model flags - CLIProxyAPI — the local multi-provider gateway behind the proxy rungs
- Gemini CLI — the last rung, and its trusted-folders behaviour
- Apple Developer — launchd jobs, used by the watchdog
Қате байқадыңыз ба?
Осы мақалада қате факт, олқы аударма немесе жалған естілетін нәрсе бар ма? Маған жазыңыз — өз тіліңізде.