ข้ามไปยังเนื้อหา
Tayakorn
aiอัปเดต 2026-07-13อ่านฟรี

Harness Engineering Handbook

ศาสตร์ของการออกแบบระบบรอบ AI agent — agent loop, context, tool design, feedback loops, guardrails, observability, memory, subagents, evals จนถึงผ่า Claude Code ทั้งตัว

#harness-engineering#ai-agents#claude-code#tool-design#guardrails#evals
สารบัญ

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
system prompt ของ harnessบุคลิก + กติกา (คงที่)tool schemasเมนูเครื่องมือ (คงที่)ประวัติการคุยโตขึ้นทุกรอบผล tool รอบก่อน ๆโตเร็วสุดประกอบเสร็จ = สิ่งที่โมเดล "เห็น" ในรอบนั้นส่งทั้งก้อนโมเดลอ่านทั้งหมด → ตอบคำตอบ หรือtool callผลถูกยัดกลับเข้ากอง — รอบหน้า harness ประกอบใหม่ทั้งชุดโมเดลไม่ได้ "จำ" — มันเห็นของที่ถูกประกอบให้ใหม่ทุกรอบ
FIG 2.1 สิ่งที่โมเดลเห็นในหนึ่งรอบ ไม่ใช่ความจำ แต่คือกองเอกสารที่ harness จับประกอบสด ๆ — ใครคุมการประกอบ คนนั้นคุมพฤติกรรม

2.3 แผนที่ของทั้งเล่ม — ทุกบทยึดจุดใดจุดหนึ่งของ loop

ความลับของเล่มนี้: ทุกบทที่เหลือคือการปรับแต่งจุดใดจุดหนึ่งของวงจรข้างบน · ดูรูปนี้ค้างไว้ — มันคือแผนที่ที่เราจะเดินตลอดเล่ม:

บท 3 · งบ context ┊ บท 9 · ความรู้ถาวรเสียบตรงนี้① รวบ contextsystem prompt + tools + ประวัติ + ผลเก่าตอบผู้ใช้ · จบงาน② โมเดลคิดตอบข้อความ หรือ tool callบท 10 · subagent = loop ซ้อน loop③ harness รัน toolผ่านด่านสิทธิ์ก่อนรันจริงบท 4 · ออกแบบ tools ┊ บท 6 · ด่านสิทธิ์④ ผลกลับเข้า contextแล้ววนรอบใหม่บท 5 · ผล tool = feedbackไม่ขอ tool =บอกว่าเสร็จบท 8 · เสร็จจริง?วนรอบละไม่กี่วินาทีagent ที่ทำงานเป็นชั่วโมง = วงนี้หลายร้อยรอบบท 7 · observability — มองเห็นทุกจุดของวงบท 11 · evals — วัดทั้งวงซ้ำ ๆ
FIG 2.2 แผนที่ประจำเล่ม: agent 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 ยาวเหยียด และทุกอย่างกองอยู่บนโต๊ะไปตลอดเซสชันถ้าไม่มีใครจัดการ

ก่อน compaction — งานเดินมา 40 นาที8%10%ประวัติ 30%ผล tool เก่า ๆ 44%ว่างใกล้เต็ม → ต้องบีบsystem prompttool schemasประวัติการคุยผล tool — ตัวใหญ่สุด มักถูกมองข้ามcompaction: สรุปประวัติ + ผลเก่า เหลือย่อสั้น ๆ แล้วเริ่มโต๊ะใหม่หลัง compaction — โต๊ะโล่ง งานเดินต่อ8%10%สรุป ~7%พื้นที่สำหรับงานที่เหลือสรุปที่ดีเก็บ: การตัดสินใจ + เหตุผล + สถานะล่าสุด — ไม่ใช่เก็บบทสนทนาดิบ
FIG 3.1 งบ context ถูกใช้ไปกับอะไร และ compaction เข้ามาเกิดตรงไหน · ตัวกินพื้นที่ตัวจริงคือผล tool เก่า ๆ ที่ไม่มีใครใช้แล้ว

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

