SSD Nodes Learn 🎉 VPS เริ่ม $5.50/เดือน
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-13

วิธีใช้ Claude ช่วยงานดูแลเซิร์ฟเวอร์ Linux อย่างมืออาชีพ

เรียนรู้วิธีใช้ Claude วิเคราะห์ log ไฟล์ systemd และตรวจสอบ config ของ nginx หรือ Docker Compose อย่างปลอดภัย พร้อมข้อควรระวังเรื่องข้อมูลสำคัญที่ห้ามนำไปวางในแชทเด็ดขาด

Claude สำหรับผู้ดูแลระบบ: คำแนะนำต้องมาก่อน การลงมือทำทีหลัง

Claude สำหรับผู้ดูแลระบบทำงานได้ดีที่สุดในฐานะผู้ตรวจสอบ คุณสามารถคัดลอกข้อความจาก log, ไฟล์ config, คำสั่งที่คุณไม่คุ้นเคย หรือข้อความแสดงข้อผิดพลาดมาให้วิเคราะห์ แล้วคุณจะได้รับคำอธิบายที่คุณสามารถตรวจสอบได้ก่อนที่จะทำการเปลี่ยนแปลงใดๆ บนเซิร์ฟเวอร์ คำตอบที่ผิดจะไม่สร้างความเสียหายจนกว่าคุณจะนำไปรันจริง ดังนั้นการให้โมเดลทำหน้าที่เพียงแค่ให้คำแนะนำจึงเป็นหัวใจสำคัญของรูปแบบความปลอดภัยนี้

งาน 6 ประเภทมักเกิดขึ้นเป็นประจำทุกสัปดาห์บน Linux VPS (virtual private server) ที่เช่าไว้ แต่ละหัวข้อด้านล่างนี้มีรูปแบบคำสั่ง (prompt pattern) ที่ใช้งานได้จริง คำสั่งสำหรับตรวจสอบความถูกต้องของคำตอบ และรูปแบบความล้มเหลวที่คุณควรคาดการณ์ไว้ ทั้งหมดนี้ไม่จำเป็นต้องให้โมเดลเข้าถึงเซิร์ฟเวอร์ของคุณโดยตรง

ลำดับขั้นตอนมีความสำคัญอย่างยิ่งบนเซิร์ฟเวอร์ที่ใช้งานจริง (production): อ่านคำอธิบาย ตรวจสอบด้วยตัวเอง แล้วจึงตัดสินใจ การปล่อยให้โมเดลทำงานอัตโนมัติอาจทำได้ใน VM สำหรับทดสอบ แต่สำหรับเซิร์ฟเวอร์ที่ให้บริการลูกค้า การตรวจสอบด้วยตนเองคือสิ่งสำคัญที่สุด เพราะโมเดลไม่สามารถมองเห็นสถานะจริงที่มันกำลังคาดการณ์อยู่ได้

สิ่งที่คุณห้ามคัดลอกและวางโดยเด็ดขาด

ทุกสิ่งที่อยู่ในพรอมต์จะถูกส่งออกจากเซิร์ฟเวอร์ของคุณ ข้อมูล 4 ประเภทต่อไปนี้ต้องเก็บไว้ในเครื่องเท่านั้น:

  • Private keys: ~/.ssh/id_ed25519, /etc/ssh/ssh_host_*_key และ TLS (transport layer security) key ใดๆ ภายใต้ /etc/letsencrypt/live/
  • ไฟล์ข้อมูลรับรอง (Credential files): .env, ~/.aws/credentials, /root/.docker/config.json และรหัสผ่านฐานข้อมูลในไฟล์ใดๆ หรือบรรทัดใดๆ ใน log
  • ข้อมูลบัญชี: /etc/shadow และ /etc/gshadow ไม่มีคำถามของผู้ดูแลระบบข้อใดที่จำเป็นต้องใช้ password hash ในการตอบ
  • สิ่งใดก็ตามที่เป็นของผู้ใช้ของคุณ: ที่อยู่อีเมล, แถวข้อมูลคำสั่งซื้อ, log ของคำขอที่มี session cookies หรือ PII (ข้อมูลที่สามารถระบุตัวตนได้)

