ตอนตีสอง งานที่ตั้งเวลาไว้เริ่มทำงานบน VPS ที่ไม่เคยหลับ การรันแบบ headless ด้วย claude -p จะทำงานที่รออยู่ในคิวภายในรีโปที่โคลนไว้โดยไม่ถามใครเลย แล้วจบการทำงาน พอคุณมาดูตอนเช้าก็จะเจอ commit รออยู่ หรือรายงาน หรือ log ที่บอกชัดว่าหยุดตรงไหนและเพราะอะไร ไม่มีใครนั่งเฝ้าเลย
นี่ต่างจากการเปิดเทอร์มินัลทิ้งไว้ทั้งคืนแล้วภาวนาให้การเชื่อมต่อ SSH อยู่รอด จุดล้มเหลวที่พบบ่อยของการรัน agent ข้ามคืนคือตัวเครื่องโฮสต์เอง เช่น โน้ตบุ๊กเข้าสู่โหมดสลีป ฝาปิดลง เน็ตหลุด หรืออัปเดตระบบปฏิบัติการรีบูตเครื่องกลางคัน ความล้มเหลวด้านการยืนยันตัวตน ข้อผิดพลาดของ API และการค้างรอสิทธิ์ยังทำให้งานล้มได้อยู่ แต่โฮสต์ที่เปิดตลอดเวลาจะตัดสาเหตุที่ง่ายที่สุดออกไป
คู่มือนี้พูดถึงกลไกจริง ๆ ได้แก่ แฟล็ก headless ที่ CLI ของ coding agent รายใหญ่แต่ละตัวมีมาให้ สองวิธีในการสั่งรันตามตารางเวลาและควรเลือกแบบไหน โฮสต์ที่อยู่ข้างใต้ต้องมีอะไรบ้าง และการ์ดเรลที่กันไม่ให้การรันแบบไม่มีคนดูแลใช้เงินหรือพังมากกว่าที่คุณอยากต้องมาอธิบายทีหลัง
เวอร์ชันสั้น
- CLI ของ coding agent รายใหญ่ทุกตัวมีโหมดไม่โต้ตอบที่มีเอกสารกำกับ ซึ่งรันพรอมต์เดียวจนจบแล้วออก Claude Code ใช้
claude -p, Codex CLI ใช้codex exec, และ Gemini CLI ใช้gemini -p. นี่ไม่ใช่ทางเลี่ยง แต่เป็นฟีเจอร์อย่างเป็นทางการ - Claude Code ยังมีระบบตั้งเวลาของตัวเองด้วย ได้แก่ Routines, งานตั้งเวลาบน Desktop และ
/loop. สำหรับผู้อ่านบางคนแค่นี้ก็พอจริง ๆ และดูแลน้อยกว่าการมี VPS - cron ใช้ได้ดีสำหรับงานรายคืน แต่ systemd timer เป็นตัวเลือกตั้งต้นที่ดีกว่าบนเครื่องที่อาจรีบูต เพราะ
Persistent=trueจะไล่ตามการรันที่ cron จะข้ามไปเงียบ ๆ - ตัว CLI เองเบามาก เพราะการอนุมานเกิดขึ้นบน API ของผู้ให้บริการ ให้เลือกสเปก VPS ตามคำสั่งที่มันจะรัน (เทส บิลด์ คอนเทนเนอร์ งานขนาน) ไม่ใช่ตามโมเดล
- สิ่งที่ทำให้ปล่อยตารางเวลาไว้เองได้อย่างปลอดภัยคือการ์ดเรล ได้แก่ การจำกัดเครื่องมือ การกำหนดเพดานจำนวนเทิร์น และการแตกเงื่อนไขตาม exit code ตัวตารางเวลาเองไม่ใช่กลไกความปลอดภัย
สิ่งที่คุณต้องมี
เตรียมห้าอย่างนี้ให้พร้อมก่อนจะเขียน crontab สักบรรทัดหรือไฟล์ unit สักไฟล์:
- VPS ที่คุณ SSH เข้าได้ และรันดิสโทร Linux ที่ใช้ systemd
- CLI ของ agent ที่ติดตั้งบน VPS นั้น ได้แก่ Claude Code, Codex CLI หรือ Gemini CLI
- ข้อมูลรับรองแบบไม่โต้ตอบสำหรับ CLI ที่คุณเลือก โหมด bare ของ Claude Code ไม่อ่านการล็อกอินบัญชี จึงต้องมี
ANTHROPIC_API_KEYในสภาพแวดล้อม หรือไม่ก็apiKeyHelperในไฟล์ตั้งค่า ส่วนการรันโหมด print แบบปกติ รวมถึง Codex และ Gemini ก็ใช้ข้อมูลล็อกอินบัญชีตามที่เอกสารระบุได้เช่นกัน - รีโปหรือไดเรกทอรีงานที่ agent จะทำงานด้วย
- สิทธิ์เข้าถึงเชลล์ที่แก้ crontab หรือเขียนไฟล์ unit ของ systemd ได้
รัน Agent โดยไม่ต้องมีเซสชันเปิดอยู่
CLI ของ coding agent รายใหญ่ทุกตัวมีโหมดไม่โต้ตอบที่ออกแบบมาเพื่อสิ่งนี้โดยเฉพาะ Claude Code รับ -p, หรือเขียนเต็มว่า --print. Codex CLI รับ codex exec. Gemini CLI รับ -p, หรือเขียนเต็มว่า --prompt. แต่ละตัวรับพรอมต์ รันจนจบ แล้วออก ไม่มีลูปแชต ไม่ต้องเปิดเทอร์มินัลค้างไว้ ไม่มีอะไรให้ต้องกลับไปเชื่อมต่อ
Claude Code รันโดยไม่มีเซสชันเปิดอยู่ได้ไหม? ได้ การส่ง -p จะรันพรอมต์ในโหมดไม่โต้ตอบ Claude Code จะทำจนจบ พิมพ์ผลลัพธ์ แล้วออก ไม่มีลูปแชตและไม่มีอะไรต้องคอยประคอง อีกทั้งยังทำงานบน Agent SDK ตัวเดียวกับที่ขับเคลื่อน CLI แบบโต้ตอบ อ้างอิงจาก เอกสารโหมด headless ของ Anthropic เอง.
| CLI | แฟล็กแบบไม่โต้ตอบ | พฤติกรรม | เอาต์พุตแบบมีโครงสร้าง |
|---|---|---|---|
| Claude Code | -p / --print | รันพรอมต์จนจบ พิมพ์ผลลัพธ์ แล้วออก | --output-format ตั้งค่าเป็น text, json หรือ stream-json |
| Codex CLI | codex exec | สตรีมความคืบหน้าไปที่ stderr เขียนข้อความสุดท้ายลง stdout แล้วออก | --json สำหรับสตรีมอีเวนต์แบบ JSONL |
| Gemini CLI | -p / --prompt | รันพรอมต์แบบไม่โต้ตอบ แล้วออก | --output-format json |
ตรงนี้แฟล็กของ Claude Code เองสำคัญที่สุด เพราะเป็นสิ่งที่คุณจะเขียนสคริปต์ใช้จริง สองตัวในนั้นช่วยให้การรันเดินหน้าต่อได้โดยไม่หยุดรอขอสิทธิ์ที่ไม่มีใครตื่นมาอนุมัติ: --allowedToolsซึ่งอนุมัติเครื่องมือที่ระบุไว้ล่วงหน้า และ --permission-modeซึ่งกำหนดระดับพื้นฐานให้ทั้งการรัน --max-turns จำกัดจำนวนเทิร์นที่การรันหนึ่งครั้งใช้ได้ ก่อนจะจบด้วยข้อผิดพลาด
--bare จะข้าม hook, skill, ปลั๊กอิน, เซิร์ฟเวอร์ MCP และคำสั่งระดับโปรเจกต์อย่าง CLAUDE.mdเพื่อให้การรันแบบสคริปต์เร็วขึ้นและคาดเดาได้มากขึ้น นั่นแปลว่าทุกคำสั่งที่งานต้องพึ่งพาต้องอยู่ในพรอมต์หรือในคำสั่งเอง อีกทั้งโหมด bare ยังไม่อ่านการล็อกอินบัญชีของคุณ ดังนั้น เอกสารของ Anthropic บอกให้ตั้งค่า API key ไว้ในสภาพแวดล้อม ก่อนจะรัน Claude Code จะปฏิเสธ --bg ทันทีเมื่อใช้ร่วมกับ -p, และปฏิเสธ --cloud แบบเดียวกันเมื่อคุณใส่คำอธิบายงานให้ มันจะบอกว่าอะไรขัดกันแล้วหยุด แทนที่จะทำอะไรกำกวม
ตัวอย่างคำสั่งจริง ปรับพรอมต์และรายการเครื่องมือให้เข้ากับงานของคุณ:
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
ปรับงบประมาณและรูปแบบคำสั่งให้เข้ากับงาน ตัวอย่างนี้ยังถือว่าบัญชีที่รันได้ตั้งค่าการยืนยันตัวตนของ GitHub CLI ไว้แล้ว
ถ้าคุณกำลังตั้ง Claude Code บน VPS ใหม่ และอยากได้ขั้นตอนการยืนยันตัวตนบนเครื่องที่ไม่มีเบราว์เซอร์ เรื่องนั้นมีอธิบายแยกไว้ใน วิธียืนยันตัวตน Claude Code บนเซิร์ฟเวอร์แบบ headless; เวอร์ชันสั้นด้านบนก็เพียงพอที่จะทำให้การรันตามตารางเวลาใช้งานได้แล้ว
โหมด exec ของ Codex CLI ซึ่งอธิบายไว้ใน เอกสารโหมดไม่โต้ตอบของ OpenAI, รับ --sandbox เพื่อเลือกนโยบาย read-only คือค่าเริ่มต้น workspace-write ให้ agent เขียนไฟล์ในเวิร์กสเปซของตัวเองได้ ส่วน --json จะเปลี่ยน stdout ให้เป็นสตรีมอีเวนต์ที่เครื่องอ่านได้แทนข้อความธรรมดา หลีกเลี่ยง danger-full-access ในงานที่ไม่มีคนดูแล เว้นแต่กระบวนการถูกแยกออกมาแล้วและคุณยอมรับความเสี่ยงนั้นโดยตั้งใจ
โหมด headless ของ Gemini CLI ซึ่งมีเอกสารอยู่ใน เอกสาร headless ของโปรเจกต์เอง, จะเปิดใช้งานอัตโนมัติในสภาพแวดล้อมที่ไม่มี TTY หรือระบุอย่างชัดเจนด้วย -p. มันจะออกด้วยรหัสที่ไม่ใช่ศูนย์ซึ่งแยกกันสำหรับข้อผิดพลาดทั่วไป ข้อผิดพลาดของอินพุต และการชนเพดานจำนวนเทิร์น แทนที่จะใช้รหัสความล้มเหลวเดียวแบบรวม ๆ
ตารางเวลาควรอยู่ที่ไหน
ก่อนจะลงมือตั้งค่าทั้งหมดนี้: ผู้ให้บริการ agent อาจตั้งเวลาให้คุณอยู่แล้ว Claude Code มีตัวเลือกในตัวสามแบบ และหนึ่งในนั้นอาจเหมาะกับคุณจริง ๆ มากกว่าการดูแล VPS เอง
| คลาวด์ (Routines) | งานตั้งเวลาบน Desktop | /loop | |
|---|---|---|---|
| รันบน | คลาวด์ของ Anthropic | เครื่องของคุณ | เครื่องของคุณ |
| เครื่องต้องเปิดอยู่ | ไม่จำเป็น | จำเป็น | จำเป็น |
| ต้องมีเซสชันเปิดอยู่ | ไม่จำเป็น | ไม่จำเป็น | จำเป็น |
| ช่วงเวลาต่ำสุด | 1 ชั่วโมง | 1 นาที | 1 นาที |
| การเข้าถึงไฟล์ในเครื่อง | ไม่มี เพราะรันจากโคลนใหม่ | เข้าถึงได้เต็มที่ | เข้าถึงได้เต็มที่ |
เอกสารเรื่องงานตั้งเวลาของ Anthropic เอง นำเสนอเรื่องนี้เป็นทางเลือกสามทางจริง ๆ ไม่ใช่ลำดับชั้นที่มี VPS อยู่บนสุด ถ้างานของคุณไม่ต้องใช้สถานะในเครื่อง ทนกับขั้นต่ำหนึ่งชั่วโมงได้ และคุณใช้แค่ Claude Code แล้ว Routines ก็ดูแลน้อยกว่าวิธีที่จะเล่าต่อจากนี้ เพราะ Anthropic รันให้บนคลาวด์จากโคลนใหม่ขณะที่เครื่องคุณปิดอยู่
/loop น่ารู้ไว้ แต่ไม่เหมาะกับกรณีนี้ เพราะมันต้องมีเซสชันที่เปิดอยู่และว่าง ซึ่งเป็นข้อจำกัดที่คุณกำลังพยายามกำจัดพอดี เอกสารชุดเดียวกันยังชี้ไปที่ GitHub Actions เป็นทางเลือกที่สี่ สำหรับทีมที่ทริกเกอร์อยู่ใน CI อยู่แล้ว แทนที่จะเป็นตารางเวลาที่ผูกกับเครื่องใดเครื่องหนึ่ง
VPS ที่คุณดูแลเองคุ้มค่าเมื่องานต้องเข้าถึงระบบไฟล์และเครื่องมือในเครื่องอย่างเต็มที่ เมื่อคุณอยากได้กลไกเดียวกันที่ทำงานเหมือนกันทั้งบน Claude Code, Codex CLI และ Gemini CLI หรือเมื่อช่วงเวลาที่ Routines อนุญาตหยาบเกินไป ฟังก์ชันไร้เซิร์ฟเวอร์แบบทั่วไปมักไม่ค่อยเข้ากับงานนี้ เพราะต้องกู้คืนข้อมูลรับรอง โคลนรีโป และทำให้เสร็จภายในขีดจำกัดเวลารันของแพลตฟอร์ม ตัวรัน CI แบบชั่วคราวอย่าง GitHub Actions ยังเป็นทางที่สามที่ใช้ได้ ถ้าการ checkout ใหม่ทุกครั้งเป็นเรื่องที่ยอมรับได้ ถ้าคุณมีฮาร์ดแวร์ที่เปิดตลอดและว่างอยู่แล้ว เครื่อง homelab ก็ใช้ได้เหมือนกัน แลกกับการต้องพึ่งความเสถียรของเน็ตบ้านและการเข้าถึงระยะไกลของคุณเอง แทนของผู้ให้บริการ
cron หรือ systemd timer?
เครื่องมือทั้งสองสั่งคำสั่งเดียวกันตามตารางเดียวกันได้ แต่ต่างกันตรงว่าเกิดอะไรขึ้นเมื่อเครื่องรีบูต และแต่ละตัวต้องตั้งค่ามากแค่ไหน:
| cron | systemd timer | |
|---|---|---|
| ภาระการตั้งค่า | crontab หนึ่งบรรทัด | ไฟล์ .timer และไฟล์ .service |
| การตามเก็บการรันที่พลาด | ไม่มี การรันที่ถูกข้ามก็หายไปเลย | Persistent=true จะรันทันทีที่ระบบกลับมา |
| การเข้าสู่ระบบ | ทำเอง คุณต้องเปลี่ยนทางเอาต์พุตเอง | อัตโนมัติ เก็บโดย journald |
| การจัดลำดับ dependency | ไม่มี | จัดลำดับแบบ systemd เต็มรูปแบบด้วย After= และ Requires= |
cron ธรรมดาก็พอสำหรับงานรายคืนบนเครื่องที่แทบไม่รีบูต จุดที่ต้องระวังคือสภาพแวดล้อม เพราะ cron เริ่มต้นด้วย PATHแบบขั้นต่ำ ไม่พาคุณเข้าไปในรีโปให้ และพร้อมจะเริ่มสำเนาที่สองทั้งที่ตัวแรกยังทำงานอยู่ ให้ย้ายพาธของรีโป คำสั่ง agent ที่จำกัดขอบเขต และการโหลดข้อมูลรับรอง ไปไว้ในสคริปต์ห่อหุ้มที่ตั้งสิทธิ์ไว้ดี แล้วใช้ flock เพื่อกันไม่ให้การรันทับซ้อนกัน
# /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
สร้างไดเรกทอรีสำหรับข้อมูลรับรองและ log ไว้ครั้งเดียว แล้วทำให้สคริปต์ห่อหุ้มรันได้:
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
วางเฉพาะ API key ลงในไฟล์ข้อมูลรับรอง อย่าใส่ไว้ใน crontab โดยตรง
systemd timer ต้องตั้งค่ามากกว่า แต่ให้สองอย่างที่ cron ไม่มี ได้แก่ การเก็บ log ผ่าน journald โดยไม่ต้องเปลี่ยนทางเอง และ Persistent=true. ตัวอย่างด้านล่างสมมติว่าบัญชีเฉพาะชื่อ agent-runner เป็นเจ้าของ /srv/myrepo. เก็บ API key ไว้ในไฟล์ข้อมูลรับรองที่มีแต่ root อ่านได้ แทนที่จะฝังไว้ในไฟล์ unit
ตาม คู่มือ systemd.timer, การตั้งค่า Persistent=true หมายความว่า "service unit จะถูกทริกเกอร์ทันที ถ้ามันควรจะถูกทริกเกอร์อย่างน้อยหนึ่งครั้งในช่วงที่ timer ไม่ทำงาน" ดังนั้นการรันที่ควรเกิดขึ้นตอน VPS ของคุณกำลังรีบูตเพื่ออัปเดตเคอร์เนล จะเริ่มทันทีที่เครื่องกลับมา แทนที่จะหายไปเงียบ ๆ จนถึงรอบถัดไป
สร้างไฟล์ข้อมูลรับรองที่มีแต่ root อ่านได้ ซึ่งเซอร์วิสจะใช้:
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
วางเฉพาะ API key ลงในไฟล์นี้
# /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
รีโหลด systemd เปิดใช้งาน timer แล้วสั่งรันเซอร์วิสทันทีหนึ่งครั้ง เพื่อให้ปัญหาเรื่องข้อมูลรับรอง สิทธิ์ และพาธโผล่ตอนนี้ ไม่ใช่ตอนตีสอง:
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 คือความต่างที่ชี้ขาด: timer จะจำการรันตามปฏิทินที่พลาดไป แทนที่จะทิ้งไปเงียบ ๆ
จริง ๆ แล้ว VPS ต้องมีอะไรบ้าง
นี่คือส่วนที่ทำให้คนเลือกสเปกครั้งแรกประหลาดใจ: ตัว CLI เองเบามาก เพราะการอนุมานเกิดบน API ของผู้ให้บริการ แต่ agent ยังสั่งบิลด์ เทส ตัวจัดการแพ็กเกจ language server และคอนเทนเนอร์ในเครื่องได้อยู่ดี ภาระงานของรีโปจึงเป็นตัวกำหนดขั้นต่ำจริง ๆ
สำหรับงานตั้งเวลาเบา ๆ หนึ่งงาน ให้เริ่มที่ 1-2 vCPU และแรม 2-4 GB พร้อมสตอเรจ NVMe รีโปขนาดใหญ่ คอมไพเลอร์ การบิลด์ Docker ชุดเทส หรือการรันพร้อมกันหลายงาน อาจต้องการมากกว่านั้นมาก สิ่งที่ทำให้ต้องอัปสเปกคือคำสั่งในเครื่องที่หนักที่สุดที่ agent จะรัน ไม่ใช่โมเดลที่อยู่หลัง API ถ้าคุณรันงาน Docker บน VPS นี้อยู่แล้วและอยากเห็นภาพงบประมาณที่ครบกว่านี้ การเลือกสเปกและรักษาความปลอดภัยเครื่องบิลด์ อธิบายการแลกได้แลกเสียแบบเดียวกันสำหรับงานไร้คนดูแลอีกประเภทหนึ่ง
อีกเรื่องที่ควรวางแผนไว้: การรันแบบไม่มีคนดูแลจะสร้าง log ทุกคืน ไม่ว่าจะมีอะไรผิดพลาดหรือไม่ ให้เพิ่ม logrotate ถ้า cron เขียนลงไฟล์ และตรวจขีดจำกัดการเก็บของ journald แทนที่จะเดาว่าค่าเริ่มต้นเหมาะกับดิสก์ของ VPS อยู่แล้ว
แนวทางทั้งหมดนี้ขึ้นอยู่กับโฮสต์ที่ตื่นอยู่ตอนตีสองและอยู่แบบนั้นต่อไป ไม่ว่าโน้ตบุ๊กคุณจะทำอะไรอยู่ นั่นคืองานที่ Linux VPS ที่มีสิทธิ์ root ถูกสร้างมาเพื่อทำโดยเฉพาะ ไม่มีอะไรทำให้มันหลับ และคุณไม่ต้องแชร์กับ cron job ของใครอีก
พัฒนาบน Linux VPS พร้อมสิทธิ์รูท, NVMe และพลัง AMD EPYC
ดูแพ็กเกจ Linuxกันไม่ให้การรันแบบไม่มีคนดูแลพลาด
ความต่างที่ใหญ่ที่สุดระหว่างการรันตามตารางที่สำเร็จกับที่ล้มเหลว คือ งานนั้นถูกจำกัดขอบเขตแคบพอจะจบได้โดยไม่ต้องมีคนมาตอบคำถามกลางทางหรือไม่ พรอมต์ที่ทะเยอทะยานจะค้างรอการตัดสินใจที่ไม่มีใครอยู่ตรงนั้นให้ตัดสิน ส่วนงานที่แคบและครบในตัวจะทำเสร็จและออกอย่างสะอาด
แฟล็กเรื่องสิทธิ์สองตัวมีไว้เพื่อไม่ให้การรันค้างรอคำขออนุมัติตอนตีสอง แต่การเปิด Bash แบบเปล่า ๆ ไม่ใช่การ์ดเรลที่แคบเลย เพราะมันทำได้เกือบทุกอย่างที่บัญชีเซอร์วิสทำได้ ให้เลือกกฎที่เจาะจงคำสั่ง เช่น Bash(git status *), จับคู่กับ --permission-mode dontAskและรันเซอร์วิสภายใต้บัญชีเฉพาะที่ไม่ใช่ root จำนวนเทิร์นและค่าใช้จ่ายก็มีเพดานของตัวเอง: --max-turns จำกัดว่า agent จะเดินวนได้นานแค่ไหน ส่วน --max-budget-usd กำหนดเพดานว่าการรันครั้งเดียวจะใช้จ่ายกับการเรียก API ได้เท่าไร
เคล็ดลับ: รันด้วย --output-format json แล้วบันทึกฟิลด์ total_cost_usd จากทุกครั้งที่เรียกใช้ นี่คือจุดเชื่อมที่สะอาดที่สุดสำหรับติดตามว่าการรันตามตารางมีค่าใช้จ่ายจริงคืนละเท่าไร และสำหรับตั้งแจ้งเตือนเมื่อการรันครั้งหนึ่งแพงกว่าครั้งอื่นอย่างชัดเจน คุ้มกับห้านาทีที่ต้องเสียไปตั้งค่า เพราะสิ่งที่มันติดตามคือบิลของคุณเอง ไม่ใช่เรื่องนามธรรม
ค่าใช้จ่ายบานปลายจากการรันแบบไม่มีคนดูแลไม่ใช่เรื่องสมมติ ในโพสต์หนึ่งบน Hacker Newsมีผู้ใช้รายหนึ่งเล่าถึงบิล AWS Bedrock รวม 37,901.73 ดอลลาร์ ที่เกิดจากเวิร์กโฟลว์ coding agent รายวัน ซึ่งการแคชพรอมต์ได้ผลเพียงบางส่วน ทำให้มีอินพุตราว 6.47 พันล้านโทเคนไม่ถูกแคช เรื่องนี้เกิดบนสแตกอื่น ไม่ใช่โหมด headless ของ Claude Code แต่แสดงให้เห็นว่าทำไมการบันทึกค่าใช้จ่ายและงบต่อการรันแบบตายตัวจึงควรอยู่ในแผนตั้งเวลาด้วย
เคล็ดลับ: Claude Code จะออกด้วยรหัส 0 เมื่อสำเร็จ และรหัสที่ไม่ใช่ศูนย์เมื่อล้มเหลว สคริปต์ห่อหุ้มที่ตรวจสถานะการออกสามารถส่งการแจ้งเตือนให้คุณเมื่อเกิดความล้มเหลว ทำให้คืนที่มีปัญหาถูกพบตั้งแต่เช้าวันรุ่งขึ้น แทนที่จะเป็นสามวันถัดมาตอนที่คุณบังเอิญไปเปิดดู
อย่างน้อยที่สุด ให้รันแต่ละงานบนสาขาเฉพาะหรือ worktree แบบใช้แล้วทิ้ง และกำหนดให้มีคนรีวิวก่อนรวมโค้ด ส่วนเรื่องข้อมูลรับรองที่จำกัดขอบเขต การแยกระบบไฟล์ และการควบคุมรัศมีความเสียหายระดับเซิร์ฟเวอร์ เป็นหัวข้อใหญ่ที่ควรมีบทความของตัวเอง มากกว่าจะเป็นย่อหน้าที่แปะท้ายคู่มือการตั้งเวลา
สิ่งที่ทำให้ปล่อยตารางเวลาไว้เองได้อย่างปลอดภัยคือการ์ดเรล ไม่ใช่ตัวตารางเวลาเอง
เมื่อ cron เริ่มไม่พอ
พรอมต์เดียวที่ตั้งเวลาไว้ ไม่ต้องการอะไรมากไปกว่าที่เล่ามาแล้ว แต่สามขั้นตอนต่อกัน พร้อมเงื่อนไข การลองใหม่ และการแจ้งเตือนเข้า Slack นั้นต้องใช้อย่างอื่น
มีสามตัวเลือกที่ควรรู้จัก แต่ละตัวเป็นการขยับขึ้นด้วยเหตุผลที่ต่างกัน:
- Dagu คือการขยับที่เบาที่สุด: งานที่ครบในตัวและนิยามด้วย YAML มี dependency แบบ DAG มีการลองใหม่ และมีเว็บ UI ให้ดูว่าอะไรรันไปแล้วบ้าง
- n8n เหมาะที่สุดเมื่อการรัน agent เป็นเพียงหนึ่งโหนดท่ามกลางการเชื่อมต่อและการแจ้งเตือนหลายอย่าง ไม่ใช่ทั้งเวิร์กโฟลว์
- Kestra หนักที่สุดในสามตัว ถูกสร้างมาเพื่อจัดการไปป์ไลน์ข้อมูลและโครงสร้างพื้นฐาน และเป็นคำตอบที่ถูกต้องเมื่อการตั้งเวลา agent เป็นส่วนหนึ่งของไปป์ไลน์ที่ใหญ่กว่า ไม่ใช่จุดประสงค์หลัก
สำหรับคนที่รันพรอมต์เดียวทุกคืน ทั้งสามตัวถือว่าเกินจำเป็น และพูดตรง ๆ แบบนี้ดีกว่าจะเชียร์ให้คุณไปตั้งอะไรที่หนักเกินความจำเป็น แต่ถ้าวันหนึ่งชุดขั้นตอนของคุณคุ้มค่าจะใช้จริง Dagu, n8n, และ Kestra ทั้งสามตัวติดตั้งได้ในคลิกเดียว ซึ่งเป็นความสะดวกจริง ๆ ตรงจังหวะที่คุณกำลังชั่งใจว่าค่าใช้จ่ายในการตั้งค่านั้นคุ้มไหม
เฟรมเวิร์กออร์เคสเตรตหลาย agent อย่าง LangChain หรือ CrewAI เป็นคนละเรื่องกันเลย นั่นคือการสร้างระบบ agent ไม่ใช่การตั้งเวลาให้ CLI ที่มีอยู่แล้ว
คำถามที่พบบ่อย
Claude Code รันโดยไม่มีเซสชันเปิดอยู่ได้ไหม?
ได้ การส่ง -p จะรันพรอมต์ในโหมดไม่โต้ตอบ Claude Code จะทำจนจบ พิมพ์ผลลัพธ์ แล้วออก โดยไม่มีลูปแชตและไม่มีเซสชันที่ต้องเปิดค้างไว้
ถ้า Claude Code มี Routines อยู่แล้ว ยังต้องใช้ VPS ไหม?
ไม่เสมอไป Routines รันบนคลาวด์ของ Anthropic ได้แม้เครื่องคุณปิดอยู่ และเริ่มจากโคลนใหม่ แต่มันเข้าถึงไฟล์ที่มีอยู่แค่บนเครื่องคุณไม่ได้ และมีช่วงเวลาขั้นต่ำหนึ่งชั่วโมง ส่วน VPS ที่คุณดูแลเองจะคุ้มเมื่องานต้องใช้ไฟล์ในเครื่อง ต้องการช่วงเวลาอิสระ หรือต้องการกลไกที่ทำงานเหมือนกันบน CLI ของผู้ให้บริการมากกว่าหนึ่งราย
ควรใช้ cron หรือ systemd timer สำหรับ agent ที่ตั้งเวลาไว้?
ใช้ systemd timer ถ้า VPS มีโอกาสรีบูตเพื่อบำรุงรักษา Persistent=true จะรันงานที่ควรทำงานระหว่างที่ระบบล่ม ทันทีที่ระบบกลับมา ซึ่ง cron ไม่มีอะไรเทียบเท่า ส่วน cron ก็เพียงพอสำหรับงานรายคืนบนเครื่องที่เปิดค้างตลอด
AI Agent ที่ตั้งเวลาไว้ต้องใช้แรมเท่าไรบน VPS?
เริ่มที่ราว 1-2 vCPU และแรม 2-4 GB สำหรับงานตั้งเวลาเบา ๆ หนึ่งงาน แล้วค่อยเลือกสเปกตามคำสั่งในเครื่องที่หนักที่สุดที่ agent จะรัน การบิลด์ การเทส Docker รีโปขนาดใหญ่ และการรันพร้อมกัน สำคัญกว่าการอนุมานของโมเดลฝั่งรีโมตมาก
การรัน agent ตามตารางเวลาทำให้การคิดเงินเปลี่ยนไปไหม?
การตั้งเวลาไม่ได้สร้างโหมดคิดเงินแยกต่างหาก Claude Code -p ใช้ข้อมูลรับรองแบบสมัครสมาชิกหรือ API key ก็ได้ แต่ --bare จะไม่สนใจการล็อกอินแบบสมัครสมาชิก จึงต้องมี ANTHROPIC_API_KEY ในสภาพแวดล้อม หรือไม่ก็ apiKeyHelper ในไฟล์ตั้งค่า ส่วน Codex และ Gemini จะใช้วิธียืนยันตัวตนตามที่คุณตั้งไว้ให้ CLI ของมัน เนื่องจากราคาและเงื่อนไขการใช้งานเปลี่ยนเร็ว ให้ตรวจราคาปัจจุบันของผู้ให้บริการและข้อมูลการใช้งานของคุณเองตอนที่ตั้งค่า สำหรับการรัน Claude Code ผ่าน API คุณยังบันทึกฟิลด์ total_cost_usd จากเอาต์พุต JSON ได้ด้วย
การสนทนา
ความคิดเห็น
เข้าสู่ระบบเพื่อร่วมสนทนา