RAG · ระบบ PUSH ให้ระบบค้นเอกสารที่ "น่าจะเกี่ยว"แปะให้โมเดลก่อนตอบ — ครั้งเดียวจบโมเดลตอบจากที่ได้รับมาระบบตัดสินใจแทนว่าโมเดลควรเห็นอะไรเดาเอกสารพลาด = จบตั้งแต่ยังไม่เริ่มAGENTIC SEARCH · โมเดล PULL เองโมเดลถือเครื่องมือค้นเองค้น → ดูผล → ค้นใหม่ให้แคบลงตอบเมื่อเจอของที่ใช่จริงโมเดลตัดสินใจเอง: ค้นอะไร เมื่อไหร่ กี่รอบจ่ายเฉพาะที่หยิบ — ตรงหลัก just-in-time
FIG 3.2 RAG คือ just-in-time แบบระบบ push ให้ · agent ยุคนี้ pull เอง — หลักเดียวกัน แต่คนตัดสินใจย้ายจากระบบไปอยู่ที่โมเดล

สรุปบทที่ 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 ห่วยที่ส่งซ้ำอัตโนมัติตลอดกาล

tool หนึ่งตัว = สัญญา 3 ส่วนname: search_customer_ordersชื่อบอก intent ของงาน ไม่ใช่ชื่อ endpointdescription ← prompt ที่ฝังถาวร"ค้นออร์เดอร์จากชื่อ/อีเมลลูกค้าใช้เมื่อถูกถามสถานะการสั่งซื้อ · คืน ≤20 แถว"ทำอะไร · ใช้เมื่อไหร่ · ขอบเขต — ครบในนี้input_schema: {customer*, status?, page?}ฟอร์มที่โมเดลกรอก — required/enum ต้องชัดโมเดลtool call (JSON)harnessตรวจ schema + สิทธิ์รันจริงAPI · ไฟล์ · เชลล์ผลลัพธ์กลับเข้า contextทุกตัวอักษรของผลลัพธ์ = ค่าเช่า contextที่จ่ายซ้ำทุกรอบที่เหลือ (บท 3)
FIG 4.1 สัญญา 3 ส่วนของ tool กับเส้นทางไป-กลับใน loop · โมเดลเขียนแค่คำขอ — harness เป็นคนตรวจและรันจริงเสมอ

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 เปลี่ยนเกม

OPEN LOOP · ทำเสร็จแล้วส่งเลยขั้น 1ขั้น 2ขั้น 3…✗ ✗✗ ✗ ✗พลาดเล็ก ๆ สะสมเงียบ ๆคนมาเจอบั๊กตอนจบแก้ตอนนี้แพงสุด — ต้องย้อนทั้งสายCLOSED LOOP · ทำ → ตรวจ → แก้ → วนลงมือทำขั้นนั้นตรวจกับ verifierเทสต์ · compiler · lintไม่ผ่าน→ แก้ วนใหม่ผ่าน ✓ส่งงานที่ตรวจแล้วความผิดถูกดักในรอบนั้นทันที — ไม่ทบต้น
FIG 5.1 open loop: ความผิดสะสมจนไปโผล่ตอนจบ · closed loop: verifier ดักไว้ทุกขั้น — งานยาวแค่ไหนก็เดินได้

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 ดีแค่ไหน:

