ข้ามไปยังเนื้อหาหลัก

บทเรียน Claude Fable 5.1 API: สร้างเอเจนต์นักพัฒนาแบบรันต่อเนื่องใน Python

เรียนรู้การใช้โมเดลเรือธงล่าสุดของ Anthropic เพื่อสร้างเอเจนต์ Python ที่อ่านคลังโค้ด Flask ก่อนวางแผนการเปลี่ยนแปลง เพิ่มอัปเดตความคืบหน้า เครื่องมืออ่านไฟล์อย่างเดียว และการควบคุมต้นทุน
อัปเดตแล้ว 3 ก.ย. 2569  · 15 นาที อ่าน

สำรวจด้วย AI

ChatGPTClaudePerplexity

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

เรภาพรวม Claude Fable 5.1 ครอบคลุมการเปิดตัว เบนช์มาร์ก และการเปรียบเทียบโมเดลในภาพกว้าง ที่นี่จะเริ่มจากการเรียก Python ขนาดเล็กและสร้าง ลูปเอเจนต์ รอบๆ มัน เอเจนต์สุดท้ายจะรับคำขอฟีเจอร์ อ่านโปรเจ็กต์ Flask และส่งคืนแผนที่ผูกกับไฟล์ที่ตรวจจริง

เนื้อหาที่จะครอบคลุมมีดังนี้:

  • เรียก Claude Fable 5.1 API และอ่าน content blocks อย่างปลอดภัย
  • กำหนดระดับ reasoning effort และเปลี่ยนระหว่างการสนทนา (เบต้า)
  • จำกัดขอบเขต system instruction ให้มีผลเพียงหนึ่งเทิร์น (เบต้า)
  • ส่งคืนแผนแบบมีโครงสร้างด้วย Pydantic
  • เพิ่มเครื่องมือคลังโค้ดแบบอ่านอย่างเดียวโดยมีขอบเขตรากโปรเจ็กต์
  • รันลูปเครื่องมือแบบหลายเทิร์น
  • อ่านอัปเดตความคืบหน้าของเอเจนต์ระหว่างการเรียกเครื่องมือ (เบต้า)
  • คงความถูกต้องของ thinking blocks ด้วยประวัติแบบ append-only
  • แคชบริบทซ้ำและประเมินต้นทุนคำขอด้วยอัตราที่ประกาศ
  • จัดการการปฏิเสธและเปิดเอเจนต์ผ่าน FastAPI

ฟีเจอร์เบต้ามีการใช้ headers แบบระบุวันที่ ควรตรวจสอบกับเอกสารของ Anthropic ก่อนนำขึ้นใช้งานจริง

รัน Claude Fable 5.1 ในลูปเอเจนต์มีค่าใช้จ่ายเท่าไร?

เอเจนต์จะส่ง system prompt แบบเดิม คำจำกัดความของเครื่องมือ และบริบทคลังโค้ดซ้ำทุกเทิร์น ดังนั้นอัตราที่มีผลต่อบิลคืออัตราการอ่านจากแคช ไม่ใช่อัตราขาเข้า

Fable 5.1 มีค่าใช้จ่าย $10 ต่อหนึ่งล้านโทเค็นขาเข้า และ $50 ต่อหนึ่งล้านโทเค็นขาออก ไม่เปลี่ยนจาก Fable 5 การอ่านจากแคชคิด $0.25 ต่อหนึ่งล้าน ลดลงจาก $1 และการเขียนแคชแบบห้านาทีคงที่ที่ $12.50 ต่อหนึ่งล้าน คู่มือ Claude Fable 5.1 ของเรามีตารางอัตราฉบับเต็มและประมาณการประหยัดของ Anthropic

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

เพดานโทเค็นมาจากโมเดล ไม่ใช่งบประมาณ Fable 5.1 ให้หน้าต่างบริบท 1M โทเค็น พร้อมโทเค็นออกสูงสุด 128K ต่อคำตอบ และ max_tokens เป็นขีดจำกัดแข็งรวมส่วนคิดกับข้อความตอบกลับ ที่ effort สูงต้องเผื่อพื้นที่ทั้งสองส่วน จึงตั้งค่าในลูปเอเจนต์ด้านล่างไว้ที่ 16,000 แทนที่จะเป็นค่ากลมๆ

การเก็บข้อมูล ระดับความสำคัญ และลายน้ำ

รายละเอียดการเข้าถึงบางอย่างสำคัญก่อนลงมือเขียนโค้ด และมีสองข้อที่ทำให้คำขอถูกปฏิเสธทันที:

  • Fable 5.1 ต้องการการเก็บข้อมูล 30 วัน และไม่พร้อมใช้ภายใต้การไม่เก็บข้อมูลเลย เว้นแต่ Anthropic จะอนุมัติ คำขอจาก workspace ที่ไม่รองรับจะได้ 400 invalid_request_error โดยไม่มีคำใบ้อื่น

  • โมเดลไม่รองรับ Priority Tier ขณะที่ Fable 5 รองรับ ข้อนี้จึงมักสะดุดเมื่อย้ายโมเดล

  • เอาต์พุตข้อความของ Fable 5.1 มีลายน้ำข้อความของ Anthropic ไม่เพิ่มโทเค็นและไม่ต้องเปลี่ยนคำขอ

ใช้ Claude Fable 5.1 ผ่าน API เพื่อสร้างเอเจนต์นักพัฒนาที่เข้าใจคลังโค้ด

เวิร์กโฟลว์มีสองช่วง:

  1. ลูปตรวจสอบแบบมีขอบเขตอ่านไฟล์โปรเจ็กต์ที่อนุญาต
  2. คำขอสุดท้ายใช้ structured outputs เพื่อแปลงบริบทเป็นแผน

