Skip to main content

วิธีการทำงานของ Agent Loop

ทำความเข้าใจวงจรชีวิตของข้อความ การดำเนินการ tool context window และสถาปัตยกรรมที่ขับเคลื่อน SDK agents

Agent SDK ช่วยให้คุณฝัง agent loop อัตโนมัติของ Claude Code ลงในแอปพลิเคชันของคุณ SDK เป็น package แบบ standalone ที่ให้คุณควบคุม tools, permissions, ขีดจำกัดต้นทุน และ output ได้ด้วยโปรแกรม คุณไม่จำเป็นต้องติดตั้ง Claude Code CLI เพื่อใช้งาน

เมื่อคุณเริ่ม agent SDK จะรัน execution loop เดียวกับที่ขับเคลื่อน Claude Code: Claude ประเมิน prompt ของคุณ เรียกใช้ tools เพื่อดำเนินการ รับผลลัพธ์ และวนซ้ำจนกว่างานจะเสร็จ หน้านี้จะอธิบายสิ่งที่เกิดขึ้นภายใน loop นั้น เพื่อให้คุณสร้าง debug และปรับแต่ง agents ได้อย่างมีประสิทธิภาพ

ภาพรวมของ Loop

ทุก agent session ทำตามวงจรเดียวกัน:

  1. รับ prompt Claude รับ prompt ของคุณ พร้อมกับ system prompt, tool definitions และประวัติการสนทนา SDK จะส่ง SystemMessage ที่มี subtype "init" ซึ่งประกอบด้วย session metadata
  2. ประเมินและตอบสนอง Claude ประเมินสถานะปัจจุบันและตัดสินใจว่าจะดำเนินการอย่างไร อาจตอบด้วยข้อความ ร้องขอการเรียกใช้ tool หนึ่งรายการขึ้นไป หรือทั้งสองอย่าง SDK จะส่ง AssistantMessage ที่ประกอบด้วยข้อความและคำขอเรียกใช้ tool ต่างๆ
  3. ดำเนินการ tools SDK รัน tool ที่ร้องขอแต่ละรายการและรวบรวมผลลัพธ์ ผลลัพธ์ของแต่ละชุด tool จะส่งกลับไปยัง Claude เพื่อการตัดสินใจครั้งถัดไป คุณสามารถใช้ hooks เพื่อดักจับ แก้ไข หรือบล็อก tool calls ก่อนที่จะรัน
  4. วนซ้ำ ขั้นตอนที่ 2 และ 3 วนซ้ำเป็นวัฏจักร แต่ละรอบเต็มคือหนึ่ง turn Claude ยังคงเรียก tools และประมวลผลผลลัพธ์จนกว่าจะสร้างการตอบสนองที่ไม่มี tool calls
  5. ส่งคืนผลลัพธ์ SDK ส่ง AssistantMessage สุดท้ายพร้อมการตอบสนองข้อความ (ไม่มี tool calls) ตามด้วย ResultMessage พร้อมข้อความสุดท้าย การใช้ token ต้นทุน และ session ID

Turns และ Messages

Turn คือการเดินทางไปกลับหนึ่งครั้งภายใน loop: Claude สร้าง output ที่มี tool calls, SDK ดำเนินการ tools เหล่านั้น และผลลัพธ์จะส่งกลับไปยัง Claude โดยอัตโนมัติ สิ่งนี้เกิดขึ้นโดยไม่ต้องคืนการควบคุมกลับไปยังโค้ดของคุณ Turns ดำเนินต่อไปจนกว่า Claude จะสร้าง output ที่ไม่มี tool calls

ลองพิจารณาว่า session เต็มรูปแบบอาจมีลักษณะอย่างไรสำหรับ prompt "Fix the failing tests in auth.ts":

  1. Turn 1: Claude เรียก Bash เพื่อรัน npm test SDK ส่ง AssistantMessage พร้อม tool call ดำเนินการคำสั่ง จากนั้นส่ง UserMessage พร้อม output (ความล้มเหลวสามรายการ)
  2. Turn 2: Claude เรียก Read บน auth.ts และ auth.test.ts SDK ส่งคืนเนื้อหาไฟล์และส่ง AssistantMessage
  3. Turn 3: Claude เรียก Edit เพื่อแก้ auth.ts จากนั้นเรียก Bash เพื่อรัน npm test อีกครั้ง
  4. Turn สุดท้าย: Claude สร้างการตอบสนองแบบข้อความเท่านั้นโดยไม่มี tool calls

