นี่คือการแปลเนื้อหาภาษาอังกฤษเป็นภาษาไทยตามที่คุณต้องการ:
เจาะลึกวิธีการที่ Claude Code ค้นพบ ส่งต่อ และเรียกใช้งานเครื่องมือ
บทนำ
ในโพสต์ก่อนหน้านี้ เราได้ย้อนวิศวกรรมระบบหน่วยความจำของ Anthropic Harness จากซอร์สโค้ดที่รั่วไหลออกมา หน่วยความจำกลับกลายเป็นสิ่งที่เรียบง่ายอย่างน่าประหลาดใจ — ไฟล์ Markdown, frontmatter, และวิศวกรรมพร้อมต์ ระบบเครื่องมือกลับตรงกันข้าม มันเป็นระบบย่อยที่ถูกออกแบบทางวิศวกรรมมากที่สุดในโค้ดเบสทั้งหมด: เครื่องมือกว่า 43 รายการ, ไพพ์ไลน์การดำเนินการแบบสตรีมมิ่ง, ระบบสิทธิ์แบบหลายชั้น, เฟรมเวิร์กฮุค, และตัวจัดตารางการทำงานพร้อมกัน — ทั้งหมดถูกประกอบเข้าด้วยกันเพื่อเปลี่ยนโมเดลภาษาที่ไร้สถานะให้เป็นสิ่งที่สามารถอ่านไฟล์, รันคำสั่งเชลล์, ค้นหาเว็บ, และสร้างตัวแทนย่อยได้
โพสต์นี้จะพาคุณเดินผ่านวงจรชีวิตของเครื่องมือ ตั้งแต่การนิยามเครื่องมือ, วิธีการที่คำสั่งเรียกใช้เครื่องมือของโมเดลถูกส่งต่อ, ไปจนถึงวิธีการที่ผลลัพธ์ไหลกลับเข้าสู่การสนทนา โดยภาพรวม ระบบประกอบด้วยสี่ชั้น: อินเทอร์เฟซของเครื่องมือ ที่ทุกเครื่องมือนำไปใช้งาน, ทะเบียน ที่รวบรวมกลุ่มเครื่องมือ, ไพพ์ไลน์การส่งต่อ ที่ตรวจสอบความถูกต้อง, ตรวจสอบสิทธิ์, และดำเนินการแต่ละคำสั่งเรียกใช้, และ ตัวจัดตารางการทำงานพร้อมกัน ที่ตัดสินว่าสิ่งใดควรทำงานแบบขนาน
สถาปัตยกรรมโดยสังเขป

