SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor

วิธีเขียนโปรแกรม Claude API บน Ubuntu 24.04 VPS

เรียนรู้วิธีสร้างเครื่องมือวิเคราะห์ Log ด้วย Claude API บน Ubuntu 24.04 ตั้งแต่การจัดการ API Key การทำ Streaming ไปจนถึงการเขียนโปรแกรมควบคุมค่าใช้จ่ายอย่างปลอดภัย

สิ่งที่คุณกำลังสร้าง

เครื่องมือบรรทัดคำสั่งบน Ubuntu 24.04 VPS ที่ติดตั้งใหม่ ซึ่งคุณสามารถส่งข้อความแสดงข้อผิดพลาดหรือส่วนหนึ่งของบันทึก (log) เข้าไปเพื่อรับคำวินิจฉัยเป็นภาษาอังกฤษที่เข้าใจง่าย: journalctl -u nginx -n 50 | explain เครื่องมือนี้มีความยาวประมาณ 60 บรรทัดในภาษา Python และเป็นการฝึกฝนทุกองค์ประกอบที่แอปพลิเคชัน Claude API จริงจำเป็นต้องมี ได้แก่ คีย์ที่จัดเก็บอย่างถูกต้อง, virtualenv, รูปแบบการตอบสนองของ SDK, การสตรีมข้อมูล, ลำดับข้อยกเว้นที่มีการระบุประเภท และ systemd unit เพื่อให้โปรแกรมทำงานได้โดยที่คุณไม่ต้องคอยดูแล

ผมเลือกโปรเจกต์นี้โดยตั้งใจ บทเรียน "แอปพลิเคชัน API แรก" ส่วนใหญ่จะให้คุณสร้างแชทบอทที่คุณจะไม่มีวันเปิดใช้งานอีกเลย แต่เครื่องมืออธิบายบันทึก (log explainer) นั้นมีประโยชน์บนเซิร์ฟเวอร์ตั้งแต่วันแรก และมันจะบังคับให้คุณเรียนรู้สองสิ่งที่ผู้เริ่มต้นมักทำผิดพลาดจริง ๆ คือ การอ่านออบเจกต์การตอบสนองอย่างถูกต้อง และการควบคุมค่าใช้จ่าย API จะเรียกเก็บเงินตามจำนวนโทเค็นโดยไม่มีเพดานจำกัดนอกจากที่คุณกำหนดไว้ ดังนั้นการควบคุมต้นทุนจึงเป็นปัจจัยในการออกแบบตั้งแต่ต้น ไม่ใช่สิ่งที่ค่อยมาคิดภายหลัง ซึ่งเป็นวินัยเดียวกันกับที่สำคัญเมื่อคุณก้าวไปสู่ การรัน Claude Code บน VPS เดียวกันนี้ใน tmux

รับ API key จาก Console

การเข้าถึง API จะจัดการผ่าน Anthropic Console ที่ platform.claude.com ให้ลงทะเบียนใช้งาน จากนั้นสร้างคีย์ได้ที่ Settings → API Keys (เอกสารจะลิงก์ตรงไปยัง platform.claude.com/settings/keys) Console จะให้คุณตั้งชื่อคีย์ เลือกวันหมดอายุ และเชื่อมโยงคีย์กับตัวคุณเองหรือ service account โดย Anthropic แนะนำให้ใช้คีย์แบบ service account สำหรับบริการที่ใช้งานจริงและสิ่งที่ต้องมีการแชร์ร่วมกัน คีย์จะแสดงให้เห็นเพียงครั้งเดียว โดยขึ้นต้นด้วย sk-ant- และไม่สามารถเรียกดูซ้ำได้ ดังนั้นให้คัดลอกเก็บไว้ทันที หรือหากทำหายให้ลบคีย์เดิมแล้วสร้างใหม่