งานverifieragent ทำงานยาวได้แค่ไหน
แก้บั๊กใน 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 ย้อนยาก · อีเมลที่ส่งแล้ว ย้อนไม่ได้เลย
ทำได้ แต่บอกให้รู้ + อยู่ใน sandboxแก้ 30 ไฟล์บน branch (git ย้อนได้)รัน migration บนฐานข้อมูลทดสอบห้าม / คนทำเองเท่านั้นrm -rf นอก repo · git push --forceอีเมลหาลูกค้าทั้งลิสต์ · แตะ prod DBทำเลย ไม่ต้องถามอ่านไฟล์ · ls · grep · รันเทสต์ทุกอย่างที่แค่ "ดู" ไม่ "แตะ"ถามก่อนทุกครั้งลบไฟล์ที่ git ไม่คุม · ติดตั้ง packageส่งข้อความหาคนหนึ่งคนย้อนกลับ: ง่าย ────→ ยากรัศมีเสียหาย: แคบ ──→ กว้าง
FIG 6.1 แผนที่การให้อิสระ: ยิ่งขวาบน (ย้อนยาก × วงกว้าง) อำนาจตัดสินใจยิ่งต้องเลื่อนกลับไปหาคน · เส้นแบ่งจริงแต่ละทีมขยับเองได้ — แต่ต้องขยับบนแผนที่นี้อย่างตั้งใจ

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": เพราะเราออกแบบระบบไว้กันวันที่มันโดนหลอก ไม่ใช่วันที่มันทำงานปกติ
🌐 เว็บที่ agent เปิด📧 อีเมล · issue ที่อ่าน📄 ไฟล์ที่คนอื่นเขียนtool resultไหลเข้า loop เองชั้นซอฟต์ผล tool = data ไม่ใช่คำสั่งโมเดลอ่านอาจหลงเชื่อชั้นแข็งsandbox · permission⚠ ความเสียหายข้อมูลรั่ว · ระบบพังคนนอกเขียนได้ =ฝังคำสั่งแอบได้เสมอลดโอกาสหลงเชื่อแต่ไม่ 100%จำกัดความเสียหายวันที่หลงเชื่อจริงโมเดลฉลาดแค่ไหนก็ถูกหลอกได้ — ชั้นซอฟต์ลดโอกาส · ชั้นแข็งการันตีเพดานความเสียหาย
FIG 6.2 เส้นทางของคำสั่งแฝง กับกำแพงสองชั้นที่ต้องมีคู่กัน · เส้นประหยุดที่กำแพงแข็ง — นั่นคือทั้งเหตุผลของ 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 ที่โตแล้วให้การมองเห็นเป็นชั้น ๆ — แต่ละชั้นตอบคำถามของคนละคน ในคนละจังหวะ:

① progress narration — เล่าสดว่ากำลังทำอะไร"รันเทสต์รอบ 3 — เหลือแดง 2 ตัว กำลังแก้ mock ที่ผิด"ผู้ใช้ · เรียลไทม์"ตอนนี้มันทำอะไรอยู่?"② transcript / trace — บันทึกดิบครบทุกรอบทุก prompt ที่ประกอบ · ทุก tool call · ทุกผลลัพธ์ ไล่ย้อนได้คนสร้าง harness · ตอน debug"ทำไมมันตัดสินใจแบบนั้น?"③ metrics — ตัวเลขรวมข้ามหลายงานtoken · cost · เวลา · จำนวนรอบ · อัตรางานสำเร็จทีม/เจ้าของระบบ · รายสัปดาห์"โดยรวมดีขึ้นหรือแย่ลง?"ยิ่งลึก ยิ่งขยับจาก "เรื่องเดียว เรียลไทม์" → "หลายงาน มองย้อนหลัง"
FIG 7.1 สามชั้นของการมองเห็น: narration ให้คนตัดสินใจว่าปล่อยต่อหรือเบรก · trace ให้ไล่การตัดสินใจ · metrics ให้เห็นเทรนด์

ชั้นแรกมีของแถมที่คนมองข้าม: 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วนแก้ที่เดิมท่าเดิมซ้ำ ๆscope creep — แผนบานเกินคำสั่งcontext ที่สะสมมาประวัติ + ผล toolโมเดลวางแผนขั้นถัดไปทำอะไรรัน tool → ดูผลแล้ววนกลับcontext poisoningของเสียเก่าค้าง ลากรอบใหม่เพี้ยนประกาศเสร็จ← เสร็จปลอม — พูดว่าเสร็จทั้งที่ไม่(แก่นเดียวกับ reward hacking)⛑ max turns · token budget · timeout — ตัดวงจร⛑ ต้องผ่าน verifier ก่อนประกาศเสร็จ (บท 5)
FIG 8.1 failure modes สี่ตัวเกิดคนละจุดของ loop · การ์ดสองชุดข้างล่างคือเข็มขัดนิรภัยที่ดักมันเกือบทั้งหมด