โปรเจ็กต์ตัวอย่างคือ Flask JSON API ขนาดเล็กสำหรับบันทึกและค้นหาบุ๊กมาร์ก มี app factory, สาม blueprint, โมดูล config, โมเดล และชุด pytest ใช้การจำกัดอัตราเป็นงานที่ดำเนินต่อเนื่อง เพราะเอเจนต์ต้องตรวจการตั้งค่าแอป เส้นทาง config และเทสต์ ก่อนจะระบุไฟล์และเทสต์ที่ต้องใช้ โค้ดสมบูรณ์และโปรเจ็กต์ตัวอย่างอยู่ใน GitHub repository

แผนภาพแสดงคำขอฟีเจอร์ไหลผ่านเอเจนต์ Claude Fable 5.1 รายการอนุญาตเส้นทาง และโปรเจ็กต์ตัวอย่าง ก่อนส่งคืนแผนแบบมีโครงสร้าง

คำขอเข้าถึงไฟล์ผ่านขอบเขตเดียว ภาพโดยผู้เขียน

เอเจนต์ใช้ได้เพียงสามเครื่องมือ: list_project_files, read_project_file, และ get_project_metadata Claude จะไม่เข้าถึงไฟล์ระบบโดยตรง มันจะขอพาธ แล้วโค้ดของคุณจะตัดสินใจว่าพาธนั้นอนุญาตหรือไม่

ตั้งค่า Claude Fable 5.1 API ใน Python

เริ่มด้วยสภาพแวดล้อม Python แยกต่างหากและเก็บคีย์ API ไว้บนเซิร์ฟเวอร์

ข้อกำหนดเบื้องต้น

ต้องใช้ Python 3.10 ขึ้นไปและคีย์ Anthropic API ที่เข้าถึง claude-fable-5-1 ได้

หากต้องการสร้างคีย์ API ให้ลงชื่อเข้าใช้ Claude Console เปิด หน้า API keys คลิก Create key แล้วคัดลอกคีย์ ควรตั้งชื่อเพื่อช่วยจำวัตถุประสงค์ เลือกวันหมดอายุ และเก็บรักษาคีย์อย่างปลอดภัย

ติดตั้ง SDK และเพิ่มคีย์ API

สร้าง virtual environment และติดตั้งแพ็กเกจ:

python -m venv .venv
source .venv/bin/activate          # macOS or Linux
.venv\Scripts\Activate.ps1         # Windows PowerShell
pip install anthropic==1.3.0 pydantic fastapi uvicorn python-dotenv

ตรึงเวอร์ชัน SDK ไว้เพราะฟีเจอร์เบต้าเปลี่ยนบ่อย การอัปเดตความคืบหน้าต้องใช้อย่างน้อย 1.1.0 และตัวอย่างใช้ 1.3.0.

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

ANTHROPIC_API_KEY=sk-ant-your-key-here

เมื่อตั้งค่าแล้ว ไคลเอนต์จะค้นหาคีย์ได้เอง

เรียก Claude Fable 5.1 API ครั้งแรกใน Python

ส่งคำขอ API ที่เล็กที่สุดก่อนจะสร้างสิ่งอื่นต่อยอด

ส่งคำขอ API แรก

เริ่มต้นไคลเอนต์ ส่งข้อความจากผู้ใช้หนึ่งครั้ง และพิมพ์เมทาดาต้าคำตอบ:

from anthropic import Anthropic
from dotenv import load_dotenv

load_dotenv()

client = Anthropic()
MODEL = "claude-fable-5-1"

response = client.messages.create(
    model=MODEL,
    max_tokens=512,
    messages=[{"role": "user", "content": "Reply in one sentence to confirm the API connection is working."}],
)

text = next((b.text for b in response.content if b.type == "text"), None)
print(text if text is not None else f"No text returned ({response.stop_reason})")
print(f"Model: {response.model}")
print(f"Stop reason: {response.stop_reason}")
print(f"Input tokens: {response.usage.input_tokens}")
print(f"Output tokens: {response.usage.output_tokens}")
print(f"Request ID: {response._request_id}")

เทอร์มินัลแสดงการตอบกลับจาก Claude Fable 5.1 API พร้อมรหัสโมเดล สาเหตุการหยุด จำนวนโทเค็น และรหัสคำขอ

การเรียกครั้งแรกให้ทั้งข้อความและเมทาดาต้า ภาพโดยผู้เขียน

การเรียก next(...) เลือกบล็อกข้อความแรก โหมด adaptive thinking เปิดตลอดและปิดไม่ได้ ดังนั้นคำตอบอาจเริ่มด้วย thinking block; การส่ง thinking: {"type": "disabled"} จะได้ 400 แทนที่จะปิดมัน เมื่อมี thinking block มาก่อน การเรียก response.content[0].text จะเกิดข้อยกเว้น

วิธีแก้คือกรองตามชนิดบล็อกแทนการเดาตำแหน่งตายตัว ให้บันทึก response._request_id ด้วย เพราะฝ่ายสนับสนุนของ Anthropic ใช้เพื่อติดตามคำขอ

นี่คือคำขอที่ใช้ในตัวอย่างการวางแผนและ effort ต้องการให้เอเจนต์ตรวจไฟล์หลายไฟล์:

feature_request = (
    "Add rate limiting to the public API endpoints so one client cannot exhaust "
    "the search endpoint or brute force the token endpoint."
)

คงข้อความนี้ไว้ระหว่างการเปรียบเทียบระดับ effort และจำนวนโทเค็น เพื่อให้ผลลัพธ์สะท้อนการตั้งค่า API ไม่ใช่พรอมป์ต์ที่ต่างกัน

ตั้งค่า reasoning effort ด้วย output_config