ในส่วนของค่าใช้จ่าย: ณ เดือนตุลาคม 2026 API ไม่มีระดับการใช้งานฟรีแบบต่อเนื่อง เอกสารราคาของ Anthropic ระบุว่าผู้ใช้ใหม่จะได้รับเครดิตฟรีจำนวนหนึ่งเพื่อใช้ทดสอบ โดยจำนวนที่แน่นอนจะเป็นไปตามที่ Console แสดงให้เห็นเมื่อลงทะเบียน และเมื่อเครดิตหมดลง คุณจะต้องเติมเงินเข้าบัญชีก่อนจึงจะส่งคำขอได้ ทั้งนี้ เครดิตส่วนนี้แยกจากค่าสมาชิก claude.ai และการมี API key ไม่ได้หมายความว่าคุณจะสามารถใช้งานแอปแชทได้ แผน Pro จะไม่รวมเครดิต API แต่แผน Max และ Team จะรวมอยู่ด้วย: ณ เดือนตุลาคม 2026 แผน Max 5x จะได้รับเครดิต 100 ดอลลาร์ต่อเดือน และ Max 20x จะได้รับเครดิต 200 ดอลลาร์ (แผน Team จะรวมเครดิต 20 ดอลลาร์ต่อที่นั่งแบบ Standard และ 100 ดอลลาร์ต่อที่นั่งแบบ Premium โดยจำกัดสูงสุดที่ 500 ดอลลาร์) ซึ่งจะได้รับสิทธิ์โดยการเชื่อมโยง Console organization จากการตั้งค่าการเรียกเก็บเงินใน claude.ai ของคุณ เครดิตที่ไม่ได้ใช้งานจะหมดอายุเมื่อสิ้นสุดรอบบิลและไม่ครอบคลุมการใช้งาน Claude Code รายละเอียดเพิ่มเติมอยู่ใน วิธีการทำงานของเครดิต API รายเดือนสำหรับแผน Max และ Team หากคุณกำลังพิจารณาเปรียบเทียบระหว่างการสมัครสมาชิกกับการใช้ API การตัดสินใจเลือกนั้นเป็นหัวข้อเฉพาะ: แผน Claude แบบไหนที่คุณต้องการจริงๆ

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

อย่าเก็บคีย์ไว้ใน .bashrc

การกระทำที่ทำตามสัญชาตญาณคือการใช้ export ANTHROPIC_API_KEY=sk-ant-... ใน ~/.bashrc อย่าทำเช่นนั้น เพราะจะเกิดปัญหา 3 ประการดังนี้:

  • ทุกกระบวนการจะสืบทอดคีย์นี้ไป ตัวแปรสภาพแวดล้อมที่ถูก export ใน login shell ของคุณจะส่งต่อไปยังทุกสิ่งที่คุณเริ่มทำงาน ไม่ว่าจะเป็นเว็บแอปพลิเคชัน, โปรแกรมรายงานข้อผิดพลาดที่มักจะ dump สภาพแวดล้อมลงในรายงานบั๊กโดยไม่ตั้งใจ หรือหน้า phpinfo() ที่ใครบางคนเปิดทิ้งไว้ พื้นที่เสี่ยงต่อการถูกเปิดเผยของคีย์จะกลายเป็น "ทุกสิ่งที่ผู้ใช้นี้เรียกใช้งาน"
  • การพิมพ์คีย์จะถูกบันทึกลงใน ~/.bash_history หากคุณรันคำสั่ง export ด้วยตนเองเพียงครั้งเดียว คีย์ของคุณจะค้างอยู่ในไฟล์ข้อความธรรมดาตลอดไป และจะถูกซิงค์ไปยังทุกการสำรองข้อมูลในโฮมไดเรกทอรีของคุณ
  • คีย์จะไม่อยู่ในที่ที่ systemd ต้องการ บริการต่างๆ ไม่ได้อ่านไฟล์ .bashrc ของคุณ ดังนั้นรูปแบบนี้จะล้มเหลวทันทีที่คุณยกระดับสคริปต์ให้เป็น unit ซึ่งมักจะปรากฏเป็นข้อผิดพลาด 401 ที่หาสาเหตุไม่ได้ในเวลา 6 โมงเช้า

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

sudo mkdir -p /opt/explain
sudo install -m 600 -o root -g root /dev/null /etc/claude-explain.env
printf 'ANTHROPIC_API_KEY=sk-ant-YOUR-KEY-HERE\n' | sudo tee /etc/claude-explain.env >/dev/null

ให้ใช้ tee จากคำสั่ง printf แทนการใช้โปรแกรมแก้ไขข้อความ หากคุณต้องการป้องกันไม่ให้คีย์หลุดเข้าไปอยู่ในไฟล์ swap ของโปรแกรมแก้ไขข้อความ ไม่ว่าจะใช้วิธีใด ให้ตรวจสอบด้วย ls -l /etc/claude-explain.env ว่าไฟล์ดังกล่าวอ่านได้เฉพาะ -rw------- และมี root เป็นเจ้าของ สำหรับ interactive shell ให้รับคีย์ผ่าน wrapper (ด้านล่าง) ในแต่ละครั้งที่เรียกใช้งาน ส่วน systemd ให้รับคีย์ผ่าน EnvironmentFile= โดยที่ root จะอ่านไฟล์ก่อนที่จะลดระดับสิทธิ์ลง ทำให้ผู้ใช้ที่เป็นเจ้าของบริการไม่จำเป็นต้องมีสิทธิ์อ่านไฟล์นี้ คีย์จะไม่ปรากฏในโค้ด, ใน git, ในผลลัพธ์ของ ps หรือในประวัติการใช้งาน shell

การติดตั้ง SDK ใน venv

