Harness Engineering: ออกแบบ 'โครงครอบ' รอบ model ให้ coding agent เชื่อถือได้
บทความนี้ เรียบเรียงเป็นภาษาไทยเพื่อการศึกษา โดยยึด “Harness engineering for coding agent users” ของ Birgitta Böckeler (Distinguished Engineer, Thoughtworks) เผยแพร่บน martinfowler.com เมื่อ 2 เมษายน 2026 เป็นแกนหลัก
และเสริมด้วย “Effective harnesses for long-running agents” โดย Justin Young บน Anthropic Engineering (26 พฤศจิกายน 2025)
เขียนด้วยสำนวนของผู้เรียบเรียงในลักษณะสังเคราะห์ ไม่ใช่การแปลคำต่อคำ วลีเด่นที่ยกมาได้ให้เครดิตไว้ในเนื้อหา ศัพท์เทคนิคคงเป็นภาษาอังกฤษพร้อมคำอธิบายไทยเมื่อพบครั้งแรก และ ไดอะแกรมวาดใหม่เป็น Mermaid (label เป็นภาษาอังกฤษ) ลิขสิทธิ์ของเนื้อหาต้นฉบับเป็นของผู้เขียนแต่ละท่าน
ในซีรีส์นี้เราไล่ดูวิวัฒนาการของการทำงานกับ AI agent มาเป็นลำดับ เริ่มจากการเขียน prompt ให้ดี ต่อด้วย context engineering ที่มอง context เป็นทรัพยากรจำกัดและคัดเฉพาะ token ที่ให้สัญญาณสูง
คำถามถัดไปที่ใหญ่กว่าตัว prompt และ context คือ แล้ว ระบบทั้งหมดที่ห่อหุ้ม model อยู่ ล่ะ ควรออกแบบอย่างไรให้ coding agent ทำงานได้อย่างเชื่อถือได้ใน codebase จริง คำตอบของ Böckeler คือคำว่า harness engineering
harness คืออะไร: “ทุกอย่างใน agent ยกเว้นตัว model”
หัวข้อที่มีชื่อว่า “harness คืออะไร: “ทุกอย่างใน agent ยกเว้นตัว model””Böckeler ให้นิยามที่คมและจำง่าย: harness (โครงครอบรอบ model) คือ ทุกอย่างใน AI agent ยกเว้นตัว model เอง
พูดอีกอย่าง model คือ “เครื่องยนต์” ส่วน harness คือทุกชิ้นส่วนที่เราในฐานะผู้ใช้ประกอบขึ้นรอบ ๆ มันเพื่อกำกับและควบคุมพฤติกรรมให้เข้ากับบริบทของเรา ได้แก่
- system prompt และ instruction file (เช่น
AGENTS.md,CLAUDE.md) - ชุด tools
- Model Context Protocol (MCP — โพรโทคอลมาตรฐานสำหรับป้อน context/เครื่องมือให้ LLM)
- sandbox และสภาพแวดล้อมรัน
- memory
- feedback loop
- quality gate (ประตูตรวจคุณภาพ) ต่าง ๆ
นัยสำคัญที่ตามมาคือ การเปลี่ยนไปใช้ model ที่เก่งขึ้นเพียงอย่างเดียว มักไม่ได้ทำให้ agent ของเราดีขึ้นเท่ากับการลงมือออกแบบ harness ที่ดี เพราะ model ที่เก่งแค่ไหนก็ยังไม่รู้ธรรมเนียม codebase ของเรา ไม่รู้ว่าอะไรคือ “เสร็จ” ในองค์กรเรา และไม่มีทางรับ feedback ที่ดีถ้าเราไม่ได้วางกลไกไว้ให้
harness คือที่ที่ความรู้เฉพาะบริบทเหล่านั้นถูกฝังลงไป
harness = everything in an AI agent except the model itself หรือในสูตรจำง่ายของ Böckeler คือ Agent = Model + Harness — model เป็นเพียงชิ้นเดียวในระบบ ส่วนที่เหลือทั้งหมด (prompts, tools, MCP, sandbox, memory, feedback loop, quality gate) คือสิ่งที่ เราออกแบบได้ และเป็นตัวชี้ขาดว่า agent จะเชื่อถือได้แค่ไหน — เรียบเรียงจาก Böckeler
ตำแหน่งในซีรีส์: prompt สู่ context สู่ harness สู่ loop
หัวข้อที่มีชื่อว่า “ตำแหน่งในซีรีส์: prompt สู่ context สู่ harness สู่ loop”มองในภาพวิวัฒนาการ harness engineering คือชั้นถัดไปที่ต่อยอดจาก context engineering โดยตรง
prompt engineering ดูแลถ้อยคำของคำสั่ง context engineering ขยายออกไปดูแลว่าอะไรควรอยู่ใน context window ณ แต่ละก้าว ส่วน harness engineering ถอยออกมาอีกขั้นเพื่อดูแล ระบบทั้งก้อนที่ล้อมรอบ model
และในบทถัดไปเราจะไปต่อที่ loop engineering ที่ว่าด้วยการออกแบบวงรอบการทำงานให้ agent วนแก้ตัวเองได้อย่างมีเสถียรภาพ
flowchart LR P["Prompt engineering"] --> C["Context engineering"] C --> H["Harness engineering"] H --> L["Loop engineering"] classDef focus fill:#2563eb,stroke:#1e3a8a,color:#ffffff; class H focus;
ภาพ 1 — วิวัฒนาการของการทำงานกับ agent แต่ละชั้นไม่ได้แทนที่ชั้นก่อนหน้า แต่ห่อหุ้มมันไว้ในกรอบที่กว้างขึ้น harness engineering เป็นชั้นที่ดูแลทุกอย่างรอบ model และเป็นฐานที่ loop engineering จะมาต่อยอด
Guides กับ Sensors: feedforward และ feedback
หัวข้อที่มีชื่อว่า “Guides กับ Sensors: feedforward และ feedback”หัวใจของกรอบคิดที่ Böckeler เสนอคือการแยกกลไกควบคุมออกเป็นสองประเภทที่เสริมกัน โดยยืมภาษาจากทฤษฎีระบบควบคุม (control theory):
- Guides (feedforward) — กลไกที่ นำทาง agent ก่อนที่มันจะลงมือ generate เพื่อเพิ่มโอกาสให้ได้ผลลัพธ์ที่ดีตั้งแต่ครั้งแรก เช่น เอกสารมาตรฐานการเขียน code, rule/instruction file, spec, skill, codemod (script แปลง code อัตโนมัติทั้ง codebase) หรือ scaffold (โครงเริ่มต้นของ project) ที่ตั้งโครงให้ถูกตั้งแต่ต้น
- Sensors (feedback) — กลไกที่ จับปัญหาหลัง agent ลงมือไปแล้ว เพื่อให้มันแก้ตัวเองได้ เช่น linter, type checker, ชุด test, fitness function (function ที่วัดว่า code ยังรักษาคุณลักษณะเชิงสถาปัตยกรรมที่ต้องการไว้ได้หรือไม่) และ AI code review
ทั้งสองอย่างขาดกันไม่ได้ ถ้ามีแต่ feedback อย่างเดียว agent จะเดินผิดซ้ำ ๆ โดยไม่เรียนรู้ทิศทางล่วงหน้า แต่ถ้ามีแต่ feedforward อย่างเดียว กฎที่เราวางไว้ก็ไม่เคยถูกตรวจสอบว่าได้ผลจริงหรือไม่
Böckeler ยังเพิ่มแกนที่สองที่สำคัญไม่แพ้กัน: กลไกแต่ละตัวจะทำงานแบบ computational หรือ inferential
- computational — ทำงานแบบ deterministic (กำหนดผลตายตัว) รันบน CPU เร็วระดับมิลลิวินาทีถึงวินาที เช่น linter, type checker, test, การวิเคราะห์โครงสร้าง code ผลลัพธ์แน่นอนและถูกเสมอในสิ่งที่มันตรวจ
- inferential — อาศัย LLM ตีความเชิงความหมาย (semantic) ช้ากว่า ใช้ทรัพยากรมากกว่า และไม่ deterministic แต่จับปัญหาเชิงความหมายที่กฎตายตัวจับไม่ได้ เช่น AI code review หรือ custom judge ที่ประเมินคุณภาพ
flowchart LR
subgraph GUIDES["Guides - feedforward (before generate)"]
direction TB
GC["Computational: codemods, scaffolds"]
GI["Inferential: AGENTS.md, skills, specs"]
end
M["Model"]
subgraph SENSORS["Sensors - feedback (after generate)"]
direction TB
SC["Computational: linters, types, tests"]
SI["Inferential: AI review, LLM judges"]
end
GUIDES --> M
M --> SENSORS
SENSORS -->|self-correct| M
ภาพ 2 — harness ห่อหุ้ม model ด้วยสองด้าน Guides นำทางก่อน generate ส่วน Sensors จับปัญหาหลัง generate แล้วป้อนกลับให้ agent แก้ตัวเอง แต่ละด้านยังแยกได้เป็น computational (เร็ว แน่นอน) และ inferential (อาศัย LLM ตีความ)
จัดวางตัวอย่างลงในสองแกนนี้จะได้ตารางที่ช่วยให้เห็นภาพว่าเครื่องมือแต่ละชิ้นทำหน้าที่อะไร:
| กลไก | Feedforward (Guide) | Feedback (Sensor) |
|---|---|---|
| Computational | codemod, scaffold, project generator | linter, type checker, test, structural/architecture test |
| Inferential | AGENTS.md, skill, spec, ตัวอย่าง code | AI code review, LLM-as-judge |
สามหมวดของ harness และหมวดที่ยังอ่อนที่สุด
หัวข้อที่มีชื่อว่า “สามหมวดของ harness และหมวดที่ยังอ่อนที่สุด”Böckeler จัดกลุ่ม harness ตามสิ่งที่มันพยายามควบคุมได้เป็นสามหมวด และชี้ว่าแต่ละหมวด “โต” ไม่เท่ากัน
- Maintainability harness (แข็งแรงที่สุด) — ดูแลคุณภาพภายในของ code และความง่ายในการดูแลรักษา เป็นหมวดที่เครื่องมือสุกงอมที่สุด computational sensor จับปัญหาเชิงโครงสร้างได้อย่างเชื่อถือได้ ทั้งความซ้ำซ้อน (duplication), ความซับซ้อน (complexity), ช่องโหว่ของ coverage และการละเมิดสไตล์ ส่วน inferential sensor ช่วยจับปัญหาเชิงความหมาย เช่น test ที่ซ้ำซ้อนหรือการ over-engineer ได้บางส่วน แต่แพงและเป็นความน่าจะเป็น
- Architecture-fitness harness (ปานกลาง) — นิยามและตรวจคุณลักษณะเชิงสถาปัตยกรรมผ่าน fitness function เช่น ข้อกำหนดด้าน performance ที่มี performance test คอยให้ feedback หรือมาตรฐานด้าน observability (ธรรมเนียมการ logging) พร้อมคำแนะนำสำหรับการ debug
- Behaviour harness (อ่อนที่สุด) — Böckeler เรียกว่าเป็น “ช้างในห้อง” ทุกวันนี้ฝั่ง feedforward พึ่ง functional specification ที่ละเอียดบ้างหยาบบ้าง ส่วนฝั่ง feedback พึ่งชุด test ที่ AI generate ขึ้นมาบวกกับการทดสอบด้วยมือ ปัญหาคือแนวทางนี้ ฝากความเชื่อมั่นไว้กับ test ที่ AI สร้างเองมากเกินไป ซึ่งยังไม่ดีพอ การตรวจว่า code “ทำสิ่งที่ควรทำจริงหรือไม่” จึงยังเป็นด่านที่เทคโนโลยีปัจจุบันยังไปไม่ถึง
ข้อสังเกตที่เจ็บแต่จริงคือ ไม่ว่า sensor ฝั่ง maintainability จะเก่งแค่ไหน มันก็ยังจับปัญหาที่กระทบมากที่สุดไม่ได้อย่างน่าเชื่อถือ ไม่ว่าจะเป็นการวินิจฉัยโจทย์ผิด (misdiagnosis), feature เกินความจำเป็น หรือการเข้าใจคำสั่งคลาดเคลื่อน ปัญหาเหล่านี้ขึ้นกับความชัดเจนของมนุษย์เป็นหลัก
Shift-left: จับปัญหาให้เร็วและถูกที่
หัวข้อที่มีชื่อว่า “Shift-left: จับปัญหาให้เร็วและถูกที่”แนวคิด shift-left ยืมมาจากโลก CI/CD ตรงที่ว่า ยิ่งจับปัญหาได้เร็วใน pipeline ต้นทุนการแก้ยิ่งถูก การออกแบบ harness จึงต้องตอบคำถามเรื่อง “จังหวะเวลา” ว่าจะวาง sensor แต่ละตัวไว้ตรงไหน
- ก่อน commit / ตอน integrate — วางการตรวจที่ เร็วและถูก เช่น linter, type checker, agent รีวิวแบบเบา ๆ และชุด test ที่รันไว
- ใน pipeline หลัง integrate — วางการวิเคราะห์ที่ แพงกว่า เช่น mutation testing (การจงใจกลายพันธุ์ code เพื่อวัดว่าชุด test จับข้อผิดพลาดได้จริง) หรือการรีวิวเชิงลึกด้วย AI
- เฝ้าระวังต่อเนื่อง — จับ drift (code ตาย, coverage ที่คุณภาพตก, ช่องโหว่ของ dependency) และ feedback จาก runtime เช่น SLO (Service Level Objective — เป้าหมายระดับบริการที่วัดได้) ที่เสื่อมลง และคุณภาพคำตอบ
harnessability: ไม่ใช่ทุก codebase รับ harness ได้เท่ากัน
หัวข้อที่มีชื่อว่า “harnessability: ไม่ใช่ทุก codebase รับ harness ได้เท่ากัน”จุดที่ Böckeler ขุดลึกและน่าสนใจคือแนวคิด harnessability — codebase แต่ละแห่ง “รับ” harness ได้ไม่เท่ากัน
เธอเรียกคุณสมบัติที่ทำให้สภาพแวดล้อมอ่านง่ายและควบคุมได้ง่ายสำหรับ agent ว่า ambient affordances เช่น ภาษาที่ strongly-typed, ขอบเขต module ที่ชัด และ framework ที่มีความเห็นชัด (opinionated) ล้วนรองรับ sensor ที่ซับซ้อนได้ตามธรรมชาติ
จากตรงนี้เกิดเป็นข้อขัดแย้งที่น่าปวดหัว: ระบบ legacy ที่มีหนี้ทางเทคนิคสูงคือระบบที่ต้องการ harness มากที่สุด แต่ก็เป็นระบบที่ harnessable น้อยที่สุด เพราะไม่มีขอบเขตชัดให้ตรวจ ไม่มี type ให้พึ่ง และไม่มี test ให้ยึด
นี่คือเหตุผลว่าทำไมการลงทุนกับโครงสร้างพื้นฐาน (types, module boundaries, ชุด test) จึงเป็นการลงทุนกับความสามารถในการใช้ AI ไปพร้อมกัน
“A good harness should not necessarily aim to fully eliminate human input, but to direct it to where our input is most important.”
harness ที่ดี ไม่จำเป็นต้องเล็งไปที่การกำจัด input ของมนุษย์ให้หมด แต่ควรนำพา input นั้นไปยังจุดที่มันสำคัญที่สุด — มนุษย์ยังนำสิ่งที่ agent ให้ไม่ได้มาด้วย ทั้งความรับผิดชอบทางสังคม รสนิยมเชิงออกแบบ ความรู้ว่าธรรมเนียมท้องถิ่นข้อไหน “รับน้ำหนัก” สำคัญ และบริบททางธุรกิจ
harness ที่ดีคือการ externalize ประสบการณ์ของนักพัฒนาออกมา ไม่ใช่การแทนที่ดุลยพินิจของมนุษย์
harness สำหรับ long-running agent (มุมมองจาก Anthropic)
หัวข้อที่มีชื่อว่า “harness สำหรับ long-running agent (มุมมองจาก Anthropic)”เมื่อขยับจากงานสั้น ๆ ไปสู่งานที่ยาวจน agent ต้องทำงานข้าม หลาย context window ปัญหาใหม่ก็โผล่ขึ้นมา
บทความ “Effective harnesses for long-running agents” ของ Justin Young (Anthropic) เปรียบภาพไว้คมมาก: มันเหมือน project ซอฟต์แวร์ที่มีวิศวกรทำงานเป็นกะ โดยวิศวกรกะใหม่ทุกคนมาถึงโดยไม่มีความทรงจำใด ๆ จากกะก่อนหน้า
จากการให้ Claude ลองสร้างเว็บ app ที่ซับซ้อน ทีม Anthropic พบรูปแบบความล้มเหลวสองแบบ: แบบแรกคือ ทะเยอทะยานเกินไป พยายามทำทุกอย่างในคราวเดียว (one-shot) จน context หมดกลางคัน แล้วทิ้ง feature ที่ทำค้างไว้แบบไม่มีเอกสาร
แบบที่สองคือ ประกาศว่าเสร็จก่อนเวลา agent รอบถัดมาเห็นว่ามีความคืบหน้าอยู่แล้วก็ “ประกาศว่างานจบ” ทั้งที่ function ยังไม่ครบ
ทางแก้ที่เสนอคือ harness แบบสองส่วน: initializer agent ทำหน้าที่ตั้งโครงใน session แรก แล้วส่งต่อให้ coding agent ที่โฟกัสทีละ feature ใน session ถัด ๆ ไป
flowchart TB U["User prompt"] --> INIT["Initializer Agent"] INIT --> FL["Feature list (JSON)"] INIT --> SH["init.sh"] INIT --> PF["Progress file"] INIT --> GIT["Git baseline commit"] FL --> CODE["Coding Agent (per session)"] SH --> CODE PF --> CODE GIT --> CODE CODE --> R1["Recover context: read git log and progress"] R1 --> R2["Implement one feature"] R2 --> R3["Verify end-to-end"] R3 --> R4["Commit and update progress"] R4 -->|next session| CODE
ภาพ 3 — harness แบบ long-running: initializer agent ตั้งโครงครั้งเดียว (feature list, init.sh, progress file, git baseline) แล้ว coding agent วนทำงานทีละ feature ต่อเนื่องข้าม session โดยใช้ git และ progress file เป็นจุดส่งต่องานระหว่างกะ
initializer agent ตั้งอะไรบ้าง
หัวข้อที่มีชื่อว่า “initializer agent ตั้งอะไรบ้าง”initializer agent วางรากฐานผ่านสิ่งประดิษฐ์ (artifact) หลักไม่กี่อย่าง:
- feature list (file JSON) — ขยายคำสั่งเริ่มต้นของผู้ใช้ออกเป็นรายการ feature ย่อยที่ทดสอบได้ (ตัวอย่างในบทความมี “กว่า 200 feature” สำหรับ project เลียนแบบ Claude.ai) แต่ละ feature เริ่มต้นสถานะเป็น “failing” และมี field boolean ชื่อ
passesโดยห้ามแก้หรือลบรายการทิ้งเด็ดขาด เพราะการลบ test อาจกลบ function ที่ยังขาดหรือยัง bug อยู่ - init.sh — script รันได้ที่จุดสภาพแวดล้อมพัฒนาให้ทำงาน ทำให้ session ถัด ๆ ไปเปิด server ขึ้นมาได้เร็ว
- progress file — file บันทึกความคืบหน้า (เช่น
claude-progress.txt) พร้อม git commit แรก ที่ตรึงสถานะ baseline ไว้
coding agent ทำงานเป็นวงรอบอย่างไร
หัวข้อที่มีชื่อว่า “coding agent ทำงานเป็นวงรอบอย่างไร”coding agent แต่ละตัวเดินตามวินัยเดียวกันในทุก session:
- กู้ context กลับมาให้เร็ว (rapid context recovery) — อ่าน git log และ progress file เพื่อเข้าใจว่ากะก่อนทำอะไรไปแล้ว รัน test end-to-end แบบพื้นฐานผ่าน dev server และซ่อมสถานะที่พังก่อนเดินหน้า
- โฟกัสทีละ feature — ทำเพียง feature เดียวต่อครั้ง ต้านแรงยั่วให้ทำหลายเรื่องพร้อมกัน
- ทดสอบแบบ end-to-end จริง — ใช้เครื่องมืออัตโนมัติ (เช่น browser automation ผ่าน Puppeteer MCP สำหรับเว็บ app) ยืนยัน feature แบบที่ผู้ใช้จริงจะเจอ ไม่ใช่แค่ unit test หรือเรียก API
- รักษาความสะอาดของสภาพแวดล้อม (environmental cleanliness) — commit ลง git พร้อมข้อความที่สื่อความ อัปเดต progress file และทิ้ง code ไว้ในสถานะที่ merge ขึ้น main ได้ (ไม่มี bug ใหญ่ โครงสร้างเป็นระเบียบ มีเอกสารครบ)
หลักการที่อยู่เบื้องหลังสรุปได้สามข้อ:
- incremental progress ดีกว่า one-shot (แตกงานเป็น feature ย่อยกันไม่ให้ context ระเบิดและสร้างจุด checkpoint ตามธรรมชาติ)
- environmental cleanliness (ทิ้งงานไว้ในสถานะที่กะถัดไปหยิบต่อได้ทันที)
- rapid context recovery (อ่าน git log/progress ก่อนเริ่มเสมอ)
ทั้งหมดนี้คือ harness ที่เปลี่ยน “วิศวกรที่ความจำเสื่อมทุกกะ” ให้กลายเป็นทีมที่ส่งงานต่อกันได้อย่างมีระเบียบ
Böckeler มองจากมุมของ ผู้ใช้ agent ในงานประจำวัน ว่าจะประกอบ Guides/Sensors อย่างไรให้ agent เชื่อถือได้ ส่วน Anthropic มองจากมุม งานที่ยาวข้ามหลาย context window ว่าจะรักษาความต่อเนื่องอย่างไร
แต่ทั้งคู่ชี้ไปที่แก่นเดียวกัน: คุณภาพของ agent อยู่ที่ ระบบรอบ model — feature list, git baseline, progress file และ end-to-end test ก็คือ Guides และ Sensors ใน version ของงาน long-running นั่นเอง
harness คือฐานของ loop engineering
หัวข้อที่มีชื่อว่า “harness คือฐานของ loop engineering”จุดที่ต้องย้ำก่อนปิดคือ harness ไม่ใช่การตั้งค่าครั้งเดียวจบ แต่เป็น practice ที่ต้องดูแลต่อเนื่อง และมันคือ ฐาน ที่ loop engineering จะมาต่อยอด เพราะหัวใจของการปล่อย agent ให้วนแก้ตัวเองคือคุณภาพของ feedback ที่มันได้รับในแต่ละรอบ
นัยที่สำคัญคือ ถ้า harness ไม่ดี ยิ่งปล่อยให้วน loop ยิ่งพังเร็ว — เพราะ agent จะวนขยายความผิดพลาดบนสัญญาณที่ผิดหรือไม่ครบ (test ที่ AI สร้างเองแบบหละหลวม, quality gate ที่ agent เลี่ยงได้, progress file ที่ไม่ตรงความจริง)
การลงทุนกับ harness ที่ดีก่อนจึงเป็นเงื่อนไขที่ทำให้ loop engineering ได้ผล เราจะเจาะเรื่องการออกแบบวงรอบนั้นในบทถัดไป loop engineering
- harness = ทุกอย่างใน agent ยกเว้นตัว model (Agent = Model + Harness) และมันคือสิ่งที่เราออกแบบได้
- แยกกลไกเป็น Guides (feedforward) กับ Sensors (feedback) และแต่ละตัวเป็น computational หรือ inferential
- หมวด behaviour ยังอ่อนที่สุด เพราะพึ่ง test ที่ AI สร้างเองมากเกินไป
- งาน long-running ต้องการ harness ที่รักษาความต่อเนื่องข้าม session: initializer + coding agent, progress file, git baseline
- harness ที่ดีนำ input ของมนุษย์ไปยังจุดที่สำคัญที่สุด และเป็นฐานที่ loop engineering จะต่อยอด
อ่านต่อ / ที่มา
หัวข้อที่มีชื่อว่า “อ่านต่อ / ที่มา”- ต้นฉบับหลัก: Harness engineering for coding agent users — Birgitta Böckeler, martinfowler.com (2 เมษายน 2026)
- แหล่งเสริม: Effective harnesses for long-running agents — Justin Young, Anthropic Engineering (26 พฤศจิกายน 2025)
- บทก่อนหน้าในซีรีส์: Context Engineering ที่ได้ผลสำหรับ AI Agents
- บทถัดไปในซีรีส์: Loop Engineering
- อ่านประกอบ: ดัน AI autonomy ในการเขียน code ได้ไกลแค่ไหน? และ ทำความเข้าใจ Spec-Driven Development