Public keys สามารถคัดลอกและวางได้อย่างปลอดภัย แต่ Private keys ไม่สามารถทำได้ และไฟล์ทั้งสองประเภทนี้ดูคล้ายกันมากในแวบแรก ดังนั้นโปรดอ่านบรรทัดแรกก่อนที่คุณจะคัดลอก: ไฟล์ที่มีบรรทัดแรกประกอบด้วย BEGIN OPENSSH PRIVATE KEY ห้ามนำไปใส่ในพรอมต์โดยเด็ดขาด การจัดการวัสดุ SSH key ของคุณให้ถูกต้อง เป็นเรื่องที่คุ้มค่าที่จะใช้เวลาศึกษาด้วยตัวเองสัก 10 นาที

ให้ทำการปกปิดข้อมูล (Redact) ก่อนที่คุณจะวาง แทนที่จะเชื่อมั่นในตัวเองว่าจะมองเห็น token หนึ่งตัวใน 200 บรรทัด:

sudo journalctl -u myapp -n 200 --no-pager | sed -E 's/(token|secret|password|api[_-]?key)[=:][^[:space:]]+/\1=REDACTED/gI'

กับดักหนึ่งอย่างที่เฉพาะเจาะจงสำหรับ Docker คือ docker compose config ซึ่งจะแทรกค่า .env ของคุณลงในผลลัพธ์ที่พิมพ์ออกมา ดังนั้นผลลัพธ์นั้นจึงเป็นความลับแม้ว่าไฟล์บนดิสก์จะไม่ใช่ก็ตาม ให้ใช้ docker compose config -q แทน ซึ่งจะตรวจสอบความถูกต้องและไม่พิมพ์ข้อมูลใดๆ ออกมา สำหรับนโยบายในวงกว้างเกี่ยวกับสิ่งที่ AI agent ได้รับอนุญาตให้มองเห็น การเก็บความลับให้พ้นจาก AI agents จะครอบคลุมถึงด้านสภาพแวดล้อม (environment)

งานที่ 1: ทำไมบริการนี้ถึงล้มเหลว?

เริ่มต้นด้วยคำสั่งสองคำสั่งที่เป็นกุญแจสำคัญในการหาคำตอบ:

systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager -o short-iso

ให้วางคำสั่งทั้งสองพร้อมกับบริบทที่โมเดลไม่สามารถคาดเดาได้เอง เช่น รุ่นของ distribution, สิ่งที่คุณเพิ่งแก้ไขล่าสุด, บริการนี้เคยทำงานได้หรือไม่ และหยุดทำงานไปนานเท่าใดแล้ว ให้ถามถึงกลไกการทำงานก่อน

Ubuntu 24.04. myapp.service เคยทำงานได้ปกติจนกระทั่งผมแก้ไข unit เมื่อหนึ่งชั่วโมงที่แล้ว นี่คือ systemctl status และ log 100 บรรทัดสุดท้ายจาก journal บรรทัดไหนคือข้อผิดพลาดที่แท้จริงบรรทัดแรก และมันหมายความว่าอย่างไร? ยังไม่ได้แก้ไขอะไร

คำว่า "ยังไม่ได้แก้ไขอะไร" มีความสำคัญมากใน prompt นี้ เนื่องจาก log มักจะกลบข้อผิดพลาดแรกด้วยการพยายามเริ่มทำงานซ้ำๆ หากคุณขอให้โมเดลแก้ไข มันจะอธิบายแค่บรรทัดสุดท้ายที่มันเห็น แต่บรรทัดที่สำคัญจริงๆ มักจะอยู่เหนือเสียงรบกวนเหล่านั้นขึ้นไปประมาณยี่สิบบรรทัด

ผลลัพธ์ที่ได้มักจะเป็นบรรทัดในลักษณะ Main PID: 1841 (code=exited, status=203/EXEC) สถานะการออก (exit status) 203/EXEC หมายความว่า kernel ไม่สามารถรันไฟล์ที่ระบุใน ExecStart ได้: อาจเป็นเพราะ path นั้นไม่มีอยู่จริง หรือไฟล์มีอยู่แต่ไม่ได้ถูกตั้งค่าให้เป็น executable บรรทัด #! ที่ระบุถึง interpreter ที่ไม่ได้ติดตั้งไว้ก็จะทำให้เกิดสถานะเดียวกัน ทั้งหมดนี้สามารถตรวจสอบได้ด้วย ls -l และ head -1