Ubuntu 24.04 มาพร้อมกับ Python 3.12 ซึ่งมีการบังคับใช้ PEP 668 ดังนั้นการรัน pip install anthropic โดยตรงกับอินเทอร์พรีเตอร์ของระบบจะล้มเหลวพร้อมกับข้อผิดพลาด error: externally-managed-environment ข้อผิดพลาดดังกล่าวคือการทำงานตามปกติของระบบปฏิบัติการ โปรดใช้ virtualenv แทน:

sudo apt update && sudo apt install -y python3-venv
sudo python3 -m venv /opt/explain/venv
sudo /opt/explain/venv/bin/pip install anthropic

ไม่จำเป็นต้องทำขั้นตอนการเปิดใช้งาน (activation) บนเซิร์ฟเวอร์: การเรียกใช้ /opt/explain/venv/bin/python โดยตรงจะใช้งานแพ็กเกจภายใน venv เสมอ

การเรียกใช้งานครั้งแรกและการอ่านการตอบกลับอย่างถูกต้อง

import anthropic

client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY from the environment

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1000,
    messages=[{"role": "user", "content": "Explain what a systemd unit file is in three sentences."}],
)

for block in response.content:
    if block.type == "text":
        print(block.text)

เนื้อหาใน 12 บรรทัดนั้นมีสิ่งที่แสดงถึงแนวคิดหลักของ API อยู่ 2 ประการ ประการแรกคือ anthropic.Anthropic() ที่ไม่มีอาร์กิวเมนต์ ซึ่งจะอ่านคีย์จาก environment โดยตรง ห้ามส่งคีย์เป็น string literal โดยเด็ดขาด ประการที่สองคือ response.content ซึ่งเป็น รายการของบล็อกเนื้อหา (list of content blocks) ไม่ใช่ string หากคุณสั่งพิมพ์ค่านี้โดยตรง คุณจะได้ผลลัพธ์ที่มือใหม่มักพบเจอเป็นประจำ:

[TextBlock(citations=None, text='A systemd unit file is...', type='text')]

นั่นไม่ใช่บั๊ก แต่เป็น repr ของออบเจกต์ เนื่องจากการตอบกลับสามารถประกอบด้วยบล็อกหลายประเภท (เช่น ข้อความ, การเรียกใช้เครื่องมือ, หรือกระบวนการคิด) คุณจึงต้องวนลูปและตรวจสอบ block.type == "text" ก่อนที่จะเข้าถึง .text สำหรับ Opus 5.5 เรื่องนี้มีความสำคัญตั้งแต่การเรียกใช้งานครั้งแรก เพราะกระบวนการคิด (thinking) จะถูกเปิดใช้งานเสมอ ดังนั้นหากโมเดลไม่ได้ข้ามขั้นตอนการคิดในคำขอที่เรียบง่าย รายการจะเริ่มต้นด้วยบล็อก thinking ซึ่งโดยปกติจะมีข้อความว่างเปล่า และ response.content[0].text จะไม่ใช่คำตอบที่คุณต้องการ การเขียนลูปเพื่อจัดการส่วนนี้ตั้งแต่วันแรกจะช่วยป้องกันปัญหา "พิมพ์ค่าขยะออกมา" ได้อย่างถาวร

ให้ใช้ ID ของโมเดลที่ระบุไว้คือ claude-opus-5-5 ตั้งแต่รุ่น 4.6 เป็นต้นมา ID ของโมเดลจะไม่มีการระบุวันที่ และ ID ที่ไม่มีวันที่นี้คือ snapshot ที่ถูกตรึงไว้ ดังนั้นอย่าใช้ความเคยชิน (หรือบทความเก่า) ที่บอกให้คุณเติม suffix วันที่ต่อท้ายชื่อโมเดลปัจจุบัน เพราะจะทำให้เกิดข้อผิดพลาด 404 ซึ่งจะกล่าวถึงในหัวข้อถัดไป ส่วนโมเดลรุ่นเก่าจะทำงานในทางกลับกัน โดย ID มาตรฐานของ Haiku 4.5 คือ claude-haiku-4-5-20251001 ที่มีการระบุวันที่ไว้

เครื่องมือจริง: คำอธิบาย

นี่คือโปรแกรมฉบับสมบูรณ์ ซึ่งรับข้อมูลผ่าน stdin, ส่งออกการวินิจฉัยแบบสตรีม และจัดการข้อผิดพลาดไว้แล้ว:

#!/usr/bin/env python3
"""explain: pipe an error or log excerpt in, get a diagnosis out."""
import sys
import anthropic

MODEL = "claude-opus-5-5"

