Přejít na hlavní obsah
Sleva 50% všechny plány, omezený čas. Od $2.48/mo
15 min left
AI a strojové učení

Jak naplánovat AI agenty na noční běh na VPS

S Autor: Sajjad 15 min čtení
Schedule AI Agents Overnight: a dark terminal showing a 02:00 timestamp and a green exit code 0 line, next to a clock and a completed job card

Ve dvě hodiny ráno se na VPS, který nikdy neusnul, spustí naplánovaná úloha. Headless běh claude -p zpracuje úlohu z fronty v naklonovaném repozitáři, aniž by se kohokoli na cokoli ptal, a skončí. Ráno na vás čeká commit, zpráva nebo log, který přesně ukazuje, kde se běh zastavil a proč. Nikdo u toho nebyl.

To je něco jiného než nechat terminál otevřený přes noc a doufat, že SSH spojení vydrží. Častým bodem selhání nočního běhu agenta je samotný hostitel: notebook usne, víko se zavře, vypadne síť, nebo aktualizace systému restartuje stroj uprostřed úlohy. Chyby autentizace, chyby API a zaseknutí na oprávnění mohou úlohu stále zabít, ale stále běžící hostitel odstraní ten nejsnadnější způsob selhání.

Tento návod popisuje skutečný mechanismus: headless přepínače, které nabízí každé velké CLI kódovacího agenta, dva způsoby, jak spustit běh podle plánu, a který z nich zvolit, co potřebuje hostitel pod tím, a pojistky, které zabrání tomu, aby běh bez dozoru stál nebo rozbil víc, než byste chtěli později vysvětlovat.

Zkrácená verze

  • Každé velké CLI kódovacího agenta nabízí zdokumentovaný neinteraktivní režim, který provede jeden prompt až do konce a skončí. Claude Code má claude -p, Codex CLI má codex exec, a Gemini CLI má gemini -p. Není to obcházení, je to oficiální funkce.
  • Claude Code má i vlastní plánování: Routines, naplánované úlohy v Desktopu a /loop. Pro některé čtenáře to opravdu stačí a je toho na údržbu méně než u VPS.
  • Pro noční úlohu cron bohatě stačí. Na stroji, který se může restartovat, je lepší výchozí volbou systemd timer, protože Persistent=true zachytí běh, který by cron tiše přeskočil.
  • Samotné CLI je lehké, protože inference běží na API poskytovatele. Dimenzujte VPS podle příkazů, které bude spouštět (testy, buildy, kontejnery, paralelní úlohy), ne podle modelu.
  • Bezpečné nechat plán běžet o samotě dělají teprve pojistky: omezené nástroje, strop na počet tahů a větvení podle návratového kódu. Samotný plán bezpečnostním mechanismem není.

Co budete potřebovat

Než napíšete jediný řádek crontabu nebo unit soubor, připravte si těchto pět věcí:

  • VPS, na který se dostanete přes SSH, s linuxovou distribucí založenou na systemd.
  • CLI agenta nainstalované na tomto VPS: Claude Code, Codex CLI nebo Gemini CLI.
  • Neinteraktivní přihlašovací údaj pro zvolené CLI. Režim bare v Claude Code nečte přihlášení k účtu, takže potřebuje ANTHROPIC_API_KEY v prostředí, nebo apiKeyHelper v nastavení. Běžný běh v režimu print, Codex i Gemini mohou použít i zdokumentované přihlašovací údaje k účtu.
  • Repozitář nebo adresář s úlohou, se kterým bude agent pracovat.
  • Přístup k shellu s oprávněním upravit crontab nebo napsat systemd unit soubor.

Spuštění agenta bez připojené relace

Porovnání headless režimů: Claude Code spouští claude -p s výstupem text, json nebo stream-json, Codex CLI spouští codex exec s JSONL streamem a politikou sandboxu a Gemini CLI spouští gemini -p bez TTY

Každé velké CLI kódovacího agenta nabízí neinteraktivní režim navržený přesně pro tohle. Claude Code přijímá -p, psáno také --print. Codex CLI přijímá codex exec. Gemini CLI přijímá -p, psáno také --prompt. Každý z nich přijme prompt, provede ho až do konce a skončí. Žádná chatovací smyčka, žádný terminál, který je třeba nechat otevřený, nic, k čemu se vracet.