เคส 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 แต่คราวนี้ใช้กับความรู้ของระบบเอง

① อยู่ใน context ตลอดsystem prompt · CLAUDE.md — สั้นที่สุดเท่าที่จะสั้นได้② โหลดเมื่องานเรียกskills — หัวข้อโผล่ตลอด (1 บรรทัด) เนื้อเต็มเปิดเมื่อใช้③ ค้นเมื่อต้องใช้memory ที่จดไว้ · โค้ดใน repo · เอกสาร — agent ใช้ tool ไปหยิบเองต้นทุน token ต่อรอบ: ต่ำ → สูงความจุ: น้อย → มหาศาลความรู้เลื่อนขึ้นชั้นบน "เฉพาะตอนถูกเรียก" — progressive disclosure (โครงเดียวกับบท 3)
FIG 9.1 สามชั้นความรู้: ยิ่งบนยิ่งแพงจึงต้องเล็ก ยิ่งล่างยิ่งจุได้มหาศาลเพราะจ่ายเฉพาะที่หยิบ · ศิลปะคือการวางของให้ถูกชั้น

สรุปบทที่ 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 ตัวรันพร้อมกัน เวลารวมเท่างานที่ช้าสุด ไม่ใช่ผลบวกของทุกงาน
agent หลัก (orchestrator)ถือภาพรวม · แตกงาน · ประกอบผลคำสั่งงาน =prompt ที่ครบในตัวส่งกลับได้แค่ข้อสรุปสั้น ๆลูก A — สำรวจ repocontext ของตัวเอง:อ่าน 40 ไฟล์ · จดโครงสร้างทิ้งไว้ที่นี่ — ไม่ไหลขึ้นไปลูก B — ไล่สาเหตุบั๊กcontext ของตัวเอง:อ่าน trace · ไล่ 3 สมมติฐานทิ้งไว้ที่นี่ — ไม่ไหลขึ้นไปลูก C — ลองแก้ใน sandboxcontext ของตัวเอง:แก้ 5 ไฟล์ · รันเทสต์ 9 รอบทิ้งไว้ที่นี่ — ไม่ไหลขึ้นไปงานที่ต้องแชร์ state ละเอียดตลอดเวลา — อย่าแตก: ค่าสื่อสารจะแพงกว่าตัวงาน
FIG 10.1 เส้นการไหลของ context: คำสั่งลงไปต้องครบในตัว (ทึบ) ผลกลับขึ้นมาเหลือแค่สรุป (ประ) — ของหนักทั้งหมดตายอยู่ในลูก และนั่นแหละคือประโยชน์

10.2 รูปแบบที่เจอบ่อย

  • orchestrator–worker — ตัวหลักถือแผนและประกอบผล ลูกรับงานชิ้นเดียวจบ · ท่ามาตรฐานของงานใหญ่
  • pipeline — ต่อแถว: ผลของตัวหนึ่งเป็นวัตถุดิบของตัวถัดไป (ค้น → ร่าง → ตรวจ) · แต่ละขั้นได้ context สะอาดเฉพาะเรื่องของตัว
  • fan-out / verify — กระจายงานเดียวกันให้หลายลูกทำจากคนละมุม (ไล่หาบั๊กด้วย 5 มุมมอง) แล้วมีตัวตรวจ/รวมผล · ญาติทางความคิดกับ pass@k ที่จะเจอในบทที่ 11