คุณสามารถจำกัด loop ด้วย max_turns / maxTurns ซึ่งนับเฉพาะ turns ที่ใช้ tool หรือใช้ max_budget_usd / maxBudgetUsd เพื่อจำกัด turns ตามค่าใช้จ่าย

ประเภทข้อความ

ขณะที่ loop รัน SDK จะส่งสตรีมของข้อความ ห้าประเภทหลักได้แก่:

  • SystemMessage: เหตุการณ์ lifecycle ของ session. field subtype บ่งบอกความแตกต่าง: "init" คือข้อความแรก (session metadata) และ "compact_boundary" จะเกิดหลัง compaction
  • AssistantMessage: ส่งหลังจากการตอบสนองของ Claude แต่ละครั้ง
  • UserMessage: ส่งหลังจากการดำเนินการ tool แต่ละครั้งพร้อมผลลัพธ์ tool ที่ส่งกลับไปยัง Claude
  • StreamEvent: ส่งเฉพาะเมื่อเปิดใช้งาน partial messages ประกอบด้วย raw API streaming events
  • ResultMessage: ทำเครื่องหมายจุดสิ้นสุดของ agent loop ประกอบด้วยผลลัพธ์ข้อความสุดท้าย การใช้ token ต้นทุน และ session ID

จัดการข้อความ

ข้อความที่คุณจัดการขึ้นอยู่กับสิ่งที่คุณกำลังสร้าง:

  • ผลลัพธ์สุดท้ายเท่านั้น: จัดการ ResultMessage เพื่อรับ output, ต้นทุน และว่างานสำเร็จหรือถึงขีดจำกัด
  • การอัปเดตความคืบหน้า: จัดการ AssistantMessage เพื่อดูสิ่งที่ Claude ทำในแต่ละ turn
  • Streaming แบบ live: เปิดใช้งาน partial messages เพื่อรับ StreamEvent messages แบบ real-time
from claude_agent_sdk import query, AssistantMessage, ResultMessage

async for message in query(prompt="Summarize this project"):
if isinstance(message, AssistantMessage):
print(f"Turn completed: {len(message.content)} content blocks")
if isinstance(message, ResultMessage):
if message.subtype == "success":
print(message.result)
else:
print(f"Stopped: {message.subtype}")
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({ prompt: "Summarize this project" })) {
if (message.type === "assistant") {
console.log(`Turn completed: ${message.message.content.length} content blocks`);
}
if (message.type === "result") {
if (message.subtype === "success") {
console.log(message.result);
} else {
console.log(`Stopped: ${message.subtype}`);
}
}
}

การดำเนินการ Tool

Tools ให้ agent ของคุณสามารถดำเนินการได้ หากไม่มี tools, Claude จะตอบด้วยข้อความเท่านั้น

Tools ในตัว

SDK มี tools เดียวกับที่ขับเคลื่อน Claude Code:

หมวดหมู่Toolsฟังก์ชัน
การดำเนินการไฟล์Read, Edit, Writeอ่าน แก้ไข และสร้างไฟล์
การค้นหาGlob, Grepค้นหาไฟล์ตามรูปแบบ ค้นหาเนื้อหาด้วย regex
การดำเนินการBashรัน shell commands, scripts, git operations
เว็บWebSearch, WebFetchค้นหาเว็บ ดึงและแยกวิเคราะห์หน้าเว็บ
การค้นพบToolSearchค้นหาและโหลด tools ตามต้องการ
การประสานงานAgent, Skill, AskUserQuestion, TaskCreate, TaskUpdateSpawn subagents, เรียกใช้ skills, ถามผู้ใช้