อินเทอร์เฟซของเครื่องมือ
ทุกเครื่องมือใน Claude Code ใช้อินเทอร์เฟซเดียวกัน ซึ่งนิยามไว้ใน Tool.ts ชนิดข้อมูลเป็นเจนเนอริกเหนือพารามิเตอร์สามตัว: Input (สคีมา Zod), Output (ชนิดผลลัพธ์), และ P (ข้อมูลความคืบหน้า) ในทางปฏิบัติ เครื่องมือคือออบเจกต์ที่มีประมาณ 30 เมธอด แต่มีเพียงไม่กี่เมธอดที่สำคัญต่อการทำความเข้าใจระบบ
โครงสร้างหลัก:
1type Tool<Input, Output, P> = {2 name: string3 inputSchema: ZodType // Zod schema for input validation4 call(input, context, canUseTool,5 parentMessage, onProgress): Promise<ToolResult>67 // Behavior declarations8 isConcurrencySafe(input): boolean // Can run in parallel?9 isReadOnly(input): boolean // Read-only operation?10 isDestructive(input): boolean // Destructive action?1112 // Permission and validation13 checkPermissions(input, context): Promise<PermissionResult>14 validateInput(input, context): Promise<ValidationResult>1516 // API integration17 description(input, options): Promise<string>18 prompt(options): Promise<string> // System prompt text for this tool19 mapToolResultToToolResultBlockParam(result, toolUseId): ToolResultBlockParam2021 // UI rendering (React)22 renderToolUseMessage(input, options): ReactNode23 renderToolResultMessage(content, ...): ReactNode24}
ไม่มีเครื่องมือใดที่เริ่มต้นจากศูนย์ ฟังก์ชันโรงงานที่ชื่อ buildTool() จะเติมค่าเริ่มต้นที่ปลอดภัยให้:

ค่าเริ่มต้นนั้นตั้งใจให้อนุรักษ์นิยม ผู้เขียนเครื่องมือที่ลืมประกาศความปลอดภัยในการทำงานพร้อมกันจะได้รับการดำเนินการแบบเรียงลำดับ ผู้เขียนเครื่องมือที่ลืมใช้การตรวจสอบสิทธิ์จะได้รับขั้นตอนสิทธิ์เริ่มต้น ระบบจะล้มเหลวในลักษณะปิดตัวลงอย่างปลอดภัย
ชนิด ToolResult ก็ควรค่าแก่การสังเกต:
1type ToolResult<T> = {2 data: T // The actual output3 newMessages?: Message[] // Optional follow-up messages4 contextModifier?: (ctx) => ToolUseContext // Mutate context for next tool5 mcpMeta?: { ... } // MCP protocol metadata6}
contextModifier มีความสำคัญ — มันช่วยให้เครื่องมือเปลี่ยนบริบทการดำเนินการสำหรับเครื่องมือถัดไปในรอบเดียวกัน นี่คือวิธีที่เครื่องมืออย่าง EnterWorktree เปลี่ยนไดเรกทอรีการทำงานสำหรับทุกสิ่งที่ตามมา ที่สำคัญ ตัวปรับเปลี่ยนบริบทจะอนุญาตเฉพาะเครื่องมือที่ไม่ปลอดภัยต่อการทำงานพร้อมกันเท่านั้น หากเครื่องมือทำงานแบบขนาน มันจะไม่สามารถแก้ไขสถานะที่ใช้ร่วมกันได้
ทะเบียนเครื่องมือ
เครื่องมือทั้งหมดถูกลงทะเบียนในฟังก์ชันเดียว: getAllBaseTools() ใน tools.ts มันคืนค่าเป็นอาร์เรย์แบบแบนราบ เครื่องมือบางรายการมีอยู่เสมอ ส่วนบางรายการถูกจำกัดด้วยแฟล็กคุณสมบัติ, ตัวแปรสภาพแวดล้อม, หรือการตรวจสอบแพลตฟอร์ม
มีให้ใช้งานเสมอ (16 เครื่องมือ)

เครื่องมือที่ถูกจำกัดด้วยแฟล็กคุณสมบัติ (~27 เครื่องมือ)
เครื่องมือที่เหลือจะถูกรวมไว้ตามเงื่อนไข บางรายการถูกจำกัดด้วยตัวแปรสภาพแวดล้อม (USER_TYPE=ant สำหรับเครื่องมือภายในของ Anthropic อย่าง config และ tungsten) บางรายการถูกจำกัดด้วยแฟล็กคุณสมบัติผ่าน Statsig (web_browser, sleep, monitor) บางรายการจำกัดเฉพาะแพลตฟอร์ม (powershell บน Windows) บางรายการถูกจำกัดด้วยเงื่อนไขผสม — เครื่องมือ repl ต้องใช้ทั้ง USER_TYPE=ant และแฟล็กคุณสมบัติ REPL
รายการเต็มของเครื่องมือที่ถูกจำกัดด้วยแฟล็กคุณสมบัติ
เฉพาะ Ant: config, tungsten, suggest_background_pr, repl (ต้องใช้แฟล็ก REPL ด้วย)
แฟล็กคุณสมบัติ: web_browser, web_search, sleep, monitor, overflow_test, ctx_inspect, terminal_capture, list_peers, workflow, snip
ทริกเกอร์ตัวแทน: cron_create, cron_delete, cron_list, remote_trigger
Kairos (ตัวแทนเชิงรุก): sleep, send_user_file, push_notification, subscribe_pr
ฝูงหลายตัวแทน: team_create, team_delete, send_message
Todo v2: task_create, task_get, task_update, task_list
สภาพแวดล้อม: lsp (ENABLE_LSP_TOOL), enter_worktree / exit_worktree (โหมด worktree), powershell (Windows)
การค้นหาเครื่องมือ: tool_search (เมื่อกลุ่มเครื่องมือมีขนาดใหญ่)
สำหรับทดสอบเท่านั้น: testing_permission (NODE_ENV=test)
เครื่องมือ MCP
นอกเหนือจากเครื่องมือในตัวแล้ว Claude Code ยังรองรับ เซิร์ฟเวอร์ Model Context Protocol (MCP) — กระบวนการภายนอกที่เปิดเผยเครื่องมือของตนเองผ่านโปรโตคอลมาตรฐาน เครื่องมือ MCP ถูกลงทะเบียนแบบไดนามิกในขณะรันไทม์จากเซิร์ฟเวอร์ที่เชื่อมต่อ และถูกห่อหุ้มด้วยอินเทอร์เฟซ Tool เดียวกัน จากมุมมองของไพพ์ไลน์การส่งต่อ เครื่องมือ MCP จะแยกไม่ออกจากเครื่องมือในตัว
เครื่องมือ MCP แต่ละรายการมีข้อมูลเมตาเกี่ยวกับเซิร์ฟเวอร์ต้นทาง (mcpInfo: { serverName, toolName }) ซึ่งใช้สำหรับกฎสิทธิ์, การจัดการข้อผิดพลาด, และการตรวจสอบสิทธิ์ เมื่อเครื่องมือ MCP ล้มเหลวด้วยข้อผิดพลาดด้านการตรวจสอบสิทธิ์ ระบบจะอัปเดตสถานะของเซิร์ฟเวอร์เป็น needs-auth โดยอัตโนมัติและแสดงปัญหาให้ผู้ใช้ทราบ
การประกอบกลุ่มเครื่องมือ
ฟังก์ชันสามฟังก์ชันประกอบชุดเครื่องมือสุดท้าย:
- getAllBaseTools() — คืนค่ารายการดิบของเครื่องมือในตัวกว่า 43 รายการพร้อมใช้แฟล็กคุณสมบัติ
- getTools(permissionContext) — กรองตามกฎปฏิเสธและ isEnabled()
- assembleToolPool(permissionContext, mcpTools) — รวมเครื่องมือในตัวและ MCP
กลยุทธ์การรวมใน assembleToolPool() นั้นตั้งใจ:
เครื่องมือในตัวมาก่อน ดังนั้นเมื่อมีการชนกันของชื่อ เครื่องมือในตัวจะเป็นฝ่ายชนะ การเรียงลำดับตามตัวอักษรภายในแต่ละพาร์ติชันช่วยให้ลำดับคงที่ในทุกเซสชัน ซึ่งสำคัญสำหรับการแคชพร้อมต์ — อาร์เรย์เครื่องมือเป็นส่วนหนึ่งของคำขอ API และการจัดเรียงใหม่จะทำให้แคชเสีย
กลยุทธ์การรวมใน assembleToolPool() นั้นตั้งใจ:
1// Sort each partition alphabetically, concat, deduplicate2const byName = (a, b) => a.name.localeCompare(b.name)3return uniqBy(4 [...builtInTools].sort(byName).concat(allowedMcpTools.sort(byName)),5 'name',6)
การทำให้เป็นอนุกรมสำหรับ API
ก่อนที่เครื่องมือจะไปถึง Claude API toolToAPISchema() จะแปลงสคีมา Zod ของแต่ละเครื่องมือเป็นรูปแบบ JSON Schema ของ Anthropic API
ไพพ์ไลน์การส่งต่อ
เมื่อ Claude ตอบกลับ ข้อความของมันอาจมีบล็อก tool_use — คำขอที่มีโครงสร้างเพื่อเรียกใช้เครื่องมือ ไพพ์ไลน์การส่งต่อจะประมวลผลบล็อกเหล่านี้ผ่านเจ็ดเฟส ทุกคำสั่งเรียกใช้เครื่องมือจะผ่านทุกเฟส ตามลำดับ
เฟส 1: การสกัด
ในลูปคำสั่งหลัก (query.ts) บล็อก tool_use จะถูกกรองออกจากข้อความผู้ช่วย:
1const msgToolUseBlocks = message.message.content.filter(2 content => content.type === 'tool_use',3) as ToolUseBlock[]
แต่ละบล็อกมี name, ออบเจกต์ input, และ id ที่ไม่ซ้ำกัน id มีความสำคัญอย่างยิ่ง — ผลลัพธ์ของเครื่องมือต้องอ้างอิง id เดียวกันเมื่อส่งกลับไปยัง API มิฉะนั้นการสนทนาจะเสีย
เฟส 2: การตรวจสอบความถูกต้องของอินพุต
สคีมา Zod ของเครื่องมือจะตรวจสอบความถูกต้องของอินพุตดิบโดยใช้ safeParse() — ตัวแปรที่ไม่โยนข้อผิดพลาดซึ่งคืนค่าข้อมูลที่ถูกต้องหรือข้อผิดพลาดที่มีโครงสร้าง หากการตรวจสอบล้มเหลว โมเดลจะได้รับข้อความแสดงข้อผิดพลาดที่จัดรูปแบบพร้อมคำแนะนำสคีมา และการดำเนินการจะหยุดสำหรับเครื่องมือนั้น ไม่มีโค้ดใดทำงานบนอินพุตที่ไม่ถูกต้อง
1const parsedInput = tool.inputSchema.safeParse(input)2if (!parsedInput.success) {3 let errorContent = formatZodValidationError(tool.name, parsedInput.error)4 // Return error to model, skip execution5}
หลังจากการตรวจสอบ Zod เครื่องมือบางตัวจะรันการตรวจสอบ validateInput() รอบที่สองสำหรับการตรวจสอบความหมายที่ไม่สามารถแสดงในสคีมาได้ — ตัวอย่างเช่น การยืนยันว่าเส้นทางไฟล์เป็นแบบสัมบูรณ์ ไม่ใช่แบบสัมพัทธ์
เฟส 3: ฮุคก่อนเครื่องมือ
ก่อนการตรวจสอบสิทธิ์ ฮุคที่ผู้ใช้กำหนดค่าจะทำงาน ฮุคเหล่านี้เป็นคำสั่งเชลล์หรือสคริปต์ภายนอกที่ทำงานเมื่อมีการเรียกใช้เครื่องมือ ฮุคก่อนเครื่องมือสามารถ:
- อนุญาต การเรียกใช้เครื่องมือ โดยข้ามพร้อมต์สิทธิ์แบบโต้ตอบ
- ปฏิเสธ การเรียกใช้เครื่องมือทันที
- แก้ไขอินพุต ก่อนการดำเนินการ
- บล็อกการดำเนินการ ด้วยข้อความแสดงข้อผิดพลาด
- ให้บริบทเพิ่มเติม แก่ผู้ใช้
สิ่งสำคัญที่ไม่สามารถเปลี่ยนแปลงได้: การ อนุญาต ของฮุคจะ ไม่ ข้ามกฎปฏิเสธจากการตั้งค่า ซอร์สโค้ดมีคำอธิบายประกอบที่ชัดเจนเกี่ยวกับเรื่องนี้: "การ 'อนุญาต' ของฮุคจะไม่ข้ามกฎ deny/ask ใน settings.json" เจตนาคือฮุคสามารถเปิดประตูได้ แต่ไม่สามารถแทนที่ล็อกได้
เฟส 4: การตรวจสอบสิทธิ์
ระบบสิทธิ์เป็นส่วนที่ซับซ้อนที่สุดของไพพ์ไลน์ มันทำงานผ่านหลายชั้น ตามลำดับ:
- กฎปฏิเสธ — ตรวจสอบก่อน หากกฎปฏิเสธใดตรงกัน การดำเนินการจะหยุดทันที กฎปฏิเสธเป็นที่สิ้นสุดและไม่สามารถแทนที่ได้โดยชั้นอื่นใด
- กฎถาม — หากตรงกัน ผู้ใช้จะได้รับพร้อมต์ให้อนุมัติ (เว้นแต่การอนุญาตอัตโนมัติในแซนด์บ็อกซ์จะใช้กับ Bash)
- สิทธิ์เฉพาะเครื่องมือ — เมธอด checkPermissions() ของเครื่องมือจะทำงาน ตัวอย่างเช่น BashTool จะแยกวิเคราะห์คำสั่งเพื่อตรวจสอบกฎระดับคำสั่งย่อย
- การตรวจสอบความปลอดภัย — การป้องกันแบบฮาร์ดโค้ดสำหรับเส้นทางที่ละเอียดอ่อน (.git/, .claude/, การกำหนดค่าเชลล์) สิ่งเหล่านี้ไม่สามารถหลีกเลี่ยงได้ — แม้ในโหมดหลีกเลี่ยงทั้งหมด ก็ยังต้องมีการอนุมัติแบบโต้ตอบ
- โหมดสิทธิ์ — โหมดที่ผู้ใช้กำหนดค่าจะกำหนดพฤติกรรมเริ่มต้น
- กฎอนุญาต — ตรวจสอบเป็นรายการสุดท้าย หากกฎอนุญาตตรงกันและไม่มีกฎปฏิเสธ/ถามถูกเรียกใช้ เครื่องมือจะดำเนินการต่อ
โหมดสิทธิ์
default — ให้พร้อมต์ผู้ใช้เสมอสำหรับการตัดสินใจแบบ "ถาม"
acceptEdits — อนุญาตอัตโนมัติสำหรับการดำเนินการไฟล์ที่ปลอดภัย (อ่าน, แก้ไข) ให้พร้อมต์สำหรับสิ่งอื่นทั้งหมด
bypassPermissions — อนุญาตอัตโนมัติทุกอย่างยกเว้นกฎปฏิเสธและการตรวจสอบความปลอดภัย
plan — อนุมัติแผนก่อน จากนั้นทำตามโหมดก่อนหน้าสำหรับการดำเนินการ
auto — ใช้ตัวจำแนกประเภท AI เพื่อตัดสินใจว่าจะอนุญาตหรือให้พร้อมต์
dontAsk — แปลงการตัดสินใจแบบ "ถาม" ทั้งหมดเป็น "ปฏิเสธ" — ไม่ต้องให้พร้อมต์ เพียงแค่ปฏิเสธ
กฎสิทธิ์มาจากหลายแหล่ง โดยแก้ไขตามลำดับความสำคัญ: policySettings, localSettings, projectSettings, userSettings, flagSettings, cliArg, command, session วิธีนี้นโยบายองค์กรสามารถแทนที่การตั้งค่าผู้ใช้ และอาร์กิวเมนต์ CLI สามารถแทนที่ทั้งสองอย่าง
เฟส 5: การดำเนินการ
หากได้รับสิทธิ์ เมธอด call() ของเครื่องมือจะถูกเรียกใช้:
1const result = await tool.call(2 callInput,3 { ...toolUseContext, toolUseId: toolUseID },4 canUseTool,5 assistantMessage,6 progress => onToolProgress({ toolUseID: progress.toolUseID, data: progress.data })7)
ห้าอาร์กิวเมนต์: อินพุตที่ตรวจสอบแล้ว, บริบทการดำเนินการ (ไดเรกทอรีการทำงาน, ตัวควบคุมการยกเลิก, สถานะแอป), callback สิทธิ์ (สำหรับเครื่องมือที่ต้องขอสิทธิ์เพิ่มเติมระหว่างการดำเนินการ), ข้อความผู้ช่วยต้นทาง, และ callback ความคืบหน้าสำหรับการอัปเดตแบบเรียลไทม์ ระยะเวลาจะถูกติดตามทั่วโลก
รายละเอียดที่ละเอียดอ่อน: อินพุตที่ส่งไปยัง call() คือ อินพุตดั้งเดิม ของโมเดล ไม่ใช่เวอร์ชันที่ถูกเติมกลับหลังที่ฮุคและสิทธิ์ได้เห็น วิธีนี้รักษาความสอดคล้องของบันทึกการสนทนา — การเรียกใช้เครื่องมือที่บันทึกไว้ในการสนทนาจะตรงกับสิ่งที่โมเดลสร้างขึ้นทุกประการ
เฟส 6: ฮุคหลังเครื่องมือ
หลังจากการดำเนินการ ฮุคหลังเครื่องมือจะทำงาน ฮุคเหล่านี้สามารถแก้ไขเอาต์พุตของเครื่องมือ MCP, ให้บริบทเพิ่มเติม, หรือบล็อกการสนทนาจากการดำเนินการต่อ นอกจากนี้ยังมีฮุค PostToolUseFailure แยกต่างหากที่ทำงานเฉพาะเมื่อมีข้อผิดพลาด ทำให้ระบบภายนอกมีโอกาสบันทึกความล้มเหลวหรือแนะนำการแก้ไข
เฟส 7: การแมปผลลัพธ์
แต่ละเครื่องมือใช้ mapToolResultToToolResultBlockParam() เพื่อแปลงเอาต์พุตเป็นรูปแบบ ToolResultBlockParam ของ Anthropic API — บล็อก tool_result พร้อมการอ้างอิง tool_use_id และเนื้อหาสตริงหรือแบบมีโครงสร้าง
หากผลลัพธ์เกินเกณฑ์ขนาด มันจะถูกเก็บไว้ในดิสก์ที่ sessionDir/tool-results/{toolUseId}.txt และตัวอย่างพร้อมการอ้างอิงไฟล์จะถูกส่งไปยัง API แทน วิธีนี้ป้องกันไม่ให้เอาต์พุตขนาดใหญ่ (การอ่านไฟล์ 10,000 บรรทัด, เอาต์พุตคำสั่งที่มีรายละเอียดมาก) ทำให้บริบทการสนทนาใหญ่เกินไป
ตัวจัดตารางการทำงานพร้อมกัน
เมื่อโมเดลปล่อยคำสั่งเรียกใช้เครื่องมือหลายรายการในข้อความเดียว พวกมันไม่ได้ทำงานทั้งหมดพร้อมกัน ตัวจัดตารางจะแบ่งพวกมันเป็นชุดตามความปลอดภัยในการทำงานพร้อมกัน
อัลกอริทึมนั้นเรียบง่าย เดินผ่านคำสั่งเรียกใช้เครื่องมือตามลำดับ สำหรับแต่ละรายการ ตรวจสอบ isConcurrencySafe(input) หากปลอดภัยและชุดก่อนหน้าก็ปลอดภัยเช่นกัน ให้เพิ่มเข้าไปในชุด มิฉะนั้น ให้เริ่มชุดใหม่
1// Simplified from toolOrchestration.ts2for (const toolUse of toolUseMessages) {3 const isSafe = tool.isConcurrencySafe(parsedInput)4 if (isSafe && lastBatch.isConcurrencySafe) {5 lastBatch.blocks.push(toolUse) // Merge into concurrent batch6 } else {7 batches.push({ isConcurrencySafe: isSafe, blocks: [toolUse] })8 }9}
ชุดที่ปลอดภัยจะทำงานพร้อมกัน (สูงสุด 10 รายการ กำหนดค่าได้ผ่าน CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY) ชุดที่ไม่ปลอดภัยจะทำงานแบบเรียงลำดับ ทีละเครื่องมือ ตัวปรับเปลี่ยนบริบทจะถูกใช้เฉพาะระหว่างชุดเท่านั้น ไม่ใช่ภายในชุด
ในทางปฏิบัติ หมายความว่าข้อความอย่าง "อ่านไฟล์ 5 ไฟล์นี้" จะสร้างชุดทำงานพร้อมกันหนึ่งชุด ในขณะที่ "อ่านไฟล์นี้ แล้วแก้ไขมัน" จะสร้างชุดแบบเรียงลำดับสองชุด โมเดลสามารถกระตุ้นทั้งสองรูปแบบในรอบเดียว — การเรียกแบบอ่านอย่างเดียวที่ต่อเนื่องกันจะถูกจัดเป็นชุด และการเขียนครั้งแรกจะทำลายชุด
ตัวดำเนินการแบบสตรีมมิ่ง
มีเส้นทางการดำเนินการที่สอง: StreamingToolExecutor เมื่อเปิดใช้งานสตรีมมิ่ง เครื่องมือจะเริ่มทำงาน ในขณะที่โมเดลยังคงสร้างการตอบสนองอยู่ เมื่อแต่ละบล็อก tool_use เสร็จสมบูรณ์ในสตรีม มันจะถูกจัดคิวเพื่อดำเนินการทันที แทนที่จะรอการตอบสนองทั้งหมด
ตัวดำเนินการแบบสตรีมมิ่งใช้กฎการทำงานพร้อมกันเดียวกัน แต่เพิ่มพฤติกรรมหนึ่งอย่าง: การเรียงซ้อนข้อผิดพลาด Bash หากคำสั่ง Bash ล้มเหลวในขณะที่เครื่องมืออื่นกำลังทำงานแบบขนาน ตัวดำเนินการจะยกเลิกเครื่องมืออื่นทั้งหมด เหตุผลคือคำสั่ง Bash ที่ล้มเหลวมักจะทำให้บริบทที่เครื่องมืออื่นกำลังทำงานอยู่ไม่ถูกต้อง — การดำเนินการต่อจะเสียเวลาและอาจทำให้เกิดข้อผิดพลาดที่สับสน
1if (isErrorResult && tool.block.name === BASH_TOOL_NAME) {2 this.hasErrored = true3 this.siblingAbortController.abort('sibling_error')4}
ตัวอย่างเชิงปฏิบัติ
เพื่อให้เห็นภาพชัดเจน มาดูว่าเกิดอะไรขึ้นเมื่อโมเดลตัดสินใจอ่านไฟล์ โมเดลจะปล่อย:
1{2 "type": "tool_use",3 "id": "toolu_01XYZ",4 "name": "read",5 "input": { "file_path": "/src/index.ts" }6}
การสกัด: query.ts กรองสิ่งนี้ออกจากเนื้อหาข้อความผู้ช่วย
- การค้นหาเครื่องมือ: findToolByName(tools, "read") ค้นหา FileReadTool
- การตรวจสอบความถูกต้องของอินพุต: Zod แยกวิเคราะห์ { file_path: "/src/index.ts" } เทียบกับ z.object({ file_path: z.string(), offset: z.number().optional(), limit: z.number().optional(), pages: z.string().optional() }) มันผ่าน
- ฮุคก่อนเครื่องมือ: ฮุคที่ผู้ใช้กำหนดค่าจะทำงาน ไม่มีฮุคใดแก้ไขอินพุต
- การตรวจสอบสิทธิ์: checkPermissions() ของ FileReadTool เรียก checkReadPermissionForTool() โดยทั่วไปเครื่องมืออ่านจะได้รับอนุญาตในโหมดสิทธิ์ส่วนใหญ่
- การดำเนินการ: FileReadTool.call() อ่านไฟล์, ใช้การนับบรรทัด (รูปแบบ cat -n), จัดการ PDF/รูปภาพ/โน้ตบุ๊กเป็นกรณีพิเศษ
- การแมปผลลัพธ์: เนื้อหาไฟล์กลายเป็นบล็อก tool_result ที่อ้างอิง "toolu_01XYZ"
- การส่งคืน: ผลลัพธ์ถูกผนวกเข้ากับการสนทนาเป็นข้อความผู้ใช้และส่งในการเรียก API ครั้งถัดไป
เนื่องจาก FileReadTool ประกาศ isConcurrencySafe: () => true และ isReadOnly: () => true หากโมเดลปล่อยคำสั่งอ่านห้ารายการในข้อความเดียวกัน ทั้งห้ารายการจะดำเนินการแบบขนาน
สรุป
ระบบเครื่องมือคือกระดูกสันหลังการดำเนินการของ Claude Code มันนำเจตนาของโมเดล — ที่แสดงเป็นบล็อก tool_use ที่มีโครงสร้าง — และเปลี่ยนเป็นปฏิบัติการจริงบนเครื่องของคุณ พร้อมการตรวจสอบความถูกต้อง สิทธิ์ และการควบคุมการทำงานพร้อมกันในทุกขั้นตอน
การออกแบบเป็นแบบชั้น: ฟังก์ชันโรงงาน buildTool() ที่อนุรักษ์นิยมทำให้มั่นใจถึงค่าเริ่มต้นที่ปลอดภัย, ทะเบียนที่ถูกจำกัดด้วยแฟล็กคุณสมบัติควบคุมว่ามีอะไรบ้าง, ไพพ์ไลน์การส่งต่อเจ็ดเฟสตรวจสอบความถูกต้องและสิทธิ์ทุกคำสั่งเรียกใช้, และตัวจัดตารางการทำงานพร้อมกันเพิ่มประสิทธิภาพการทำงานแบบขนานในขณะที่รักษาความถูกต้อง ตัวดำเนินการแบบสตรีมมิ่งเพิ่มการปรับประสิทธิภาพด้านบน — เครื่องมือเริ่มทำงานก่อนที่โมเดลจะคิดเสร็จ
เมื่อเทียบกับระบบหน่วยความจำ (5 เส้นทาง, ไดเรกทอรีของไฟล์ Markdown, และวิศวกรรมพร้อมต์) ระบบเครื่องมือเป็นรันไทม์ที่แท้จริง มันคือความแตกต่างระหว่างตู้เก็บเอกสารและระบบปฏิบัติการ
สิ่งที่น่าสนใจ
โมเดลในฐานะตัวจัดตาราง
ตัวจัดตารางการทำงานพร้อมกันเป็นแบบปฏิกิริยา — มันจัดกลุ่มสิ่งที่โมเดลปล่อยออกมา แต่โมเดลเองคือตัวจัดตารางที่แท้จริง พร้อมต์ระบบบอกให้ "ทำการเรียกใช้เครื่องมืออิสระทั้งหมดแบบขนาน" และให้ "ใช้การเรียก Bash เดียวกับ && เพื่อเชื่อมโยงคำสั่งที่พึ่งพากัน" รันไทม์เชื่อถือสิ่งนี้ หากโมเดลปล่อยการอ่านห้ารายการตามด้วยการเขียนหนึ่งรายการ ตัวจัดตารางจะทำการอ่านแบบขนานและเขียนแบบเรียงลำดับ แต่โมเดลเป็นผู้ตัดสินลำดับนั้น ตัวจัดตารางกำลังบังคับใช้แผนของโมเดล ไม่ใช่สร้างแผนของตัวเอง
การปิดตัวลงอย่างปลอดภัยเป็นค่าเริ่มต้น
หลักการออกแบบที่สอดคล้องมากที่สุด: ทุกอย่างปิดตัวลงอย่างปลอดภัย เครื่องมือที่ไม่รู้จัก? ข้อผิดพลาด อินพุตที่ไม่ถูกต้อง? ข้อผิดพลาด ไม่มีการประกาศความปลอดภัยในการทำงานพร้อมกัน? การดำเนินการแบบเรียงลำดับ ไม่มีการประกาศสิทธิ์? ถามผู้ใช้ ไม่มีแฟล็กคุณสมบัติ? ไม่มีเครื่องมือ สิ่งนี้ผิดปกติสำหรับระบบที่ผู้ใช้หลักเป็นโมเดล AI ที่อาจสร้างภาพชื่อเครื่องมือหรืออินพุตที่ผิดรูป ระบบถูกออกแบบมาเพื่อควบคุมข้อผิดพลาดของโมเดล ไม่ใช่เพื่อรองรับมัน
ฮุคเป็นจุดขยาย
ระบบฮุค — ก่อนเครื่องมือ, หลังเครื่องมือ, และหลังข้อผิดพลาด — เป็นจุดขยายหลัก มันเป็นวิธีที่องค์กรบังคับใช้นโยบาย (กฎปฏิเสธในฮุคก่อน), วิธีที่ระบบบันทึกจับการใช้งานเครื่องมือ (ฮุคหลัง), และวิธีที่ไปป์ไลน์ CI/CD รวมเข้าด้วยกัน (ฮุคข้อผิดพลาด) ที่สำคัญ ฮุคสามารถทำให้ข้อจำกัดเข้มงวดขึ้นเท่านั้น ไม่ใช่ผ่อนคลายลง ฮุคสามารถปฏิเสธเครื่องมือที่การตั้งค่าอนุญาต แต่มันไม่สามารถอนุญาตเครื่องมือที่การตั้งค่าปฏิเสธ
43 เครื่องมือ, 1 อินเทอร์เฟซ
บางทีสิ่งที่โดดเด่นที่สุดคือความสม่ำเสมอ คำสั่ง bash, web_fetch, การสร้างตัวแทนย่อย, การสร้างงาน cron, และการแจ้งเตือนแบบพุชทั้งหมดใช้อินเทอร์เฟซ 30 เมธอดเดียวกัน, ผ่านไพพ์ไลน์เจ็ดเฟสเดียวกัน, และเคารพระบบสิทธิ์เดียวกัน ไม่มีกรณีพิเศษในตัวส่งต่อ ความซับซ้อนอยู่ที่การใช้งานเครื่องมือแต่ละรายการและในกฎสิทธิ์ ไม่ใช่ในการกำหนดเส้นทาง