Může Claude Code běžet bez živé relace? Ano. Předání -p spustí prompt v neinteraktivním režimu: Claude Code ho provede až do konce, vypíše výsledek a skončí. Žádná chatovací smyčka ani nic, co je třeba udržovat naživu, a běží na stejném Agent SDK jako interaktivní CLI, podle vlastní dokumentace Anthropicu k headless režimu.

CLINeinteraktivní přepínačChováníStrukturovaný výstup
Claude Code-p / --printProvede prompt až do konce, vypíše výsledek, skončí--output-format nastavené na text, json nebo stream-json
Codex CLIcodex execStreamuje průběh na stderr, konečnou zprávu zapíše na stdout, skončí--json pro proud událostí ve formátu JSONL
Gemini CLI-p / --promptProvede prompt neinteraktivně a skončí--output-format json

Tady jsou nejdůležitější vlastní přepínače Claude Code, protože právě proti nim budete skriptovat. Dva z nich umožní běhu pokračovat, aniž by se zastavil kvůli oprávnění, které nemá kdo v noci udělit: --allowedTools, který předem schválí konkrétní nástroje, a --permission-mode, který nastaví výchozí úroveň pro celý běh. --max-turns omezuje, kolik agentních tahů může běh udělat, než skončí chybou.

--bare přeskakuje hooky, skills, pluginy, MCP servery a projektové instrukce jako CLAUDE.md, kvůli rychlejšímu a předvídatelnějšímu skriptovanému běhu. To také znamená, že každá instrukce, na které úloha závisí, musí být v promptu nebo v příkazu. Režim bare navíc nečte přihlášení k vašemu účtu, takže dokumentace Anthropicu doporučuje nastavit API klíč v prostředí před spuštěním. Claude Code odmítne --bg rovnou, pokud je zkombinován s -p, a odmítne --cloud stejně, když mu k němu dáte popis úlohy. Pojmenuje konflikt a zastaví se, místo aby udělal něco nejednoznačného.

Ukázkové volání, prompt a seznam nástrojů si přizpůsobte své úloze:

claude --bare -p "Review open PRs in this repo and summarize any blockers in NOTES.md" \
  --allowedTools "Bash(gh pr list *),Bash(gh pr view *),Bash(gh pr diff *),Read,Edit" \
  --permission-mode dontAsk \
  --max-turns 8 \
  --max-budget-usd 5.00 \
  --output-format json

Rozpočet a vzory příkazů si přizpůsobte úloze; tento příklad také předpokládá, že autentizace GitHub CLI je pro spouštějící účet už nastavená.

Pokud nastavujete Claude Code na čerstvém VPS a chcete postup, jak ho ověřit na stroji bez prohlížeče, je to popsáno zvlášť v článku jak ověřit Claude Code na headless serveru; krátká verze výše stačí na to, aby naplánovaný běh fungoval.

Režim exec v Codex CLI, popsaný v dokumentace OpenAI k neinteraktivnímu režimu, přijímá --sandbox pro volbu politiky. read-only je výchozí volba, workspace-write umožní agentovi zapisovat ve svém pracovním prostoru a --json změní stdout na strojově zpracovatelný proud událostí místo prostého textu. Vyhněte se danger-full-access u úlohy bez dozoru, pokud proces není izolovaný a to riziko není vědomé.

Headless režim Gemini CLI, zdokumentovaný v vlastní headless dokumentace projektu, se aktivuje automaticky v prostředí bez TTY, nebo explicitně pomocí -p. Skončí konkrétním nenulovým kódem pro obecnou chybu, chybu vstupu nebo dosažení limitu tahů, místo jediného obecného chybového kódu.

Kde má plán bydlet

Ještě před vším tím nastavováním: možná to za vás už plánuje sám dodavatel agenta. Claude Code nabízí tři vestavěné možnosti a jedna z nich může být opravdu vhodnější než VPS, který si spravujete sami.

