กลับไป Workshop
AI Engineering · 19 ก.ย. 2026 · ลงมือทำ ~30 นาที

ให้ Claude เรียกฟังก์ชันของคุณครั้งแรก: จับมือกันรอบเดียวใน 30 นาที

#Claude API#Python#Tool Use#AI Engineering
จบ workshop นี้คุณจะได้

ไฟล์ ask_file.py ของคุณเองที่ Claude ขอให้มันอ่านไฟล์ในเครื่องคุณได้จริง โดยคุณเป็นคนรันฟังก์ชันเอง พร้อมเข้าใจคำว่า tool, tool_use, tool_result และ stop_reason ซึ่งเป็นชิ้นส่วนสุดท้ายก่อนถึง agent

ระดับ เริ่มต้น
ใช้งบ ค่า API ไม่ถึง 10 บาท (ทั้งชิ้นเรียกโมเดลราว 8 ครั้ง ใช้เครดิตเดิมจาก workshop ก่อนหน้า)
ต้องมีก่อนเริ่ม ผ่าน workshop แชตมีความจำมาแล้ว (มีไฟล์ chat.py ที่รันผ่าน และตั้ง ANTHROPIC_API_KEY ไว้) · Python 3.10 ขึ้นไป
ให้ Claude เรียกฟังก์ชันของคุณครั้งแรก: จับมือกันรอบเดียวใน 30 นาที

ใน workshop ก่อนหน้า เราได้แชตบอตที่มีบทบาทและจำบทสนทนาได้ แต่มันยังทำได้อย่างเดียวคือ ตอบจากสิ่งที่อยู่ใน messages ถามถึงไฟล์ในเครื่องคุณ ถามยอดขายวันนี้ ถามอะไรที่มันไม่เคยเห็น มันก็ได้แต่เดาหรือขอให้คุณก๊อปมาวาง วันนี้เราจะเปิดประตูบานนั้นด้วยการ ประกาศฟังก์ชันของเราให้มันรู้จัก แล้วให้มันขอเรียกเมื่อจำเป็น

สิ่งที่ต้องเข้าใจก่อนเริ่มและจะเห็นกับตาในขั้นที่ 2 คือ โมเดลไม่ได้รันอะไรเองเลย มันแค่บอกว่าอยากเรียกฟังก์ชันไหนด้วยค่าอะไร คนที่รันจริงคือโค้ดของคุณ แล้วคุณส่งผลกลับเข้าไปใน messages เดิม วันนี้เราทำการจับมือแบบนี้ รอบเดียวจบ ยังไม่มี loop (ภาพใหญ่ว่า agent ทำงานยังไงอ่านได้ใน AI Agent ทำงานยังไง)

ขั้นที่ 1: พิสูจน์ก่อนว่ามันมองไม่เห็นไฟล์ของคุณ

สร้างโฟลเดอร์ใหม่สำหรับชิ้นนี้ แล้วสร้างไฟล์ shopping.py ที่มีบั๊กไว้ให้มันตรวจ (คิดเงินตะกร้าสินค้าแต่ได้ยอดผิด):

# โปรแกรมคิดเงินตะกร้าสินค้า
prices = {"ข้าวสาร": 180, "ไข่ไก่": 145, "นม": 62}
cart = ["ข้าวสาร", "ไข่ไก่", "ไข่ไก่", "นม"]

total = 0
for item in cart:
    total = prices[item]

print("รวมทั้งหมด", total, "บาท")
python3 shopping.py
รวมทั้งหมด 62 บาท

ของ 4 ชิ้นรวมกันต้องได้ 532 บาท แต่ได้ 62 คือราคานมชิ้นเดียว ทีนี้ลองให้ติวเตอร์จาก workshop ก่อนช่วยดู สร้าง no_tool.py:

import anthropic

client = anthropic.Anthropic()
SYSTEM = "คุณคือติวเตอร์สอน Python สำหรับมือใหม่ ตอบเป็นภาษาไทย ไม่เกิน 3 ประโยค ห้ามใช้ศัพท์เทคนิคโดยไม่อธิบาย"

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=800,
    system=SYSTEM,
    messages=[
        {"role": "user", "content": "ไฟล์ shopping.py ในโฟลเดอร์นี้คิดเงินผิด ช่วยดูให้หน่อยว่าบั๊กอยู่บรรทัดไหน"}
    ],
)