def main() -> int:
    text = sys.stdin.read().strip()
    if not text:
        print("usage: journalctl -u nginx -n 50 | explain", file=sys.stderr)
        return 1

    client = anthropic.Anthropic()
    try:
        with client.messages.stream(
            model=MODEL,
            max_tokens=4096,
            system=(
                "You are a senior Linux sysadmin. The user pipes you server "
                "logs or error output. Name the most likely cause outright, "
                "then give the commands to confirm and fix it. Be terse."
            ),
            messages=[{"role": "user", "content": text}],
        ) as stream:
            for chunk in stream.text_stream:
                print(chunk, end="", flush=True)
        print()
    except anthropic.RateLimitError as e:
        retry_after = e.response.headers.get("retry-after", "60")
        print(f"rate limited; retry in {retry_after}s", file=sys.stderr)
        return 2
    except anthropic.APIStatusError as e:
        print(f"API error {e.status_code}: {e.message}", file=sys.stderr)
        return 2
    except anthropic.APIConnectionError:
        print("network error reaching the API", file=sys.stderr)
        return 2
    return 0

if __name__ == "__main__":
    sys.exit(main())

บันทึกไฟล์นี้เป็น /opt/explain/explain.py จากนั้นเพิ่ม wrapper เพื่อโหลดคีย์สำหรับการใช้งานแบบโต้ตอบ:

sudo tee /usr/local/bin/explain >/dev/null <<'EOF'
#!/bin/sh
set -a; . /etc/claude-explain.env; set +a
exec /opt/explain/venv/bin/python /opt/explain/explain.py "$@"
EOF
sudo chmod 755 /usr/local/bin/explain

(wrapper จำเป็นต้องรันผ่าน sudo หรือไฟล์ env ต้องอยู่ในกลุ่มที่ผู้ดูแลระบบของคุณเป็นสมาชิกอยู่ ให้เลือกวิธีใดวิธีหนึ่งอย่างตั้งใจ แทนที่จะลดระดับสิทธิ์ไฟล์เป็น 644)

ทำไมต้องสตรีม client.messages.stream จะพิมพ์โทเค็นออกมาทันทีที่ได้รับ แทนที่จะนิ่งเงียบจนกว่าจะสร้างข้อความเสร็จสมบูรณ์ และยังช่วยเลี่ยงปัญหา HTTP timeout เมื่อผลลัพธ์มีความยาวมาก โดย SDK จะปฏิเสธค่า max_tokens ที่มีขนาดใหญ่มากในการเรียกแบบไม่สตรีมด้วยเหตุผลนี้เอง text_stream จะส่งคืนเฉพาะข้อความคำตอบเท่านั้น และด้วยการตั้งค่าแสดงผลการคิดเริ่มต้นใน Opus 5.5 จะไม่มีการสตรีมข้อความการคิดออกมา ทำให้ผลลัพธ์ที่ได้สะอาดตา หากคุณต้องการวัตถุที่ประกอบเสร็จแล้วในภายหลัง ให้เรียก stream.get_final_message() ภายในบล็อก with

ทำไมต้องเรียงลำดับข้อยกเว้นแบบนั้น SDK จะยกข้อยกเว้นตามประเภท โดยเรียงจากกรณีเฉพาะเจาะจงที่สุดก่อน: RateLimitError คือสถานะ 429 และมีส่วนหัว retry-after ที่ระบุระยะเวลาที่คุณต้องรอ; APIStatusError ครอบคลุมการตอบกลับที่ไม่ใช่ 2xx อื่นๆ (ให้ตรวจสอบ e.status_code >= 500 สำหรับปัญหาที่ฝั่งเซิร์ฟเวอร์); APIConnectionError หมายความว่าคำขอไม่ได้รับการตอบกลับเลย และก่อนที่คุณจะสร้างลูปสำหรับลองใหม่: SDK ได้ทำการลองใหม่สำหรับข้อผิดพลาด 429 และ 5xx ด้วยตัวเองแล้ว โดยค่าเริ่มต้นจะลอง 2 ครั้งพร้อมการถอยกลับแบบทวีคูณ (max_retries บนฝั่งไคลเอนต์) เมื่อถึงเวลาที่ except ของคุณทำงาน การลองใหม่ทั้งหมดก็ถูกใช้ไปจนหมดแล้ว ดังนั้นสิ่งที่ควรทำใน CLI คือการรายงานผลและจบการทำงาน ไม่ใช่การสั่ง sleep แล้วส่งคำขอซ้ำไปเรื่อยๆ

การควบคุมค่าใช้จ่าย

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