สิทธิ์การใช้งาน Tool

Claude กำหนดว่าจะเรียก tools ใด แต่คุณควบคุมว่า calls เหล่านั้นจะได้รับอนุญาตให้รันหรือไม่:

  • allowed_tools / allowedTools อนุมัติอัตโนมัติสำหรับ tools ที่ระบุ
  • disallowed_tools / disallowedTools บล็อก tools ที่ระบุ ไม่ว่าการตั้งค่าอื่นจะเป็นอย่างไร
  • permission_mode / permissionMode ควบคุมสิ่งที่เกิดขึ้นกับ tools ที่ไม่ได้ครอบคลุมโดย allow หรือ deny rules

ควบคุมวิธีการรัน Loop

Turns และงบประมาณ

ตัวเลือกควบคุมค่าเริ่มต้น
Max turns (max_turns / maxTurns)จำนวน tool-use round trips สูงสุดไม่จำกัด
Max budget (max_budget_usd / maxBudgetUsd)ต้นทุนสูงสุดก่อนหยุดไม่จำกัด

ระดับ Effort

ตัวเลือก effort ควบคุมว่า Claude ใช้การให้เหตุผลมากน้อยเพียงใด:

ระดับพฤติกรรมเหมาะสำหรับ
"low"การให้เหตุผลขั้นต่ำ การตอบสนองเร็วการค้นหาไฟล์ การแสดงรายการไดเรกทอรี
"medium"การให้เหตุผลที่สมดุลการแก้ไขทั่วไป งานมาตรฐาน
"high"การวิเคราะห์อย่างละเอียดการ refactor การ debugging
"xhigh"ความลึกในการให้เหตุผลที่ขยายงานเขียนโค้ดและ agentic
"max"ความลึกในการให้เหตุผลสูงสุดปัญหาหลายขั้นตอนที่ต้องการการวิเคราะห์เชิงลึก

Permission Mode

Modeพฤติกรรม
"default"Tools ที่ไม่ได้ครอบคลุมโดย allow rules จะเรียก approval callback ของคุณ
"acceptEdits"อนุมัติการแก้ไขไฟล์และคำสั่ง filesystem ทั่วไปโดยอัตโนมัติ
"plan"Claude สำรวจและวางแผนโดยไม่แก้ไขไฟล์ source ของคุณ
"dontAsk"ไม่มีการแจ้งเตือน Tools ที่ได้รับการอนุมัติล่วงหน้าโดย rules รัน ส่วนที่เหลือถูกปฏิเสธ
"auto" (TypeScript เท่านั้น)ใช้ model classifier เพื่ออนุมัติหรือปฏิเสธแต่ละ tool call
"bypassPermissions"รัน tools ที่ได้รับอนุญาตทั้งหมดโดยไม่ถาม

Context Window

Context window คือข้อมูลทั้งหมดที่ใช้ได้สำหรับ Claude ระหว่าง session มันจะไม่รีเซ็ตระหว่าง turns ภายใน session ทุกอย่างสะสม: system prompt, tool definitions, ประวัติการสนทนา, tool inputs และ tool outputs

การบีบอัดอัตโนมัติ

เมื่อ context window ใกล้ถึงขีดจำกัด SDK จะบีบอัดการสนทนาโดยอัตโนมัติ: สรุปประวัติเก่าเพื่อเพิ่มพื้นที่ และรักษาการแลกเปลี่ยนล่าสุดและการตัดสินใจสำคัญไว้

คุณสามารถปรับแต่งพฤติกรรมการบีบอัดได้หลายวิธี:

  • คำแนะนำการสรุปใน CLAUDE.md: ผู้บีบอัดจะอ่าน CLAUDE.md ของคุณเหมือนกับ context อื่นๆ
  • PreCompact hook: รันตรรกะแบบกำหนดเองก่อนการบีบอัด เช่น การเก็บถาวร transcript เต็ม
  • การบีบอัดด้วยตนเอง: ส่ง /compact เป็น prompt string เพื่อเรียกการบีบอัดตามต้องการ

Sessions และความต่อเนื่อง