print("stop_reason:", response.stop_reason)
for block in response.content:
    if block.type == "text":
        print(block.text)
python3 no_tool.py
stop_reason: end_turn
ตอนนี้ผมยังมองไม่เห็นไฟล์ในเครื่องของคุณนะครับ ผมอ่านได้เฉพาะข้อความที่คุณพิมพ์หรือวางมาในแชทเท่านั้น
รบกวนคัดลอกโค้ดใน shopping.py มาวางให้ดู พร้อมบอกด้วยว่าคิดเงินได้เท่าไร และที่ถูกต้องควรเป็นเท่าไร
แล้วผมจะช่วยหาจุดผิดให้ครับ

จำคำว่า stop_reason: end_turn ไว้ให้ดี แปลว่า “พูดจบแล้ว ไม่ขออะไรเพิ่ม” เดี๋ยวขั้นถัดไปค่านี้จะเปลี่ยน

ได้คำตอบทำนอง “ผมมองไม่เห็นไฟล์ของคุณ” และเห็น end_turn = ผ่าน ไปติดตั้งเครื่องมือให้มันกัน

ขั้นที่ 2: ประกาศ tool ให้มันรู้จัก แล้วดูมันขอเรียก

การประกาศ tool คือการเขียน “เมนู” ให้โมเดลดู 3 อย่าง: ชื่อฟังก์ชัน, คำอธิบายว่าใช้ตอนไหน, และหน้าตาของค่าที่ต้องส่งเข้าฟังก์ชัน (input_schema) สร้าง tool_v1.py โดยเติม TOOLS กับ tools=TOOLS เข้าไป ที่เหลือเหมือนเดิมทุกบรรทัด:

import anthropic

client = anthropic.Anthropic()
SYSTEM = "คุณคือติวเตอร์สอน Python สำหรับมือใหม่ ตอบเป็นภาษาไทย ไม่เกิน 3 ประโยค ห้ามใช้ศัพท์เทคนิคโดยไม่อธิบาย"

TOOLS = [
    {
        "name": "read_file",
        "description": "อ่านไฟล์ข้อความในโฟลเดอร์ปัจจุบันแล้วคืนเนื้อในไฟล์ทั้งหมด ใช้เมื่อผู้ใช้ถามถึงไฟล์ในเครื่องของเขาโดยระบุชื่อไฟล์",
        "input_schema": {
            "type": "object",
            "properties": {
                "filename": {
                    "type": "string",
                    "description": "ชื่อไฟล์ที่จะอ่าน เช่น shopping.py",
                }
            },
            "required": ["filename"],
        },
    }
]

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=800,
    system=SYSTEM,
    tools=TOOLS,
    messages=[
        {"role": "user", "content": "ไฟล์ shopping.py ในโฟลเดอร์นี้คิดเงินผิด ช่วยดูให้หน่อยว่าบั๊กอยู่บรรทัดไหน"}
    ],
)

print("stop_reason:", response.stop_reason)
for block in response.content:
    print("block:", block.type)
    if block.type == "tool_use":
        print("  ขอเรียก:", block.name)
        print("  ด้วยค่า:", block.input)
        print("  id:", block.id)
python3 tool_v1.py
stop_reason: tool_use
block: tool_use
  ขอเรียก: read_file
  ด้วยค่า: {'filename': 'shopping.py'}
  id: toolu_017PnTy5JCvaMMytFtmaYg3b

หยุดดูตรงนี้ให้นานหน่อย เพราะนี่คือหัวใจของทั้งเรื่อง ไฟล์ยังไม่ถูกเปิดเลยสักครั้ง เรายังไม่ได้เขียนฟังก์ชัน read_file ด้วยซ้ำ สิ่งที่เกิดขึ้นคือโมเดลอ่านเมนูแล้วตอบกลับมาว่า “ขอเรียก read_file ด้วย filename เท่ากับ shopping.py นะ” เท่านั้น

  • stop_reason เปลี่ยนจาก end_turn เป็น tool_use คือสัญญาณว่ามันหยุดพูดกลางคันเพื่อรอของจากเรา
  • block.input คือค่าที่มันกรอกให้เองตาม input_schema ที่เราประกาศไว้
  • block.id คือเลขใบสั่งงาน ตอนส่งผลกลับต้องอ้างเลขนี้ให้ตรง ไม่งั้นมันไม่รู้ว่าผลลัพธ์นี้ตอบคำขอไหน