กำหนดระดับ reasoning effort ผ่าน output_config ที่รับค่า low, medium, high, xhigh, และ max ค่าเริ่มต้นของ API คือ high

response = client.messages.create(
    model=MODEL,
    max_tokens=8192,
    output_config={"effort": "high"},
    messages=[{"role": "user", "content": feature_request}],
)

ระดับ effort มีผลต่อการใช้โทเค็น พฤติกรรมการใช้เครื่องมือ และความหน่วงเวลา ทดลองคำขอฟีเจอร์เดียวกันสามครั้งในแต่ละสี่ระดับ แล้วนำค่าเฉลี่ยมาสรุปดังตาราง:

Effort

วินาที

Thinking tokens

โทเค็นออกทั้งหมด

ต้นทุน

low

7.7

111

173

$0.0093

medium

8.1

129

186

$0.0099

high

7.9

136

199

$0.0106

xhigh

20.0

151

1,764

$0.0888

โทเค็นส่วนคิดถูกรวมอยู่ในโทเค็นออกทั้งหมดแล้ว อย่าบวกรวมสองคอลัมน์ ในการรันเหล่านี้ค่า low, medium และ high มีความหน่วงและต้นทุนใกล้เคียงกัน

xhigh ใช้เวลานานกว่าสองเท่าครึ่ง สร้างโทเค็นออกเกือบเก้าเท่า และมีต้นทุนมากขึ้นแปดเท่า

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

จำกัดขอบเขตเอเจนต์ด้วย system prompt

system prompt กำหนดพฤติกรรมของเอเจนต์:

SYSTEM_PROMPT = """You are a senior engineer who turns feature requests into implementation plans for an existing codebase.

Stay inside the requested feature. Do not propose unrelated refactors, dependency upgrades, or style changes.

If a file or dependency you need does not exist, say so plainly instead of inventing it.

Write in plain sentences and do not use em dashes.

Finish with concrete guidance: what changes, where, in what order, what could break, and which tests to add."""

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

ส่งคืนแผนแบบมีโครงสร้างด้วย Pydantic

กำหนดแผนด้วย Pydantic เพื่อให้แอปพลิเคชันตรวจสอบความถูกต้องและส่งต่อไปยังโค้ดอื่นได้:

from pydantic import BaseModel, Field

class FeaturePlan(BaseModel):
    summary: str = Field(description="One or two sentences on what will be built.")
    implementation_steps: list[str]
    files_to_modify: list[str]
    risks: list[str]
    tests: list[str]

response = client.messages.parse(
    model=MODEL,
    max_tokens=8192,
    system=SYSTEM_PROMPT,
    messages=[{"role": "user", "content": feature_request}],
    output_format=FeaturePlan,
)

if response.stop_reason == "refusal":
    category = (
        response.stop_details.category
        if response.stop_details and response.stop_details.category
        else "unspecified"
    )
    print(f"Declined: {category}")
elif response.parsed_output is None:
    print(f"No plan. Stop reason: {response.stop_reason}")
else:
    print(response.parsed_output.summary)

messages.parse() แปลงโมเดล Pydantic เป็น JSON schema ส่งออก ตรวจสอบคำตอบ และส่งคืนอ็อบเจกต์แบบมีชนิดใน parsed_output structured outputs พร้อมใช้งานทั่วไป จึงไม่ต้องใช้ header เบต้า ตรวจ stop_reason ก่อน เพราะกรณีปฏิเสธ (จะกล่าวในภายหลัง) จะข้ามสคีมาและไม่มีอะไรให้พาร์ส

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

Claude Fable 5.1 เทียบกับ Fable 5: การย้าย API

ก่อนเพิ่มเครื่องมือ ให้คำนึงถึงข้อจำกัดการบังคับเลือกเครื่องมือ ความเข้ากันได้ของ thinking block และประวัติแบบเพิ่มอย่างเดียว

  • Fable 5.1 ไม่ยอมรับการบังคับเลือกเครื่องมือ ส่วนลูปเครื่องมือด้านล่างจะแสดงข้อผิดพลาดและการตั้งค่า auto ที่ใช้แทน

  • thinking blocks เข้ากันได้เพียงทางเดียว Fable 5.1 อ่านบล็อกจาก Claude รุ่นก่อนหน้าได้ แต่รุ่นก่อนหน้าอ่านบล็อกของมันไม่ได้

เมื่อตัวจัดเส้นทางหรือ fallback ย้ายการสนทนาไปยังโมเดลเก่ากว่า API จะลบบล็อกที่เข้ากันไม่ได้ก่อนที่โมเดลเป้าหมายจะเห็น ประวัติส่วนที่เหลือยังคงอยู่ แต่โมเดลเก่าต้องวางแผนโดยไม่มีบล็อกเหล่านั้น

การแก้ไขเทิร์นก่อนหน้าเป็นโมฆะกับ thinking blocks ที่ตามมา ซึ่งอาจทำให้การตัดประวัติและการสรุปฝั่งไคลเอนต์เสีย

ดูการเปลี่ยนแปลงทั้งหมดได้ใน migration guide

เพิ่มเครื่องมือคลังโค้ดแบบอ่านอย่างเดียว

ตอนนี้ให้โมเดลมองเห็นบริบทของคลังโค้ดผ่านเครื่องมือแบบอ่านอย่างเดียว

กำหนดเครื่องมือแบบอ่านอย่างเดียว

เลเยอร์เครื่องมือมีสองส่วน: ฟังก์ชัน Python ที่บังคับกฎการเข้าถึง และสคีมาที่ Claude เรียกใช้ได้

จำกัดพาธให้อยู่ใต้โฟลเดอร์รากของโปรเจ็กต์