รูปแบบความล้มเหลว: การคาดเดาสาเหตุขึ้นมาเอง หากคุณให้ข้อมูลน้อยเกินไป โมเดลจะเติมช่องว่างด้วยสาเหตุทั่วไป เช่น "พอร์ตถูกใช้งานอยู่" วิธีแก้ไขคือการถามกลับไปหนึ่งคำถามว่า: "บรรทัดไหนในข้อมูลที่ผมให้ไปที่สนับสนุนข้อสรุปนั้น?" หากไม่มีใครสามารถชี้ให้เห็นสาเหตุในข้อความที่ให้ไปได้ นั่นถือเป็นการเดา

งานที่ 2: ร่าง systemd unit หรือ cron entry

ระบุข้อมูลที่จำเป็นสำหรับไฟล์ unit ได้แก่ คำสั่งที่ถูกต้อง, ผู้ใช้งานที่รันคำสั่ง, ไดเรกทอรีทำงาน, ความจำเป็นในการรอเครือข่าย และสิ่งที่ต้องเกิดขึ้นเมื่อโปรแกรมจบการทำงานด้วยสถานะที่ไม่ใช่ศูนย์ จากนั้นให้ตรวจสอบผลลัพธ์ก่อนที่จะเปิดใช้งานใดๆ

sudo systemd-analyze verify /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl start myapp.service
systemctl status myapp.service --no-pager

systemd-analyze verify จะวิเคราะห์ไฟล์ในลักษณะเดียวกับที่ systemd ทำ จึงสามารถตรวจพบข้อผิดพลาดที่สายตามนุษย์มักมองข้าม หากสะกด directive ผิด โปรแกรมจะแสดง /etc/systemd/system/myapp.service:7: Unknown key name 'Enviroment' in section 'Service', ignoring. หากระบุ binary ไม่พบ โปรแกรมจะแสดง Command /usr/local/bin/myapp is not executable: No such file or directory ทั้งสองกรณีนี้จะไม่แสดงข้อความแจ้งเตือนระหว่างการทำ daemon-reload ซึ่งเป็นสาเหตุที่ทำให้ unit โหลดผ่านได้ปกติแต่กลับล้มเหลวทันทีที่เริ่มรัน

ข้อผิดพลาดในการร่างไฟล์ที่พบได้บ่อยมีอยู่สองประการ ประการแรกคือ After=network.target ซึ่งหมายถึงเพียงแค่ว่า network stack ถูกตั้งค่าแล้วเท่านั้น ไม่ได้หมายความว่ามี IP address พร้อมใช้งานจริง บริการที่ผูกกับ IP เฉพาะจะล้มเหลวขณะบูตด้วยข้อผิดพลาด bind: Cannot assign requested address วิธีแก้ไขคือการใช้ Wants=network-online.target ร่วมกับ After=network-online.target ประการที่สองคือการใช้ Type=simple กับโปรแกรมที่ทำตัวเป็น daemon โดย systemd จะถือว่า process แรกคือตัวบริการ เมื่อ parent process จบการทำงานทันที unit จะถูกทำเครื่องหมายว่าหยุดทำงาน (dead) ในขณะที่ process จริงยังคงรันอยู่โดยไม่มีการจัดการ

สำหรับการตั้งเวลา ให้ตรวจสอบด้วยคำสั่งแทนการอ่านไฟล์ด้วยตัวเอง:

systemd-analyze calendar 'Mon *-*-* 04:00:00'

คำสั่งนี้จะแสดงรูปแบบที่ปรับให้เป็นมาตรฐานและเวลาถัดไปที่คำสั่งจะทำงาน ซึ่งช่วยยุติข้อโต้แย้งเกี่ยวกับความหมายของนิพจน์นั้น หากคุณกำลังตัดสินใจเลือกระหว่าง timer กับ crontab เนื้อหาใน systemd services and timers on a VPS จะช่วยเปรียบเทียบข้อดีข้อเสียให้คุณ