ถ้าคุณเห็น block: thinking โผล่มาก่อนด้วยก็ไม่ผิด รุ่นที่คิดก่อนตอบจะส่งก้อนความคิดมาเป็น block แรกเสมอ นี่คือเหตุผลที่เราวน loop เช็ก block.type แทนที่จะหยิบ content[0] ตรง ๆ

เห็น stop_reason: tool_use และเห็นชื่อไฟล์ที่มันขอ = ผ่าน คราวนี้ถึงตาเราลงมือรันให้มัน

ขั้นที่ 3: รันฟังก์ชันเอง แล้วส่งผลกลับด้วย tool_result

การจับมือครบรอบมี 3 จังหวะ: เก็บคำขอของมันเข้า messages, รันฟังก์ชันจริง, แล้วส่งผลกลับเป็นข้อความชนิด tool_result ที่อ้าง id เดิม จากนั้นเรียกโมเดลอีกครั้งด้วย messages ที่ยาวขึ้น สร้าง tool_v2.py:

import anthropic

client = anthropic.Anthropic()
SYSTEM = "คุณคือติวเตอร์สอน Python สำหรับมือใหม่ ตอบเป็นภาษาไทย ไม่เกิน 3 ประโยค ห้ามใช้ศัพท์เทคนิคโดยไม่อธิบาย"

TOOLS = [
    {
        "name": "read_file",
        "description": "อ่านไฟล์ข้อความในโฟลเดอร์ปัจจุบันแล้วคืนเนื้อในไฟล์ทั้งหมด ใช้เมื่อผู้ใช้ถามถึงไฟล์ในเครื่องของเขาโดยระบุชื่อไฟล์",
        "input_schema": {
            "type": "object",
            "properties": {
                "filename": {
                    "type": "string",
                    "description": "ชื่อไฟล์ที่จะอ่าน เช่น shopping.py",
                }
            },
            "required": ["filename"],
        },
    }
]

def read_file(filename):          # ฟังก์ชันจริงของเรา Claude ไม่เคยแตะไฟล์เอง
    with open(filename, encoding="utf-8") as f:
        return f.read()

messages = [
    {"role": "user", "content": "ไฟล์ shopping.py ในโฟลเดอร์นี้คิดเงินผิด ช่วยดูให้หน่อยว่าบั๊กอยู่บรรทัดไหน"}
]

first = client.messages.create(
    model="claude-opus-5", max_tokens=800, system=SYSTEM, tools=TOOLS, messages=messages,
)

tool_use = next(b for b in first.content if b.type == "tool_use")
print("มันขออ่าน:", tool_use.input["filename"])

result = read_file(tool_use.input["filename"])     # 1) เรารันเอง
print("เราอ่านไฟล์ได้", len(result), "ตัวอักษร ส่งกลับให้มัน\n")

messages.append({"role": "assistant", "content": first.content})   # 2) เก็บคำขอของมัน
messages.append({                                                  # 3) ส่งผลกลับเป็น tool_result
    "role": "user",
    "content": [
        {"type": "tool_result", "tool_use_id": tool_use.id, "content": result}
    ],
})

second = client.messages.create(
    model="claude-opus-5", max_tokens=800, system=SYSTEM, tools=TOOLS, messages=messages,
)

print("stop_reason:", second.stop_reason)
for block in second.content:
    if block.type == "text":
        print(block.text)
python3 tool_v2.py
มันขออ่าน: shopping.py
เราอ่านไฟล์ได้ 214 ตัวอักษร ส่งกลับให้มัน

stop_reason: end_turn
บั๊กอยู่บรรทัดที่ 7 คือ `total = prices[item]` ซึ่งเป็นการ "เขียนทับ" ยอดเดิมทุกครั้ง ทำให้เหลือแค่
ราคาของชิ้นสุดท้าย (นม 62 บาท) แก้เป็น `total += prices[item]` ซึ่งหมายถึง "บวกเพิ่มเข้าไปในยอดเดิม"
แล้วผลลัพธ์จะได้ 532 บาทตามที่ควรเป็น

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

