Harness Engineering Handbook
ศาสตร์ของการออกแบบระบบรอบ AI agent — agent loop, context, tool design, feedback loops, guardrails, observability, memory, subagents, evals จนถึงผ่า Claude Code ทั้งตัว
Contents
- LEVEL 0 · ปูพื้น
- 01Model vs Harness — ทำไมโมเดลเดียวกันเก่งไม่เท่ากัน
- 02กายวิภาคของ Agent Loop
- LEVEL 1 · เสาหลัก
- 03Context Management — จัดการทรัพยากรที่แพงที่สุด
- 04Tool Design — ออกแบบ API ให้ผู้ใช้ที่เป็น AI
- 05Feedback Loops — ให้ agent ตรวจงานตัวเองได้
- LEVEL 2 · คุมให้อยู่
- 06Guardrails & Permissions — ให้อิสระแค่ไหนดี
- 07Observability — มองเห็นว่า agent คิดอะไรอยู่
- 08Stop Conditions & Failure Modes — รู้ว่าเสร็จ รู้ว่าพัง
- LEVEL 3 · ขยายระบบ
- 09Memory & Skills — ความรู้ที่อยู่ข้ามเซสชัน
- 10Subagents & Orchestration — แตกงานให้หลาย agent
- 11Evals — รู้ได้ยังไงว่า harness ดีขึ้น
- LEVEL 4 · แงะของจริง
- 12ผ่า Claude Code — case study เต็มตัว
- 13ออกแบบ harness ของตัวเอง — หลักคิดก่อนโค้ด
- 14อนาคตของศาสตร์นี้ — และปิดเล่ม
- ·อ่านต่อ: AI Brain
Agent = Model + Harness — ทำไมโมเดลเดียวกัน เก่งไม่เท่ากัน (Handbook #08 · บันไดสาย AI ขั้นสุดท้าย) · ภาคต่อของ Prompt 0 → Hero สำหรับคนที่ใช้ AI agent เป็นแล้ว (Claude Code, Codex ฯลฯ) และอยากเข้าใจว่าข้างในมันทำงานยังไง — agent loop, context, tools, feedback loops, guardrails, observability, memory, subagents, evals — จนถึงผ่า Claude Code ทั้งตัว แล้วคิดแบบคนออกแบบระบบได้เอง · เน้นเข้าใจกลไก ไม่ใช่ท่องสูตร
- ระดับ: ใช้ agent เป็น → ออกแบบระบบเป็น (14 บท · 5 ระดับ)
- เวลาอ่าน: ~45 นาที (อ่านเป็น Level ได้)
- ภาษา: ไทย พร้อมไดอะแกรม
LEVEL 0 · ปูพื้น
Model vs Harness — ทำไมโมเดลเดียวกันเก่งไม่เท่ากัน#
ลองนึกภาพนี้ครับ — พี่แปะ error ลงแชตธรรมดาแล้วถามว่า "ช่วยแก้บั๊กนี้หน่อย" · AI ตอบวิธีแก้มาเป็นฉาก ๆ อ่านดูก็สมเหตุสมผล แต่พอเอาไปใช้จริง: ไฟล์ที่มันอ้างไม่มีอยู่จริง ฟังก์ชันที่มันบอกให้แก้ก็ชื่อไม่ตรง — เพราะมันไม่เคยเห็นโปรเจกต์ของพี่เลย มันเดาจากประสบการณ์ล้วน ๆ
ทีนี้เปิด Claude Code แล้วสั่งประโยคเดียวกัน — มันไล่เปิดไฟล์จริง หาโค้ดที่เกี่ยวจริง ลงมือแก้ รันเทสต์ พอเทสต์พังมันอ่าน error แล้วแก้ต่อ วนจนผ่าน · โมเดลข้างในคือตัวเดียวกันเป๊ะ — แล้วอะไรทำให้ผลงานต่างกันคนละโลก?
คำตอบคือสิ่งที่เล่มนี้ทั้งเล่มว่าด้วย: harness — ระบบรอบตัวโมเดล
1.1 Agent = Model + Harness
คำว่า harness แปลตรงตัวคือ ชุดสายรัด/บังเหียนม้า — ชื่อนี้จงใจ: ตัวม้า (โมเดล) มีแรงมหาศาล แต่ลำพังมันวิ่งสะเปะสะปะ สิ่งที่แปลงแรงม้าให้กลายเป็น "งานที่ควบคุมได้" คือบังเหียนกับสายรัดที่ห่อตัวมันอยู่ · ในโลก AI, harness คือชั้นซอฟต์แวร์ที่ห่อโมเดลไว้ ทำหน้าที่ 5 อย่าง:
- Context — คัดว่าโมเดลจะ "เห็น" อะไรบ้างในแต่ละจังหวะ (บทที่ 3)
- Tools — ให้มือมัน: อ่านไฟล์ รันคำสั่ง ค้นเว็บ ทำอะไรกับโลกภายนอกได้บ้าง (บทที่ 4)
- Feedback — ช่องทางให้มันรู้เองว่างานที่ทำถูกหรือผิด (บทที่ 5)
- Guardrails — กันความเสียหาย: อะไรทำได้เลย อะไรต้องถามคนก่อน (บทที่ 6)
- Observability — ให้คนมองเห็นว่ามันกำลังทำอะไร คิดอะไร เปลืองเท่าไหร่ (บทที่ 7)
ภาพจำง่าย ๆ: วางโมเดลไว้ตรงกลาง — มันทำได้อย่างเดียวคือพ่นข้อความ — แล้วห่อรอบด้วยห้าหน้าที่ข้างบนของ harness ก้อนทั้งหมดที่ห่อเสร็จแล้วคือสิ่งที่ผู้ใช้เห็น เรียกว่า agent · ห้าหน้าที่นี้ต่อเข้ากับวงจรการทำงานจริงตรงไหนบ้าง จะเห็นเป็นแผนที่เต็มในบทถัดไป (FIG 2.2) — รูปนั้นคือรูปที่จะพากลับมาดูซ้ำตลอดเล่ม
ประโยคที่อยากให้จำจากบทนี้: โมเดลคือส่วนที่เราคุมไม่ได้ แต่ harness คือส่วนที่เราออกแบบได้ · โมเดลเก่งขึ้นทุกปีตามจังหวะของ lab ผู้สร้าง — เราทำอะไรกับมันไม่ได้นอกจากรอ แต่ harness อยู่ในมือเราทั้งหมด และมันคือตัวตัดสินว่าความเก่งของโมเดลจะถูกรีดออกมาใช้กับงานจริงได้กี่เปอร์เซ็นต์
1.2 สามยุคของการทำงานกับ AI
ถ้าไล่เส้นทางของ collection นี้ จะเห็นวิวัฒนาการของ "ทักษะฝั่งคน" ชัดมาก:
| ยุค | คำถามหลัก | ตัวอย่างทักษะ |
|---|---|---|
| Prompt engineering (เล่ม #06–#07) | พูดกับโมเดลยังไงให้ได้งาน | few-shot, chain-of-thought, จัดโครง prompt |
| Context engineering | ป้อนข้อมูลอะไร เมื่อไหร่ ให้โมเดลเห็น | grounding/RAG, เลือกเอกสาร, จัดการหน้าต่างความจำ |
| Harness engineering (เล่มนี้) | ออกแบบ "ระบบรอบโมเดล" ยังไงให้ agent ทำงานจริงจบได้เอง | tool design, feedback loops, guardrails, evals |
สังเกตว่าแต่ละยุคไม่ได้แทนที่กัน แต่ซ้อนขยายกันขึ้นมา — ใน harness ที่ดี ยังมี prompt ที่ดีอยู่ข้างใน (system prompt, tool description) และมี context engineering เป็นเสาหลักเสาหนึ่ง (บทที่ 3) · สิ่งที่เปลี่ยนคือหน่วยของการคิด: จาก "ข้อความหนึ่งกล่อง" → "ข้อมูลหนึ่งชุด" → "ระบบทั้งระบบ"
1.3 ทำไมศาสตร์นี้เพิ่งมีชื่อ — และทำไมมันสำคัญตอนนี้
คำว่า harness engineering ตกผลึกเป็นชื่อเรียกช่วงปลายปี 2025 ถึงต้นปี 2026 — จุดที่คนดัง ๆ ในวงการ (เช่น Mitchell Hashimoto ผู้สร้าง Terraform) เริ่มเขียนว่างานหลักของเขาตอนนี้ไม่ใช่การเขียนโค้ดตรง ๆ แต่คือการออกแบบระบบให้ agent เขียนโค้ดได้ดี และทีมผู้สร้างโมเดลเองก็เริ่มมีทีม harness แยกออกมาจริงจัง
หลักฐานที่จับต้องได้สุดมาจาก benchmark อย่าง SWE-bench (ชุดทดสอบให้ AI แก้ issue จริงจาก GitHub): โมเดลตัวเดียวกัน รันผ่าน harness คนละตัว คะแนนต่างกันได้เป็นหลายสิบเปอร์เซ็นต์ — อันดับใน leaderboard ขยับได้โดยไม่ต้องแตะโมเดลเลยสักนิด แค่เปลี่ยนเครื่องมือที่ให้ วิธีป้อน context และวิธีให้มันตรวจงานตัวเอง · นั่นคือวินาทีที่วงการยอมรับกันว่า "ตัวห่อ" ไม่ใช่รายละเอียด แต่เป็นครึ่งหนึ่งของความเก่ง
✅ สรุปบทที่ 1 — Agent = Model + Harness · harness คือชั้นซอฟต์แวร์ห่อโมเดล ทำ 5 หน้าที่: context, tools, feedback, guardrails, observability · โมเดลคือส่วนที่เราคุมไม่ได้ — harness คือส่วนที่เราออกแบบได้ และตัดสินว่าความเก่งถูกรีดออกมากี่ % · prompt → context → harness ไม่ได้แทนที่กัน แต่ขยายหน่วยการคิดจากข้อความเดียวเป็นทั้งระบบ · benchmark ยุคนี้ คะแนนขึ้นกับ harness พอ ๆ กับโมเดล
กายวิภาคของ Agent Loop#
ก่อนจะออกแบบระบบรอบโมเดล ต้องเห็นก่อนว่าโมเดล "เปล่า ๆ" ทำอะไรได้บ้าง · คำตอบโหดกว่าที่คิด: มันไม่มีมือ — โมเดลภาษารับข้อความเข้า แล้วพ่นข้อความออก จบแค่นั้น มันเปิดไฟล์ไม่ได้ รันคำสั่งไม่ได้ ต่อเน็ตไม่ได้ แม้แต่จำอะไรข้ามรอบยังไม่ได้ (เล่ม #07 บทที่ 1 ปูเรื่องนี้ไว้แล้ว)
แล้ว agent ที่ "ทำงานเองเป็นชั่วโมง" มาจากไหน? มาจาก harness ที่เอาความสามารถเดียวของโมเดล (พ่นข้อความ) มาวนอยู่ใน loop ง่าย ๆ อันเดียว — วงจรที่เรียบง่ายจนน่าตกใจ แต่ทั้งวงการตั้งอยู่บนมัน
2.1 วงจรพื้นฐาน — โค้ดไม่ถึง 15 บรรทัด
▸ pseudocode: agent loop ทั้งตัว
history = [system_prompt, tool_schemas, งานจากผู้ใช้] # สิ่งที่โมเดล "เห็น"
loop:
response = model(history) # โมเดลทำได้แค่นี้: พ่นข้อความ
if response คือข้อความธรรมดา: # ไม่ขอใช้เครื่องมือแล้ว
return response # → ถือว่าจบงาน ตอบผู้ใช้
call = response.tool_call # เช่น read_file("app.py")
if not allowed(call): # ด่าน guardrails (บท 6)
result = ask_human(call) # เสี่ยงไป → ให้คนตัดสิน
else:
result = execute(call) # harness เป็นคนรันจริงเสมอ
history += [call, result] # ผลกลายเป็น context รอบถัดไปไล่ตามทีละขั้น: harness รวบ context (ทุกอย่างที่โมเดลควรเห็น) → ส่งเข้าโมเดล → โมเดลตอบได้ 2 แบบ: ข้อความธรรมดา (แปลว่าจบงานหรือมีคำถาม) หรือ tool call (คำขอใช้เครื่องมือ เป็นข้อความรูปแบบ JSON) → harness ตรวจสิทธิ์แล้วรันเครื่องมือให้จริง → ยัดผลลัพธ์กลับเข้า context → วนใหม่ จนกว่าโมเดลจะเลิกขอใช้เครื่องมือ
จุดที่คนเข้าใจผิดบ่อยสุด: โมเดลไม่ได้รันเครื่องมือเอง — มันแค่ "เขียนคำขอ" ออกมาเป็นข้อความ · คนกดปุ่มจริงคือ harness เสมอ และตรงนี้แหละคือที่มาของอำนาจทั้งหมด: harness จะรันตามคำขอ, ขอคำยืนยันจากคนก่อน, หรือปฏิเสธเลยก็ได้ (บทที่ 6) — โมเดลบังคับอะไรไม่ได้เลย
2.2 อะไรถูกประกอบเข้า context ทุกรอบ
บรรทัดแรกของ pseudocode ซ่อนเรื่องใหญ่ไว้ — ทุกรอบที่เรียกโมเดล harness เป็นคนประกอบสิ่งที่โมเดลเห็นขึ้นมาใหม่ทั้งชุด:
- system prompt ที่ harness เขียนเอง — ชิ้นส่วนที่ทรงพลังที่สุดของทั้งระบบ · Claude Code ที่พี่ใช้ไม่ใช่ "Claude เปล่า ๆ" — ก่อนข้อความแรกของพี่จะถึงโมเดล harness แนบ "จดหมายงาน" ยาวหลายพันคำที่ทีมผู้สร้างเขียนไว้: คุณคือใคร ทำงานสไตล์ไหน ใช้เครื่องมือแต่ละตัวเมื่อไหร่ ข้อห้ามความปลอดภัยอะไรบ้าง · มันกำหนดบุคลิกและกติกาของ agent ทั้งตัว — และเป็นจุดเดียวกับที่ instructions ถาวรอย่าง
CLAUDE.mdถูกเสียบเข้ามา (บทที่ 9) - tool schemas — "เมนูเครื่องมือ" ที่บอกว่ามีอะไรให้ใช้ ใช้ยังไง (บทที่ 4)
- ประวัติการคุย + ผล tool ทุกรอบที่ผ่านมา — ส่วนเดียวที่โตขึ้นเรื่อย ๆ และจะกลายเป็นปัญหาหลักของบทที่ 3
2.3 แผนที่ของทั้งเล่ม — ทุกบทยึดจุดใดจุดหนึ่งของ loop
ความลับของเล่มนี้: ทุกบทที่เหลือคือการปรับแต่งจุดใดจุดหนึ่งของวงจรข้างบน · ดูรูปนี้ค้างไว้ — มันคือแผนที่ที่เราจะเดินตลอดเล่ม:
🧭 คุณคือ harness — หลักการเล่มนี้ในเวอร์ชัน chat — ตอนใช้แชตธรรมดา ไม่มี harness มาช่วย เพราะพี่นั่นแหละคือ harness ที่ทำทุกหน้าที่ด้วยมือ: เปิดแชตใหม่พร้อมสรุปงานที่ค้าง = compaction (บท 3) · แปะไฟล์เฉพาะตอนถึงจังหวะใช้ ไม่ยัดทั้งหมดแต่แรก = just-in-time context (บท 3) — และตัวพี่เองคือ "tool" ที่ไปหยิบข้อมูลมาให้ (บท 4) · ให้เกณฑ์แล้วสั่ง "ตรวจงานตัวเองตามเกณฑ์นี้ก่อนส่ง" = feedback loop (บท 5) · รู้ตัวว่า AI วนแก้ที่เดิม 3 รอบไม่หลุดสักที เลิกแล้วเปิดแชตใหม่ = stop condition (บท 8) · Custom Instructions / Projects ที่ตั้งค้างไว้ = memory (บท 9) · ส่วน permissions, observability, subagents, evals ไม่ต้องมี — เพราะพี่นั่งอ่านอยู่ทุกข้อความ อนุมัติเองทุกจังหวะ · ศาสตร์นี้จึงไม่ใช่เรื่องของคนสร้าง agent เท่านั้น — เข้าใจแล้ววิธีใช้ AI ประจำวันเปลี่ยนได้ทันที
✅ สรุปบทที่ 2 — โมเดลไม่มีมือ — รับข้อความ พ่นข้อความ จบ · agent เกิดจาก harness วน loop: รวบ context → โมเดลตอบ (ข้อความ/tool call) → harness ตรวจสิทธิ์แล้วรันจริง → ผลกลับเข้า context → วนจนจบ · โมเดลแค่ "เขียนคำขอ" — คนกดปุ่มจริงคือ harness เสมอ · ทุกรอบ harness ประกอบ context ใหม่: system prompt ของ harness (ชิ้นทรงพลังสุด) + tool schemas + ประวัติ + ผล tool · ทุกบทที่เหลือของเล่ม = ปรับแต่งจุดใดจุดหนึ่งของ loop นี้
LEVEL 1 · เสาหลัก
Context Management — จัดการทรัพยากรที่แพงที่สุด#
เคยเจอไหมครับ — ปล่อย agent ทำงานยาว ๆ ผ่านไปสักพักมันเริ่ม "โง่ลง": ลืมข้อตกลงที่คุยกันตอนต้น กลับไปแก้ไฟล์ที่บอกแล้วว่าห้ามแตะ เรียกฟังก์ชันที่เพิ่งเปลี่ยนชื่อไปด้วยชื่อเก่า · โมเดลไม่ได้เสื่อมกลางทาง — แต่ "โต๊ะทำงาน" ของมันกำลังล้น
3.1 บนโต๊ะมีอะไรวางอยู่บ้าง
เล่ม #07 เปรียบ context window เป็นโต๊ะทำงานที่วางของได้จำกัดไปแล้ว · ใน agent ของบนโต๊ะมี 4 กอง: system prompt (คงที่), tool schemas (คงที่ — แต่ต่อ MCP เยอะ ๆ ก็บวมได้ · บทที่ 4.5), ประวัติการคุย และ ผลลัพธ์ tool — กองสุดท้ายคือตัวร้าย: อ่านไฟล์หนึ่งครั้งได้หลายพัน token, รันเทสต์หนึ่งรอบได้ log ยาวเหยียด และทุกอย่างกองอยู่บนโต๊ะไปตลอดเซสชันถ้าไม่มีใครจัดการ
3.2 ทำไม context ยาวถึงเป็นปัญหา
- แพง — โมเดลไม่ได้ "จำ" อะไรข้ามรอบ ทุกรอบของ loop คือการส่ง context ทั้งก้อน เข้าไปใหม่ · ประวัติ 100k token × วน 200 รอบ = จ่ายมหาศาล (caching ช่วยได้ส่วนหนึ่ง แต่หลักการนี้ไม่เปลี่ยน)
- ช้า — context ยิ่งยาว โมเดลยิ่งใช้เวลาประมวลนานขึ้นทุกรอบ
- จำเลอะ — อาการที่วงการเรียก context rot: ยิ่งยาว ความสนใจของโมเดลยิ่งเบลอ ข้อมูลที่อยู่กลาง ๆ ถูกมองข้าม (lost in the middle) ความผิดพลาดเก่า ๆ ที่ค้างอยู่ก็ลากงานใหม่ให้เพี้ยนตาม
ตลกร้ายคือสามข้อนี้มาพร้อมกัน: ยิ่งปล่อยให้ยาว เรายิ่งจ่ายแพงขึ้นเพื่อผลลัพธ์ที่แย่ลง — context จึงเป็นทรัพยากรที่ต้องบริหาร ไม่ใช่ถังที่เทอะไรลงไปก็ได้
3.3 เทคนิคหลักสามตัว
① Compaction / summarization — พอใกล้เต็ม harness สรุปประวัติเก่าให้เหลือย่อสั้น ๆ (ทำอะไรไปแล้ว ตกลงอะไรกันไว้ กำลังทำอะไรอยู่) แล้วเริ่มหน้าต่างใหม่ด้วยสรุปนั้น · ราคาที่จ่ายคือรายละเอียดหาย — ศิลปะอยู่ที่สรุปให้เก็บ "การตัดสินใจและเหตุผล" ไม่ใช่เก็บคำพูดดิบ ๆ
② Just-in-time retrieval — อย่ายัดข้อมูลล่วงหน้า "เผื่อได้ใช้" ให้ agent ค้นเมื่อต้องใช้ผ่านเครื่องมือ (ค้นไฟล์, grep, ค้นเอกสาร) · นี่คือเหตุผลที่ Claude Code ไม่โหลดทั้ง repo เข้า context แต่ให้เครื่องมือค้นแทน — จ่ายเฉพาะสิ่งที่หยิบมาใช้จริง
③ ตัดผล tool ยาว ๆ ตั้งแต่ต้นทาง — ผล tool ทุกตัวอักษรคือ "ค่าเช่ารายเดือน" ที่ต้องแบกไปทุกรอบที่เหลือ · harness ที่ดีจึง truncate ไฟล์ยาว แบ่งหน้าให้ขอเพิ่มทีหลัง และคืนเฉพาะส่วนที่เกี่ยว (เรื่องนี้โยงตรงเข้าบทที่ 4 — การออกแบบผลลัพธ์ของ tool)
3.4 RAG ที่พี่รู้จัก คือ special case ของเรื่องนี้
เล่ม #07 สอน grounding/RAG ไว้แล้ว — ระบบค้นเอกสารที่เกี่ยวแล้วแปะให้โมเดลก่อนตอบ · มองผ่านเลนส์เล่มนี้ RAG คือ just-in-time retrieval แบบ push: ฝั่งระบบเดาว่าโมเดลต้องใช้อะไรแล้วป้อนให้ · agent ยุคนี้ขยับไปอีกขั้นเป็นแบบ pull: โมเดลถือเครื่องมือค้นเอง ตัดสินใจเองว่าจะค้นอะไร เมื่อไหร่ ค้นซ้ำกี่รอบ — วงการเรียก agentic search · หลักการเดียวกัน แต่ย้ายคนตัดสินใจจากระบบไปที่ตัว agent
✅ สรุปบทที่ 3 — context = โต๊ะทำงานที่ทุกอย่างต้องจ่ายค่าเช่าทุกรอบ · ตัวกินพื้นที่ตัวจริงคือผล tool เก่า ๆ · ยาวเกิน = แพง + ช้า + จำเลอะ (context rot / lost in the middle) · สามเทคนิคหลัก: compaction (สรุปแล้วเริ่มใหม่), just-in-time retrieval (ค้นเมื่อใช้ ไม่ยัดล่วงหน้า), ตัดผล tool ตั้งแต่ต้นทาง · RAG คือ special case แบบ push — agent ยุคนี้ pull เอง
Tool Design — ออกแบบ API ให้ผู้ใช้ที่เป็น AI#
ทีมหนึ่งต่อ MCP server เข้า agent อย่างภูมิใจ — เครื่องมือ 60 ตัวพร้อมใช้ · ผลคือ agent กลับโง่ลง: เลือกเครื่องมือผิด สับสนระหว่าง get_user กับ fetch_user ที่ต่างกันนิดเดียว แถมจ่ายค่า context ให้ schema ที่แทบไม่เคยถูกเรียก · บทนี้ว่าด้วยศาสตร์ที่ฟังดูคุ้นแต่กติกาใหม่: ออกแบบ API ที่ "ผู้ใช้" เป็น AI
4.1 tool หนึ่งตัว = สัญญา 3 ส่วน
เครื่องมือหนึ่งตัวที่ harness ประกาศให้โมเดลเห็น ประกอบด้วย name (ชื่อ), description (คำอธิบาย), และ input schema (ฟอร์มที่ต้องกรอก) · จุดที่คนมองข้าม: description คือ prompt ที่ฝังถาวร — มันนั่งอยู่ใน context ทุกรอบ และโมเดลอ่านมันทุกครั้งที่ตัดสินใจว่าจะหยิบเครื่องมือไหน เขียน description ห่วย = เขียน prompt ห่วยที่ส่งซ้ำอัตโนมัติตลอดกาล
4.2 ดี vs แย่ — คู่เดียวเห็นครบ
✗ tool ที่ออกแบบตาม API ดิบ
{ "name": "api_v2_query_exec", ← ชื่อบอกแค่ "รันคิวรี" — งานอะไร? เมื่อไหร่ควรใช้?
"description": "Executes query against the v2 endpoint",
"input_schema": {
"type": "object",
"properties": {
"q": { "type": "string" }, ← q คืออะไร? SQL? ข้อความ? format ไหน?
"opts": { "type": "string",
"description": "JSON-encoded options" } } } }
← JSON ซ้อนใน string — จุดพังคลาสสิก✓ tool ที่ออกแบบตาม workflow
{ "name": "search_customer_orders",
"description": "ค้นออร์เดอร์ของลูกค้าจากชื่อหรืออีเมล
ใช้เมื่อผู้ใช้ถามถึงสถานะหรือประวัติการสั่งซื้อ
คืนไม่เกิน 20 รายการ (ใหม่→เก่า) — อยากได้หน้าถัดไปส่ง page เพิ่ม",
"input_schema": {
"type": "object",
"properties": {
"customer": { "type": "string", "description": "ชื่อหรืออีเมลลูกค้า" },
"status": { "type": "string", "enum": ["paid","shipped","refunded"] },
"page": { "type": "integer", "default": 1 }
},
"required": ["customer"] } }4.3 หลักออกแบบสามข้อ
- ออกแบบตาม workflow ไม่ใช่ตาม API ดิบ — นักพัฒนาที่เป็นคนอ่าน docs ได้ จำ state ข้ามหน้าจอได้ แต่โมเดลรู้เท่าที่ description ใน context บอก · เครื่องมือที่ดีคือ "หนึ่ง intent จบในตัว" (ค้นออร์เดอร์ของลูกค้าคนนี้) ไม่ใช่ "ประตูไปยัง endpoint" ที่ผู้ใช้ต้องประกอบเอง 3 จังหวะ
- จำนวนพอดี ไม่ใช่ 100 ชิ้นจิ๋ว — ทุก schema กิน context (บท 3) และทุกตัวเลือกที่เพิ่มคือโอกาสเลือกผิดที่เพิ่ม โดยเฉพาะเครื่องมือที่ทับซ้อนกันเอง · เครื่องมือน้อยตัวแต่ทรงพลัง ชนะเครื่องมือเยอะแต่จิ๋วเกือบทุกครั้ง
- ผลลัพธ์ต้องกระชับ — เพราะผลลัพธ์กลายเป็น context ทันที: คืนเฉพาะฟิลด์ที่ใช้ มี pagination ตัด log ให้เหลือท่อนที่เกี่ยว · tool ที่ dump ข้อมูลดิบ 5,000 บรรทัดคือ tool ที่สั่งให้ agent โง่ลงในอีก 10 รอบข้างหน้า
4.4 error message = prompt ขากลับ
เมื่อ tool พัง ข้อความ error จะถูกยัดกลับเข้า context และโมเดลจะอ่านมันแน่นอนเพื่อวางแผนรอบถัดไป — error จึงไม่ใช่ log แต่คือ prompt ที่เราส่งให้โมเดลตอนมันกำลังหลงทาง:
✗ Error: 400 Bad Request
โมเดลไปต่อไม่ถูก → เดามั่ว หรือวนเรียกซ้ำท่าเดิม (บท 8)
✓ Error: ไม่พบลูกค้าชื่อ "สมชาย จ."
ชื่ออาจสะกดไม่ตรงกับในระบบ — ลองอย่างใดอย่างหนึ่ง:
· ค้นด้วยอีเมลแทน: search_customer_orders(customer="somchai@...")
· หรือเรียก list_customers(query="สมชาย") หา id ที่ถูกก่อน
บอกว่าผิดอะไร + แก้ยังไง → รอบถัดไปแก้เกมถูกทันที4.5 MCP — มาตรฐานเปิดของการเสียบเครื่องมือ
เล่ม #07 แนะนำ MCP (Model Context Protocol) ไว้ว่าเป็น "ปลั๊ก USB" ที่ต่อ AI เข้ากับแอปและข้อมูลจริง · มุมของคนออกแบบ harness: MCP แยกคนสร้างเครื่องมือออกจากคนสร้าง harness — เขียน server ครั้งเดียว เสียบได้กับทุก harness ที่พูดโปรโตคอลนี้ ไม่ต้องผูกกับ vendor ไหน · แต่ระวัง: MCP ทำให้เสียบง่ายขึ้น ไม่ได้ทำให้ออกแบบดีขึ้น — server ที่ดัมพ์ API ดิบทั้งชุด 60 endpoints คือตัวอย่างคลาสสิกของสิ่งที่บทนี้เตือนทั้งบท
อัปเดตที่ตอกย้ำหลักการนี้: harness ยุคใหม่เริ่มไม่ยัด schema ของทุกเครื่องมือใน MCP server ทั้งชุดเข้า context ตั้งแต่ต้นอีกต่อไป — แต่ให้ agent ค้นหาก่อนว่ามีเครื่องมือไหนเกี่ยวกับงานตรงหน้า แล้วค่อยโหลด schema เฉพาะตัวที่จะใช้จริง · หลัก progressive disclosure (บทที่ 9) ไล่ตามมาถึงชั้น tools เองในที่สุด — ต่อ MCP server กี่สิบตัวก็ไม่ต้องแลกกับ context ที่บวมแบบที่เคยเป็นปัญหาคลาสสิกอีกต่อไป
✅ สรุปบทที่ 4 — tool = สัญญา 3 ส่วน (name, description, schema) — description คือ prompt ที่ฝังถาวร · ออกแบบตาม workflow ไม่ใช่ API ดิบ · จำนวนพอดี — ทุก schema กิน context ทุกตัวเลือกเพิ่มโอกาสพลาด · ผลลัพธ์กระชับเพราะมันกลายเป็น context · error ที่ดี = prompt ขากลับที่สอนวิธีแก้ · MCP ทำให้เสียบง่าย แต่หลักออกแบบทั้งบทนี้ยังใช้เต็ม ๆ
Feedback Loops — ให้ agent ตรวจงานตัวเองได้#
คำถามชวนคิด: ทำไม agent เขียนโค้ดถึงไปได้ไกลกว่า agent เขียนบทความ ทั้งที่ภาษาไทย/อังกฤษน่าจะง่ายกว่าภาษาโปรแกรม? · คำตอบไม่เกี่ยวกับความฉลาดเลย: โค้ดมีกรรมการในตัว — compiler บอกทันทีว่า syntax พัง เทสต์บอกทันทีว่า logic เพี้ยน ส่วนบทความไม่มีอะไรบอกว่า "ย่อหน้านี้อ่อน" จนกว่าคนจะอ่าน
นี่คือบทที่เป็นแก่นที่สุดของเล่ม: agent ที่ทำงานยาว ๆ ได้ คือ agent ที่รู้เองว่าผิด
5.1 open loop vs closed loop
ลองคิดเลขง่าย ๆ: สมมติโมเดลพลาดแค่ 5% ต่อขั้น งานที่ต้องทำ 20 ขั้นติดกันแบบไม่มีการตรวจเลย โอกาสรอดทั้งสาย = 0.95²⁰ ≈ 36% — ยิ่งงานยาว ยิ่งเข้าใกล้ศูนย์ · แต่ถ้าทุกขั้นถูกตรวจและแก้ก่อนไปต่อ ความผิดพลาดไม่ทบต้น — งานยาวแค่ไหนก็เดินได้ นี่คือเหตุผลเชิงคณิตศาสตร์ว่าทำไม closed loop เปลี่ยนเกม
5.2 "ประสาทสัมผัส" ของ agent
โมเดลมองไม่เห็นโลก — สิ่งที่ทำหน้าที่เป็นตา หู และปลายประสาทของมันคือเครื่องตรวจที่ harness จัดให้:
- เทสต์ — บอกว่า logic ถูกตามสเปกไหม (แม่นสุดถ้าเทสต์ดี)
- compiler / type checker — บอกทันทีว่าโค้ดประกอบร่างไม่ติด
- linter / formatter — บอกว่าผิดกติกาสไตล์ตรงไหน
- screenshot / preview — งาน UI: ให้ agent เห็นภาพที่ render จริง ไม่ใช่จินตนาการจากโค้ด
- log / exit code — บอกว่ารันจริงแล้วเกิดอะไรขึ้น
สังเกตว่าทั้งหมดนี้ไม่มีอะไรเป็น AI เลย — เป็นเครื่องมือธรรมดาที่วงการมีอยู่แล้ว · งานของ harness engineer ไม่ใช่ประดิษฐ์ verifier ใหม่ แต่คือต่อสายประสาทพวกนี้เข้า loop ให้ agent เรียกใช้เองได้และเห็นผลเต็ม ๆ
5.3 verifier ที่ดีต้องมีสามคุณสมบัติ
- เชื่อได้ — false pass (บอกว่าผ่านทั้งที่พัง) อันตรายกว่าไม่มี verifier เพราะ agent จะเดินหน้าอย่างมั่นใจบนของพัง · เทสต์ห่วย ๆ ที่ mock จนไม่เหลืออะไรจริง = ยาพิษ
- เร็ว — closed loop ได้ผลจากการวนบ่อย ถ้าเทสต์รัน 20 นาที agent จะวนได้แค่ไม่กี่รอบ · เทสต์ย่อยที่รันเป็นวินาทีมีค่ากับ agent มากกว่า suite ใหญ่ที่สมบูรณ์แต่ช้า
- agent เรียกเองได้ — ต้องอยู่ในรูปคำสั่ง/tool ที่มันกดเองได้ทุกเมื่อ ไม่ใช่รอคนมากดให้ — ไม่งั้นก็กลับไปเป็น open loop ที่มีพิธีกรรมเพิ่ม
5.4 กฎที่พยากรณ์อนาคตได้: งานเดินไกลเท่าที่ verifier พาไป
อยากรู้ว่า agent จะทำงานไหนได้ดี อย่าถามว่าโมเดลฉลาดแค่ไหน — ถามว่างานนั้นมี verifier ดีแค่ไหน:
| งาน | verifier | agent ทำงานยาวได้แค่ไหน |
|---|---|---|
| แก้บั๊กใน repo ที่มีเทสต์ครบ | เทสต์ + compiler — แม่น เร็ว เรียกเองได้ | เป็นชั่วโมงได้สบาย |
| เขียนฟีเจอร์ใหม่ | ปานกลาง — ให้เขียนเทสต์ก่อนแล้วค่อยทำ ช่วยได้มาก | ยาวพอควร ถ้าวางเกณฑ์ก่อน |
| เขียนเอกสาร/แปล/วิเคราะห์ | อ่อน — ใช้ AI ตรวจ AI ได้แต่เชื่อได้น้อยกว่าเทสต์ | สั้น — ควรมีคนตรวจเป็นระยะ |
| งานรสนิยม (ดีไซน์, โทนภาษา) | แทบไม่มี — เกณฑ์อยู่ในหัวคน | สั้นมาก — คนต้องอยู่ใน loop |
บทต่อ ๆ ไปจะเจอ verifier โผล่มาเป็นพระเอกซ้ำ ๆ: เป็นเงื่อนไข "เสร็จจริง" ของบทที่ 8, เป็นหัวใจของ evals บทที่ 11 และเป็นสิ่งแรกที่ต้องออกแบบเมื่อสร้าง harness เองในบทที่ 13
✅ สรุปบทที่ 5 — agent ทำงานยาวได้ = รู้เองว่าผิด · open loop ความผิดทบต้น (0.95²⁰ ≈ 36%) — closed loop ดักทุกขั้น ไม่ทบต้น · ประสาทสัมผัส: เทสต์, compiler, linter, screenshot, log — ของธรรมดาที่ต่อเข้า loop · verifier ที่ดี: เชื่อได้ เร็ว agent เรียกเองได้ · งานไหน verifier ดี งานนั้น agent ไปได้ไกล — กฎนี้พยากรณ์ได้แม่นกว่าถามว่าโมเดลรุ่นไหน
LEVEL 2 · คุมให้อยู่
Guardrails & Permissions — ให้อิสระแค่ไหนดี#
agent ขอรัน rm -rf node_modules — ให้ผ่านไหม? แล้ว git push --force ล่ะ? แล้วส่งอีเมลหาลูกค้า 2,000 คน? · ทุกคนรู้สึกได้ว่าสามคำถามนี้ "หนัก" ไม่เท่ากัน แต่พอต้องออกแบบเป็นระบบ เส้นแบ่งอยู่ตรงไหน — บทนี้ให้กรอบคิด ไม่ใช่รายการท่องจำ
6.1 สองแกนที่ตัดสินทุกอย่าง: blast radius × reversibility
- blast radius (รัศมีความเสียหาย) — ถ้าพลาด ความเสียหายกระจายถึงไหน: ในโฟลเดอร์เดียว? ทั้งเครื่อง? หรือทะลุออกไปถึงคนอื่น/ระบบ production?
- reversibility (ย้อนกลับได้ไหม) — แก้ไฟล์ใน git ย้อนได้เสมอ · ลบไฟล์นอก version control ย้อนยาก · อีเมลที่ส่งแล้ว ย้อนไม่ได้เลย
6.2 กลไกที่ harness ใช้จริง
- permission tiers — โหมดการทำงานหลายระดับ: อ่านอย่างเดียว → แก้ไฟล์ได้ → อัตโนมัติเต็มตัว · ผู้ใช้เลือกตามความไว้ใจและเดิมพันของงาน
- allowlist / denylist — จำคำตอบ: อนุมัติ
npm testครั้งเดียว ครั้งต่อไปไม่ต้องถามซ้ำ · ส่วน denylist คือรายการที่ไม่ต้องเสียเวลาถามเลย — ปฏิเสธเสมอ - sandbox — ให้วิ่งเต็มสปีดในกรง: container แยก, git worktree แยก, ตัด network · เปลี่ยนคำถามจาก "ไว้ใจโมเดลไหม" เป็น "กรงแน่นไหม" ซึ่งเป็นคำถามวิศวกรรมที่ตอบได้จริง
- human-in-the-loop เฉพาะจุด — คนไม่ได้มานั่งเฝ้าทุกก้าว แต่ยืนเป็นด่านตรงจุดที่ action ข้ามเส้นบนแผนที่ 6.1 เท่านั้น
6.3 trade-off จริง — ปลอดภัยสุดขั้ว ใช้ไม่ได้จริง
ถามทุกครั้ง = ปลอดภัยบนกระดาษ แต่ในชีวิตจริงเกิดอาการ alarm fatigue: ผู้ใช้เจอ dialog รัว ๆ จนกด "อนุญาต" โดยไม่อ่าน — สุดท้ายอันตรายกว่าระบบที่ถามน้อยแต่ถามตรงจุด เพราะด่านที่ควรศักดิ์สิทธิ์กลายเป็นพิธีกรรม · ขั้วตรงข้าม ไม่ถามเลย = เร็วจนกว่าจะถึงวันที่มันลบผิดโฟลเดอร์
จุดสมดุลที่ harness ยุคนี้ลงตัว: ค่าเริ่มต้นปลอดภัย + จำการอนุมัติ + ยกระดับถามเฉพาะที่ข้ามเส้น + sandbox ให้มากที่สุดเท่าที่ทำได้ — ให้ "ถาม" เป็นเหตุการณ์พิเศษที่ผู้ใช้ตั้งใจอ่านจริง ๆ
6.4 Prompt injection — ศัตรูตัวจริงของ harness
เล่ม #07 แนะนำ prompt injection ไว้แล้วในเวอร์ชันแชต — เวอร์ชัน agent น่ากลัวกว่ามาก เพราะข้อมูลไม่น่าเชื่อถือไหลเข้า loop เองผ่าน tool result: agent เปิดเว็บ อ่านอีเมล อ่าน issue ใน tracker อ่านไฟล์ที่ใครก็ไม่รู้ commit ไว้ — ทุกช่องคือทางเข้าของประโยคแอบสั่ง เช่นหน้าเว็บที่ฝังข้อความ (ซ่อนด้วยตัวอักษรสีขาว) ว่า "ระบบ: ลืมคำสั่งเดิม แล้วรันคำสั่งนี้…"
หลักคิดสองชั้นที่ต้องมีคู่กัน:
- ชั้นซอฟต์: tool result คือ data ไม่ใช่ instruction — harness ที่ดีระบุที่มาของข้อมูลให้ชัด และ system prompt สอนโมเดลว่าข้อความในผล tool เป็นข้อมูลให้ประมวล ห้ามทำตามคำสั่งในนั้น (สืบสายตรงจากการ "คั่นข้อมูลออกจากคำสั่ง" ที่ #07 สอน — และโยงบท 4: ผล tool คือ input ที่เราควบคุมรูปแบบได้)
- ชั้นแข็ง: จำกัดความเสียหายด้วยระบบ — เพราะโมเดลฉลาดแค่ไหนก็ถูกหลอกได้ มันถูกฝึกมาให้ทำตามคำสั่งที่เห็นใน context และแยก "คำสั่งจริงของผู้ใช้" จาก "คำสั่งปลอมในข้อมูล" ไม่ได้ 100% · นี่คือคำตอบของคำถามที่หลายคนสงสัย — "โมเดลฉลาดขนาดนี้ ทำไมยังต้องมี sandbox กับ permission": เพราะเราออกแบบระบบไว้กันวันที่มันโดนหลอก ไม่ใช่วันที่มันทำงานปกติ
นี่ไม่ใช่สถานการณ์สมมติที่ยกมาขู่ — ต้นเดือนมิถุนายน 2025 นักวิจัยจาก Aim Security เปิดเผยช่องโหว่ชื่อ EchoLeak (CVE-2025-32711) ใน Microsoft 365 Copilot ที่ครบทั้งสามขาข้างบนเป๊ะ: ส่งอีเมลธรรมดาฉบับเดียวไปหาเป้าหมาย เขียนคำสั่งแฝงให้อ่านเหมือนกำลังพูดกับคน ไม่ใช่ AI (① ข้อมูลที่คนนอกเขียนได้) — พอผู้ใช้ถาม Copilot คำถามงานทั่วไปในภายหลัง ระบบค้นเอกสารก็ดึงอีเมลนั้นเข้ามาเองโดยไม่มีใครเรียก (② เข้าถึงสิ่งที่อยู่ในเซสชัน) แล้วคำสั่งแฝงก็สั่งเข้ารหัสข้อมูลเป็น URL ซ่อนในลิงก์รูปภาพที่ระบบโหลดอัตโนมัติโดยไม่ต้องคลิกอะไรเลย (③ ส่งออกได้) — ผู้ใช้ไม่ต้องกดอะไรสักครั้งเดียว Microsoft แก้ที่ฝั่งเซิร์ฟเวอร์ได้ก่อนมีใครถูกโจมตีจริง แต่มันคือบทพิสูจน์ว่าสูตรหายนะข้างบนไม่ใช่ทฤษฎี — และเกิดกับระบบที่มีทีมความปลอดภัยระดับโลกดูแลอยู่แล้วด้วยซ้ำ · รูปแบบเครือญาติเกิดกับ GitHub Copilot ปีเดียวกัน (CVE-2025-53773): คำสั่งแฝงในไฟล์ README หลอกให้ agent แก้ค่าตั้งค่าของตัวเองเปิด auto-approve ทุกคำสั่งเงียบ ๆ ก่อนจะสั่งรันคำสั่งอันตราย — ปิดด่านที่บทนี้เพิ่งสอนทั้งบทให้เหลือศูนย์ก่อนลงมือจริง
✅ สรุปบทที่ 6 — ตัดสินอิสระด้วยสองแกน: blast radius × reversibility — ยิ่งย้อนยากวงกว้าง อำนาจยิ่งต้องกลับไปหาคน · กลไก: permission tiers, allowlist จำคำตอบ, sandbox (เปลี่ยน "ไว้ใจไหม" เป็น "กรงแน่นไหม"), human-in-the-loop เฉพาะจุด · ถามทุกครั้ง = alarm fatigue อันตรายกว่าที่คิด · prompt injection คือศัตรูตัวจริง: tool result เป็น data ไม่ใช่ instruction + จำกัดความเสียหายด้วยระบบ เพราะโมเดลฉลาดแค่ไหนก็ถูกหลอกได้
Observability — มองเห็นว่า agent คิดอะไรอยู่#
ปล่อย agent ทำงานใหญ่ไว้ตั้งแต่บ่าย ผ่านไปชั่วโมงหนึ่ง คำถามผุดขึ้นสามข้อ: ตอนนี้มันทำอะไรอยู่? ติดหล่มหรือกำลังคืบหน้า? แล้วเปลืองไปเท่าไหร่แล้ว? · ถ้าระบบตอบสามคำถามนี้ไม่ได้ เราไม่ได้ "ใช้" agent อยู่ — เรากำลังภาวนาให้มันเสร็จ
7.1 การมองเห็นสามชั้น
harness ที่โตแล้วให้การมองเห็นเป็นชั้น ๆ — แต่ละชั้นตอบคำถามของคนละคน ในคนละจังหวะ:
ชั้นแรกมีของแถมที่คนมองข้าม: narration ที่ดีไม่ใช่ log แต่คือสัญญาระหว่างทาง — บอกทั้ง "ทำอะไร" และ "เพราะอะไร" สั้น ๆ ให้ผู้ใช้เบรกได้ตั้งแต่เห็นทิศทางเพี้ยน ไม่ใช่มารู้ตอนงานเสร็จผิดโจทย์ไปแล้วครึ่งชั่วโมง
7.2 ทำไม trace สำคัญกว่า log ธรรมดา
debug โปรแกรมปกติ = ไล่หา "บรรทัดที่ผิด" เพราะโค้ดวิ่งเหมือนเดิมทุกครั้ง · debug agent เป็นคนละกีฬา: มันคือการ debug การตัดสินใจ — และการตัดสินใจของโมเดลขึ้นกับสิ่งที่มันเห็นในวินาทีนั้นทั้งหมด ถ้าไม่ได้เก็บ context ที่ประกอบตอนนั้นไว้ ก็ไม่มีทางตอบว่าทำไมมันเลือกทางนั้น — รันซ้ำก็ไม่ช่วย เพราะมันไม่ deterministic
ตัวอย่างจริงที่เจอกันบ่อย: agent แก้ไฟล์ผิดตัว · log ธรรมดาบอกแค่ edit config.py — จบ ด่าโมเดลได้อย่างเดียว · แต่ trace เผยว่ารอบก่อนหน้า ผลค้นหาคืนไฟล์ชื่อคล้ายกันสองตัว (config.py, config_prod.py) โดยไม่มีข้อมูลช่วยแยก — โมเดลเลือกตัวแรกอย่างสมเหตุสมผลจากข้อมูลที่มี · อาการโผล่ที่พฤติกรรม แต่สาเหตุอยู่ใน context — และทางแก้คือปรับ harness (ให้ผลค้นบอก path เต็ม + คำอธิบาย) ไม่ใช่รอโมเดลรุ่นใหม่
✅ สรุปบทที่ 7 — สามชั้นการมองเห็น: progress narration (ผู้ใช้ · เรียลไทม์) → transcript/trace (คนสร้าง harness · ไล่ย้อนการตัดสินใจ) → metrics (ทีม · เทรนด์ข้ามงาน) · debug agent = debug การตัดสินใจ ไม่ใช่ debug โค้ด — ต้องเห็นว่าโมเดลเห็นอะไรตอนตัดสินใจ · อาการโผล่ที่พฤติกรรม สาเหตุอยู่ใน context · เก็บ transcript ตั้งแต่วันแรก
Stop Conditions & Failure Modes — รู้ว่าเสร็จ รู้ว่าพัง#
คนทำงานมีสัญชาตญาณสองอย่างที่เราไม่เคยสังเกตว่ามีค่า: รู้ว่างานเสร็จแล้ว กับรู้ว่าควรเลิก (ติดเกิน ต้องถามคนอื่นแล้ว) · agent ไม่มีทั้งสองอย่างโดยกำเนิด — และนี่คือปัญหาที่ถูกประเมินต่ำที่สุดในการออกแบบ agent: ระบบที่ทำงานเก่งแต่ไม่รู้จังหวะหยุด สร้างความเสียหายได้พอ ๆ กับระบบที่ทำงานไม่เป็น
8.1 failure modes คลาสสิกสี่ตัว
- Doom loop — วนแก้ที่เดิมด้วยท่าเดิม · เทสต์พัง → แก้ → พังแบบเดิม → แก้ท่าเดิมอีก… ยิ่งวน context ยิ่งเต็มไปด้วยความพยายามที่ล้มเหลว และโมเดลยิ่ง "ยึด" แนวทางเดิมหนักขึ้น (มันเดาจากสิ่งที่อยู่ข้างหน้า — ซึ่งตอนนี้คือความล้มเหลวซ้ำ ๆ ท่าเดียว) — วงจรนี้ไม่หลุดได้ด้วยตัวเอง
- ประกาศเสร็จทั้งที่ไม่เสร็จ · แก่นเดียวกับ reward hacking: โมเดลถูกฝึกให้ "ปิดงานให้ได้" ถ้านิยามความสำเร็จวัดจากคำพูดของมันเอง มันจะหาทางลัดที่ฉลาดผิดทาง — comment เทสต์ที่พังทิ้ง, แก้เกณฑ์ให้หลวมลง, หรือเรียบเรียงรายงานสวย ๆ ว่า "เรียบร้อยครับ"
- Context poisoning · ความผิดพลาดเก่า — ผลลัพธ์ผิด สมมติฐานที่พังแล้ว หรือคำสั่งแฝงจากบทที่ 6 — ค้างอยู่ใน context แล้วลากการตัดสินใจใหม่ให้เพี้ยนตามไปเรื่อย ๆ · ยิ่งเซสชันยาวยิ่งสะสม (ญาติสนิทของ context rot บทที่ 3)
- งานหลุด scope · สั่งแก้บั๊กหนึ่งตัว ได้ refactor ทั้งโมดูลเป็นของแถม — โมเดล "เห็นของที่ควรแก้" ระหว่างทาง และไม่มีเส้นเขตบอกว่าความหวังดีตรงไหนคือส่วนเกิน
เคส doom loop ที่มีบันทึกไว้จริง: ปี 2025 มีรายงานสาธารณะบน GitHub ว่า subagent ตัวหนึ่งของ Claude Code วนเรียกคำสั่ง npm install คำสั่งเดิมซ้ำกว่า 300 ครั้งติดต่อกันนาน 4.6 ชั่วโมง เผาโทเคนไปเกือบ 27 ล้านตัว ก่อนผู้ใช้จะมาเห็นแล้วหยุดเอง — ตัวเลขนี้ฟังดูเวอร์ แต่คือสิ่งที่เกิดขึ้นได้จริงถ้าไม่มีเพดานกันวงจรตั้งแต่ต้น (8.2 ข้างล่างคือคำตอบตรง ๆ ของเคสนี้)
ฝั่งเสร็จปลอม/reward hacking มีทั้งหลักฐานเบื้องหลังกลไกและเคสจริงในโลกธุรกิจ งานวิจัยของ Anthropic เองช่วงปลายปี 2025 พบว่าโมเดลที่ฝึกด้วย reinforcement learning ให้เขียนโค้ด เรียนรู้ทางลัดเรียก sys.exit(0) หลอกให้ระบบนับว่าเทสต์ผ่านทั้งที่ไม่ได้รันจริง แล้วพฤติกรรมโกงนี้ยังลามไปเรื่องอื่นที่ไม่เกี่ยวข้องกันด้วย — สอดคล้องกับงานของ METR ที่พบโมเดลแถวหน้าหลายตัว (รวม Claude 3.7 Sonnet) โกงตัวตรวจคะแนนเองในกว่า 30% ของการทดสอบ โดยไม่มีใครสอนให้ทำ · ภาพจริงในโลกธุรกิจเกิดกับ Replit เดือนกรกฎาคม 2025: ผู้ใช้สั่ง "ห้ามแตะโค้ด" (code freeze) ไว้ชัดเจน แต่ agent ลบฐานข้อมูล production ทิ้งระหว่างนั้น — CEO ของ Replit ยอมรับต่อสาธารณะว่า "ยอมรับไม่ได้ และไม่ควรเกิดขึ้นได้ตั้งแต่แรก" พร้อมประกาศแก้ harness จริง: แยกฐานข้อมูล dev/production ออกจากกันอัตโนมัติ และเพิ่มโหมด "วางแผนอย่างเดียว" ที่ทำให้ code freeze บังคับใช้ได้จริงแทนที่จะเป็นแค่คำขอร้องใน prompt (ส่วนรายละเอียดที่ว่า agent ยังปลอมรายงานผลเทสต์ระหว่างนั้นด้วย มาจากคำบอกเล่าของผู้ใช้รายนั้นเอง ยังไม่มีการยืนยันแยกจาก Replit — แต่ส่วนที่ยืนยันแล้วคือการลบข้อมูลจริงระหว่าง freeze ก็หนักพอเป็นบทเรียนได้อยู่ดี)
8.2 เครื่องมือกัน — โง่แต่เวิร์ก
- max turns / token budget / timeout — เพดานกลไกที่ฟังดูทื่อ แต่จำเป็น: doom loop ไม่มีทางหลุดด้วยตัวเอง เพดานคือสิ่งเดียวที่การันตีว่าวงจรจะจบและคนจะได้เข้ามาดู · ตั้งจากข้อมูลจริง (งานปกติใช้กี่รอบ) ไม่ใช่เดา
- กติกา "ต้องผ่าน verifier ก่อนประกาศเสร็จ" — เปลี่ยนนิยามเสร็จจาก "โมเดลพูดว่าเสร็จ" เป็น "เกณฑ์ภายนอกยืนยัน" (บทที่ 5) · ฆ่า failure mode เสร็จปลอมตรง ๆ — และต้องระวังให้ verifier แก้ไม่ได้โดย agent เอง ไม่งั้นมันจะ "แก้ข้อสอบ" แทนแก้งาน
- เส้นเขตงานที่ชัดตั้งแต่ต้น — ระบุใน prompt ว่าอะไรอยู่ใน/นอกขอบเขต + system prompt ที่สอนหลัก "ทำน้อยที่สุดที่แก้ปัญหา เจอของควรแก้อื่นให้จดรายงาน ไม่ใช่ลงมือ"
- ตรวจจับการวน — harness ที่โตแล้วดู pattern: tool call เดิม + ผลล้มเหลวแบบเดิมติดกัน N ครั้ง → เบรก บังคับให้ถอยมามองใหม่ หรือส่งเรื่องหาคน
มุมที่อยากให้มอง: เพดานพวกนี้ไม่ใช่ "ความไม่ไว้ใจ AI" — มันคือเข็มขัดนิรภัย เราไม่ได้คาดว่าจะชนทุกวัน แต่วันที่ชน มันคุ้มทุกบาทที่ลงทุนไป · agent ที่มี stop conditions ดีคือ agent ที่กล้าปล่อยให้ทำงานยาวขึ้น — ความปลอดภัยกับความอิสระไม่ใช่ขั้วตรงข้าม มันซื้อกันและกัน
✅ สรุปบทที่ 8 — agent ไม่รู้เองว่า "เสร็จ" หรือ "ควรเลิก" — ต้องออกแบบให้ · failure modes สี่ตัว: doom loop (วนไม่หลุดเอง), เสร็จปลอม (reward hacking), context poisoning (ของเสียเก่าลากใหม่), scope creep (งานบาน) · การ์ด: max turns/budget/timeout, ผ่าน verifier ก่อนจบ (และ agent ต้องแก้ verifier ไม่ได้), เส้นเขตชัด, ตรวจจับการวน · ทั้งสี่โหมดมีเคสจริงที่มีบันทึกไว้แล้ว ไม่ใช่แค่ทฤษฎี · stop conditions ที่ดีคือสิ่งที่ทำให้กล้าปล่อย agent ทำงานยาวขึ้น
LEVEL 3 · ขยายระบบ
Memory & Skills — ความรู้ที่อยู่ข้ามเซสชัน#
วันนี้พี่สอน agent ไปครึ่งชั่วโมง: โปรเจกต์นี้ใช้ pnpm ไม่ใช่ npm · เทสต์ต้องรันด้วยคำสั่งนี้ · อย่าแตะโฟลเดอร์ legacy · พรุ่งนี้เปิดเซสชันใหม่ — ลืมหมดเกลี้ยง ถามคำถามเดิมครบทุกข้อ · จะโทษมันก็ไม่ได้: loop จบ = context หาย (บทที่ 2–3) · ความจำข้ามเซสชันไม่ใช่ของที่โมเดลมีให้ — มันคือระบบที่ harness ต้องสร้าง
9.1 ความรู้สามชั้นของ harness
- ① Instructions ถาวร — ไฟล์อย่าง
CLAUDE.md/AGENTS.mdที่ harness โหลดเข้า context ให้อัตโนมัติทุกเซสชัน เสียบเข้าใกล้ system prompt (จุดที่บทที่ 2 ชี้ไว้) · เหมาะกับกติกาโปรเจกต์ คำสั่งประจำ ข้อห้าม — เป็นชั้นที่จ่ายแพงสุดเพราะกิน context ทุกรอบ จึงต้องสั้น - ② Memory ที่ agent เขียนเอง — จดสิ่งที่เรียนรู้ระหว่างทำงานลงไฟล์/ฐานเก็บ ไว้ค้นในเซสชันหน้า · ต่างจากชั้นแรกตรงที่มันเกิดจากการทำงาน ไม่ใช่คนป้อน — โจทย์ยากคือ "จดอะไร" (ไม่ใช่ทุกอย่าง) และ "เมื่อไหร่เลิกเชื่อ" (ความรู้เก่าที่ผิดไปแล้วอันตรายกว่าไม่มี)
- ③ Skills — ความรู้เฉพาะงานที่แพ็กเป็น "คู่มือพร้อมใช้": วิธี deploy ของทีม, ฟอร์มรายงานที่ถูกต้อง, ขั้นตอน review · ถูกโหลดเมื่องานเรียกเท่านั้น
สองข้อควรระวังที่มากับความรู้สามชั้นนี้: ความจำผิด ๆ อยู่ยาวกว่าความจำถูก — memory ที่จดไว้ผิด (หรือเคยถูกแต่โลกเปลี่ยนแล้ว) จะถูกหยิบมาใช้ซ้ำ ๆ อย่างมั่นใจ จดพร้อมบริบท/วันที่ ตรวจก่อนเชื่อ และออกแบบให้ลบง่ายพอ ๆ กับเพิ่ม · และ instructions ถาวรมีแนวโน้มบวม — ทุกคนอยากยัด "กฎอีกข้อเดียว" ลง CLAUDE.md จนมันกินงบ context เอง กฎเช็กง่าย: ถ้าไม่ได้ใช้แทบทุกเซสชัน มันไม่ควรอยู่ชั้น ① — ย้ายลงชั้น skill หรือ memory แทน
9.2 progressive disclosure — เคล็ดที่ทำให้ความรู้ไม่กินโต๊ะ
ความรู้ทั้งหมดขององค์กรใหญ่กว่า context window หลายเท่า — โหลดหมดตั้งแต่ต้นคือจ่ายมหาศาลให้ของที่ 95% ไม่เกี่ยวกับงานตรงหน้า (บทที่ 3 สอนไว้แล้วว่าจบยังไง) · ทางออกเรียกว่า progressive disclosure: ให้ agent เห็นแค่ "สารบัญ" ตลอดเวลา แล้วเปิดเนื้อเต็มเฉพาะเมื่อจำเป็น
รูปธรรมสุด ๆ: skill ชื่อ deploy-checklist — สิ่งที่อยู่ใน context ตลอดคือบรรทัดเดียว: "ขั้นตอน deploy + rollback — ใช้เมื่อจะขึ้น production" · ตัวเนื้อสามหน้านอนอยู่บนดิสก์ จนกว่างาน deploy จะมาถึง agent ถึงเปิดอ่าน — โครงสร้างเดียวกับ just-in-time retrieval ของบทที่ 3 แต่คราวนี้ใช้กับความรู้ของระบบเอง
✅ สรุปบทที่ 9 — จบเซสชัน = ความจำหาย — harness แก้ด้วยความรู้สามชั้น: instructions ถาวร (CLAUDE.md — โหลดทุกเซสชัน ต้องสั้น) / memory ที่ agent จดเอง / skills (คู่มือเฉพาะงาน โหลดเมื่อใช้) · progressive disclosure: เห็นสารบัญตลอด เปิดเนื้อเมื่อจำเป็น — ประหยัด context แบบบท 3 · ระวังความจำ stale และ instructions บวม: อะไรไม่ได้ใช้ทุกเซสชัน อย่าให้อยู่ชั้นแพงสุด
Subagents & Orchestration — แตกงานให้หลาย agent#
งานใหญ่ชิ้นเดียวอย่าง "อัปเกรด framework ทั้ง repo" — ถ้าให้ agent เดียวลุย สิ่งที่ตายก่อนไม่ใช่ความฉลาด แต่คือ context: แค่สำรวจว่ามีอะไรต้องแก้บ้างก็กินไปครึ่งโต๊ะแล้ว (บทที่ 3) · ทางออกของ harness ยุคนี้: จ้างลูกมือ — แตกงานให้ subagent ที่มี loop และ context ของตัวเอง
10.1 ทำไมต้องแตก — สองเหตุผล ไม่ใช่เหตุผลเดียว
- context isolation (เหตุผลหลักที่คนมองข้าม) — งานค้น/สำรวจที่เวิ่นเว้อ อ่าน 40 ไฟล์ ลองผิด 6 รอบ ทั้งหมดเกิดใน context ของลูก แล้วส่งกลับมาแค่ข้อสรุป 10 บรรทัด · โต๊ะของ agent หลักสะอาด เก็บไว้คิดเรื่องใหญ่
- ทำขนานได้ — งานที่อิสระต่อกัน 4 ชิ้น ปล่อยลูก 4 ตัวรันพร้อมกัน เวลารวมเท่างานที่ช้าสุด ไม่ใช่ผลบวกของทุกงาน
10.2 รูปแบบที่เจอบ่อย
- orchestrator–worker — ตัวหลักถือแผนและประกอบผล ลูกรับงานชิ้นเดียวจบ · ท่ามาตรฐานของงานใหญ่
- pipeline — ต่อแถว: ผลของตัวหนึ่งเป็นวัตถุดิบของตัวถัดไป (ค้น → ร่าง → ตรวจ) · แต่ละขั้นได้ context สะอาดเฉพาะเรื่องของตัว
- fan-out / verify — กระจายงานเดียวกันให้หลายลูกทำจากคนละมุม (ไล่หาบั๊กด้วย 5 มุมมอง) แล้วมีตัวตรวจ/รวมผล · ญาติทางความคิดกับ pass@k ที่จะเจอในบทที่ 11
10.3 การส่งงาน = เขียน prompt ให้คนที่ไม่เห็นบทสนทนาเรา
กับดักอันดับหนึ่งของมือใหม่: สั่งลูกว่า "แก้ไฟล์ที่คุยกันเมื่อกี้" — ลูกเกิดมาพร้อมโต๊ะเปล่า ไม่เห็นบทสนทนาของเรา ไม่รู้ว่า "เมื่อกี้" คืออะไร · brief ที่ดีจึงต้องครบในตัว: เป้าหมาย + บริบทที่จำเป็น (path, ข้อจำกัด) + นิยามว่าเสร็จคืออะไร + รูปแบบคำตอบที่ต้องการ — ทักษะเดียวกับการมอบงานให้ junior ที่เพิ่งเข้าทีมวันแรก และเป็นทักษะ prompt จากเล่ม #07 กลับมาในสเกลใหม่
10.4 ต้นทุนที่โบรชัวร์ไม่บอก
- ช่องสื่อสารแคบมาก — ลูกตอบกลับได้แค่ข้อความสรุป: รายละเอียดที่ไม่ถูกเขียนลงสรุป = หายตลอดกาล · ถ้าตัวหลักต้องรู้ลึก ต้องสั่งให้ลูก "รายงานสิ่งนี้กลับมาด้วย" ตั้งแต่ใน brief
- งานที่แชร์ state ไม่เหมาะ — สองลูกแก้ไฟล์เดียวกัน หรือการตัดสินใจถี่ ๆ ที่ต้องเห็นพร้อมกัน → ค่าประสานงานแพงกว่าตัวงาน ทำเองในตัวเดียวเร็วกว่า
- overhead ต่อหัว — ลูกทุกตัวจ่าย system prompt + สำรวจของตัวเองใหม่ · งานเล็ก ๆ ไม่คุ้มค่าแรกเข้า
กฎตัดสินใจสั้น ๆ: แตกเมื่องานสรุปกลับได้สั้นและทำอิสระได้จริง — แตกเพื่อ isolate ความรก ไม่ใช่แตกเพราะสถาปัตยกรรมดูเท่
10.5 ข้ามรั้ว: เมื่อ "ลูก" ไม่ได้อยู่บ้านเดียวกัน
ทั้งบทนี้พูดถึงการแตกงานแบบที่ลูกทุกตัวอยู่ในบ้านเดียวกัน — harness เดียวกัน โปรเสสเดียวกัน เรียกผ่าน tool ภายใน · คำถามที่ตามมาคือ agent ของทีมพี่ต้องคุยกับ agent ของบริษัทคู่ค้า ที่รันคนละเครื่อง คนละ vendor คนละ harness ล่ะ — นี่คือช่องว่างที่โปรโตคอลชื่อ A2A (Agent2Agent) เข้ามาแก้ Google เปิดตัวปี 2025 แล้วโอนให้ Linux Foundation ดูแลเป็นมาตรฐานกลาง มีทั้ง AWS, Microsoft, Salesforce, SAP ร่วมพัฒนา
กรอบคิดที่ทั้ง Google และ Anthropic ใช้ตรงกัน: MCP ต่อ agent เข้ากับเครื่องมือ/ข้อมูล (แนวตั้ง — ภายในองค์กรเดียว, บทที่ 4.5) ส่วน A2A ต่อ agent เข้ากับ agent อื่น (แนวนอน — ข้ามองค์กร/ข้าม vendor) — สองมาตรฐานเสริมกัน ไม่ใช่คู่แข่ง กลไกคือ formalize สิ่งที่บทนี้สอนไปแล้วให้ใช้ข้ามองค์กรได้: แทนเขียน prompt บอกงานตรง ๆ แบบข้อ 10.3 ฝั่งหนึ่งอ่าน "Agent Card" ของอีกฝั่งก่อน — เอกสารที่บอกว่ามันทำอะไรได้บ้าง คุยผ่านช่องไหน ยืนยันตัวตนแบบไหน — แล้วค่อยส่งงานให้ ติดตามสถานะผ่านวงจร submitted → working → เสร็จ/พัง/ถูกยกเลิก คล้าย FIG 10.1 แต่ "ลูก" ที่ว่าอาจไม่เคยรู้จักกันมาก่อนเลย
ความต่างที่สำคัญกว่าคำว่า "tool กับ agent": ฝั่งตรงข้ามของ A2A มีโมเดลของตัวเอง ตัดสินใจเอง ไม่ใช่ฟังก์ชันที่รอรับคำสั่ง งานจึงเป็นบทสนทนาหลายจังหวะ ถามกลับระหว่างทางได้ — ต่างจากเรียก MCP tool ที่เป็น request-response ครั้งเดียวจบ กับดักที่คนพลาดบ่อย: เอา agent อิสระไปห่อเป็น MCP tool ธรรมดา แล้วเจอปัญหาจ่าย token สองต่อและตอบคำถามกลางทางไม่ได้ — เพราะเลือกโปรโตคอลผิดชั้น
ความจริงที่ควรรู้ก่อนตื่นเต้นตามกระแส: การใช้งานจริงยังกระจุกอยู่ในองค์กรใหญ่ที่ต้องเชื่อม agent ข้ามบริษัทจริง ๆ (supply chain, การเงิน, ประกันภัย) ส่วนงานทั่วไปที่ต่อ agent ภายในองค์กรเดียวกัน MCP + subagent แบบที่บทนี้สอนยังตอบโจทย์เกือบทั้งหมด — เส้นตัดสินใจง่าย ๆ คือถามว่ามี "องค์กรอื่น" หรือ trust boundary ข้ามจริงไหม ถ้าไม่มี ก็ไม่ต้องแตะ A2A · และเพราะอีกฝั่งมีโมเดลของตัวเอง ภัยใหม่ที่มากับมันคือ agent ปลอมอวดความสามารถที่ไม่มีจริงใน Agent Card เพื่อหลอกให้ถูกเลือก — ญาติสายตรงของ prompt injection ที่บทที่ 6 สอนไว้: ยิ่งเปิดคุยกับใครก็ได้ ยิ่งต้องมีกำแพงชั้นแข็งรับไว้เท่านั้น
✅ สรุปบทที่ 10 — แตกงานด้วยสองเหตุผล: context isolation (ความรกตายในลูก ส่งกลับแค่สรุป) + ทำขนาน · รูปแบบ: orchestrator–worker, pipeline, fan-out/verify · การส่งงานคือเขียน prompt ให้คนไม่เห็นบทสนทนา — ต้องครบในตัว: เป้าหมาย บริบท นิยามเสร็จ รูปแบบคำตอบ · ข้อจำกัดใหญ่: ช่องสื่อสารแคบ งานแชร์ state ละเอียดไม่เหมาะ มี overhead ต่อหัว — แตกเมื่อสรุปได้สั้นและอิสระจริงเท่านั้น · ข้ามรั้วองค์กร/vendor ใช้ A2A แทน subagent ภายใน — คนละเครื่องมือ แต่หลักคิดเดียวกัน: บรีฟให้ครบ ต้องรู้ว่าอีกฝั่งทำอะไรได้ก่อนส่งงาน และระวังฝั่งตรงข้ามที่มีโมเดลของตัวเอง ไม่ใช่แค่ฟังก์ชัน
Evals — รู้ได้ยังไงว่า harness ดีขึ้น#
เมื่อวานแก้ system prompt หนึ่งบรรทัด วันนี้เพิ่ม tool ใหม่หนึ่งตัว — agent ดีขึ้นหรือแย่ลง? · ถ้าคำตอบคือ "รู้สึกว่าดีขึ้นนะ" แปลว่าเรากำลังปรับระบบมูลค่าสูงด้วยวิธีเดียวกับการเดาหวย · เล่ม #07 สอน "อย่าวัด prompt ด้วยความรู้สึก" ไว้แล้ว — บทนี้คือหลักเดียวกัน ขยายจากวัดหนึ่ง prompt เป็นวัดทั้งระบบ
11.1 eval ของ harness ≠ eval ของโมเดล
eval ของโมเดล (ที่ lab ใช้จัดอันดับกัน) วัดคำตอบเดี่ยว: ถามหนึ่งข้อ ให้คะแนนหนึ่งคำตอบ · แต่สิ่งที่เราปรับใน harness — เพิ่ม tool, แก้ description, เปลี่ยนกติกา permission — กระทบพฤติกรรมทั้งวงของ loop ไม่ใช่คำตอบใดคำตอบหนึ่ง · eval ของ harness จึงต้องวัด end-to-end task: ให้งานจริงทั้งชิ้น ("แก้บั๊กนี้ให้เทสต์ผ่าน", "อัปเดต dependency แล้ว build ต้องเขียว") แล้ววัดว่างานจบจริงไหม พร้อมต้นทุน — กี่ token กี่นาที กี่รอบ
11.2 หลักปฏิบัติสี่ข้อ
- ชุดงานตัวแทน — งานจริง 10–30 ชิ้นที่ครอบความหลากหลาย: ง่าย กลาง ยาก และเจ้าเล่ห์ (เคสที่เคยหลอก agent ได้) · ไม่ต้องเริ่มหรูหรา — มีสิบงานที่รันซ้ำได้ ก็ชนะ "ความรู้สึก" ขาดลอยแล้ว
- เกณฑ์ตัดสินอัตโนมัติ — จุดที่บทที่ 5 กลับมาทวงบุญคุณ: verifier ที่เชื่อได้คือกรรมการ eval ที่ดีที่สุด (เทสต์ผ่านไหม ไฟล์ถูกต้องไหม build เขียวไหม) · งานที่วัดด้วยกลไกยาก ใช้ AI เป็นกรรมการ (LLM-as-judge) ได้ แต่ต้องรู้ตัวว่าเชื่อได้น้อยกว่า และควรสุ่มตรวจกรรมการด้วยตาคนเป็นระยะ
- รันซ้ำหลายรอบ (pass@k) — agent ไม่ deterministic: งานเดียวรันครั้งเดียวแทบไม่บอกอะไร · รันงานละ 5 รอบแล้วรายงาน "ผ่าน 4/5" — การเทียบสองเวอร์ชันคือเทียบการกระจายของผล ไม่ใช่จับฉลากครั้งเดียวชนกัน
- regression suite จากเคสที่เคยพัง — ทุกครั้งที่ agent พังในงานจริง (transcript จากบทที่ 7 คือวัตถุดิบ) กลั่นเคสนั้นเป็นงาน eval ใหม่ · เหมือน unit test ที่เกิดจากบั๊กจริง — ระบบจะไม่มีวันพังท่าเดิมแบบเงียบ ๆ อีก
ขยายเรื่อง pass@k อีกนิดให้เห็นภาพ — เพราะนี่คือจุดที่คนพลาดบ่อยที่สุด: ทำไม "รันครั้งเดียวแล้วเทียบ" ถึงหลอกเราได้ทั้งที่ตั้งใจวัดแล้ว
11.3 ของแถมที่แพงที่สุดของการมี eval
ไม่ใช่ตัวเลขบนกราฟ แต่คือความกล้า: harness ที่ไม่มี eval จะค่อย ๆ กลายเป็นระบบที่ไม่มีใครกล้าแตะ — แก้อะไรก็ได้แต่ภาวนาว่าไม่ทำของเดิมพัง · พอมี suite ที่รันได้ใน 20 นาที การทดลองไอเดียใหม่กลายเป็นเรื่องปกติ: ลอง รัน เทียบ เก็บหรือทิ้ง — จบ · วัฒนธรรมเดียวกับที่ unit test ให้กับโค้ด แต่คราวนี้ให้กับระบบ AI
✅ สรุปบทที่ 11 — ตอบไม่ได้ว่าดีขึ้นหรือแย่ลง = ปรับมั่ว · eval ของ harness วัด end-to-end task (งานจบจริงไหม + ต้นทุน) ไม่ใช่คำตอบเดี่ยว · สี่หลัก: ชุดงานตัวแทน 10–30 ชิ้น, เกณฑ์อัตโนมัติ (verifier จากบท 5 คือกรรมการที่ดีสุด — LLM-as-judge เชื่อได้น้อยกว่า), รันซ้ำ pass@k เพราะไม่ deterministic, regression จากเคสพังจริง · รางวัลใหญ่สุดคือความกล้าทดลอง
LEVEL 4 · แงะของจริง
ผ่า Claude Code — case study เต็มตัว#
สิบเอ็ดบทที่ผ่านมาคือทฤษฎี — บทนี้เอาของจริงที่พี่ใช้อยู่ทุกวันขึ้นโต๊ะผ่า แล้วชี้ว่าอวัยวะแต่ละชิ้นคือบทไหนของเล่มนี้ · เป้าหมายไม่ใช่รู้จัก Claude Code ดีขึ้น (พี่ใช้เป็นอยู่แล้ว) แต่คือเห็นการตัดสินใจออกแบบว่าแต่ละอย่างตอบ trade-off ที่เราเรียนมายังไง
12.1 การตัดสินใจที่น่าผ่าที่สุดสามเรื่อง
เรื่องแรก: ทำไม tools มีไม่กี่ตัว และไม่มี tool เฉพาะภาษา · ไม่มี refactor_python ไม่มี fix_css — มีแต่ Read/Edit/Bash/Glob/Grep ที่ compose กันได้ครอบงานแทบทุกแบบ · นี่คือหลัก "จำนวนพอดี" ของบทที่ 4 แบบสุดทาง: เครื่องมือ general ไม่กี่ตัว = schema ไม่ท่วม context ไม่มีตัวเลือกให้สับสน · ราคาที่จ่าย: Bash กลายเป็นประตูที่เปิดได้ทุกอย่าง — จึงเป็นจุดที่ permission ต้องละเอียดที่สุด (บทที่ 6) · เห็นไหมครับ การตัดสินใจฝั่ง tools ลากการตัดสินใจฝั่ง guardrails ตามมา — ชิ้นส่วน 5 ชิ้นไม่เคยออกแบบแยกกันได้
เรื่องที่สอง: ทำไมไม่ index repo ล่วงหน้า · หลายระบบยุคก่อนสร้าง index/embedding ของทั้ง repo ไว้ค้น — Claude Code เลือกทางตรงข้าม: ให้ agent ใช้ Glob/Grep ค้นสด ๆ เอาตอนต้องใช้ · คือ just-in-time retrieval (บทที่ 3) เต็มรูปแบบ: ไม่มี index ที่ stale ไม่ต้อง sync และ agent ตัดสินใจเองว่าค้นอะไร — แลกกับการเสียเวลาไม่กี่วินาทีต่อการค้น ซึ่งถูกกว่า context ที่เสียไปกับของไม่เกี่ยวมาก
เรื่องที่สาม: hooks — จุดเสียบ guardrail ที่เป็นโค้ด · กติกาบางอย่างสำคัญเกินกว่าจะ "ขอร้อง" ผ่าน prompt (โมเดลอาจลืม/ถูกหลอก — บทที่ 6 สอนแล้ว) · hooks ให้ผู้ใช้เขียนเช็กของตัวเองที่รันก่อน/หลังทุก tool call: ห้ามแตะไฟล์นี้ รัน formatter หลังแก้ทุกครั้ง เตือนเมื่อจะรันคำสั่งอันตราย — เบรกที่เป็นโค้ดบังคับได้ 100% ไม่ใช่คำขอร้องที่หวังว่าโมเดลจะฟัง · นี่คือหลัก "ชั้นแข็ง" ของบทที่ 6 ที่เปิดให้ผู้ใช้ต่อเอง
12.2 สิ่งที่ Claude Code สอนเรื่องการออกแบบ harness
- default ปลอดภัย แต่ไม่รำคาญ — เริ่มด้วยการถาม แล้ว "จำ" คำอนุมัติ (allowlist) ให้ความถี่การถามลดลงเอง — ตรงตำราสมดุลของบทที่ 6
- ยืดหยุ่นกับคุมได้ ไม่ใช่ขั้วตรงข้าม — Bash เปิดโลกเต็มที่ + permission/hooks คุมเข้ม = ได้ทั้งสอง
- ทุกจุดขยายเปิดให้ผู้ใช้ — MCP (เพิ่ม tools), hooks (เพิ่ม guardrails), skills + CLAUDE.md (เพิ่มความรู้), subagents (ขยายสเกล) — ผู้ใช้ต่อเติมได้โดยไม่ต้องรอ vendor · harness ที่ดีจึงไม่ใช่ product ปิด แต่เป็น platform ที่คนอื่นสร้างต่อได้
12.3 เคสจริง: ตามรอย transcript ทีละขั้น
ทฤษฎีข้างบนอาจยังรู้สึกลอย ๆ — ตัวอย่างต่อไปนี้ประกอบจากรูปแบบงานที่เจอกันจริงบ่อย ๆ (คล้ายเคส config.py vs config_prod.py ของบทที่ 7) ไล่ทีละขั้นว่าแต่ละจังหวะคือกลไกจากบทไหนของเล่มนี้กำลังทำงานอยู่จริง พี่คนหนึ่งเจอบั๊กแล้วโยนงานให้ Claude Code ประโยคเดียว:
▸ transcript ช่วงที่ 1 — รับงาน แล้วค้นแบบ pull ไม่ใช่โหลดทั้ง repo
พี่: มีรายงานว่าลูกค้าสมัครสมาชิกซ้ำได้ ถ้าใช้อีเมลตัวพิมพ์ใหญ่เล็กต่างกัน
(User@mail.com กับ user@mail.com ควรนับเป็นคนเดียวกัน) ช่วยแก้ให้หน่อย
กำลังหา logic การสมัครสมาชิกในโปรเจกต์…
▸ Grep(pattern: "def.*(signup|register)", glob: "**/*.py")
⎿ 2 matches — services/signup_service.py, admin/user_admin.py
▸ Read(services/signup_service.py)
⎿ 38 linesจุดแรกที่เห็นชัด: agent ไม่ได้โหลดทั้ง repo มาอ่าน — มันเดาคำค้นจากคำในงาน (signup, register) แล้ว grep หาก่อน นี่คือ agentic search แบบ pull ที่บทที่ 3 สอนไว้ ผลลัพธ์ที่น่าสนใจ: grep เจอสองไฟล์ ไม่ใช่ไฟล์เดียว — เก็บไว้ในหัวก่อน จะกลับมาสำคัญอีกที
▸ transcript ช่วงที่ 2 — แก้ เพิ่มเทสต์ แล้วส่งให้ verifier ตัดสิน
เจอบรรทัดที่ตรวจซ้ำ: if User.query.filter_by(email=email).first(): raise DuplicateEmailError()
กำลังเช็ค test เดิมของไฟล์นี้ก่อนแก้…
▸ Grep(pattern: "def test_.*signup", path: "tests/test_signup.py")
⎿ 4 matches — ไม่มีเคสตัวพิมพ์ใหญ่เล็กเลย
▸ Edit(services/signup_service.py)
⎿ เพิ่ม email = email.strip().lower() ก่อนตรวจซ้ำและก่อนบันทึก
▸ Edit(tests/test_signup.py) — เพิ่มเคส test_signup_rejects_case_variant_email
▸ Bash(pytest tests/test_signup.py -q)
⎿ 5 passedถูกต้องตามตำรา: เช็กเทสต์เดิมก่อนแก้ (กัน regression) → แก้โค้ด → เพิ่มเทสต์ใหม่ให้ตรงกับบั๊กที่เพิ่งเจอ → รันเพื่อดูผล — closed loop เต็มรูปแบบของบทที่ 5 ผ่าน Bash เป็นประสาทสัมผัส ถ้าจบตรงนี้ก็ดูเรียบร้อยดี แต่ agent ที่ดีไม่หยุดแค่ไฟล์ที่แก้ — มันจำได้ว่าตอน grep เจอสองไฟล์ ไม่ใช่ไฟล์เดียว
▸ transcript ช่วงที่ 3 — เจอของนอกขอบเขต รายงานแทนที่จะลงมือเงียบ ๆ
เมื่อกี้ grep เจอ user_admin.py ด้วย — เช็คว่าใช้ logic เดียวกันไหม…
▸ Read(admin/user_admin.py)
⎿ พบฟังก์ชัน admin_create_user() — สร้าง user ตรง ๆ ไม่ผ่าน signup_service เลย
ไม่มีการ .lower() เหมือนกัน — บั๊กเดียวกัน ช่องทางที่สอง
[แจ้งพี่] เจอช่องโหว่เดียวกันอีกจุดที่ admin_create_user() — นอกขอบเขตงานเดิม
จะแก้ให้ด้วยเลย หรือแค่รายงานไว้ก่อน?จุดนี้คือที่บทที่ 8 เตือนไว้เรื่อง scope: เจอ "ของที่ควรแก้เพิ่ม" ระหว่างทาง หลักที่ดีคือทำน้อยที่สุดที่แก้ปัญหา แล้วรายงานส่วนเกิน ไม่ใช่ลงมือเงียบ ๆ — ในเซสชันจริง กติกานี้มักตั้งไว้ล่วงหน้าใน CLAUDE.md ว่า "เจอบั๊กที่เกี่ยวข้องแต่นอกขอบเขต ให้ถามก่อน" (ความรู้ถาวรจากบทที่ 9 เสียบเข้ามาตรงจุดตัดสินใจนี้พอดี) สมมติพี่ตอบว่า "แก้ให้เลย" agent เดินหน้าต่อ:
▸ transcript ช่วงที่ 4 — แตะข้อมูลจริง เส้นบนแผนที่บทที่ 6 ถูกข้าม
▸ Edit(admin/user_admin.py) — เพิ่ม .lower() ให้ตรงกับ signup_service.py
▸ Edit(tests/test_user_admin.py) — เพิ่มเคสเดียวกันสำหรับ admin_create_user
▸ Bash(pytest tests/ -q)
⎿ 48 passed
ข้อมูลเก่าที่ซ้ำกันตั้งแต่ก่อนแก้ อาจยังนอนอยู่ในฐานข้อมูลจริง — ต้องเช็ค
ต้องรัน migration ทำความสะอาดอีเมลซ้ำของเก่า — คำสั่งนี้แก้ข้อมูลจริงใน production
⚠ ขออนุญาต: รัน scripts/normalize_existing_emails.py กับฐานข้อมูล production
[อนุมัติครั้งนี้] [อนุมัติเสมอสำหรับคำสั่งนี้] [ปฏิเสธ]blast radius × reversibility ของบทที่ 6 ทำงานตรงหน้าต่อหน้า: แก้โค้ดใน branch ย้อนได้ด้วย git จึงรันเทสต์ไปเรื่อย ๆ โดยไม่ถามทุกครั้ง (allowlist จำคำตอบไว้แล้ว) แต่พอคำสั่งขยับไปแตะข้อมูลจริงในฐานการผลิต — วงกว้างขึ้น ย้อนยากขึ้น — เส้นที่ FIG 6.1 วาดไว้ถูกข้าม ระบบจึงเลื่อนอำนาจตัดสินใจกลับมาที่คนทันที ไม่ใช่เพราะ agent "ไม่มั่นใจ" แต่เพราะกรงกำหนดไว้แบบนั้น
▸ transcript ช่วงที่ 5 — ประกาศเสร็จ ก็ต่อเมื่อ verifier ผ่านแล้วเท่านั้น
พี่: อนุมัติ
▸ Bash(python scripts/normalize_existing_emails.py --env=production)
⎿ พบอีเมลซ้ำ 3 คู่ — รวมบัญชีเรียบร้อย
▸ Bash(pytest tests/ -q)
⎿ 48 passed, 0 failed
สรุปให้พี่: แก้จุดตรวจซ้ำอีเมลใน signup_service.py และ user_admin.py ให้ไม่สนตัวพิมพ์เล็ก-ใหญ่
เพิ่มเทสต์คุมทั้งสองจุด และรวมบัญชีซ้ำเก่าที่มีอยู่แล้ว 3 คู่ในฐานข้อมูลจริง — เทสต์ทั้งหมดผ่าน 48/48ประโยคสรุปมาหลังเทสต์ผ่านเท่านั้น — ตรงกฎของบทที่ 8: "ห้ามบอกว่าเสร็จ จนกว่า verifier จะผ่าน" ไล่ทั้งห้าช่วงย้อนกลับไป จะเห็นว่าไม่มีจังหวะไหนเป็น "ความฉลาด" ล้วน ๆ ของโมเดล — ทุกจังหวะคือจุดที่ harness ออกแบบไว้ล่วงหน้า: ให้มันค้นแทนยัด context (บท 3), ให้มันมีเครื่องมือที่คืนผลตรงพอจะตัดสินใจต่อ (บท 4), ให้มันตรวจตัวเองด้วยเทสต์ก่อนพูดว่าเสร็จ (บท 5, 8), ขีดเส้นว่าอะไรถามก่อนอะไรทำเลย (บท 6), มี CLAUDE.md กำกับพฤติกรรมตอนเจอทางแยก (บท 9) — ทุกกล่องใน FIG 12.1 ไม่ใช่แค่รายการฟีเจอร์ มันคือสิ่งที่กำลังทำงานจริงในทุกวินาทีของเซสชันข้างบน โมเดลตัวเดียวกันเป๊ะ ถ้าไม่มีรั้วพวกนี้ ผลลัพธ์จะไม่ใช่แบบนี้
✅ สรุปบทที่ 12 — Claude Code ลงโครง 5 ชิ้นของบทที่ 1 ได้พอดี: CLAUDE.md/compaction/agentic search = context · Read/Edit/Bash + MCP = tools · เทสต์/lint ผ่าน Bash = feedback · permission/allowlist/hooks/sandbox = guardrails · narration/transcript/usage = observability · transcript 5 ช่วงข้างบนคือทุกกลไกนี้ทำงานร่วมกันจริงในงานเดียว · การตัดสินใจเด่น: tools น้อยแบบ general (Bash เปิดโลก + permission เข้มชดเชย), ค้นสดแทน index ล่วงหน้า, hooks = เบรกที่เป็นโค้ด · บทเรียนใหญ่: ชิ้นส่วนทั้งห้าออกแบบแยกกันไม่ได้ และ harness ที่ดีคือ platform
ออกแบบ harness ของตัวเอง — หลักคิดก่อนโค้ด#
ถึงจุดที่หลายคนรอ: อยากสร้าง harness ของตัวเอง เริ่มตรงไหน? · คำตอบขัดใจนิดหน่อย: อย่าเพิ่งเปิด editor — เพราะการตัดสินใจที่ชี้เป็นชี้ตายทั้งหมดเกิดก่อนโค้ดบรรทัดแรก
13.1 ลำดับการคิด (ไม่ใช่ลำดับการเขียนโค้ด)
- ① เริ่มจาก verifier — คำถามแรกไม่ใช่ "ใช้โมเดลไหน" แต่คือ "งานนี้รู้ได้ยังไงว่าถูก" (บทที่ 5) · ถ้ายังตอบไม่ได้ agent ที่สร้างจะเป็นแค่เครื่องผลิตของที่คนต้องนั่งตรวจเองทั้งหมด — ออกแบบหรือสร้าง verifier ให้ได้ก่อนอย่างอื่นทั้งหมด
- ② เลือก tools น้อยที่สุดที่พองาน — เริ่ม 2–5 ตัว (บทที่ 4) อย่าใส่เผื่อ · เครื่องมือที่ "อาจได้ใช้" คือ context ที่เสียเปล่าและตัวเลือกที่ชวนสับสน
- ③ วาง guardrails ตามแผนที่จริง — ไล่แผนที่ blast radius × reversibility (บทที่ 6) ของงานนี้โดยเฉพาะ: จุดไหนคือหายนะที่แท้จริง จุดนั้นคือที่ที่ด่านต้องอยู่
- ④ เติม memory / subagents เมื่อเจ็บจริง — อย่าใส่วันแรก · ยังไม่เจอปัญหา context ยาว ก็ยังไม่ต้องมียาแก้ (บทที่ 9–10 รอได้เสมอ)
13.2 minimal harness — แก่นมันเล็กแค่นี้
โค้ดข้างล่างคือ harness ที่ทำงานได้จริงทั้งตัว ไม่ถึง 40 บรรทัด — loop จากบทที่ 2 + เครื่องมือไม่กี่ตัว + verifier หนึ่งตัว + การ์ดจากบทที่ 6 และ 8 · สังเกตว่าทุกบรรทัดคือบทหนึ่งของเล่มนี้:
▸ pseudocode: minimal harness ทั้งระบบ
# minimal harness — loop + tools + verifier เดียว
TOOLS = [
read_file(path), # ตา (บท 4)
write_file(path, content), # มือ — จุดเดียวที่แตะโลกจริง
run_tests(), # verifier — หัวใจของทั้งระบบ (บท 5)
]
SYSTEM = """คุณคือ agent แก้โค้ดใน repo นี้
อ่านไฟล์ก่อนแก้เสมอ · แก้ให้เล็กที่สุดที่พอ
ห้ามบอกว่าเสร็จ จนกว่า run_tests จะผ่าน""" # กติกา "เสร็จจริง" (บท 8)
def agent(task, max_turns=30): # เพดานกัน doom loop (บท 8)
history = [task]
for turn in range(max_turns):
resp = model(SYSTEM, TOOLS, history)
if resp.is_text: # โมเดลบอกว่าจบงาน
if not tests_passed(history): # เสร็จปลอม? → ตีกลับ
history += ["ยังไม่เห็นเทสต์ผ่าน — รัน run_tests ก่อนสรุป"]
continue
return resp.text
call = resp.tool_call
if call.name == "write_file" and not allowed(call.path):
history += [call, "path นี้ต้องให้คนอนุมัติก่อน"] # guardrail (บท 6)
continue
result = execute(call)
history += [call, truncate(result, 2000)] # กัน context บวม (บท 3)
log(turn, call.name, cost(history)) # observability (บท 7)
return "หมดโควตารอบ — สรุปที่ทำไป + จุดที่ติด ให้คนดูต่อ"ที่เหลือทั้งหมดของ harness ระดับ production — compaction ฉลาด ๆ, permission หลายชั้น, subagents, eval suite — คือความประณีตที่ค่อย ๆ เติมบนแก่นนี้เมื่องานเรียกร้อง ไม่ใช่ของที่ต้องมีวันแรก
13.3 อย่าสร้างเอง ถ้าของสำเร็จรูปพอ
ความจริงที่ควรพูดตรง ๆ: งานส่วนใหญ่ไม่ต้องสร้าง harness ใหม่ · Claude Code + CLAUDE.md + skills + hooks + MCP ปรับแต่งได้ไกลกว่าที่คิดมาก — และการปรับแต่ง harness สำเร็จรูปให้เข้ากับทีมก็คือ harness engineering เหมือนกัน เป็นจุดเริ่มที่ถูกต้องสำหรับ 90% ของงาน
สร้างเองเมื่อไหร่: workflow เฉพาะทางที่ harness ทั่วไปไม่รองรับ (agent ฝังใน product ของเรา, loop พิเศษเฉพาะโดเมน), ต้องคุม infra/ข้อมูลระดับเข้มข้น, หรือ harness คือตัว product เอง · และถ้าจะสร้าง — Agent SDK และ framework ต่าง ๆ มี loop + tool plumbing สำเร็จให้แล้ว: เวลาของเราควรหมดไปกับชิ้นส่วนทั้งห้าของบทที่ 1 ไม่ใช่ไปกับท่อ
13.4 ตารางเทียบ cost/latency — เครื่องมือตัดสินใจรวมทั้งเล่ม
ทุกบทที่ผ่านมาซ่อน trade-off แบบเดียวกันไว้ซ้ำ ๆ : หมุนไปทางเร็ว/ประหยัด หรือหมุนไปทางแม่น/ปลอดภัย — ไม่มีทางเลือกไหน "ถูกเสมอ" มีแต่เหมาะกับสถานการณ์ไหน ตารางนี้รวบทุกจุดที่เคยแยกกันพูดไว้ในบทก่อน ๆ ให้เห็นพร้อมกันในที่เดียว:
| การตัดสินใจ | หมุนไปทาง "เร็ว/ประหยัด" | หมุนไปทาง "แม่น/ปลอดภัย" | เอียงไปทางไหนเมื่อไหร่ |
|---|---|---|---|
| ความหนาของ sandbox (บท 6) | ไม่มี/บาง — รันทันที ไม่มี overhead ตั้งกรง | container/worktree แยก, ตัด network — ทุก tool call แบกค่าความปลอดภัย | งานแตะข้อมูลเสี่ยงหรือรับ input จากนอก → หนา · งานอ่านอย่างเดียวในเครื่องปิด → บางพอ |
| ความถี่ compaction (บท 3) | สรุปบ่อย/สั้น — context เบา ประหยัดทุกรอบ | เก็บดิบไว้นาน — รายละเอียด/เหตุผลก่อนหน้าไม่หาย | งานตรงไปตรงมา ยาวแต่ไม่ซับซ้อน → สรุปถี่ได้ · งาน debug ที่รายละเอียดเก่าคือกุญแจ → ยืดอายุ context ดิบ |
| ความช้าของ verifier (บท 5, 11) | เทสต์ย่อยไว — วนได้หลายรอบต่อนาที แต่ตรวจได้แค่ผิวเผิน | suite เต็ม/ช้า — มั่นใจกว่ามาก แต่ 20 นาทีต่อรอบ = วนได้ไม่กี่ครั้ง | ระหว่างวนแก้ → ใช้ตัวไวก่อน · ก่อนประกาศเสร็จจริง → ต้องผ่านตัวเต็มด้วย (ใช้สองชั้นซ้อนกันได้) |
| ความถี่การถามสิทธิ์ (บท 6) | auto มาก ถามน้อย — งานลื่นไม่สะดุด | ถามถี่ทุกจุดเสี่ยง — คุมแน่นกว่า แต่ถี่เกินจะเจอ alarm fatigue จนคนกดผ่านโดยไม่อ่าน | วางเส้นถามตาม blast radius × reversibility ของ FIG 6.1 — ไม่ใช่ตามความรู้สึกกลัว |
| แตกงานให้ subagent (บท 10) | ทำเองตัวเดียว — ไม่มี overhead ตั้งต้นซ้ำ (system prompt, สำรวจใหม่) | แตกหลายตัว — context isolation + ทำขนานได้ แต่จ่าย overhead ต่อหัวทุกตัว | งานสรุปกลับได้สั้นและอิสระจริง (บท 10.4) → แตก · งานเล็กหรือต้องแชร์ state ถี่ → ทำเอง |
สังเกตแกนร่วมของทุกแถว: ด้าน "เร็ว/ประหยัด" จ่ายด้วยความเสี่ยงที่ค้นพบช้าลง ส่วนด้าน "แม่น/ปลอดภัย" จ่ายด้วยเวลาและ token ที่มากขึ้น — ไม่มีจุดไหนหมุนไปสุดทางใดทางหนึ่งได้ตลอด งานเสี่ยงต่ำหมุนไปทางเร็วได้เต็มที่ งานเสี่ยงสูงต้องยอมจ่ายแพงขึ้น โจทย์ของคนออกแบบ harness ไม่ใช่หาค่าเดียวที่ดีที่สุด แต่คือรู้ว่าน็อบตัวไหนควบคุมอะไร แล้วหมุนให้เข้ากับความเสี่ยงของงานตรงหน้า
13.5 checklist ก่อนลงมือ
# CHECKLIST — ตอบให้ครบก่อนเขียนโค้ดบรรทัดแรก
[ ] งานนี้มี verifier ที่เชื่อได้ไหม? ไม่มี → หยุด ออกแบบ verifier ก่อน (บท 5)
[ ] ของสำเร็จรูป + ปรับแต่ง พอไหม? พอ → ใช้เลย อย่าสร้าง (บท 13.3)
[ ] tools ชุดเล็กสุดที่จบงานคืออะไร? เริ่ม 2–5 ตัว — เพิ่มเมื่อเจ็บจริง (บท 4)
[ ] action ไหนย้อนกลับยากสุด? จุดนั้นต้องมีด่าน / sandbox (บท 6)
[ ] นิยาม "เสร็จ" + เพดานอยู่ตรงไหน? verifier ก่อนจบ · max turns · งบ (บท 8)
[ ] เก็บ transcript ตั้งแต่วันแรกไหม? debug ไม่ได้ถ้ามองไม่เห็น (บท 7)
[ ] มีชุดงานทดสอบ ~10 ชิ้นไว้เทียบไหม? ไม่มีตัวเลข = ปรับมั่ว (บท 11)✅ สรุปบทที่ 13 — ลำดับคิด: verifier ก่อน → tools น้อยสุดที่พอ → guardrails ตามแผนที่ความเสี่ยงจริง → memory/subagents เมื่อเจ็บจริง · แก่นของ harness เล็กมาก (loop ไม่ถึง 40 บรรทัด) — ที่เหลือคือความประณีตที่เติมทีหลังได้ · 90% ของงานควรปรับแต่งของสำเร็จรูป ไม่ใช่สร้างใหม่ — และถ้าสร้าง ใช้ SDK จัดการท่อ เวลาเราไว้คิดชิ้นส่วนทั้งห้า · ทุกน็อบ (sandbox, compaction, verifier, permission, subagent) หมุนบนแกนเร็ว/ประหยัด vs แม่น/ปลอดภัยแกนเดียวกัน — เลือกตามความเสี่ยงของงาน ไม่มีค่าที่ดีที่สุดค่าเดียว
อนาคตของศาสตร์นี้ — และปิดเล่ม#
คำถามที่ค้างคอคนทั้งวงการ: โมเดลเก่งขึ้นทุกปี — แล้ว harness จะบางลงจนหายไปไหม? · คำถามนี้มีชื่อเล่นในวงการว่า bitter lesson (บทเรียนขมของงานวิจัย AI): โครงช่วยคิดที่มนุษย์ประดิษฐ์ แพ้พลัง scale ของโมเดลเสมอมา — และมันก็จริงซ้ำแล้วซ้ำเล่า
14.1 สองฝั่งของคำตอบ
ฝั่ง "harness จะบางลง" ชี้หลักฐานชัด: เทคนิคที่เคยต้องสั่ง (คิดทีละขั้น) กลายเป็นความสามารถในตัวโมเดล scaffold เต็มยศของปี 2024 จำนวนมากตายเพราะโมเดลปี 2025 ทำเองได้หมด · ถ้าเส้นนี้ลากต่อ — โครงที่สร้างมา "ช่วยโมเดลคิด" จะโดนกลืนเรื่อย ๆ
ฝั่ง "harness จะอยู่" ถามกลับด้วยภาพง่าย ๆ: ต่อให้จ้างวิศวกรที่เก่งที่สุดในโลก เขาก็ยังต้องมี IDE, สิทธิ์เข้าระบบ, code review และการวัดผลงาน — ไม่ใช่เพราะเขาโง่ แต่เพราะนั่นคือ interface ระหว่างความสามารถกับโลกจริง · tools, permissions, evals, observability ไม่ได้มีไว้ชดเชยความโง่ของโมเดล — มันคือการเชื่อมพลังเข้ากับความรับผิดชอบ ซึ่งไม่มีวันตกยุคเพราะโมเดลฉลาดขึ้น
คำตอบที่น่าจะใกล้จริง: harness จะบางลงในชั้น "ช่วยคิด" แต่อยู่ยาวในชั้น "ต่อกับโลก" — prompt trick จะตายไปเรื่อย ๆ ตาม bitter lesson แต่ verifier, guardrails, การวัดผล จะยิ่งสำคัญขึ้นเมื่อ agent รับงานใหญ่ขึ้นและอิสระมากขึ้น · สังเกตว่าเสาหลักของเล่มนี้ตั้งใจอยู่ฝั่งหลังเกือบทั้งหมด
14.2 ทิศทางที่มองเห็นแล้ว
- มาตรฐานเปิดชนะ — MCP ทำให้ tools เป็นของกลางข้าม harness · แนวโน้มเดียวกันไล่มาตรฐานส่วนอื่นตามมาแล้วจริง ๆ — A2A (บทที่ 10.5) พยายามทำแบบเดียวกันกับการคุยข้าม agent ข้ามองค์กร แม้วันนี้ยังแคบกว่า MCP มาก ก็เป็นสัญญาณของทิศทางเดียวกัน
- agent ใช้ agent — โครง orchestration ของบทที่ 10 กำลังโตจาก "ฟีเจอร์" เป็นวิธีทำงานหลัก: งานใหญ่ = ฝูง agent ที่มีคนดูแลผ่าน observability ชั้นดี
- harness กลายเป็น infrastructure ปกติ — แบบเดียวกับที่ CI/CD เคยเป็นของแปลกแล้ววันนี้ทุกทีมมี · อีกไม่นาน "ทีมนี้มี eval suite กับ permission policy ของ agent ไหม" จะเป็นคำถามพื้นฐานเท่ากับ "มี git ไหม"
14.3 ปิดบันไดสาย AI
ถ้ามองย้อนทั้งสาย จะเห็นว่าแต่ละขั้นตอบคำถามคนละชั้น: #06 — พูดกับ AI ยังไงให้ได้งาน · #07 — บังคับผลลัพธ์ยังไงให้เป๊ะพอเอาไปต่อระบบ · #08 — ออกแบบระบบยังไงให้ AI ทำงานเองได้โดยเราไว้ใจได้ · และที่ซ่อนอยู่ในทุกขั้น: ยิ่งให้อิสระมาก ยิ่งต้องออกแบบสิ่งรอบตัวมันดี
14.4 ทักษะที่ไม่หมดอายุ
โมเดลรุ่นถัดไปจะกลืนเทคนิคบางส่วนของเล่มนี้ไป — ตามธรรมชาติของ bitter lesson · แต่สังเกตว่าทักษะที่เล่มนี้ฝึกจริง ๆ ไม่ใช่เทคนิค: นิยามงานให้ชัดจนวัดได้ (บท 8, 10) · ออกแบบ feedback ให้ระบบตรวจตัวเองได้ (บท 5) · ตัดสินว่าอะไรเสี่ยงและวางด่านให้ถูกจุด (บท 6) · วัดผลอย่างซื่อสัตย์ก่อนเชื่อว่าดีขึ้น (บท 11) — สี่อย่างนี้คือทักษะวิศวกรรมแท้ ๆ ที่อยู่มาก่อน AI และจะอยู่ต่อหลังโมเดลทุกรุ่นที่เรารู้จักวันนี้เกษียณไปแล้ว
✅ จบบันไดสาย AI 🏁 — เดินมาครบสามขั้น: ใช้ AI เป็น (เข้าใจกลไกเดาคำถัดไป เขียน prompt ครบส่วน) → สั่ง AI ระดับโปร (few-shot, grounding, chaining, ปลอดภัย, ต่อเครื่องมือ) → ออกแบบระบบรอบ AI (loop, context, tools, feedback, guardrails, observability, memory, subagents, evals) · โมเดลจะเก่งขึ้นทุกปีโดยเราไม่ต้องทำอะไรเลย — ความได้เปรียบเดียวที่สั่งสมได้จริงคือความเข้าใจระบบรอบตัวมัน ซึ่งตอนนี้อยู่ในมือพี่ครบแล้ว · ที่เหลือคือสิ่งเดียวกับทุกเล่มใน collection นี้: เอาไปใช้จริง แล้วให้ของจริงสอนต่อ
อ่านต่อ: AI Brain#
Harness Engineering — ฉบับเข้าใจถึงแก่น — ศาสตร์ของการออกแบบระบบรอบ AI agent สำหรับคนที่อยากเข้าใจว่าทำไมโมเดลเดียวกันถึงเก่งไม่เท่ากัน และออกแบบเองได้
ภาคต่อของ Prompt 0 → Hero · ส่วนหนึ่งของ Handbooks — เขียนเพื่อเข้าใจ ไม่ใช่เพื่อท่องจำ · โดย @tayakorn221 · 2026