อ่านอย่างเดียวไม่ได้แปลว่าปลอดภัย โมเดลสามารถขอ ../../.env ได้ง่ายพอๆ กับ config.py ดังนั้นแนวป้องกันควรอยู่ในโค้ด ไม่ใช่ในพรอมป์ต์:

def _resolve(self, relative_path: str) -> Path:
    relative = Path(relative_path)
    if relative.is_absolute() or relative.drive:
        raise ToolError(f"path is outside the project root: {relative_path}")

    cursor = self.root
    for part in relative.parts:
        cursor /= part
        if cursor.is_symlink():
            raise ToolError(f"symlinks are not followed: {relative_path}")

    candidate = (self.root / relative).resolve()

    # After resolving "..", the path still has to sit under the allowed root.
    if candidate != self.root and self.root not in candidate.parents:
        raise ToolError(f"path is outside the project root: {relative_path}")
    if candidate.name in DENY_NAMES:
        raise ToolError(f"reading {candidate.name} is not allowed")

    return candidate

ปฏิเสธพาธแบบ absolute และส่วนประกอบ symlink จากนั้น resolve พาธและยืนยันว่ายังอยู่ใต้โฟลเดอร์รากโปรเจ็กต์ การขอ ../.env จะได้ข้อความ "path is outside the project root." การคืนค่าเป็นข้อผิดพลาดของเครื่องมือช่วยให้เอเจนต์ดำเนินการต่อกับไฟล์ที่อนุญาตได้

กำหนดสคีมาของเครื่องมือให้เข้มงวด

คลาสตัวอ่านควบคุมว่า Python เปิดอะไรได้บ้าง Claude ยังต้องการ JSON schema ที่อธิบายสามการกระทำที่สามารถร้องขอได้:

EMPTY_SCHEMA = {
    "type": "object",
    "properties": {},
    "additionalProperties": False,
}

TOOLS = [
    {
        "name": "list_project_files",
        "description": "List readable text files in the project.",
        "input_schema": EMPTY_SCHEMA,
        "strict": True,
    },
    {
        "name": "read_project_file",
        "description": "Read one text file relative to the project root.",
        "input_schema": {
            "type": "object",
            "properties": {"path": {"type": "string"}},
            "required": ["path"],
            "additionalProperties": False,
        },
        "strict": True,
    },
    {
        "name": "get_project_metadata",
        "description": "Read project metadata and dependency manifests.",
        "input_schema": EMPTY_SCHEMA,
        "strict": True,
    },
]

strict ตรวจสอบอาร์กิวเมนต์เมื่อโมเดลเลือกเครื่องมือ ไม่ได้บังคับให้เรียกเครื่องมือ ซึ่งสำคัญกับ Fable 5.1

รันลูปเครื่องมือแบบหลายเทิร์น

เริ่มด้วยลูปพื้นฐาน: ส่งเครื่องมือ ตรวจ stop_reason รันสิ่งที่ร้องขอ เพิ่มผลลัพธ์ และทำซ้ำ

MAX_AGENT_TURNS = 8
reader = ProjectReader("sample_project")
messages = [{"role": "user", "content": feature_request}]

for turn in range(1, MAX_AGENT_TURNS + 1):
    response = client.messages.create(
        model=MODEL,
        max_tokens=16000,
        system=SYSTEM_PROMPT,
        tools=TOOLS,
        messages=messages,
    )

    if response.stop_reason == "refusal":
        return declined(response.stop_details.category)
    if response.stop_reason == "max_tokens":
        return cutoff()
    if response.stop_reason != "tool_use":
        messages.append({"role": "assistant", "content": response.content})
        break

    messages.append({"role": "assistant", "content": response.content})
    results = []
    for block in response.content:
        if block.type != "tool_use":
            continue
        output, is_error = reader.run(block.name, block.input)
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": output,
            "is_error": is_error,
        })

    messages.append({"role": "user", "content": results})
else:
    return turn_limit()

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

เหตุใดการบังคับเลือกเครื่องมือจึงได้ 400

บน Fable 5 สามารถบังคับการเรียกแรกด้วย tool_choice: {"type": "any"} Fable 5.1 จะส่งข้อผิดพลาดนี้ก่อนประมวลผลคำขอ:

tool_choice: type "tool" and "any" are not supported for this model.

การบังคับเรียกจะข้ามการคิดที่เปิดตลอดเวลา ควรตั้ง tool_choice เป็น auto ใช้สคีมาแบบเข้มที่กำหนดไว้ด้านบน และเอ่ยชื่อเครื่องมือในพรอมป์ต์เมื่อขั้นตอนนั้นต้องใช้

Fable 5.1 บางครั้งเรียกเครื่องมือหนึ่งครั้งต่อเทิร์น ขณะที่ Fable 5 รวมหลายคำขอไว้ด้วยกัน ซึ่งเพิ่มรอบการสื่อสาร ให้เพิ่มบรรทัดนี้ในพรอมป์ต์: “ขอไฟล์ที่ไม่ขึ้นต่อกันในเทิร์นเดียวกันแทนการขอทีละไฟล์” การรันตัวอย่างรวมคำขอไฟล์ที่เป็นอิสระเก้าไฟล์ แม้จำนวนจะต่างกันไป

สตรีมคำตอบและอัปเดตความคืบหน้าของ Claude Fable 5.1

การสตรีมข้อความจะส่งเนื้อหาคำตอบตามที่สร้าง ส่วนอัปเดตความคืบหน้าครอบคลุมช่วงหยุดระหว่างการเรียกเครื่องมือ

สตรีมคำตอบแบบข้อความ

โปรเจ็กต์เต็มใช้ context_system() เพื่อรวม SYSTEM_PROMPT กับสรุปโปรเจ็กต์ก่อนเริ่มสตรีม:

with client.messages.stream(
    model=MODEL,
    max_tokens=8192,
    system=context_system(),
    messages=[{"role": "user", "content": feature_request}],
) as stream:
    for chunk in stream.text_stream:
        print(chunk, end="", flush=True)
    final = stream.get_final_message()

print(f"\nOutput tokens: {final.usage.output_tokens}")

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

แสดงความคืบหน้าระหว่างการเรียกเครื่องมือ

การสตรีมข้อความไม่ครอบคลุมความล่าระหว่างการเรียกเครื่องมือ Fable 5.1 สามารถเขียนอัปเดตความคืบหน้าสั้นๆ ก่อนเรียกเครื่องมือ ภายใต้ค่าเริ่มต้นของ thinking.display เป็น "omitted" บล็อก thinking เฉพาะความคืบหน้าจะว่าง แม้โมเดลอาจสร้างข้อความนำแบบปกติ

ด้วย display: "updates" และ thinking-display-updates-2026-08-18 เบต้าเฮดเดอร์ เอกสาร API กำหนดว่าอัปเดตความคืบหน้าที่อ่านได้คือบล็อก thinking ที่ไม่ว่างในขณะที่เหตุผลยังซ่อนอยู่ ในการรันจริงของโปรเจ็กต์นี้ ฟิลด์ thinking ว่าง และสถานะที่อ่านได้มากับบล็อก text ธรรมดาทันที ก่อน tool_use ตัวช่วยจึงตรวจทั้งสองชนิดบล็อก และลูปจะเรียกมันเฉพาะเทิร์นที่จบด้วย tool_use:

PROGRESS_BETA = "thinking-display-updates-2026-08-18"

response = client.beta.messages.create(
    model=MODEL,
    max_tokens=16000,
    betas=[PROGRESS_BETA],
    thinking={"type": "adaptive", "display": "updates"},
    system=SYSTEM_PROMPT,
    tools=TOOLS,
    messages=messages,
)

def status_lines(response) -> list[str]:
    lines = []
    for block in response.content:
        if block.type == "thinking":
            text = (block.thinking or "").strip()
        elif block.type == "text":
            text = (block.text or "").strip()
        else:
            continue
        if text:
            lines.append(text)
    return lines

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

เทอร์มินัลแสดงลูปเอเจนต์ Claude Fable 5.1 พร้อมการใช้โทเค็นต่อเทิร์น ข้อความความคืบหน้า และการอ่านไฟล์แบบแบตช์

เอเจนต์อ่านไฟล์พร้อมรายงานความคืบหน้า ภาพโดยผู้เขียน

Fable 5.1 เขียนข้อความเหล่านี้น้อยกว่า Fable 5 โดยเฉพาะที่ effort สูง หากอินเทอร์เฟซต้องการอัปเดตสม่ำเสมอ ให้ขอประโยคเปิด อัปเดตระหว่างทาง และสรุปปิดท้าย

เปลี่ยนค่า Effort ของ Claude Fable 5.1 ระหว่างการสนทนา

ฟีเจอร์ถัดไปน่าสนใจมาก เป็นที่ทราบกันว่าเอเจนต์คลังโค้ดไม่ต้องใช้ความลึกในการให้เหตุผลเท่ากันทุกเทิร์น

เปลี่ยน effort ระหว่างเทิร์น

ในลูปเอเจนต์ ให้ลด effort สำหรับเทิร์นดึงข้อมูลประจำ และเพิ่มกลับสำหรับเทิร์นวางแผนสุดท้าย

ด้วย mid-conversation-output-config-2026-07-01 เบต้าเฮดเดอร์ สามารถเพิ่มข้อความ system ที่เปลี่ยนเฉพาะระดับ effort ได้:

EFFORT_BETA = "mid-conversation-output-config-2026-07-01"

messages.append({"role": "system", "content": [], "output_config": {"effort": "low"}})
messages.append({"role": "user", "content": "Summarize the repository evidence in five words."})

response = client.beta.messages.create(
    model=MODEL,
    max_tokens=4096,
    betas=[EFFORT_BETA],
    output_config={"effort": "high"},
    messages=messages,
)

ระดับใหม่มีผลตั้งแต่เทิร์นผู้ใช้ถัดไป ไม่ใช่กลางเทิร์นปัจจุบัน และไม่ทำให้แคชพรอมป์ต์เป็นโมฆะ การเปลี่ยน output_config.effort ระดับบนระหว่างคำขอจะทำให้แคชเป็นโมฆะ

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

ใช้ system instruction แบบมีผลเพียงหนึ่งเทิร์น

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

ตั้งค่า clear_at: "next_user_message" บนข้อความ system พร้อม mid-conversation-system-clear-at-2026-08-21 เบต้าเฮดเดอร์ API จะถือว่าข้อความเป็นคำสั่ง system สำหรับเทิร์นปัจจุบัน แล้วหยุดแสดงหลังข้อความผู้ใช้ถัดไป มันยังอยู่ใน messages จึงไม่เปลี่ยนประวัติก่อนหน้า แคชยังตรงกัน และข้อความที่เคลียร์แล้วไม่คิดโทเค็นขาเข้า

SCOPED_SYSTEM_BETA = "mid-conversation-system-clear-at-2026-08-21"

messages.append({"role": "system", "content": [], "output_config": {"effort": "high"}})
messages.append({"role": "user", "content": "Write the implementation plan now."})
messages.append({
    "role": "system",
    "content": (
        "For this turn only: do not request more files. Base the plan on what "
        "you have already read, and name only paths you actually opened."
    ),
    "clear_at": "next_user_message",
})

response = client.beta.messages.create(
    model=MODEL,
    max_tokens=16000,
    betas=[EFFORT_BETA, SCOPED_SYSTEM_BETA],
    tool_choice={"type": "none"},
    output_config={"format": {"type": "json_schema", "schema": plan_schema()}},
    system=agent_system(),
    tools=TOOLS,
    messages=messages,
)