สังเกต messages ที่โตขึ้นด้วย ตอนนี้มันมี 3 ข้อความ: คำถามของเรา, คำขอของมัน (assistant), และผลลัพธ์ที่เราส่งกลับ (user) ซึ่งเป็น list เดียวกับความจำที่เราสร้างใน workshop ก่อน ไม่มีของใหม่

มันตอบโดยอ้างเนื้อในไฟล์ได้ถูกต้อง และ stop_reason กลับมาเป็น end_turn = ผ่าน จับมือครบรอบแล้ว

ขั้นที่ 4: ปล่อยให้มันเลือกเองว่าจะใช้เครื่องมือไหม

ข้อที่คนเข้าใจผิดบ่อยคือคิดว่าประกาศ tool แล้วโมเดลจะเรียกทุกครั้ง ความจริงคือมันอ่าน description แล้วตัดสินใจเองทุกรอบ ลองพิสูจน์ด้วยการทำให้คำถามพิมพ์จากบรรทัดคำสั่งได้ สร้าง ask_file.py (เวอร์ชันนี้จะเป็นไฟล์จบของ workshop เดี๋ยวขั้นที่ 5 มาแก้ต่อ):

import sys
import anthropic

client = anthropic.Anthropic()
SYSTEM = "คุณคือติวเตอร์สอน Python สำหรับมือใหม่ ตอบเป็นภาษาไทย ไม่เกิน 3 ประโยค ห้ามใช้ศัพท์เทคนิคโดยไม่อธิบาย"

TOOLS = [
    {
        "name": "read_file",
        "description": "อ่านไฟล์ข้อความในโฟลเดอร์ปัจจุบันแล้วคืนเนื้อในไฟล์ทั้งหมด ใช้เมื่อผู้ใช้ถามถึงไฟล์ในเครื่องของเขาโดยระบุชื่อไฟล์",
        "input_schema": {
            "type": "object",
            "properties": {
                "filename": {"type": "string", "description": "ชื่อไฟล์ที่จะอ่าน เช่น shopping.py"}
            },
            "required": ["filename"],
        },
    }
]

def read_file(filename):
    with open(filename, encoding="utf-8") as f:
        return f.read()

question = sys.argv[1]
messages = [{"role": "user", "content": question}]

first = client.messages.create(
    model="claude-opus-5", max_tokens=800, system=SYSTEM, tools=TOOLS, messages=messages,
)
print("รอบที่ 1 stop_reason:", first.stop_reason)

if first.stop_reason != "tool_use":
    for block in first.content:
        if block.type == "text":
            print(block.text)
    sys.exit()

tool_use = next(b for b in first.content if b.type == "tool_use")
print("มันขออ่าน:", tool_use.input["filename"])
messages.append({"role": "assistant", "content": first.content})
messages.append({
    "role": "user",
    "content": [{"type": "tool_result", "tool_use_id": tool_use.id, "content": read_file(tool_use.input["filename"])}],
})

second = client.messages.create(
    model="claude-opus-5", max_tokens=800, system=SYSTEM, tools=TOOLS, messages=messages,
)
print("รอบที่ 2 stop_reason:", second.stop_reason)
for block in second.content:
    if block.type == "text":
        print(block.text)

ลองถามคำถามที่ไม่เกี่ยวกับไฟล์เลย ทั้งที่ประกาศ tool ไว้แล้ว:

python3 ask_file.py "list กับ tuple ต่างกันยังไง"
รอบที่ 1 stop_reason: end_turn
list (ลิสต์) คือกล่องเก็บของหลายชิ้นที่แก้ไขได้ เช่น เพิ่ม ลบ หรือเปลี่ยนค่าข้างในได้ เขียนด้วยวงเล็บ
เหลี่ยม `[1, 2, 3]` ส่วน tuple (ทูเพิล) เขียนด้วยวงเล็บโค้ง `(1, 2, 3)` และแก้ไขไม่ได้เลยหลังสร้างเสร็จ
จึงเหมาะกับข้อมูลที่ไม่ควรเปลี่ยน เช่น พิกัดตำแหน่ง หรือวันเดือนปีเกิด