Cron มีกับดักอย่างหนึ่งที่ไม่มีโมเดลใดจะเตือนคุณหากคุณไม่ถาม Cron จะรันงานด้วย environment ที่จำกัดมาก ดังนั้น PATH จึงมีค่าเท่ากับ /usr/bin:/bin โดยประมาณ และ shell profile ของคุณจะไม่มีการถูกอ่าน งานที่รันได้ปกติเมื่อคัดลอกไปวางใน terminal จะล้มเหลวเมื่อรันผ่าน cron ด้วยข้อผิดพลาด /bin/sh: 1: docker: not found เนื่องจาก binary นั้นอยู่ใน /usr/local/bin ดังนั้นควรใช้ absolute path ใน crontab เสมอ

งานที่ 3: ตรวจสอบไฟล์ Nginx หรือไฟล์ Compose ก่อนเริ่มใช้งานจริง

งานนี้ให้ผลลัพธ์คุ้มค่าที่สุด ให้วางไฟล์ที่ต้องการตรวจสอบ ระบุสิ่งที่ต้องการให้ไฟล์นั้นทำ และขอคำอธิบายทีละบรรทัดว่าไฟล์นั้นทำงานอย่างไรจริง

vhost นี้ควรให้บริการ example.com ผ่าน HTTPS และทำหน้าที่เป็น proxy ส่ง /api ไปยังบริการภายในที่พอร์ต 8080 ช่วยอ่านทวนให้ฟังและระบุส่วนใดที่ไม่ตรงกับคำอธิบายนี้

จากนั้นให้รันเครื่องมือที่ตรวจสอบไวยากรณ์:

sudo nginx -t
docker compose config -q

nginx -t จะแสดง nginx: configuration file /etc/nginx/nginx.conf test is successful หรือระบุชื่อไฟล์และบรรทัดที่มีปัญหา เช่น nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12 ส่วน docker compose config -q จะไม่แสดงผลใดๆ หากไฟล์มีไวยากรณ์ถูกต้อง และจะแสดงข้อความตรงไปตรงมา เช่น yaml: line 7: did not find expected key เมื่อมีการเยื้องบรรทัดผิดพลาด

เครื่องมือทั้งสองไม่ได้ตรวจสอบเจตนาของผู้ใช้ ไฟล์ config ที่ผ่านการตรวจสอบด้วย nginx -t อาจยังคงส่ง proxy ไปยังพอร์ตที่ผิด หรือเปิดฟังที่ 0.0.0.0 ในขณะที่คุณตั้งใจให้เป็น 127.0.0.1 ช่องว่างตรงนี้คือจุดที่โมเดลภาษาเข้ามามีบทบาทสำคัญ แต่ก็เป็นจุดที่อาจเกิดข้อผิดพลาดได้เช่นกัน: เมื่อถูกขอให้แก้ไข directive เพียงจุดเดียว โมเดลอาจส่งไฟล์ที่เขียนใหม่ทั้งหมดกลับมาโดยที่ directive ของคุณหายไปสองบรรทัดโดยไม่แจ้งให้ทราบ ดังนั้นควรขอให้ระบุเฉพาะบรรทัดที่เปลี่ยนแปลงและเหตุผลของแต่ละจุด แล้วจึงแก้ไขด้วยตนเอง

ตรวจสอบสิ่งที่เปิดใช้งานจริง:

sudo ss -tulpn

หากไม่มี sudo คุณจะเห็นเพียง socket ที่เปิดฟังอยู่แต่ไม่เห็น process ที่เป็นเจ้าของ หากผลลัพธ์ที่ได้ทำให้คุณประหลาดใจ พอร์ตคืออะไรและ Linux ผูกพอร์ตอย่างไร เป็นบทความที่อ่านเข้าใจได้รวดเร็ว

งานที่ 4: อธิบายคำสั่งที่ไม่คุ้นเคยก่อนเรียกใช้งาน