แต่ละการโต้ตอบกับ SDK จะสร้างหรือดำเนินต่อ session จับ session ID จาก ResultMessage.session_id เพื่อ resume ในภายหลัง

เมื่อคุณ resume ประวัติบริบทเต็มรูปแบบจาก turns ก่อนหน้าจะถูกกู้คืน: ไฟล์ที่ถูกอ่าน การวิเคราะห์ที่ดำเนินการ และการกระทำที่เกิดขึ้น

ดู Session management สำหรับคำแนะนำเต็มรูปแบบเกี่ยวกับรูปแบบ resume, continue และ fork

จัดการผลลัพธ์

เมื่อ loop สิ้นสุด ResultMessage จะบอกคุณว่าเกิดอะไรขึ้นและให้ output:

Result subtypeสิ่งที่เกิดขึ้นfield result พร้อมใช้งาน?
successClaude เสร็จสิ้นงานตามปกติใช่
error_max_turnsถึงขีดจำกัด maxTurns ก่อนเสร็จสิ้นไม่
error_max_budget_usdถึงขีดจำกัด maxBudgetUsd ก่อนเสร็จสิ้นไม่
error_during_executionข้อผิดพลาดทำให้ loop หยุดชะงักไม่
error_max_structured_output_retriesไม่มี structured output ที่ถูกต้องภายในขีดจำกัด retryไม่

ตัวอย่างแบบครบถ้วน

ตัวอย่างนี้รวมแนวคิดหลักจากหน้านี้เป็น agent เดียวที่แก้ไขการทดสอบที่ล้มเหลว:

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def run_agent():
session_id = None

async for message in query(
prompt="Find and fix the bug causing test failures in the auth module",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Edit", "Bash", "Glob", "Grep"],
setting_sources=["project"],
max_turns=30,
effort="high",
),
):
if isinstance(message, ResultMessage):
session_id = message.session_id

if message.subtype == "success":
print(f"Done: {message.result}")
elif message.subtype == "error_max_turns":
print(f"Hit turn limit. Resume session {session_id} to continue.")
elif message.subtype == "error_max_budget_usd":
print("Hit budget limit.")
else:
print(f"Stopped: {message.subtype}")
if message.total_cost_usd is not None:
print(f"Cost: ${message.total_cost_usd:.4f}")


asyncio.run(run_agent())
import { query } from "@anthropic-ai/claude-agent-sdk";

let sessionId: string | undefined;

for await (const message of query({
prompt: "Find and fix the bug causing test failures in the auth module",
options: {
allowedTools: ["Read", "Edit", "Bash", "Glob", "Grep"],
settingSources: ["project"],
maxTurns: 30,
effort: "high"
}
})) {
if (message.type === "system" && message.subtype === "init") {
sessionId = message.session_id;
}

if (message.type === "result") {
if (message.subtype === "success") {
console.log(`Done: ${message.result}`);
} else if (message.subtype === "error_max_turns") {
console.log(`Hit turn limit. Resume session ${sessionId} to continue.`);
} else if (message.subtype === "error_max_budget_usd") {
console.log("Hit budget limit.");
} else {
console.log(`Stopped: ${message.subtype}`);
}
console.log(`Cost: $${message.total_cost_usd.toFixed(4)}`);
}
}

ขั้นตอนถัดไป

  • ยังไม่ได้รัน agent? เริ่มต้นด้วย quickstart เพื่อติดตั้ง SDK และดูตัวอย่างแบบครบถ้วน
  • พร้อม hook เข้ากับโปรเจกต์? โหลด CLAUDE.md, skills และ filesystem hooks เพื่อให้ agent ปฏิบัติตามแบบแผนโปรเจกต์ของคุณ
  • สร้าง interactive UI? เปิดใช้งาน streaming เพื่อแสดงข้อความแบบ live และ tool calls ขณะที่ loop รัน
  • ต้องการการควบคุมที่เข้มงวดขึ้น? ล็อค tool access ด้วย permissions และใช้ hooks เพื่อตรวจสอบ บล็อก หรือแปลง tool calls