มันไม่เรียก tool เลยเพราะตอบเองได้ นี่คือเหตุผลที่ description สำคัญกว่าที่คิด มันคือข้อความเดียวที่โมเดลใช้ตัดสินว่างานนี้ต้องพึ่งเครื่องมือหรือไม่ ลองแก้ description ให้กำกวมเช่นเหลือแค่ “อ่านไฟล์” แล้วถามคำถามเดิมกับขั้นที่ 1 ดูว่าพฤติกรรมเปลี่ยนไหม เป็นการทดลองที่คุ้มค่า 1 นาที

คำถามทั่วไปได้ end_turn ไม่เรียก tool ส่วนคำถามเรื่องไฟล์ได้ tool_use = ผ่าน มันเลือกเองเป็นแล้ว

ขั้นที่ 5: ถามคำถามที่ต้องใช้ 2 ไฟล์ แล้วดูสคริปต์พังทั้งที่โค้ดไม่ผิด

สร้างไฟล์ที่สองชื่อ report.py ซึ่งตั้งราคาข้าวสารไว้ไม่ตรงกับ shopping.py (175 กับ 180):

# รายงานยอดขายประจำวัน
prices = {"ข้าวสาร": 175, "ไข่ไก่": 145, "นม": 62}
sold = {"ข้าวสาร": 3, "ไข่ไก่": 12, "นม": 5}

total = 0
for item, count in sold.items():
    total += prices[item] * count

print("ยอดขายวันนี้", total, "บาท")

แล้วถามคำถามที่ต้องเปิดทั้งสองไฟล์ถึงจะตอบได้:

python3 ask_file.py "shopping.py กับ report.py ตั้งราคาข้าวสารตรงกันไหม"
รอบที่ 1 stop_reason: tool_use
มันขออ่าน: shopping.py
Traceback (most recent call last):
  ...
anthropic.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type':
'invalid_request_error', 'message': 'messages.2: `tool_use` ids were found without
`tool_result` blocks immediately after: toolu_017LTwv8ryGN27vpZC7bNBAL. Each `tool_use`
block must have a corresponding `tool_result` block in the next message.'}}

โค้ดเราไม่ได้ผิดสักบรรทัด สิ่งที่เกิดขึ้นคือ โมเดลขอเรียก read_file มา 2 ครั้งพร้อมกันในเทิร์นเดียว (ขอทั้ง shopping.py และ report.py เพราะรู้ว่าต้องเทียบกัน) แต่บรรทัด next(...) ของเราหยิบมาตอบแค่อันแรก กติกาของ API คือ ทุก tool_use ต้องมี tool_result ตอบครบทุกอันในข้อความถัดไป ขาดอันเดียวก็ 400

วิธีแก้คือเลิกคิดว่ามีคำขอเดียว แล้ววน loop เก็บผลให้ครบทุก block แทน ใน ask_file.py ให้ลบส่วนที่ขึ้นต้นด้วย tool_use = next(...) ลงไปจนถึงบรรทัด messages.append อันที่สอง แล้วใส่ชุดนี้แทน:

results = []
for block in first.content:
    if block.type == "tool_use":
        print("  มันขออ่าน:", block.input["filename"])
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": read_file(block.input["filename"]),
        })
messages.append({"role": "assistant", "content": first.content})
messages.append({"role": "user", "content": results})
python3 ask_file.py "shopping.py กับ report.py ตั้งราคาข้าวสารตรงกันไหม"
รอบที่ 1 stop_reason: tool_use
  มันขออ่าน: shopping.py
  มันขออ่าน: report.py
รอบที่ 2 stop_reason: end_turn
ไม่ตรงกันครับ — shopping.py ตั้งข้าวสารไว้ 180 บาท แต่ report.py ตั้งไว้ 175 บาท (ไข่ไก่กับนมตรงกัน
ทั้งคู่) ควรเลือกราคาที่ถูกต้องแล้วแก้ให้เหมือนกันทั้งสองไฟล์ครับ