max_tokens คือเพดานการใช้จ่ายต่อการเรียกใช้งานหนึ่งครั้ง โทเค็นขาออก (output tokens) คือส่วนที่มีราคาสูง โดยในรุ่น Opus 5.5 จะมีราคาสูงกว่าโทเค็นขาเข้าถึง 5 เท่า และ max_tokens คือขีดจำกัดสูงสุดของจำนวนโทเค็นที่โมเดลจะสร้างได้ ดังนั้น prompt ที่ทำงานผิดพลาดจะไม่สามารถสร้างค่าใช้จ่ายขาออกเกินกว่าที่คุณกำหนดไว้ สำหรับโมเดลรุ่น 5.5 ขีดจำกัดนี้จะครอบคลุมถึงการประมวลผลความคิด (thinking) ด้วย โดยโทเค็นการคิดจะถูกนับรวมใน max_tokens และคิดราคาเสมือนเป็นโทเค็นขาออก แม้ว่าข้อความการคิดนั้นจะไม่ถูกส่งกลับมาให้คุณก็ตาม ให้กำหนดขนาดให้เหมาะสมกับงาน: 4,096 โทเค็นเพียงพอสำหรับการวิเคราะห์ log แบบกระชับโดยมีพื้นที่เหลือสำหรับการคิด ส่วนงานจำพวกการจัดหมวดหมู่ต้องการจำนวนที่น้อยกว่ามาก หากการตอบสนองถูกตัดจบด้วย stop_reason: "max_tokens" แสดงว่าคุณกำหนดขนาดไว้จำกัดเกินไป ให้เพิ่มขนาดอย่างรอบคอบ (หรือลดการตั้งค่าความพยายามเพื่อให้โมเดลคิดน้อยลง) แทนที่จะตั้งค่าเป็นขนาดใหญ่ไว้ก่อนเสมอ

นับจำนวนก่อนส่ง ข้อมูลขาเข้าก็มีค่าใช้จ่ายและ log มักจะมีขนาดใหญ่ API มี endpoint สำหรับการนับโทเค็นที่ใช้งานได้ฟรี (มีอัตราการจำกัดการเรียกใช้งานแยกต่างหากจากการสร้างข้อความ):

count = client.messages.count_tokens(
    model="claude-opus-5-5",
    messages=[{"role": "user", "content": big_log_text}],
)
print(count.input_tokens)

ใช้เครื่องมือนี้เพื่อป้องกันการส่ง log ขนาด 2 GB ผ่านเครื่องมือโดยไม่ตั้งใจ และต้องระบุโมเดลที่คุณจะเรียกใช้งานจริง: Claude 4.7 และรุ่นใหม่กว่าใช้ tokenizer แบบใหม่ที่สร้างโทเค็นมากกว่ารุ่นก่อนหน้าประมาณ 30% สำหรับข้อความเดียวกัน ห้ามใช้ tiktoken สำหรับงานนี้ เนื่องจากเป็น tokenizer ของ OpenAI ไม่ใช่ของ Claude ดังนั้นจำนวนที่นับได้จะไม่ตรงกับยอดที่คุณถูกเรียกเก็บเงินจริง

เลือกโมเดลตามงาน ไม่ใช่ตามความนิยม ณ เดือนตุลาคม 2026 รุ่น Opus 5.5 (claude-opus-5-5) มีราคา $4 ต่อล้านโทเค็นขาเข้า และ $20 ต่อล้านโทเค็นขาออก; รุ่น Haiku 5.5 (claude-haiku-5-5) มีราคา $0.10/$0.50 สำหรับ prompt ที่ไม่เกิน 100,000 โทเค็น ($0.50/$2.50 หากเกินกว่านั้น) โดยรองรับ context สูงสุด 1M; รุ่น Sonnet 5.5 (claude-sonnet-5-5) อยู่ในระดับกลางที่ $2/$10 ตัวอย่างเช่น: log ขนาด 2,000 โทเค็นพร้อมคำตอบ 500 โทเค็น จะมีค่าใช้จ่ายประมาณ $0.018 บน Opus และ $0.00045 บน Haiku บวกกับค่าใช้จ่ายจากการคิดของโมเดลซึ่งคิดราคาเป็นขาออก ให้เริ่มต้นด้วย Opus ในช่วงที่คุณกำลังประเมินคุณภาพผลลัพธ์ จากนั้นลองใช้ prompt เดียวกันกับ Haiku สำหรับงานแปลงข้อมูลปริมาณมากที่เรียบง่าย ผลลัพธ์มักไม่แตกต่างกันในราคาที่ถูกกว่าถึง 40 เท่า โปรดตรวจสอบราคาปัจจุบันที่หน้าเว็บไซต์ราคาก่อนที่จะกำหนดค่าเหล่านี้ลงในงบประมาณ

ใช้ Batches สำหรับงานที่รอได้ Batches API จะประมวลผลคำขอแบบอะซิงโครนัสในราคา 50% ของราคาปกติ และ batch ส่วนใหญ่จะเสร็จสิ้นภายในหนึ่งชั่วโมง งานจำพวกสรุปข้อมูลรายคืน, การประมวลผลย้อนหลัง, การจัดหมวดหมู่จำนวนมาก หรืออะไรก็ตามที่ไม่มีมนุษย์รอผลลัพธ์อยู่ ควรใช้ช่องทางนี้