Cloud (Routines)Naplánovaná úloha v Desktopu/loop
Běží naCloud AnthropicuVáš strojVáš stroj
Stroj musí být zapnutýNení vyžadovánoPožadovánoPožadováno
Vyžaduje otevřenou relaciNení vyžadovánoNení vyžadovánoPožadováno
Minimální interval1 hodina1 minuta1 minuta
Přístup k lokálním souborůmŽádný, běží z čerstvého klonuPlný přístupPlný přístup

Vlastní dokumentace Anthropicu k naplánovaným úlohám to podává jako skutečnou volbu ze tří možností, ne jako hierarchii s VPS na vrcholu. Pokud vaše úloha nepotřebuje lokální stav, snese hodinový spodní limit a používáte jen Claude Code, Routines znamená méně údržby než to, co následuje: Anthropic ho spustí v cloudu z čerstvého klonu, zatímco váš stroj je vypnutý.

/loop stojí za to znát, ale pro tento případ se nehodí, protože vyžaduje otevřenou nečinnou relaci, tedy přesně to omezení, kterého se snažíte zbavit. Tatáž dokumentace zmiňuje i GitHub Actions jako čtvrtou možnost, pro týmy, jejichž spouštěč už žije v CI, ne v plánu svázaném s jedním konkrétním strojem.

VPS ve vlastní správě si své místo zaslouží, když úloha potřebuje plný přístup k lokálnímu souborovému systému a nástrojům, když chcete stejný mechanismus fungující identicky napříč Claude Code, Codex CLI a Gemini CLI, nebo když je interval povolený Routines příliš hrubý. Klasická serverless funkce tu bývá nepohodlná, protože musí obnovit přihlašovací údaje, naklonovat repozitář a stihnout to v rámci limitů běhu platformy. Efemérní CI runner jako GitHub Actions zůstává platnou třetí cestou, pokud je čerstvý checkout při každém běhu přijatelný. Pokud už máte nevyužitý hardware, který běží nepřetržitě, poslouží i stroj v domácí laborce; výměnou je spolehlivost domácí sítě a vzdáleného přístupu místo poskytovatelovy.

Cron, nebo systemd timer?

Cron proti systemd timeru: vlevo jeden řádek crontabu a zmeškaný běh, který se prostě ztratí; vpravo dvojice .service a .timer s dohnáním přes Persistent=true, logováním přes journald a hlídáním překryvů jedinou instancí

Oba nástroje umí spustit stejný příkaz podle stejného plánu, liší se ale v tom, co se stane po restartu stroje, a v tom, kolik nastavení každý z nich stojí:

cronsystemd timer
Náročnost nastaveníJeden řádek crontabuSoubor .timer a soubor .service
Dohnání zmeškaných běhůŽádné, zmeškaný běh je prostě pryčPersistent=true ho spustí, jakmile je systém zpět
ProtokolováníRučně, výstup si přesměrujete samiAutomaticky, zachytává journald
Řazení závislostíNicPlné řazení systemd pomocí After= a Requires=

Obyčejný cron je pro noční úlohu na stroji, který se restartuje jen zřídka, naprosto v pořádku. Háček je v prostředí: cron startuje s minimální PATHhodnotou PATH, do vašeho repozitáře za vás nevstoupí a klidně spustí druhou kopii, zatímco první ještě běží. Cestu k repozitáři, úzce vymezený příkaz agenta a načtení přihlašovacích údajů dejte do chráněného obalového skriptu a pak použijte flock , aby se běhy nepřekrývaly.

# /usr/local/bin/agent-nightly
#!/usr/bin/env bash
set -euo pipefail
export PATH=/usr/local/bin:/usr/bin:/bin
export ANTHROPIC_API_KEY="$(
  cat "$HOME/.config/agent-nightly/anthropic_api_key"
)"
cd /srv/myrepo
exec /usr/local/bin/claude --bare -p \
  "Run the nightly dependency audit and write the findings to NOTES.md" \
  --allowedTools "Bash(npm audit *),Read,Edit" \
  --permission-mode dontAsk \
  --max-turns 8 \
  --max-budget-usd 5.00 \
  --output-format json