tool_choice={"type": "none"} ป้องกันคำขอสุดท้ายจากการเรียกเครื่องมือเพิ่มเติม คำสั่งแบบมีขอบเขตจำกัดแผนให้ครอบคลุมเฉพาะไฟล์ที่เอเจนต์ตรวจแล้ว อย่าเพิ่มตัวเตือนแล้วลบทิ้งในคำขอถัดไป เพราะการแก้ไขนั้นทำให้ thinking blocks ภายหลังเป็นโมฆะ

แก้ข้อผิดพลาด 400 ของ Thinking Block ใน Claude Fable 5.1

ข้อผิดพลาด The block is bound to a different conversation หมายความว่าประวัติก่อน thinking block มีการเปลี่ยนแปลง บล็อกของ Fable 5.1 แต่ละบล็อกถูกผูกกับ system prompt คำจำกัดความเครื่องมือ และข้อความก่อนหน้าตามนั้นอย่างแม่นยำ

ผลขึ้นกับวันที่สร้างบัญชี

  • บัญชีที่สร้างตั้งแต่ 31 สิงหาคม 2026 เป็นต้นไป จะได้ 400 ระบุว่าบล็อกถูกผูกกับการสนทนาที่ต่างกัน

  • สำหรับบัญชีก่อนหน้านั้น API จะบันทึกความไม่ตรงกัน แต่จะดำเนินการเมื่อคำขอตั้งค่า thinking.block_binding.prefix_mismatch_behavior

ตรวจจับได้ด้วย thinking-binding-controls-2026-08-01 เบต้าเฮดเดอร์ ตั้งค่า thinking.block_binding.prefix_mismatch_behavior เป็น "drop_block" และดูอาร์เรย์ input_transformations ประวัติที่ถูกแก้ไขจะปรากฏเป็น reason: "prefix_binding_mismatch" รันการตรวจนี้หนึ่งครั้งกับการผสานระบบของคุณ

การกระทำต่อไปนี้ทำให้เกิดความไม่ตรงกัน:

  • แก้ไข จัดลำดับใหม่ หรือเอาเทิร์นก่อนหน้าบางส่วนออกในขณะที่คงเทิร์นหลังไว้

  • ฉีดข้อความเฉพาะคำขอเข้าไปในเทิร์นก่อนหน้าแล้วเอาออกในคำขอถัดไป

  • เปลี่ยนเนื้อหาหรือลำดับของ system หรืออาร์เรย์ tools ระดับบนระหว่างการสนทนา

  • ส่งไบต์ที่ต่างกันจาก URL รูปภาพหรือเอกสารบนคำขอถัดไป

แต่ละกรณีมีวิธีทดแทนที่คงการผูกไว้ได้:

  • เพิ่มคำสั่งด้วย system message กลางการสนทนาแทนการแก้ไข system

  • เปลี่ยนเครื่องมือด้วยการเปลี่ยนเครื่องมือกลางการสนทนาแทนการเปลี่ยนอาร์เรย์ระดับบน

  • ตัดประวัติด้วย context editing หรือ compaction ฝั่งเซิร์ฟเวอร์ ซึ่งไม่นับว่าเป็นการแก้ไข

  • ส่งคืน thinking blocks กลับไปโดยไม่เปลี่ยน

การย้ายเครื่องหมาย cache_control และการเปลี่ยน effort ระดับคำขอปลอดภัยและไม่ทำให้การผูก thinking block เป็นโมฆะ อย่างไรก็ตาม การเปลี่ยน effort ระดับบนจะรีสตาร์ตการแคชพรอมป์ต์ จึงใช้ effort ต่อข้อความเมื่ออยากให้คำนำที่แคชตรงเดิม

การแคชพรอมป์ต์และต้นทุน Claude Fable 5.1 API

การรันต่อไปนี้แยกต้นทุนของขาเข้าใหม่ การเขียนแคช การอ่านแคช และเอาต์พุต

เพิ่มการแคชพรอมป์ต์แบบอัตโนมัติ

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

ฟิลด์ cache_control ระดับบนจะย้ายจุดแบ่งไปยังบล็อกที่แคชได้ล่าสุดในแต่ละคำขอ:

response = client.beta.messages.create(
    model=MODEL,
    cache_control={"type": "ephemeral"},
    system=system,
    tools=TOOLS,
    messages=messages,
    # Other request fields...
)

คำนำที่แคชได้ซึ่งสั้นกว่า 512 โทเค็นจะไม่ถูกแคชบน Fable 5.1 แม้ทำเครื่องหมายด้วย cache_control API จะประมวลผลตามปกติและส่งค่าศูนย์สำหรับตัวนับแคชทั้งสอง การเขียนคำนำ 583 โทเค็นมีต้นทุน $0.0073; การอ่านในเทิร์นถัดไปมีต้นทุน $0.00015 เทิร์นที่สองยังต้องเขียนส่วนใหม่ลงแคช ดังนั้นการโดนแคชไม่ได้ตัดต้นทุนขาเข้าทั้งหมด

ประเมินต้นทุน API โดยคำนึงถึงแคช

response.usage รายงานขาเข้าใหม่ การสร้างแคช การอ่านแคช และเอาต์พุตแยกกัน คิดราคาทั้งสี่ตัวนับของมันเอง การบวกรวมแค่ขาเข้าและขาออกจะซ่อนต้นทุนการเขียนแคชและประเมินราคาการโดนแคชเกินจริง

นี่คือส่วนแยกต้นทุนจากการรันเต็มหนึ่งครั้งที่อ่าน 12 ไฟล์ในสามเทิร์นและสร้างแผนสุดท้าย:

รายการ

โทเค็น

ต้นคาประเมิน

สัดส่วน

เอาต์พุต

5,713

$0.2857

59.4%

การเขียนแคช

15,426

$0.1928

40.1%

ขาเข้าใหม่

50

$0.0005

0.1%

การอ่านแคช

6,549

$0.0016

0.3%

รวม

27,738

$0.4806

100%

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

ในการรันนี้ เอาต์พุตคิดเป็นเกือบ 60% ของประมาณการ และการเขียนแคชประมาณ 40% ที่อัตราห้านาที โทเค็นการเขียนแคชแพงกว่าโทเค็นการอ่านแคช 50 เท่า การเขียนแคชหนึ่งชั่วโมงแพงกว่า 80 เท่า

จัดการการปฏิเสธและการ fallback ของ Claude Fable 5.1

การปฏิเสธและคำขอที่ล้มเหลวต้องการพฤติกรรมแอปพลิเคชันที่ต่างกัน

ตรวจจับการปฏิเสธก่อนพาร์สเอาต์พุต

การปฏิเสธก่อนมีเอาต์พุตจะมาด้วย HTTP 200 พร้อม stop_reason: "refusal" เนื้อหาว่าง และ stop_details หมวดหมู่อาจเป็นค่าว่าง การปฏิเสธระหว่างสตรีมอาจตามหลังเอาต์พุตบางส่วน ซึ่งแอปควรทิ้ง try/except รอบการเรียกจะไม่จับทั้งสองกรณี

response = client.messages.create(model=MODEL, max_tokens=8192, messages=messages)

if response.stop_reason == "refusal":
    category = (
        response.stop_details.category
        if response.stop_details and response.stop_details.category
        else "unspecified"
    )
    return f"This request was declined ({category})."

จัดการในฐานะสถานะของแอป หากคำขอที่อนุญาตยังไม่ชัด ให้เขียนใหม่ให้เฉพาะเจาะจง ห้ามสร้างลูปรีทรายที่มีจุดประสงค์เพื่อเลี่ยงตัวจัดหมวดหมู่

การปฏิเสธมาพร้อม HTTP 200 ภาพโดยผู้เขียน

กำหนดค่า server-side fallback

server-side fallback สามารถรีทรายคำขอที่ถูกปฏิเสธบนโมเดลอื่น โดยใช้ fallbacks: "default" พร้อม server-side-fallback-2026-07-01 เบต้าเฮดเดอร์ เป้าหมายที่อนุญาตสำหรับ Fable 5.1 คือ Opus 4.8 และ Opus 5

fallback เริ่มทำงานเมื่อหมวดหมู่การปฏิเสธมีเป้าหมายที่แนะนำ การทดสอบกรณี reasoning_extraction ไม่กระตุ้น fallback ให้ตรวจ usage.iterations แทนการสมมติว่าทุกการปฏิเสธจะรีทราย ดังที่กล่าวก่อนหน้า การย้ายไปโมเดลเก่ากว่าจะลบบล็อก thinking ของ Fable 5.1 ด้วย

ให้บริการเอเจนต์ Claude Fable 5.1 ด้วย FastAPI

เอเจนต์ภายในเครื่องสามารถให้บริการเวิร์กโฟลว์เดียวกันผ่าน HTTP API ได้แล้ว

สร้าง endpoint สำหรับแผน

หากต้องการเพียงสคริปต์ภายในเครื่อง ให้ข้ามส่วนนี้ สำหรับเว็บเซอร์วิส ใช้ FastAPI ร่วมกับ AsyncAnthropic สร้างไคลเอนต์หนึ่งตัวสำหรับทั้งโปรเซสใน lifespan handler นำเข้า schema และพรอมป์ต์จากโมดูลเอเจนต์ที่มีอยู่

@asynccontextmanager
async def lifespan(_: FastAPI):
    global client
    client = AsyncAnthropic()
    try:
        yield
    finally:
        await client.close()


@app.post("/plan", response_model=PlanResponse)
async def create_plan(body: PlanRequest):
    reader = resolve_project(body.project)
    messages, totals, turns, tool_calls = await inspect(reader, body.feature_request)
    plan, final_usage = await write_plan(messages)
    totals.add(final_usage)
    return PlanResponse(plan=plan, turns=turns, tool_calls=tool_calls, usage=as_usage(totals))

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

รันด้วย uvicorn app:app --reload เอกสารแบบโต้ตอบอยู่ที่ http://localhost:8000/docs.

เอ็นด์พอยต์ส่งคืนแผนพร้อมประมาณการต้นทุน วิดีโอโดยผู้เขียน

เอ็นด์พอยต์ /plan/stream รันการตรวจสอบในงานเบื้องหลัง วางข้อความความคืบหน้าและเหตุการณ์เครื่องมือลงใน asyncio.Queue และส่งออกผ่าน StreamingResponse เมื่อสตรีมปิด ตัวสร้างจะยกเลิกงานเบื้องหลัง Streamlit อินเทอร์เฟซในคลังจะแสดงสตรีมเหตุการณ์เดียวกัน

Streamlit แสดงความคืบหน้าสดของเอเจนต์ วิดีโอโดยผู้เขียน