ให้วางคำสั่งที่ต้องการทราบแล้วตั้งคำถาม 4 ข้อเกี่ยวกับคำสั่งนั้น: แต่ละ flag ทำหน้าที่อะไร, คำสั่งเขียนข้อมูลลงที่ใด, คำสั่งลบข้อมูลใดบ้าง และจะเกิดอะไรขึ้นหากรันคำสั่งซ้ำสองครั้ง คำถามข้อสุดท้ายช่วยป้องกันความเสียหายได้มากกว่าข้ออื่น

ลองพิจารณา find /var/log -name '*.gz' -mtime +7 -delete คำตอบที่ดีจะระบุว่า -mtime +7 จะนับช่วงเวลา 24 ชั่วโมงเต็มและตัดเศษทิ้ง ดังนั้นมันจะจับคู่ไฟล์ที่มีอายุอย่างน้อยแปดวันแทนที่จะเป็นเจ็ดวัน นอกจากนี้ยังระบุว่า find จะประเมินนิพจน์จากซ้ายไปขวา ดังนั้นการย้าย -delete ไปไว้หน้า -name จะลบทุกอย่างภายใต้ path เริ่มต้น ประเด็นที่สองนี้ระบุไว้ในหน้า man page ของ find ในฐานะคำเตือน และมันเคยสร้างความเสียหายให้กับ /var/log ของผู้ใช้งานมาแล้ว

หรือพิจารณา rsync -a --delete /srv/app/ /backup/app/ เครื่องหมาย slash ปิดท้ายที่ source หมายถึง "เนื้อหาภายในไดเรกทอรีนี้" หากตัดออกคุณจะได้ /backup/app/app/ หากเพิ่ม --delete ข้อมูลใดก็ตามในปลายทางที่ไม่มีอยู่ในต้นทางจะถูกลบออก ซึ่งถูกต้องสำหรับการทำ mirror แต่จะเป็นหายนะหาก path ของต้นทางผิดพลาด

ตรวจสอบด้วยเครื่องมือ ไม่ใช่ด้วยโมเดล:

rsync -a --delete --dry-run /srv/app/ /backup/app/ | head -20
find /var/log -name '*.gz' -mtime +7

รัน find โดยไม่มี -delete แล้วคุณจะได้รายการแทนที่จะเป็นการสูญเสียข้อมูล

รูปแบบความล้มเหลว: การหลอนของ flag (flag hallucination) โมเดลมีความน่าเชื่อถือสูงกับเครื่องมือที่มีเอกสารประกอบมานานกว่าสามสิบปี แต่จะอ่อนกว่ามากกับ CLI ของผู้จำหน่าย (vendor CLIs) และคำสั่งย่อยที่เพิ่งออกมาใหม่ ซึ่งโมเดลอาจสร้าง flag ที่อ่านดูสมเหตุสมผลแต่ไม่มีอยู่จริง --help สามารถตรวจสอบเรื่องนี้ได้ในหนึ่งวินาที การใส่เครื่องหมายคำพูด (quoting) เป็นจุดอ่อนอีกจุดหนึ่ง ดังนั้นเมื่อคำสั่งครอบนิพจน์ $(...) ให้ศึกษา วิธีการที่ command substitution ขยายตัวก่อนที่คำสั่งจะทำงาน แทนที่จะเชื่อคำอธิบายเพียงอย่างเดียว

งานที่ 5: เปลี่ยนประวัติการใช้งาน shell ของคุณให้เป็นคู่มือการทำงาน (runbook)

คุณเพิ่งใช้เวลาสองชั่วโมงในการทำให้บางอย่างทำงานได้สำเร็จ ความรู้นั้นอยู่ในหน้าต่าง terminal ของคุณและจะหายไปในเดือนหน้า

history 200 > /tmp/session.txt

อ่านไฟล์นั้นและลบทุกบรรทัดที่มีรหัสผ่าน, token หรือข้อมูลระบุตัวตนของลูกค้าออกก่อนที่จะนำไปใช้ที่อื่น ประวัติการใช้งาน shell เป็นหนึ่งในแหล่งที่เชื่อถือได้มากที่สุดในการค้นหาความลับบนเครื่อง Linux เพราะทุกคนมักจะเผลอพิมพ์ข้อมูลเหล่านี้ลงไปในบรรทัดคำสั่งอย่างน้อยหนึ่งครั้ง ตั้งค่า HISTCONTROL=ignorespace ใน ~/.bashrc ของคุณ เพื่อให้คำสั่งที่พิมพ์โดยเว้นวรรคหน้าคำสั่งจะไม่ถูกบันทึกลงในประวัติเลย