การทำ Prompt caching สำหรับ context ที่ใช้ซ้ำ หากทุกการเรียกใช้งานมีการส่ง system prompt หรือคู่มือการทำงานขนาดใหญ่ซ้ำๆ ให้ทำเครื่องหมายว่าสามารถแคชได้:

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1000,
    system=[{
        "type": "text",
        "text": RUNBOOK_TEXT,  # the same 30K tokens on every call
        "cache_control": {"type": "ephemeral"},
    }],
    messages=[{"role": "user", "content": question}],
)
print(response.usage.cache_read_input_tokens)  # non-zero from the second call on

การเขียนแคชมีค่าใช้จ่าย 1.25 เท่าของราคาขาเข้าโดยมี TTL 5 นาที และการอ่านแคชมีค่าใช้จ่าย 0.05 เท่าบน Opus 5.5 และ Sonnet 5.5 (0.1 เท่าบนโมเดลส่วนใหญ่) ดังนั้นการเรียกใช้งานครั้งที่สองภายในช่วงเวลาดังกล่าวจะคุ้มค่ากับค่าใช้จ่ายครั้งแรกทันที มีข้อควรระวัง 2 ประการ: ส่วนนำ (prefix) ที่แคชไว้ต้องมีขนาดถึงขั้นต่ำของโมเดลนั้นๆ คือ 512 โทเค็นบน Opus 5.5 ดังนั้น system prompt ที่สั้นเกินไปจะไม่ถูกแคชเลย และหาก cache_read_input_tokens ยังคงเป็นศูนย์ในการเรียกใช้งานที่เหมือนกันทุกประการ แสดงว่ามีบางอย่างในส่วนนำของคุณเปลี่ยนแปลงไปในทุกคำขอ (มักเกิดจาก timestamp)

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

การรันภายใต้ systemd

ผลตอบแทนของการจัดการไฟล์ environment-file อย่างเป็นระเบียบ คือการมีตัวตั้งเวลาที่สรุปข้อผิดพลาดของเมื่อวานนี้ในทุกเช้า

# /etc/systemd/system/log-digest.service
[Unit]
Description=Daily error-log digest via the Claude API

[Service]
Type=oneshot
User=explain
Group=systemd-journal
EnvironmentFile=/etc/claude-explain.env
ExecStart=/bin/sh -c 'journalctl -p err --since yesterday | /opt/explain/venv/bin/python /opt/explain/explain.py >> /var/log/log-digest.txt'
# /etc/systemd/system/log-digest.timer
[Unit]
Description=Run the log digest every morning

[Timer]
OnCalendar=06:15
Persistent=true

[Install]
WantedBy=timers.target
sudo useradd -r -s /usr/sbin/nologin explain
sudo touch /var/log/log-digest.txt && sudo chown explain /var/log/log-digest.txt
sudo systemctl daemon-reload
sudo systemctl enable --now log-digest.timer
sudo systemctl start log-digest.service   # test it once, right now

โปรดสังเกตสิ่งที่ EnvironmentFile= มอบให้แก่คุณ: systemd จะอ่านไฟล์ที่เป็นของ root และมีสิทธิ์แบบ 600 ก่อน ที่จะเปลี่ยนสิทธิ์ไปเป็นผู้ใช้ explain ที่ไม่มีสิทธิ์พิเศษ ดังนั้นกระบวนการทำงานจึงได้รับตัวแปรดังกล่าวในขณะที่ผู้ใช้ไม่สามารถอ่านไฟล์คีย์ได้ กลุ่ม systemd-journal จะเป็นผู้ให้สิทธิ์ในการเข้าถึงบันทึก (log) ให้ทดสอบด้วยการใช้ systemctl start ด้วยตนเองและอ่าน journalctl -u log-digest.service อย่ารอจนถึงเวลา 06:15 เพื่อตรวจสอบหาคำผิด เมื่อรูปแบบนี้มีความซับซ้อนเกินกว่าที่จะใช้ shell pipeline วิธีการเก็บคีย์ไว้ในไฟล์ environment-file แบบเดิมนี้สามารถนำไปใช้ต่อกับ เวิร์กโฟลว์ n8n ที่ขับเคลื่อนด้วย Claude บนเครื่องเดียวกันได้โดยตรง

รูปแบบความล้มเหลวและข้อความที่คุณจะพบ

401 ทั้งที่ key ใช้งานได้จริง ข้อยกเว้นที่แสดงคือ:

anthropic.AuthenticationError: Error code: 401 - {'type': 'error', 'error': {'type': 'authentication_error', 'message': 'invalid x-api-key'}, 'request_id': 'req_011CSHoEeqs5C35K2UUqR7Fy'}