แถมอีกอย่างที่เจอ: ใน shopping.py บรรทัด `total = prices[item]` ใช้เครื่องหมาย `=` ซึ่งเป็นการ
"แทนที่" ค่าเดิม ทำให้ได้ราคาของชิ้นสุดท้ายอย่างเดียว ควรเปลี่ยนเป็น `total += prices[item]` ที่แปลว่า
"บวกเพิ่มเข้าไป" เหมือนใน report.py ครับ

มันเทียบสองไฟล์ได้ถูกต้อง และแถมบั๊กที่เจอระหว่างทางมาให้โดยไม่ได้สั่ง สังเกตว่าเราไม่ได้เพิ่มความฉลาดอะไรให้มันเลย แค่ตอบคำขอให้ครบเท่านั้น

ได้คำตอบที่เทียบราคาสองไฟล์ถูกต้อง = ผ่าน จบ workshop คุณมี ask_file.py ที่ใช้งานได้จริงแล้ว

ไปต่อจากตรงนี้

วันนี้คุณต่อสายไฟเส้นที่ทำให้ LLM เลิกเป็นแค่กล่องตอบคำถาม ของที่ได้กลับไปคือสคริปต์ที่ใช้จริงได้ บวกกับคำศัพท์ 4 คำที่จะเจอในทุกโค้ด agent ต่อจากนี้: tool คือเมนูที่เราเขียนให้มันดู, tool_use คือใบสั่งงานที่มันส่งกลับมา, tool_result คือผลที่เรารันแล้วส่งคืน, และ stop_reason คือตัวบอกว่ามันพูดจบหรือกำลังรอของจากเรา

ลองเล่นต่อได้ทันทีโดยไม่ต้องเปลี่ยนโครงเลย: เพิ่ม tool ตัวที่สองชื่อ list_files ที่คืนรายชื่อไฟล์ในโฟลเดอร์ แล้วถามว่า “โฟลเดอร์นี้มีไฟล์ Python กี่ไฟล์” ดูว่ามันเลือกใช้ตัวไหน

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

Ruklay Pousajja
Ruklay Pousajja BI Consultant & Data Engineer

Workshop อื่น

สร้าง AI agent ตัวแรกด้วย Python 78 บรรทัด: ครอบ tool use ด้วย loop แล้วดูมันลงมือทำงานจริงใน 45 นาทีAI Engineering
ระดับกลาง· ~45 นาที

สร้าง AI agent ตัวแรกด้วย Python 78 บรรทัด: ครอบ tool use ด้วย loop แล้วดูมันลงมือทำงานจริงใน 45 นาที

ต่อจากจับมือ tool รอบเดียว คราวนี้เติมมือที่สอง run_command แล้วครอบทั้งหมดด้วย loop ที่วนจน stop_reason เป็น end_turn ป้อนโจทย์ 5 เคสให้ดูว่ามันขอ 2 tool พร้อมกัน เขียนทับไฟล์ทั้งไฟล์ผ่าน shell ทั้งที่ไม่มี tool เขียนไฟล์ และลบไฟล์โดยไม่ถามสักคำ

26 ก.ย. 2026งบ ค่า API ราว 7 บาท (ทั้งชิ้นเรียกโมเดล 16 ครั้ง วัดจริงตอนเขียน ใช้เครดิตเดิมจาก workshop ก่อนหน้า)
ถามจากเอกสารยาว: วางคำถามไว้ตรงไหนให้ AI ตอบถูก ทดลองจริงใน 30 นาทีAI Engineering
ระดับเริ่มต้น· ~30 นาที

ถามจากเอกสารยาว: วางคำถามไว้ตรงไหนให้ AI ตอบถูก ทดลองจริงใน 30 นาที

ต่อจากสคริปต์เทียบโมเดล: ยัดเอกสาร 76,000 โทเคนใส่ Claude แล้วถามคำถามที่คำตอบอยู่กลางเอกสาร ดูโมเดลเล็กตอบว่า "ไม่พบ" ทั้งที่ข้อมูลอยู่ตรงนั้น จากนั้นสลับลำดับแค่บรรทัดเดียวให้มันตอบถูก และเห็นค่าใช้จ่ายต่อคำถามลดลง 10 เท่าเป็นของแถม

16 ก.ย. 2026งบ ~30 บาท (ค่า API หักจากเครดิตที่เติมไว้ ถ้าใกล้หมดเติมเพิ่มก่อน)