คำสั่ง (prompt) ที่จะสร้าง runbook ที่ใช้งานได้จริงต้องขอให้มีการตรวจสอบ ไม่ใช่แค่ขั้นตอนการทำงาน:

นี่คือเซสชัน shell ที่เปลี่ยนเครื่อง Debian 13 ใหม่ให้กลายเป็นระบบที่ติดตั้ง Postgres พร้อมใช้งาน จงเขียนออกมาเป็น runbook แบบมีลำดับเลข หนึ่งคำสั่งต่อหนึ่งขั้นตอน หลังจากแต่ละขั้นตอน ให้ระบุคำสั่งที่ใช้ตรวจสอบว่าทำงานได้จริงและอธิบายว่าผลลัพธ์ที่ถูกต้องควรเป็นอย่างไร ระบุขั้นตอนใดก็ตามที่ขึ้นอยู่กับโฮสต์เฉพาะของฉัน

รูปแบบความล้มเหลว: เรื่องราวที่ดูสะอาดเกินไป เซสชันของคุณมีขั้นตอนที่คุณทำผิดสองครั้งก่อนจะแก้ไขได้สำเร็จ และนั่นคือขั้นตอนที่โมเดลจะตัดออกไปเพราะบันทึกจะดูสะอาดกว่าหากไม่มีขั้นตอนนั้น เปรียบเทียบ runbook กับประวัติการใช้งานของคุณและใส่ขั้นตอนการแก้ไขกลับเข้าไป นอกจากนี้ โมเดลอาจสร้างคำสั่งตรวจสอบที่ดูสมเหตุสมผลขึ้นมาเอง ดังนั้นให้รันคำสั่งตรวจสอบทุกคำสั่งที่มันเขียนขึ้นมาก่อนที่คุณจะบันทึกไฟล์ หาก runbook ครอบคลุมถึงการบูตเครื่องครั้งแรก ให้อ่านเปรียบเทียบกับ สิบนาทีแรกบน VPS เครื่องใหม่ เพื่อให้แน่ใจว่าคุณไม่ได้เขียนขั้นตอนที่แย่กว่าวิธีแก้ปัญหาที่มีอยู่แล้ว

งานที่ 6: เปลี่ยนข้อความแสดงข้อผิดพลาดให้เป็นวิธีแก้ไข

ให้วางสตริงที่แน่นอน คำสั่งที่สร้างข้อความนั้น และสิ่งเดียวที่คุณเปลี่ยนแปลงก่อนที่ข้อความจะปรากฏขึ้น จากนั้นให้ขอการจัดลำดับสาเหตุที่เป็นไปได้พร้อมคำสั่งตรวจสอบสำหรับแต่ละสาเหตุ ซึ่งจะบังคับให้คำตอบเป็นสิ่งที่สามารถทดสอบได้

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use). จัดลำดับสาเหตุที่เป็นไปได้และให้คำสั่งหนึ่งคำสั่งต่อสาเหตุเพื่อยืนยันหรือตัดประเด็นนั้นออก

สำหรับข้อผิดพลาดนั้น กลไกไม่ได้มีความคลุมเครือ: มีกระบวนการอื่นใช้งานพอร์ต 80 อยู่แล้ว และ sudo ss -tulpn | grep ':80 ' จะระบุชื่อกระบวนการนั้น บ่อยครั้งที่เกิดจาก nginx master ตัวที่สองที่ค้างอยู่จากการ reload ที่ล้มเหลว หรือ Apache ที่ถูกดึงมาเป็น dependency และเริ่มทำงานโดยแพ็กเกจของมันเอง

รูปแบบความล้มเหลว: วิธีแก้ไขที่ได้ผลโดยการซ่อนสาเหตุ chmod 777, --privileged, การปิดใช้งาน SELinux และการรัน service ในฐานะ root ล้วนทำให้ข้อผิดพลาดหายไป ให้ปฏิเสธวิธีแก้ไขใดๆ ที่เป็นการขยายสิทธิ์จนกว่าแบบจำลองจะอธิบายได้ว่าเหตุใดสิทธิ์ที่จำกัดจึงใช้งานไม่ได้ คำอธิบายนั้นคือคำตอบที่แท้จริง ส่วนวิธีแก้ปัญหาชั่วคราว (workaround) เพียงแค่ทำให้ข้อผิดพลาดเงียบลงเท่านั้น