หาก key ใช้งานได้ใน shell ของคุณแต่ service กลับตอบกลับเป็น 401 แสดงว่า service ไม่ได้รับ key ดังกล่าว โปรดจำไว้ว่า systemd ไม่ได้อ่าน .bashrc ให้ตรวจสอบว่า EnvironmentFile= ชี้ไปยัง path ที่ถูกต้อง สาเหตุอื่นที่เป็นไปได้: มีเครื่องหมายคำพูดติดมาในไฟล์ env (ANTHROPIC_API_KEY="sk-ant-..." ซึ่ง systemd จะตัดเครื่องหมายคำพูดออก แต่ . file ใน shell wrapper ของคุณอาจเก็บเครื่องหมายนั้นไว้ในค่าตัวแปรหากคุณใส่เครื่องหมายคำพูดไว้ไม่เหมาะสม), มีช่องว่างส่วนเกิน, key ที่คุณเพิ่งยกเลิกใน Console ไปเมื่อสัปดาห์ก่อน หรือ key ที่หมดอายุตามกำหนดที่คุณตั้งไว้ตอนสร้าง

404 จากการพิมพ์ชื่อโมเดลผิด รูปแบบที่พบบ่อยที่สุดคือการเติม suffix วันที่ให้กับ ID โมเดลที่ไม่มีรูปแบบระบุวันที่:

anthropic.NotFoundError: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-opus-5-5-20260922'}, 'request_id': 'req_011CSJqymAvNw4bT3qmDdMbA'}

ID ของโมเดลรุ่นปัจจุบันต้องพิมพ์ให้ถูกต้องแม่นยำ เช่น claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5, claude-fable-5-1 โมเดลที่เก่ากว่ารุ่น 4.6 เป็นข้อยกเว้น: claude-haiku-4-5 เป็นชื่อเรียกแทน (alias) เพื่อความสะดวกสำหรับ ID ที่ระบุวันที่คือ claude-haiku-4-5-20251001 ซึ่งทั้งสองรูปแบบสามารถใช้งานได้ ให้คัดลอก ID จากเอกสารประกอบของโมเดลเท่านั้น ห้ามพิมพ์เองจากความจำหรือจากบทช่วยสอนเก่า

429 rate_limit_error สตริงประเภทข้อผิดพลาดคือ rate_limit_error และการตอบกลับจะมี header retry-after ระบุจำนวนวินาทีที่ต้องรอ SDK ได้พยายามลองใหม่ (retry) สองครั้งพร้อมการหน่วงเวลา (backoff) ก่อนที่คุณจะเห็นข้อยกเว้นนี้ ดังนั้นหากยังคงพบ 429 แสดงว่าอัตราการใช้งานของคุณเกินขีดจำกัดของ tier ที่ได้รับจริง ให้ใช้วิธี batch งานหรือกระจายการส่งคำขอ อย่าเพิ่มความถี่ในการ retry

พิมพ์ออกมาเป็น object ไม่ใช่ข้อความ ผลลัพธ์ที่ได้มีลักษณะเป็น [TextBlock(citations=None, text='...', type='text')] คุณอาจสั่งพิมพ์ response.content แทนที่จะวนลูปผ่านบล็อกต่างๆ แล้วอ่านค่า .text จากบล็อกที่ block.type == "text" ตัวอย่าง SDK ทุกรายการข้างต้นทำไว้อย่างถูกต้องแล้ว ให้คัดลอกรูปแบบการวนลูปไปใช้

error: externally-managed-environment คุณรันคำสั่ง pip install กับ Python หลักของระบบบน Ubuntu 24.04 ให้ใช้ venv เสมอ ห้ามใช้ --break-system-packages บนเซิร์ฟเวอร์ที่คุณต้องการดูแลรักษา

คำตอบถูกตัดทอน response.stop_reason == "max_tokens" หมายความว่าโมเดลทำงานถึงขีดจำกัดของ output ที่คุณตั้งไว้ในขณะที่กำลังประมวลผล นี่คือการทำงานตามปกติ ให้เพิ่มขีดจำกัดอย่างตั้งใจ และโปรดจำไว้ว่าในโมเดลรุ่น 5.5 กระบวนการคิด (thinking) จะใช้โควตาจากขีดจำกัดเดียวกันนี้

เมื่อแอปแรกของคุณทำงานได้แล้ว การสร้าง AI agent ด้วย Claude จะเปลี่ยนการเรียก API เหล่านั้นให้กลายเป็น agent ที่สามารถใช้เครื่องมือต่างๆ ได้

FAQ

Claude API มีค่าใช้จ่ายในการทดลองใช้งานเท่าไร?