# crontab -e
0 2 * * * /usr/bin/flock -n "$HOME/.local/state/agent-runs/nightly.lock" /usr/local/bin/agent-nightly >> "$HOME/.local/state/agent-runs/nightly.log" 2>&1

Jednou vytvořte adresáře pro přihlašovací údaje a logy a pak obalovému skriptu nastavte právo spuštění:

install -d -m 700 \
  "$HOME/.config/agent-nightly" \
  "$HOME/.local/state/agent-runs"
touch "$HOME/.config/agent-nightly/anthropic_api_key"
chmod 600 "$HOME/.config/agent-nightly/anthropic_api_key"
"${EDITOR:-nano}" \
  "$HOME/.config/agent-nightly/anthropic_api_key"
sudo chmod 755 /usr/local/bin/agent-nightly

Do souboru s přihlašovacím údajem vložte jen API klíč. Nedávejte ho přímo do crontabu.

systemd timer vyžaduje víc nastavení a přinese vám dvě věci, které cron nemá: logování přes journald bez ručního přesměrování a Persistent=true. Následující příklad předpokládá, že vyhrazený účet agent-runner vlastní adresář /srv/myrepo. API klíč uložte do souboru přístupného jen rootovi, místo abyste ho vkládali přímo do unitu.

Podle manuál systemd.timer znamená nastavení Persistent=true znamená, že „service unit se spustí okamžitě, pokud by se během doby, kdy byl timer neaktivní, spustil alespoň jednou." Běh, který by proběhl, zatímco se váš VPS restartoval kvůli aktualizaci jádra, se tedy spustí ve chvíli, kdy je stroj zpět, místo aby tiše zmizel až do dalšího naplánovaného termínu.

Vytvořte soubor s přihlašovacím údajem přístupný jen rootovi, který služba používá:

sudo install -d -m 700 /etc/agent-nightly
sudo touch /etc/agent-nightly/anthropic_api_key
sudo chmod 600 /etc/agent-nightly/anthropic_api_key
sudoedit /etc/agent-nightly/anthropic_api_key

Do souboru vložte jen API klíč.

# /etc/systemd/system/agent-nightly.service
[Unit]
Description=Nightly scoped agent run
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=agent-runner
Group=agent-runner
WorkingDirectory=/srv/myrepo
Environment=HOME=/home/agent-runner
Environment=PATH=/usr/local/bin:/usr/bin:/bin
LoadCredential=anthropic_api_key:/etc/agent-nightly/anthropic_api_key
ExecStart=/bin/sh -c 'export ANTHROPIC_API_KEY="$(cat "$CREDENTIALS_DIRECTORY/anthropic_api_key")"; exec /usr/local/bin/claude --bare -p "Run the nightly dependency audit and write the findings to NOTES.md" --allowedTools "Bash(npm audit *),Read,Edit" --permission-mode dontAsk --max-turns 8 --max-budget-usd 5.00 --output-format json'
StandardOutput=journal
StandardError=journal
UMask=0077
# /etc/systemd/system/agent-nightly.timer
[Unit]
Description=Run agent-nightly.service at 2am daily, catching up missed runs

[Timer]
# Uses the VPS's configured local timezone
OnCalendar=*-*-* 02:00:00
Persistent=true
Unit=agent-nightly.service

[Install]
WantedBy=timers.target

Znovu načtěte systemd, povolte timer a jednou hned spusťte službu, aby se problémy s přihlašovacími údaji, oprávněními a cestami ukázaly teď, a ne ve dvě ráno:

sudo systemctl daemon-reload
sudo systemctl enable --now agent-nightly.timer
sudo systemctl start agent-nightly.service
systemctl list-timers agent-nightly.timer
sudo journalctl \
  -u agent-nightly.service \
  -n 100 \
  --no-pager

Persistent=true je rozhodující rozdíl: timer si zmeškaný kalendářní běh zapamatuje, místo aby ho tiše zahodil.

Co VPS opravdu potřebuje

Tohle překvapí ty, kdo to dimenzují poprvé: samotné CLI je lehké, protože inference běží na API poskytovatele. Agent ale pořád může lokálně spouštět buildy, testy, správce balíčků, jazykové servery a kontejnery, takže skutečné minimum určuje zátěž repozitáře.