สิ่งที่มักจะผิดพลาดอย่างสม่ำเสมอ

  • โมเดลไม่สามารถมองเห็นเซิร์ฟเวอร์ของคุณได้ คำตอบทุกอย่างขึ้นอยู่กับข้อมูลที่คุณคัดลอกมาให้ และโมเดลจะไม่แจ้งเตือนหากข้อความที่ให้มานั้นสั้นเกินไป
  • ข้อมูลเวอร์ชันอาจคลาดเคลื่อน ชื่อแพ็กเกจและแฟล็กเริ่มต้นมีการเปลี่ยนแปลงอยู่เสมอระหว่างดิสทริบิวชันและรุ่นของซอฟต์แวร์ ซึ่งโมเดลจะใช้วิธีหาค่าเฉลี่ยจากข้อมูลทั้งหมดที่มี
  • โมเดลสามารถให้ข้อมูลที่ดูน่าเชื่อถือแม้จะผิดพลาด กลไกที่ถูกสร้างขึ้นมาเอง (hallucination) จะอ่านดูเหมือนข้อมูลที่ถูกต้องทุกประการ นี่คือเหตุผลว่าทำไมสาเหตุแต่ละข้อข้างต้นจึงต้องมีคำสั่งสำหรับทดสอบกำกับไว้เสมอ
  • โมเดลอาจสูญเสียบริบทในการสนทนาที่ยาวนาน ข้อมูลที่ระบุไว้ในช่วงต้นของการสนทนาที่ยาวนานหลายชั่วโมงอาจไม่มีผลต่อคำตอบในช่วงท้าย

ปัญหาข้อสุดท้ายนี้เป็นปัญหาด้านการทำงานมากกว่าปัญหาของตัวโมเดลเอง โดยการ จัดการบริบทในการใช้งาน Claude Code ระยะยาว คือวิธีแก้ไขในทางปฏิบัติ ได้แก่ การแบ่งเซสชันให้สั้นลงและทำทีละงาน

การติดตั้ง agent บนเซิร์ฟเวอร์โดยตรง

เนื้อหาทั้งหมดข้างต้นเป็นเพียงการคัดลอกและวาง ดังนั้นโมเดลจะไม่มีการเข้าถึงเครื่องของคุณโดยตรง แต่เมื่อใดที่โมเดลเริ่มทำงานบนเครื่อง อ่านไฟล์ และรันคำสั่ง รูปแบบของความเสี่ยงจะเปลี่ยนไปทันที เพราะคำสั่งที่ผิดพลาดอาจทำให้บริการของคุณเสียหายได้ ควรสร้างผู้ใช้ที่ไม่มีสิทธิ์ระดับ root ให้กับ agent โดยเฉพาะ หลีกเลี่ยงการใช้งานบนเครื่อง production จนกว่าคุณจะเข้าใจพฤติกรรมของมัน และควรทำ snapshot ไว้ก่อนเสมอ การรัน Claude Code อย่างปลอดภัยบน VPS ครอบคลุมเรื่องการทำ sandboxing และโมเดลการจัดการสิทธิ์ การใช้งาน Claude Code ภายใน tmux ช่วยแก้ปัญหาอีกด้านหนึ่ง เนื่องจากหากการเชื่อมต่อ SSH (secure shell) หลุด จะทำให้ agent ที่ทำงานอยู่เบื้องหน้าหยุดชะงักกลางคัน ให้สร้างบัญชีผู้ใช้ตามแนวทางเดียวกับการสร้าง service account ทั่วไป ซึ่งอธิบายไว้ใน การกำหนดสิทธิ์ผู้ใช้แบบ least privilege บน VPS

FAQ

Claude สามารถอ่าน log ของเซิร์ฟเวอร์โดยตรงได้หรือไม่?