ถือว่าน้อยมากสำหรับเครื่องมือระดับนี้ ณ เดือนตุลาคม 2026 รุ่น Opus 5.5 มีค่าใช้จ่ายอยู่ที่ 4 ดอลลาร์ต่อ 1 ล้าน input tokens และ 20 ดอลลาร์ต่อ 1 ล้าน output tokens ดังนั้นการวิเคราะห์ log ทั่วไปที่ใช้ input ประมาณสองสามพัน tokens และ output อีกไม่กี่ร้อย tokens จะมีค่าใช้จ่ายประมาณ 2 เซนต์ (ยังไม่รวม thinking tokens ซึ่งคิดราคาเท่ากับ output) ส่วนรุ่น Haiku 5.5 (0.10 ดอลลาร์ / 0.50 ดอลลาร์) จะมีค่าใช้จ่ายไม่ถึงหนึ่งในสิบของเซนต์ การสรุปผลรายวันตลอดทั้งเดือนมีค่าใช้จ่ายน้อยกว่าค่ากาแฟหนึ่งแก้ว ความเสี่ยงไม่ได้อยู่ที่ราคาต่อการเรียกใช้งาน แต่อยู่ที่การเกิดลูปไม่จำกัดและการใช้ max_tokens ที่ไม่จำกัด ซึ่งเป็นเหตุผลว่าทำไมคู่มือนี้จึงกำหนดค่าทั้งสองอย่างไว้อย่างชัดเจน

Claude API มีระดับการใช้งานฟรีหรือไม่?

ไม่มีระดับการใช้งานฟรีแบบต่อเนื่อง ณ เดือนตุลาคม 2026 เอกสารราคาของ Anthropic ระบุว่าผู้ใช้ใหม่จะได้รับเครดิตฟรีจำนวนหนึ่งเพื่อทดสอบ API ซึ่งเป็นการทดลองใช้งานครั้งเดียว โดยจำนวนที่แน่นอนจะแสดงใน Console เมื่อสมัครใช้งาน หลังจากนั้นคุณจะต้องเติมเงินเข้าบัญชี ยกเว้นผู้สมัครสมาชิกแผน Max และ Team ซึ่งแผนดังกล่าวจะรวมเครดิต API รายเดือนไว้ให้แล้ว หากเป้าหมายของคุณคือการไม่มีต้นทุนส่วนเพิ่มต่อการเรียกใช้งานแทนที่จะเน้นคุณภาพระดับสูงสุด ทางเลือกอื่นคือการ self-host open-weight model ด้วย Ollama และจ่ายเป็นทรัพยากร RAM แทนการจ่ายเป็น tokens

ฉันจะรักษาความปลอดภัยของ API key บนเซิร์ฟเวอร์ได้อย่างไร?

ห้ามเก็บไว้ในโค้ด ห้ามเก็บไว้ใน git ห้าม export ออกมาจาก .bashrc และห้ามพิมพ์ลงใน shell ที่ประวัติการใช้งานจะบันทึกคีย์นั้นไว้ ให้เก็บไว้ในไฟล์ที่ root เป็นเจ้าของโดยกำหนดสิทธิ์เป็น 600 โหลดคีย์แยกตาม process ใช้ wrapper script สำหรับการใช้งานแบบโต้ตอบ ใช้ EnvironmentFile= สำหรับ systemd และจำกัดคีย์หนึ่งชุดต่อหนึ่งเซิร์ฟเวอร์หรือหนึ่งโปรเจกต์ เพื่อให้การเพิกถอนคีย์ที่หลุดออกไปทำได้เฉพาะจุด ไม่ส่งผลกระทบต่อส่วนอื่น หากคีย์หลุดไปบนเว็บไซต์วางข้อความหรือ git commit ให้เพิกถอนคีย์นั้นใน Console ทันที การลบ commit ไม่ได้หมายความว่าคีย์นั้นจะปลอดภัยแล้ว

ฉันควรเริ่มต้นด้วย Claude รุ่นใด?

เริ่มต้นด้วย claude-opus-5-5 ในระหว่างที่คุณกำลังประเมินว่าผลลัพธ์ที่ได้นั้นดีพอที่จะนำไปพัฒนาต่อหรือไม่ คุณควรตัดสินใจจากคุณภาพที่สูงสุดก่อน และสำหรับปริมาณการใช้งานระดับงานอดิเรก ส่วนต่างของราคานั้นเป็นเพียงแค่เศษเซนต์เท่านั้น เมื่อ prompt ลงตัวแล้ว ให้ลองรัน input จริงของคุณบน claude-haiku-5-5 อีกครั้ง สำหรับงานสรุปความ จัดหมวดหมู่ และการคัดกรอง log รุ่นนี้มักจะให้ผลลัพธ์ที่ดีเพียงพอในราคาต่อ token ที่ถูกกว่าถึง 40 เท่า ควรเปลี่ยนไปใช้ Haiku หรือ Sonnet โดยอิงจากการวัดผลจริง ไม่ใช่การเลือกตามค่าเริ่มต้น