Pro jednu lehkou naplánovanou úlohu berte jako výchozí bod 1 až 2 vCPU a 2 až 4 GB RAM s NVMe úložištěm. Velké repozitáře, kompilátory, buildy v Dockeru, testovací sady nebo souběžné běhy mohou potřebovat mnohem víc. K navyšování vás nutí nejtěžší lokální příkaz, který agent spustí, ne model za API. Pokud už na tomto VPS provozujete dockerové úlohy a chcete úplnější představu o rozpočtu, dimenzování a zabezpečení build stroje prochází stejný kompromis pro jinou úlohu běžící bez dozoru.

Ještě jedna věc, se kterou počítejte: běh bez dozoru vytváří logy každou noc, ať se něco pokazilo, nebo ne. Přidejte logrotate , pokud cron zapisuje do souboru, a zkontrolujte limity uchovávání v journaldu, místo abyste předpokládali, že výchozí hodnoty sedí na disk vašeho VPS.

Celý přístup stojí na hostiteli, který je ve dvě ráno vzhůru a zůstane tak bez ohledu na to, co dělá váš notebook. Přesně na to je Linux VPS s rootovským přístupem stavěný. Nic ho neuspí a nesdílíte ho s cizími cron úlohami.

Zobrazit Linux plány

Stavte na Linux VPS s root přístupem, NVMe a výkonem AMD EPYC.

Zobrazit Linux plány

Jak zabránit tomu, aby se běh bez dozoru pokazil

Největší rozdíl mezi naplánovaným během, který funguje, a tím, který ne, je v tom, jestli je úloha dost úzce vymezená, aby dojela bez člověka odpovídajícího uprostřed na otázku. Ambiciózní prompty se zaseknou a čekají na rozhodnutí, které nemá kdo udělat; úzké, samostatné úlohy doběhnou a čistě skončí.

Dva přepínače oprávnění existují proto, aby se běh ve dvě ráno nezasekl na dotazu, ale holý přístup k Bash není úzká pojistka: umí skoro všechno, co umí servisní účet. Dejte přednost pravidlům pro konkrétní příkazy, jako je Bash(git status *), zkombinujte je s --permission-mode dontAsk a službu spouštějte pod vyhrazeným ne-rootovským účtem. Počet tahů i útrata mají vlastní stropy: --max-turns omezuje, jak dlouho může agent bloudit, a --max-budget-usd stropuje, kolik může jeden běh utratit za volání API.

Tip: spouštějte s --output-format json a logujte pole total_cost_usd z každého volání. Je to nejčistší háček na sledování, kolik naplánovaný běh reálně stojí za noc, a na upozornění, když jeden běh stojí znatelně víc než ostatní. Těch pět minut na zapojení stojí za to, protože sleduje váš účet, ne abstrakci.

Přestřelení nákladů u běhů bez dozoru není hypotetické. V jednom příspěvku na Hacker Newsuživatel popsal hrubou fakturu z AWS Bedrock ve výši 37 901,73 dolaru z každodenního workflow s kódovacím agentem, kde cachování promptů fungovalo jen částečně a zhruba 6,47 miliardy vstupních tokenů zůstalo bez cache. Stalo se to v jiném stacku, ne v headless režimu Claude Code, ale ukazuje to, proč do plánu patří logování nákladů a tvrdý rozpočet na jeden běh.

Tip: Claude Code končí kódem 0 při úspěchu a nenulovým kódem při selhání. Obalový skript, který kontroluje návratový kód, vám při selhání může poslat upozornění, takže špatná noc vyplave hned druhý den ráno, a ne až za tři dny, kdy se náhodou podíváte.

Přinejmenším spouštějte každou úlohu na vyhrazené větvi nebo v jednorázovém worktree a před sloučením vyžadujte lidskou kontrolu. Přihlašovací údaje s omezeným rozsahem, izolace souborového systému a řízení dosahu škod na úrovni serveru jsou větší téma, které si zaslouží vlastní text, ne odstavec přilepený na konec návodu k plánování.

