โพรโทคอลส่งต่องานแบบมีโครงสร้าง
ส่งต่องานพร้อม ID สรุป การดำเนินการ และคำแนะนำ
โพรโทคอลส่งต่องานแบบมีโครงสร้าง เป็นบทเรียน Claude Architect ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Claude Architect และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Claude Architect มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดการส่งต่องานจึงต้องมีโครงสร้าง
ในระบบหลายตัวแทนแบบศูนย์กลางและกิ่งงาน ผู้ประสานงานจะส่งงานให้ตัวแทนย่อยและรับผลลัพธ์กลับมาอยู่เสมอ ข้อเท็จจริงที่เป็น CRITICAL คือ ตัวแทนย่อยจะ NOT สืบทอดประวัติการสนทนาของผู้ประสานงาน — โมเดลไม่เก็บสถานะ ดังนั้นประวัติคำขอ FULL จึงต้องเดินทางไปใน messages ทุกครั้งที่มีการโต้ตอบ
นั่นหมายความว่าการส่งต่องานทุกครั้งต้องมีบริบทของตัวเองอย่างชัดเจน การส่งข้อความที่ไม่มีโครงสร้างอย่าง "ไปแก้ข้อผิดพลาด auth" จะทำให้หมายเลขกรณี สิ่งที่ลองทำไปแล้ว และผลลัพธ์ที่ผู้ประสานงานต้องการได้รับสูญหายไป โปรโตคอลการส่งต่องานแบบมีโครงสร้างช่วยแก้ปัญหานี้ โดยการโอนแต่ละครั้งจะมีตัวระบุ สรุป การดำเนินการที่ทำไปแล้ว และคำแนะนำ
การส่งต่องานสี่ส่วน
ข้อมูลการส่งต่องานที่เชื่อถือได้มีสี่ช่อง โดยแต่ละช่องช่วยแก้ปัญหาความล้มเหลวเฉพาะด้าน:
- ID — คีย์อ้างอิงที่คงที่ (case_id, custom_id) เพื่อจับคู่ผลลัพธ์กับคำขอได้ แม้จะเป็นการเรียกใช้แบบขนาน
- สรุป — ข้อเท็จจริงจากธุรกรรมตามต้นฉบับที่ผู้รับจำเป็นต้องใช้ (ID ลูกค้าที่ตรวจสอบแล้ว หมายเลขคำสั่งซื้อ จำนวนเงิน)
- การดำเนินการ — สิ่งที่ได้ลองทำไปแล้วพร้อมผลลัพธ์ เพื่อไม่ให้ทำงานซ้ำ
- คำแนะนำ — ขั้นตอนถัดไปหรือการตัดสินใจที่เสนอ ซึ่งผู้รับต้องยืนยันหรือแก้ไข
แนวทางนี้สอดคล้องโดยตรงกับวิธีที่ผู้ประสานงานแยกงาน มอบหมายงาน รวบรวมผลลัพธ์ และกำหนดเส้นทาง
ส่งบริบทอย่างชัดเจน
เนื่องจากตัวแทนย่อยเริ่มต้นด้วยประวัติที่ว่างเปล่า คุณจึงพึ่งพาความคิดที่ว่า "มันรู้อยู่แล้ว" ไม่ได้ ให้ใส่การส่งต่องานไว้ในพรอมต์ของตัวแทนย่อยโดยตรง โปรดสังเกตว่า ID สรุป และการดำเนินการก่อนหน้านี้ถูกระบุไว้อย่างชัดเจน — ไม่มีสิ่งใดถูกถือว่าเป็นที่เข้าใจกันอยู่แล้ว
subagent_prompt = f"""
HANDOFF
id: {case_id}
summary: Verified customer C-4821 (id confirmed via get_customer).
Order O-9930, refund requested: $420.
actions_taken:
- get_customer -> identity verified
- lookup_order(O-9930) -> status DELIVERED, eligible
recommendation: Approve refund of $420; confirm against policy before process_refund.
Proceed with the recommendation or override it with justification.
"""
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
system="You are the refund-processing subagent.",
messages=[{"role": "user", "content": subagent_prompt}],
tools=refund_tools,
)บังคับรูปแบบด้วยผลลัพธ์แบบมีโครงสร้าง
การส่งต่องานด้วยข้อความอิสระอาจมีรูปแบบผิดได้ง่าย หากต้องการรับประกันว่าทั้งสี่ช่องมีอยู่ครบ ให้กำหนดการส่งต่องานเป็น เครื่องมือที่ใช้ JSON Schema และใช้ tool_choice เพื่อบังคับให้ส่งผลลัพธ์แบบมีโครงสร้าง การใช้ tool_use ร่วมกับ JSON Schema จะกำจัดข้อผิดพลาดทางไวยากรณ์และบังคับให้มีช่องที่จำเป็น
กฎสำคัญจากเอกสารข้อเท็จจริง: ให้กำหนดช่องเป็น required ONLY เมื่อช่องนั้นมีอยู่เสมอ id, summary, actions และ recommendation มีอยู่เสมอในการส่งต่องานที่ถูกต้อง ดังนั้นจึงกำหนดให้เป็นช่องที่จำเป็นได้อย่างเหมาะสม ช่องที่ไม่บังคับ เช่น escalation_reason ต้อง NOT ถูกกำหนดเป็นช่องที่จำเป็น มิฉะนั้นโมเดลจะสร้างข้อมูลขึ้นมาเอง
handoff_tool = {
"name": "emit_handoff",
"description": "Emit a structured handoff to the coordinator.",
"input_schema": {
"type": "object",
"properties": {
"id": {"type": "string"},
"summary": {"type": "string"},
"actions": {"type": "array", "items": {"type": "string"}},
"recommendation": {"type": "string"},
"escalation_reason": {"type": "string"}
},
"required": ["id", "summary", "actions", "recommendation"]
}
}บังคับการส่งต่องานด้วย tool_choice
วิธีตั้งค่า tool_choice จะเป็นตัวกำหนดว่าคุณจะได้รับการส่งต่องานแบบมีโครงสร้างจริงหรือไม่:
"auto"— โมเดลอาจตอบเป็นข้อความบรรยายแทนการส่งต่องาน จึงมีความเสี่ยงสำหรับโปรโตคอล"any"— โมเดล MUST เรียกใช้เครื่องมือบางอย่าง เพื่อรับประกันผลลัพธ์แบบมีโครงสร้าง{"type":"tool","name":"emit_handoff"}— บังคับให้ใช้เครื่องมือนี้เท่านั้น ใช้ตัวเลือกนี้เมื่องานของตัวแทนย่อยคือการส่งคืนการส่งต่องานที่มีรูปแบบถูกต้องหนึ่งรายการ
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
system="Summarize your work as a single handoff.",
messages=history,
tools=[handoff_tool],
tool_choice={"type": "tool", "name": "emit_handoff"},
)
handoff = response.content[0].input # {id, summary, actions, recommendation}เชื่อมโยงด้วย ID ที่คงที่
ID ทำให้ผู้ประสานงานรวบรวมผลลัพธ์ที่มาถึงไม่พร้อมลำดับกันได้ เมื่อคุณส่งคำขอ Task หลายรายการในการตอบกลับครั้งเดียว คำขอเหล่านั้นจะทำงานแบบ ขนาน — การตอบกลับจะไม่กลับมาตามลำดับที่คุณส่ง หากไม่มีคีย์อ้างอิง คุณจะจับคู่ผลลัพธ์กับคำขอไม่ได้
หลักการนี้เหมือนกับ custom_id ของ Batch API ซึ่งใช้เชื่อมโยงคำขอ เพื่อให้คุณส่งเฉพาะรายการที่ล้มเหลวอีกครั้งได้ ในกระบวนการหลายตัวแทนแบบซิงโครนัส id ของการส่งต่องานจะทำหน้าที่เดียวกัน
results_by_id = {}
for handoff in subagent_handoffs:
results_by_id[handoff["id"]] = handoff
# Aggregate deterministically by ID, not by arrival order
for case_id in dispatched_ids:
h = results_by_id.get(case_id)
if h is None:
log.warning("missing handoff for %s", case_id)เก็บข้อเท็จจริงตามต้นฉบับในส่วนสรุป
ส่วนสรุปเป็นจุดที่การส่งต่องานเสียหายอย่างเงียบ ๆ การสรุปแบบค่อยเป็นค่อยไปทำให้ตัวเลข เปอร์เซ็นต์ และวันที่คลุมเครือ ทั้งที่ข้อมูลเหล่านี้เป็นสิ่งที่ผู้รับต้องใช้ในการดำเนินการ ($420 กลายเป็น "เงินไม่กี่ร้อยดอลลาร์") นอกจากนี้ โมเดลยังให้ความสนใจกับต้นและท้ายบริบทมากกว่าส่วนกลาง (ข้อมูลสูญหายตรงกลาง)
วิธีแก้คือดึงข้อเท็จจริงจากธุรกรรมมาไว้ใน บล็อกข้อเท็จจริงของกรณีที่เก็บตามต้นฉบับ แยกออกจากสรุปแบบข้อความบรรยาย ช่อง summary ของการส่งต่องานควรมีข้อเท็จจริงเหล่านี้ตามต้นฉบับ และห้ามใช้การถอดความที่ทำให้ข้อมูลสูญหาย
case_facts = {
"customer_id": "C-4821",
"order_id": "O-9930",
"refund_amount_usd": 420.00,
"delivered_on": "2026-06-02",
}
# Inject verbatim; do NOT let these pass through summarization
summary = (
"Verified C-4821; order O-9930 delivered 2026-06-02; "
"refund requested $420.00."
)การดำเนินการ: แยกความล้มเหลวออกจากค่าว่าง
ช่องการดำเนินการต้องบันทึกไม่เพียงว่าสิ่งใดทำงาน แต่ต้องบันทึกด้วยว่าแต่ละการเรียกใช้ ส่งคืนอะไร — และต้องแยกความล้มเหลวในการเข้าถึงที่เป็น FAILURE (อาจลองใหม่ได้) ออกจากผลลัพธ์ EMPTY ที่ถูกต้อง (ไม่พบรายการ ไม่ต้องลองใหม่) ให้ใช้ ข้อผิดพลาดแบบมีโครงสร้าง ไม่ใช่ข้อผิดพลาดทั่วไป
ข้อผิดพลาดแบบมีโครงสร้างประกอบด้วย isError, errorCategory (ชั่วคราว / การตรวจสอบข้อมูล / ธุรกิจ / สิทธิ์), isRetryable, คำค้นหาที่ลองใช้ และผลลัพธ์บางส่วน ข้อความทั่วไปอย่าง "การดำเนินการล้มเหลว" จะขัดขวางการกู้คืน ขณะที่บริบทแบบมีโครงสร้างช่วยให้ผู้รับกำหนดเส้นทางได้อย่างเหมาะสม
actions = [
{"tool": "get_customer", "result": "verified C-4821"},
{"tool": "lookup_order", "query": "O-9930",
"isError": True, "errorCategory": "transient",
"isRetryable": True,
"message": "order service timeout",
"partial_results": []},
]คำแนะนำ ไม่ใช่การดำเนินการสุดท้าย
ช่องที่สี่คือ คำแนะนำ ซึ่งผู้รับสามารถยืนยันหรือแก้ไขได้ ไม่ใช่การดำเนินการฝ่ายเดียว วิธีนี้ช่วยให้อำนาจตัดสินใจยังอยู่กับผู้ที่ควรมีอำนาจ และรองรับการยกระดับปัญหาอย่างเป็นระบบ
เงื่อนไขที่ดีสำหรับการยกระดับปัญหาควรอยู่ในคำแนะนำ ได้แก่ คำขอจากมนุษย์โดยตรง (ยกระดับทันที) ช่องว่างของนโยบาย ไม่มีความคืบหน้าหลังจากลองดำเนินการแล้ว หรือการละเมิดค่าขีดจำกัด ส่วนเงื่อนไข BAD ต้องไม่เป็นตัวขับเคลื่อนคำแนะนำโดยเด็ดขาด ได้แก่ การวิเคราะห์ความรู้สึก คะแนนความมั่นใจที่โมเดลประเมินตัวเอง หรือเครื่องจำแนกที่ไม่ได้ฝึกมา คำแนะนำอย่าง "ลูกค้าฟังดูหงุดหงิด ให้ยกระดับปัญหา" คือรูปแบบที่ไม่ควรใช้
recommendation = (
"Refund $420 is within policy and order is eligible. "
"RECOMMEND approve. NOTE: refunds over $500 require a "
"hook-enforced check; this is under threshold."
)
# escalation_reason set ONLY on a real trigger, e.g.:
# "Customer explicitly asked for a manager."ป้องกันขั้นตอนสำคัญด้วยฮุก
คำแนะนำในการส่งต่องานมีลักษณะเป็นความน่าจะเป็น — แนวทางจากพรอมต์ถูกต้องประมาณ 90% เมื่อการดำเนินการตามการส่งต่องานมีผลกระทบด้านการเงิน กฎหมาย หรือความปลอดภัย การรับประกันต้อง กำหนดผลลัพธ์แน่นอน และบังคับใช้ด้วยฮุก ไม่ใช่ข้อความคำแนะนำ
ฮุกสำหรับการเรียกใช้งานขาออกสามารถบล็อกการดำเนินการที่ละเมิดนโยบายได้ (เช่น การคืนเงิน > $500) ไม่ว่าตัวแทนย่อยจะแนะนำอย่างไรก็ตาม เงื่อนไขก่อนการทำงานด้วยโปรแกรม — บล็อก process_refund จนกว่า get_customer จะส่งคืน ID ที่ตรวจสอบแล้ว — ให้การรับประกันที่พรอมต์ไม่สามารถให้ได้ ฮุก = กำหนดผลลัพธ์แน่นอน 100% พรอมต์ ≈ มีความน่าจะเป็น 90%
# settings.json — deterministic enforcement on the action,
# independent of the handoff recommendation
{
"hooks": {
"PreToolUse": [{
"matcher": "process_refund",
"command": "./hooks/block_refund_over_500.sh"
}]
}
}ดำเนินการต่อเทียบกับสรุปใหม่
บางครั้งการส่งต่องานเป็นการทำงานต่อจากงานก่อนหน้า --resume <name> จะดำเนินการต่อในเซสชันที่ระบุชื่อ และ fork_session จะแยกแขนงจากจุดร่วม แต่โปรดระวัง: ผลลัพธ์จากเครื่องมือที่ดำเนินการต่ออาจเป็น STALE หากโค้ดหรือข้อมูลมีการเปลี่ยนแปลงภายหลัง
เมื่อสถานะพื้นฐานเปลี่ยนไปแล้ว เซสชันใหม่ที่เริ่มต้นด้วยการส่งต่องานแบบมีโครงสร้าง (ID + ข้อเท็จจริงตามต้นฉบับ + การดำเนินการ + คำแนะนำ) มักเชื่อถือได้มากกว่าการดำเนินการต่อในเซสชันที่เต็มไปด้วยผลลัพธ์จากเครื่องมือที่ล้าสมัย การส่งต่องานแบบมีโครงสร้างทำให้การเริ่มต้นใหม่ทั้งหมดมีต้นทุนต่ำ
# Continue named work...
claude --resume refund-C4821
# ...but if state changed, start fresh and inject the handoff:
claude -p "$(cat handoff_C4821.json)" \
--system-prompt "Act on this structured handoff."ตรวจสอบความเข้าใจอย่างรวดเร็ว: ออกแบบการส่งต่องาน
ผู้ประสานงานส่งกรณีขอคืนเงินสามกรณีให้ตัวแทนย่อยด้วยคำขอ Task แบบขนาน คุณกำลังออกแบบการส่งต่องานที่ตัวแทนย่อยแต่ละตัวจะส่งคืน เพื่อให้สามารถรวบรวมผลลัพธ์และดำเนินการได้อย่างปลอดภัย การออกแบบใดถูกต้อง
สรุปทบทวน: โปรโตคอลการส่งต่องานแบบมีโครงสร้าง
ประเด็นสำคัญ:
- ตัวแทนย่อยไม่สืบทอดประวัติ — การส่งต่องานทุกครั้งต้องมีบริบทของตัวเองอย่างชัดเจน
- มีสี่ช่อง: ID (เชื่อมโยงผลลัพธ์แบบขนาน), สรุป (ข้อเท็จจริงตามต้นฉบับ), การดำเนินการ (พร้อมข้อผิดพลาดแบบมีโครงสร้าง), คำแนะนำ (ยืนยันหรือแก้ไข)
- บังคับรูปแบบด้วยเครื่องมือส่งต่องาน + JSON Schema และ
tool_choiceโดยกำหนดให้จำเป็นเฉพาะช่องที่มีอยู่เสมอ - เก็บตัวเลขและวันที่ตามต้นฉบับไว้ในบล็อกข้อเท็จจริงของกรณี — การสรุปจะทำให้ข้อมูลคลุมเครือ
- ในการดำเนินการ ให้แยกความล้มเหลวในการเข้าถึงออกจากผลลัพธ์ค่าว่างที่ถูกต้องด้วย
errorCategoryและisRetryable - ควบคุมการดำเนินการที่มีผลกระทบสำคัญด้วยฮุกที่กำหนดผลลัพธ์แน่นอน และห้ามใช้คำแนะนำเพียงอย่างเดียว
- หากผลลัพธ์จากเครื่องมือที่ดำเนินการต่ออาจเป็นข้อมูลเก่า ให้เริ่มต้นใหม่ด้วยการส่งต่องานแบบมีโครงสร้าง
เรียนรู้ Python ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 26
- บทเรียน
- 104
คำถามที่พบบ่อย
บทเรียน “โพรโทคอลส่งต่องานแบบมีโครงสร้าง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “โพรโทคอลส่งต่องานแบบมีโครงสร้าง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Claude Architect ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Claude Architect มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “โพรโทคอลส่งต่องานแบบมีโครงสร้าง”
ส่งต่องานพร้อม ID สรุป การดำเนินการ และคำแนะนำ คุณปฏิบัติ Claude Architect ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Claude Architect หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Claude Architect บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “โพรโทคอลส่งต่องานแบบมีโครงสร้าง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Claude Architect นี้ได้ไหม
ได้ บทเรียน Claude Architect ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- PostToolUse และฮุกสำหรับการเรียกออก
- การบังคับใช้แบบกำหนดแน่นอนเทียบกับพรอมต์
- เงื่อนไขก่อนทำงานในโค้ด
- โพรโทคอลส่งต่องานแบบมีโครงสร้าง