ORCHESTRATOR–WORKERหลักลูก Aลูก Bลูก Cงานอิสระหลายชิ้นพร้อมกันหลักถือแผน + ประกอบผลPIPELINEค้นร่างตรวจผลของตัวหนึ่ง = วัตถุดิบตัวถัดไปแต่ละขั้นได้ context สะอาดFAN-OUT / VERIFYมุม 1มุม 2มุม 3ตรวจ / รวมงานเดียว ยิงหลายมุมพร้อมกันตัวตรวจคัดของดี (ญาติ pass@k)กติการ่วมของทุกแบบ: brief ครบในตัว · ผลกลับเป็นสรุปสั้น
FIG 10.2 สามท่ามาตรฐานของการแตกงาน · เลือกตามรูปงาน: อิสระหลายชิ้น → orchestrator, งานเป็นขั้น → pipeline, งานเดียวอยากได้หลายมุม → fan-out

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 ร่วมพัฒนา

ในบ้านเดียวกัน — subagent (ทั้งบทนี้)orchestratorลูก Aลูก Bharness เดียวกัน · vendor เดียวกันเรียกผ่าน tool ภายในโปรเสสเดียวข้ามรั้ว — A2A (บริษัท/vendor อื่น)agent ของเราAgent Cardทำอะไรได้บ้างagent อีกฝ่ายมีโมเดลตัดสินใจเองอ่านการ์ด + ยืนยันตัวตนก่อนทุกครั้งงานเป็นวงจร: submitted → working → เสร็จ/พัง
FIG 10.3 subagent ในบทนี้อยู่บ้านเดียวกันเสมอ · A2A ขยายรูปแบบเดียวกันข้ามรั้ว โดยต้องรู้จักกันก่อน (Agent Card) และยืนยันตัวตนทุกครั้ง เพราะอีกฝั่งไม่ใช่ฟังก์ชัน แต่เป็นอีกสมองหนึ่ง

กรอบคิดที่ทั้ง 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 ที่เกิดจากบั๊กจริง — ระบบจะไม่มีวันพังท่าเดิมแบบเงียบ ๆ อีก
① ปรับ harnessเปลี่ยนทีละอย่าง: prompt / tool / กติกา② รัน eval suite20 งานตัวแทน × 5 รอบ (pass@k)③ เทียบกับ baselineงานผ่าน · token · เวลา · จำนวนรอบ④ ตัดสินใจดีขึ้น → เก็บ · แย่ลง → ย้อนวนรอบใหม่🐞 เคสพังจากงานจริง → กลั่นเป็นงานใหม่เข้า suite (กัน regression)
FIG 11.1 วงจรปรับ harness อย่างมีหลักฐาน: เปลี่ยนทีละอย่าง → รันชุดเดิม → เทียบตัวเลข → ตัดสินใจ · suite โตขึ้นเรื่อย ๆ จากแผลจริง

ขยายเรื่อง pass@k อีกนิดให้เห็นภาพ — เพราะนี่คือจุดที่คนพลาดบ่อยที่สุด: ทำไม "รันครั้งเดียวแล้วเทียบ" ถึงหลอกเราได้ทั้งที่ตั้งใจวัดแล้ว

งานเดียวกัน · รัน 5 รอบharness v1ผ่าน 2/5harness v2ผ่าน 4/5 — ดีกว่าจริง⚠ ถ้าจับฉลากเทียบแค่รอบเดียว (กรอบประ): v1 ชนะ — สรุปกลับด้านจากความจริงagent ไม่ deterministic — งานเดิมรันซ้ำได้ผลไม่ซ้ำเทียบสองเวอร์ชัน = เทียบสัดส่วนผ่านจากหลายรอบ (pass@k) ไม่ใช่ครั้งเดียวชนกัน
FIG 11.2 เหตุผลที่ต้อง 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 ที่เราเรียนมายังไง