Bezpečné nechat plán být dělají teprve pojistky: samotný plán bezpečnostním mechanismem není.

Kdy cron přestává stačit

Jeden prompt na timeru nepotřebuje nic víc, než co tu už zaznělo. Tři zřetězené kroky s podmínkou, opakováním a notifikací do Slacku potřebují něco jiného.

Stojí za to znát tři možnosti, každou o stupeň výš z jiného důvodu:

  • Dagu je nejlehčí krok nahoru: samostatné úlohy definované v YAML, se závislostmi ve formě DAG, opakováním a webovým rozhraním, kde vidíte, co proběhlo.
  • n8n sedí nejlépe tam, kde je běh agenta jen jedním uzlem mezi několika integracemi a notifikacemi, ne celým workflow.
  • Kestra je z těch tří nejtěžší, stavěný na orchestraci datových a infrastrukturních pipeline, a je správnou odpovědí tehdy, když je plánování agenta součástí větší pipeline, ne jejím smyslem.

Pro čtenáře, který spouští jeden noční prompt, jsou všechny tři přehnané, a stojí za to to říct na rovinu, místo abychom vás uvrtali do těžšího nastavení, než potřebujete. Pokud řetěz kroků nakonec jeden z nich opravdu ospravedlní, Dagu, n8n, a Kestra se nasazují jedním kliknutím, což je opravdové pohodlí právě ve chvíli, kdy zvažujete, jestli se ta námaha s nastavením vyplatí.

Frameworky pro orchestraci více agentů jako LangChain nebo CrewAI jsou úplně jiné téma: stavění agentních systémů, ne plánování už existujícího CLI.

Časté dotazy

Může Claude Code běžet bez živé relace?

Ano. Předání -p spustí prompt v neinteraktivním režimu: Claude Code ho provede až do konce, vypíše výsledek a skončí, bez chatovací smyčky a bez relace, kterou by bylo třeba držet otevřenou.

Potřebuji VPS, když má Claude Code už Routines?

Ne vždy. Routines běží v cloudu Anthropicu i s vypnutým strojem a startuje z čerstvého klonu, ale nedostane se k souborům, které existují jen na vašem počítači, a má minimální interval jednu hodinu. VPS ve vlastní správě si své místo zaslouží tehdy, když úloha potřebuje lokální soubory, libovolné intervaly nebo mechanismus fungující stejně napříč CLI více dodavatelů.

Mám pro naplánovaného agenta použít cron, nebo systemd timer?

systemd timer, pokud se VPS někdy restartuje kvůli údržbě. Persistent=true spustí úlohu, která měla proběhnout během výpadku, jakmile je systém zpět, a cron pro to nemá obdobu. Pro noční úlohu na stroji, který běží pořád, cron stačí.

Kolik paměti potřebuje naplánovaný AI agent na VPS?

Začněte zhruba na 1 až 2 vCPU a 2 až 4 GB RAM pro jednu lehkou naplánovanou úlohu a pak dimenzujte podle nejtěžšího lokálního příkazu, který agent spustí. Buildy, testy, Docker, velké repozitáře a souběžné běhy váží mnohem víc než vzdálená inference modelu.

Mění plánované spouštění agenta způsob účtování?

Plánování nevytváří samostatný režim účtování. Claude Code -p může použít přihlašovací údaje předplatného nebo API klíč, ale --bare ignoruje přihlášení k předplatnému, takže potřebuje ANTHROPIC_API_KEY v prostředí, nebo apiKeyHelper v nastavení. Codex a Gemini se řídí tím, jakou metodu ověření jste pro jejich CLI nastavili. Protože se ceny a podmínky používání rychle mění, při zavádění si ověřte aktuální ceník poskytovatele a vlastní data o spotřebě. U běhů Claude Code přes API si navíc můžete logovat pole total_cost_usd z JSON výstupu.

Sdílet

Diskuse

Komentáře

Přihlaste se a zapojte se do diskuse.

Další z blogu

Pokračuj ve čtení.

Hotov k nasazení? Od 2,48 $/měs.

Nezávislý cloud od roku 2008. AMD EPYC, NVMe, 40 Gbps. Vrácení peněz do 14 dnů.