เช็กลิสต์การดีพลอยเอเจนต์ Claude Fable 5.1

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

  • ทบทวนค่าเริ่มต้นของ SDK ที่รีทรายสองครั้งสำหรับการตอบกลับ 429 และ 5xx จากนั้นตั้ง max_retries และ timeout ให้สอดคล้องกับงบประมาณความหน่วงของบริการ

  • ตั้งค่า timeout ของคำขอและยืนยันว่าการยกเลิกงาน SSE ที่มีอยู่หยุดงานที่ค้างเมื่อไคลเอนต์ตัดการเชื่อมต่อ

  • บันทึกรหัสโมเดล เวอร์ชัน SDK รหัสคำขอ เหตุผลการหยุด และสี่หมวดหมู่โทเค็นสำหรับแต่ละการรัน

  • ตั้งการแจ้งเตือนเมื่อการเขียนแคช โทเค็นเอาต์พุต การปฏิเสธเพิ่มขึ้น และการรันที่แตะเพดานจำนวนเทิร์น

  • ยืนยันว่าการตั้งค่าการเก็บข้อมูลของบัญชีตรงกับข้อกำหนดของโมเดล

  • ตรึง SDK และตรวจสอบเบต้าเฮดเดอร์อีกครั้งก่อนออกแต่ละรุ่น

ควรใช้ Claude Fable 5.1 แทน Opus 5 หรือ Sonnet 5 เมื่อใด

  • Anthropic แนะนำ Opus 5 เป็นค่าตั้งต้นที่เหมาะสม
  • ทดสอบ Fable 5.1 เมื่อ Opus 5 ทำได้ไม่ดีพอในงานวิเคราะห์คลังโค้ดยาว การดีบักที่ยาก หรือภารกิจเชิงเอเจนต์ที่ใช้บริบทขนาดใหญ่
  • สำหรับงานคลังโค้ดและงานประจำวัน เปรียบเทียบ Sonnet 5 และ Opus 5 ในด้านคุณภาพ ความหน่วง และต้นทุน
  • สำหรับการจัดหมวดหมู่ สกัดข้อมูล คำตอบสั้น และคำขอที่ง่ายกว่า Sonnet 5 เป็นตัวเลือกที่ดี; สำหรับงานง่ายที่สุด Haiku 4.5 ก็อาจเพียงพอ

อย่าเลือก Fable 5.1 เพียงเพราะใหม่กว่า คำขอเดี่ยวยังใช้ effort และ structured outputs ได้ และสตรีมมิงก็ใช้ได้เช่นกัน โดยไม่ต้องพึ่งลูปหรือการแคชคำนำซ้ำแบบที่ใช้ในที่นี่

ข้อคิดส่งท้าย

แผนทั่วไปจากการเรียกครั้งแรกเริ่มมีประโยชน์ก็ต่อเมื่อเอเจนต์ได้อ่านคลังโค้ด ในการรันที่สมบูรณ์ มันตรวจ 12 ไฟล์ในสามเทิร์น โดยเอาต์พุตและการเขียนแคชคิดเป็น 99.5% ของต้นค่าประเมิน ควรรักษาเส้นขอบพาธและประวัติแบบเพิ่มอย่างเดียวไว้ จากนั้นทดสอบว่าการลด effort ช่วยลดต้นทุนโดยไม่ทำให้โมเดลข้ามเครื่องมือคลังโค้ดหรือไม่

หากคำตอบครั้งเดียวพอสำหรับงาน ให้หยุดที่ structured outputs ใช้ลูปเครื่องมือเมื่อคำตอบต้องขึ้นกับไฟล์ในคลังโค้ดหรือเมื่อต้องรายงานความคืบหน้าระหว่างการเรียก

สำหรับรายละเอียดการเลือกโมเดล แนะนำคอร์ส Introduction to Claude Models และสำหรับการพิมพ์พรอมป์ต์และเวิร์กโฟลว์เอเจนต์ ดูคอร์ส Software Development with Cursor

คำถามที่พบบ่อย

Claude Fable 5.1 อ่านรูปภาพนอกเหนือจากโค้ดได้ไหม?

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

เหตุใดเอเจนต์จึงช้าลงหลังเปลี่ยนจาก Fable 5?

ตรวจผลลัพธ์ของเครื่องมือก่อนโทษโมเดล หากมีคำสั่งรวมคำขอ (batching) ตามที่กล่าวไว้แล้ว ให้เปรียบเทียบทั้งจำนวนและขนาดไฟล์ ผู้อ่านปัจจุบันจำกัดไฟล์ละ 40,000 ไบต์ หากยังใหญ่เกิน ให้เพิ่มอาร์กิวเมนต์ช่วงบรรทัดหรือการค้นหาเพื่อให้เครื่องมือส่งคืนเฉพาะส่วนที่เกี่ยวข้อง

เหตุใด Claude Fable 5.1 จึงส่งกลับ 400 invalid_request_error?

อย่ารีทรายก่อน invalid_request_error มักชี้ไปที่รูปแบบคำขอหรือการตั้งค่าบัญชีที่ต้องแก้ ในโปรเจ็กต์นี้ สาเหตุที่เป็นไปได้คือการบังคับ tool_choice การตั้งค่าการเก็บข้อมูลที่ไม่รองรับ คำนำที่แก้ไขแต่คง thinking ไว้ หรือส่งฟิลด์เบต้าโดยไม่มีเฮดเดอร์ที่ตรงกัน ให้แก้สาเหตุที่ระบุแล้วค่อยส่งคำขอใหม่

ควรแคชไฟล์ซอร์สหรือสรุป?

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

Batch API รันเอเจนต์นี้ได้ไหม?

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

หัวข้อ

เรียนรู้ AI กับ DataCamp!

Tracks

วิศวกร AI ระดับ Associate สำหรับนักพัฒนา

26 ชม.
เรียนรู้วิธีผสาน AI เข้ากับแอปพลิเคชันซอฟต์แวร์โดยใช้ API และไลบรารีโอเพนซอร์ส เริ่มต้นเส้นทางสู่การเป็น AI Engineer ของคุณวันนี้!
ดูรายละเอียดRight Arrow
เริ่มหลักสูตร
ดูเพิ่มเติมRight Arrow