CLAUDE CODE — วางบนโครง 5 ชิ้นจากบทที่ 1CONTEXTบท 3 · 9CLAUDE.mdโหลดทุกเซสชันagentic searchค้นเอง ไม่ index ก่อนauto-compactionสรุปเมื่อใกล้เต็มskillsโหลดตามงานTOOLSบท 4 · 10Read·Edit·Writeไฟล์ทุกภาษาGlob·Grepมือค้นของ agentBashประตูเปิดโลกsubagentงานรกโยนให้ลูกFEEDBACKบท 5เทสต์ผ่าน Bashเห็น error ดิบเต็ม ๆlint·typecheckกติกาอัตโนมัติscreenshotงาน UI เห็นภาพจริงexit codeรู้ผลทุกคำสั่งGUARDRAILSบท 6permission modesหลายระดับอิสระallowlistจำคำตอบเดิมhooksเบรกที่เป็นโค้ดsandbox·worktreeกรงวิ่งเต็มสปีดOBSERVABILITYบท 7 · 8narration สดเล่าว่ากำลังทำอะไรtranscriptย้อนดูได้ทุกรอบ/usagetoken · เงิน · เวลาเพดานรอบ/งบกัน doom loopทุกช่องคือคำตอบของ trade-off ที่บทก่อนหน้าตั้งไว้ — ไม่มีชิ้นไหนอยู่ตรงนั้นโดยบังเอิญ
FIG 12.1 anatomy ของ Claude Code บนโครง 5 ชิ้น · ลองผ่า harness ตัวอื่นที่พี่ใช้ดูจะพบว่าลงโครงเดียวกันได้เสมอ

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 รอได้เสมอ)
ตอบข้อ ① ไม่ได้ = ยังไม่ต้องไปต่อ① verifier ก่อนรู้ได้ยังไงว่างานถูก?(บท 5)② tools น้อยสุด2–5 ตัวที่พองาน(บท 4)③ guardrailsตามความเสี่ยงจริง(บท 6)④ ค่อยขยายmemory · subagentsเมื่อเจ็บจริง (บท 9–10)นี่คือลำดับการคิด — ไม่ใช่ลำดับเขียนโค้ด · ข้อ ④ อาจไม่มาถึงเลยก็ได้ และนั่นแปลว่าออกแบบถูก
FIG 13.1 สี่ขั้นก่อนโค้ดบรรทัดแรก: เริ่มจากคำถามที่ตอบยากสุด (verifier) แล้วค่อยไล่ไปหาของที่เติมทีหลังได้

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 รับงานใหญ่ขึ้นและอิสระมากขึ้น · สังเกตว่าเสาหลักของเล่มนี้ตั้งใจอยู่ฝั่งหลังเกือบทั้งหมด

ชั้นช่วยโมเดลคิดprompt trick · ป้อนแผนคิด · scaffoldบางลงเรื่อย ๆ — โดนโมเดลกลืน (bitter lesson)ชั้นต่อกับโลกจริงtools · guardrails · verifier · evals · observabilityอยู่ยาว — ยิ่ง agent อิสระยิ่งสำคัญเวลา — โมเดลเก่งขึ้นเรื่อย ๆ →
FIG 14.1 คำตอบของ bitter lesson ที่น่าจะใกล้จริง: ชั้น “ช่วยคิด” ถูกกลืน แต่ชั้น “ต่อกับโลก” ไม่ใช่ไม้ค้ำความโง่ — มันคือ interface กับความรับผิดชอบ

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

#04 · AI Brainแอปพลิเคชันข้างทางไม่ใช่ขั้นบันได#06 · Prompt ที่ดีใช้ AI เป็นคุยกับ AI ให้ได้งาน#07 · Prompt 0 → Heroสั่ง AI ระดับโปรคุมผลลัพธ์ได้เป๊ะต่อ AI เข้าเครื่องมือและระบบ#08 · เล่มนี้ออกแบบระบบรอบ AIสร้างระบบที่ agentทำงานเองได้อย่างปลอดภัยบันไดสายทักษะ AI ของ collection — เล่มนี้คือขั้นปิด
FIG 14.2 สามขั้นของการเดินทาง: ใช้เป็น → สั่งเป็น → ออกแบบระบบเป็น · ai-brain (#04) คือแอปพลิเคชันที่แวะสร้างข้างทาง ไม่ใช่ขั้นทักษะ

ถ้ามองย้อนทั้งสาย จะเห็นว่าแต่ละขั้นตอบคำถามคนละชั้น: #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