ไม่ได้ด้วยตัวมันเอง อินเทอร์เฟซแชทจะเห็นเฉพาะข้อความที่คุณคัดลอกมาวางเท่านั้น ส่วน Claude Code ซึ่งรันบนเซิร์ฟเวอร์ในฐานะเครื่องมือบรรทัดคำสั่ง สามารถอ่านไฟล์และรันคำสั่งด้วยสิทธิ์ของผู้ใช้ที่เรียกใช้งาน ซึ่งถือเป็นการตัดสินใจด้านความเชื่อถือที่สูงกว่า สำหรับคำถามสนับสนุนทั่วไป การคัดลอกข้อความ log บางส่วนประมาณ 100 บรรทัดที่ผ่านการปกปิดข้อมูลสำคัญแล้ว จะรวดเร็วและปลอดภัยกว่าการให้สิทธิ์เข้าถึง shell แก่เอเจนต์

สิ่งใดที่ไม่ควรคัดลอกมาจากเซิร์ฟเวอร์เด็ดขาด?

Private keys, ไฟล์ .env และที่เก็บข้อมูล credential อื่นๆ, /etc/shadow รวมถึงข้อมูลใดๆ ที่เป็นของผู้ใช้ของคุณ ให้ลบ token ออกจากข้อความ log ก่อนที่จะส่งเข้าสู่ prompt กรณีที่ไม่ชัดเจนนักคือ ผลลัพธ์ของ docker compose config จะมีการแทรกค่า .env ลงไป ดังนั้นควรใช้ docker compose config -q ซึ่งจะตรวจสอบความถูกต้องของไฟล์โดยไม่แสดงผลลัพธ์ใดๆ ออกมา

การให้ Claude รันคำสั่งบน VPS ที่ใช้งานจริง (production) ปลอดภัยหรือไม่?

ให้ปฏิบัติกับมันเหมือนแอดมินคนใหม่ที่ไม่มีบริบท: สามารถใช้เพื่อการอ่านได้ แต่ต้องตรวจสอบก่อนการเขียน สำหรับระบบ production ให้ขอคำอธิบายแล้วรันคำสั่งด้วยตัวคุณเอง หากคุณต้องการให้เอเจนต์เป็นผู้รันคำสั่ง ให้สร้างบัญชีผู้ใช้ที่ไม่มีสิทธิ์พิเศษโดยเฉพาะและไม่ให้สิทธิ์ sudo แบบครอบคลุม และควรเริ่มทดสอบบน staging box ที่หากเกิดข้อผิดพลาดจะเสียเพียงแค่การสร้างระบบใหม่ ไม่ใช่การหยุดชะงักของบริการ

ทำไม Claude ถึงแนะนำ flag ที่ไม่มีอยู่จริง?

เพราะมันทำนายข้อความที่ดูสมเหตุสมผล และ flag ที่ดูสมเหตุสมผลก็มีลักษณะเหมือนกับ flag จริง เหตุการณ์นี้มักเกิดขึ้นกับ CLI ของผู้จำหน่ายและคำสั่งย่อยใหม่ๆ ซึ่งเอกสารประกอบที่โมเดลใช้มีข้อมูลน้อยหรือมีการเปลี่ยนแปลงไปแล้ว --help และ man คือผู้ตัดสินที่ดีที่สุด และคำสั่งใดก็ตามที่ลบหรือเขียนทับข้อมูลควรได้รับการทดสอบแบบ dry run ก่อนเสมอ

ฉันจะตรวจสอบ systemd unit ก่อนเปิดใช้งานได้อย่างไร?

ให้รัน sudo systemd-analyze verify /etc/systemd/system/myapp.service มันจะวิเคราะห์ไฟล์ด้วยตัววิเคราะห์ของ systemd เอง โดยจะรายงานคำสั่งที่ไม่รู้จักพร้อมหมายเลขบรรทัด และแจ้งเตือนหากไฟล์ binary ExecStart หายไปหรือไม่สามารถรันได้ จากนั้นให้รัน daemon-reload, start และอ่าน systemctl status ก่อนที่คุณจะ enable เพราะ unit ที่โหลดได้อย่างไม่มีปัญหาอาจล้มเหลวในการรันครั้งแรกได้