บทที่ 24 · Part 6 — Evidence-Driven Quality

AI-Assisted Go Engineering

ใช้ AI สร้าง change ภายใต้ contract, deterministic feedback, human review และผลลัพธ์ที่วัดได้

ทีมหนึ่งขอให้ AI coding assistant เพิ่ม retry ให้ endpoint ที่สร้าง settlement batch ไม่กี่นาทีต่อมา ทีมได้รับ pull request ขนาดเกือบ 600 บรรทัด มี helper ใหม่ dependency ใหม่ และ test ที่ผ่านครบ แต่เมื่อ อ่านลึกลงไป retry นั้นเรียก operation ที่สร้างข้อมูลซ้ำได้, เปลี่ยน context จาก request เป็น context.Background() และแปลง error ทุกชนิดเป็นข้อความเดียว

โค้ดชุดนี้ format ถูก compile ผ่าน และทำให้ test ที่ AI เขียนเองเป็นสีเขียวทั้งหมด ปัญหาจึงไม่ใช่ว่า AI เขียน Go syntax ไม่ได้ แต่คือเครื่องมือยืนยันเฉพาะสิ่งที่ถูกถาม ขณะที่ contract สำคัญหลายข้อไม่เคยถูกเขียน ลงในโจทย์หรือ test เมื่อความเร็วในการสร้าง code สูงขึ้น ความสามารถของทีมในการกำหนดขอบเขต ตรวจหลักฐาน และปฏิเสธ change ที่ดูดีแต่ผิดความหมายจึงสำคัญกว่าเดิม

จบบทนี้คุณจะ

  • แยกสิ่งที่ Go toolchain ตรวจได้ออกจาก semantic และ architectural judgment
  • เขียน task contract ที่มี scope, invariant, acceptance criteria และ stop condition
  • จำกัด AI-generated change ให้เป็น small batch ที่ review และ rollback ได้
  • ขอ evidence packet และออกแบบ human review ตามระดับความเสี่ยง
  • วัดผลจาก review, rework และ production outcome แทนจำนวน code ที่สร้าง

เมื่อ Generation เร็วกว่าการตรวจสอบ

บทความ Why Go is an Ideal Language for AI-Assisted Software Engineering เสนอว่า bottleneck ของงานพัฒนากำลังย้ายจากการเขียนไปสู่การ review, verification และ maintenance แนวคิดนี้มีประโยชน์ เพราะ coding assistant สามารถสร้าง implementation หลายทางเลือกหรือแก้หลายไฟล์ได้เร็วกว่า ที่ reviewer จะสร้าง mental model ของ change นั้น

แต่คำว่า “ideal” เป็น thesis ไม่ใช่ผลทดลองเปรียบเทียบ Go กับทุกภาษา บทความไม่ได้วัดว่า reviewer หา defect ใน Go ได้เร็วกว่าภาษาอื่นเท่าไร หรือ model เดียวกันสร้าง production defect ต่างกันแค่ไหน สิ่งที่นำมาใช้ได้ จึงไม่ใช่ข้อสรุปว่า Go ชนะ แต่คือคำถามว่า คุณสมบัติใดของ Go ช่วยสร้าง feedback ที่ตรวจซ้ำได้ และทีมต้อง เติม guardrail อะไรเอง

จุดตั้งต้นนี้สอดคล้องกับ Go at Google: Language Design in the Service of Software Engineering ซึ่งอธิบายว่า Go ถูกออกแบบสำหรับระบบขนาดใหญ่ dependency ที่ควบคุมได้ code ที่คนจำนวนมากต้องอ่าน และเครื่องมืออัตโนมัติที่ทำงานกับ syntax ได้ง่าย คุณสมบัติเหล่านี้สร้างประโยชน์ให้ทั้ง human contributor และ AI contributor แต่ไม่ได้ย้าย accountability ออกจากคนที่อนุมัติ change

Go สร้าง Deterministic Guardrails ไม่ใช่ Correctness Proof

AI model สร้างคำตอบแบบ probabilistic ขณะที่เครื่องมือบางส่วนของ Go ให้ feedback แบบ deterministic ต่อ source, tool version และ build configuration เดียวกัน ถ้า type ไม่ตรง compiler จะปฏิเสธเหมือนเดิมทุกครั้ง และถ้า source เดียวกันผ่าน gofmt ผลลัพธ์จะมีรูปแบบเดียวกัน ส่วน test เป็นหลักฐานที่รันซ้ำได้ก็ต่อเมื่อทีม ควบคุม clock, randomness, network, shared state และ concurrency scheduling ที่เกี่ยวข้อง ไม่ใช่เพียงเพราะ เขียนด้วย Go

Guardrailช่วยตรวจอะไรยังไม่พิสูจน์อะไร
compilersyntax, type mismatch, symbol ที่ไม่มีอยู่ และ import ที่ไม่ใช้business rule, authorization และ API ที่มีอยู่จริงแต่ถูกเรียกผิดความหมาย
gofmtcanonical formatting และ diff noisenaming, package boundary และความอ่านง่ายเชิงความคิด
go testexample ที่ test เขียนครอบคลุมbehavior ที่ไม่ได้ระบุ, test oracle ที่ผิด และ production integration
go vet / analyzerpattern ที่ analyzer รู้จักabsence of bugs และ architecture correctness
race detectordata race ที่เกิดขึ้นใน execution ที่รันdeadlock ทุกกรณี, goroutine ownership และ path ที่ test ไม่ได้เดิน
govulncheckknown vulnerability ที่ call graph น่าจะเรียกถึงzero-day, business authorization bug และ unsafe configuration

ความแตกต่างนี้สำคัญมาก เพราะ feedback สีเขียวอาจหมายถึง “หลักฐานที่มีไม่พบปัญหา” ไม่ใช่ “change นี้ถูกต้อง” รายละเอียดการจัด quality gate อยู่ใน Tool-Driven Review, judgment เรื่อง naming และ control flow อยู่ใน Readable Go ส่วน concurrency ต้องกลับไปตรวจ ownership และ cancellation ตาม Goroutine Ownership

แม้บทความต้นทางจะเป็นของผู้พัฒนา Go เอง factual claim ก็ยังต้องตรวจเทียบกับ specification ตัวอย่างเช่น Go ไม่ได้ปฏิเสธตัวแปรทุกตัวที่ไม่มี explicit initializer แต่กำหนด zero value ให้ตัวแปรเหล่านั้น และ Go 1 compatibility promise เป็น source compatibility ที่มีข้อยกเว้น เรื่อง security, unspecified behavior และ bug fix ไม่ใช่คำรับรองว่า code ทุกชุดจะไม่มีวันพัง

เครื่องมือยืนยันได้เฉพาะ Contract ที่มองเห็น

ถ้า idempotency, authorization, data ownership หรือ supported version ไม่อยู่ใน task, documentation หรือ executable test ผลลัพธ์ที่ compile ผ่านอาจยังผิด contract ได้อย่างสมบูรณ์

Task Contract มาก่อน Prompt

Prompt บอกให้ AI ทำบางอย่าง แต่ task contract บอกทั้งสิ่งที่ต้องสำเร็จและพื้นที่ซึ่งห้ามเปลี่ยน งานว่า “เพิ่ม retry ให้ SubmitBatch” เปิดทางให้ model เดา retry count, error category และ idempotency เอง งานที่ดี ต้องทำให้ decision เหล่านี้มองเห็นก่อนเริ่มแก้ code

ตัวอย่าง task contract สำหรับ settlement service:

task:
  goal: "ส่ง request cancellation ไปถึง batch store"
  supported_go:
    - "1.25.x"
    - "1.26.x"
  allowed_paths:
    - "internal/settlement"
    - "internal/httpapi"
  invariants:
    - "หนึ่ง request สร้าง batch ได้ไม่เกินหนึ่งรายการ"
    - "operation ที่สร้าง batch จะไม่ถูก retry หากไม่มี idempotency contract"
    - "public error code เดิมต้องไม่เปลี่ยน"
  non_goals:
    - "เปลี่ยน database schema"
    - "เพิ่ม third-party dependency"
    - "refactor package อื่น"
  acceptance:
    - "test แสดงว่า deadline cancellation ไปถึง store"
    - "existing module tests ผ่าน"
  stop_conditions:
    - "หยุดและถามเมื่อไม่พบ idempotency contract"
    - "หยุดและรายงานเมื่อ change ต้องออกนอก allowed paths"

goal กำหนด outcome ส่วน allowed_paths จำกัด blast radius ขณะที่ invariants และ non_goals ป้องกันการแก้ปัญหาหนึ่งด้วยการเปลี่ยน contract อื่นเงียบ ๆ acceptance ระบุหลักฐานขั้นต่ำ และ stop_conditions มีความสำคัญไม่แพ้คำสั่งให้เดินต่อ เพราะ model ที่ context ไม่พอมักเติมช่องว่างด้วย สมมติฐานที่ดูสมเหตุผล

Task contract ไม่จำเป็นต้องใช้ schema เดียวกันทุกทีม งานเล็กอาจเขียนเป็น issue template สั้น ๆ ส่วนงาน ที่แตะ public API หรือ migration อาจต้องแนบ ADR และ rollout plan ประเด็นสำคัญคือ reviewer ต้องแยกได้ว่า ส่วนใดเป็น requirement, ส่วนใดเป็น assumption และใครมีอำนาจตัดสินเมื่อข้อมูลไม่พอ

Repository Context ต้องอยู่ได้นานกว่า Chat

AI มองเห็น context เท่าที่เครื่องมือและ session ส่งให้ แต่ production contract มักกระจายอยู่ใน source, OpenAPI, migration, runbook และความทรงจำของทีม การเพิ่ม prompt ให้ยาวขึ้นเพียงอย่างเดียวไม่ทำให้ข้อมูลเหล่านี้ เป็น source of truth และ conversation history ไม่ควรเป็นที่เก็บ architectural decision ระยะยาว

จัด repository context ให้ทั้งคนและเครื่องมือค้นพบได้ เช่น:

AGENTS.md
docs/architecture/boundaries.md
docs/decisions/001-idempotent-batch-creation.md
docs/runbooks/settlement-worker.md
api/openapi.yaml
internal/settlement/contract_test.go

ไฟล์ระดับ root บอก command, supported toolchain, generated files และข้อห้ามข้าม repository architecture document อธิบาย dependency direction, ADR เก็บเหตุผลของ decision, machine-readable contract เก็บ API shape และ test เก็บ behavior ที่รันซ้ำได้ ชื่อไฟล์อาจต่างกัน แต่ข้อมูลต้อง versioned พร้อม code และมี owner ที่แก้เมื่อความจริงเปลี่ยน

อย่าเททุกอย่างลงไฟล์ instruction เดียวจน context เต็มไปด้วยกฎที่ไม่เกี่ยวกับงาน ให้เอกสารระดับบนทำหน้าที่ เป็นแผนที่ แล้วลิงก์ไป source ที่ละเอียดตาม boundary วิธีจัด standard ข้าม codebase อธิบายไว้ใน Organization-Wide Go Standards

Small Batch รักษา Review Budget

AI ทำให้ต้นทุนการ generate code ต่ำลง แต่ต้นทุนการเข้าใจ change ไม่ได้ลดตามจำนวนบรรทัด Pull request ขนาดใหญ่ยังทำให้ reviewer ต้องจำ state มากขึ้น มองเห็น unrelated refactor ยากขึ้น และแยกไม่ออกว่า test ใดพิสูจน์ requirement ใด

หลักเริ่มต้นคือ 1 change มี 1 behavioral purpose ถ้างานต้องแก้ contract, migration และ runtime rollout ให้แยก tracer step ที่แต่ละขั้น build ได้ ทดสอบได้ และย้อนกลับได้ งาน mechanical เช่น rename อาจแตะหลายไฟล์ แต่ควรแยกจาก behavior change เพื่อให้ diff บอกเจตนาเดียว

ระดับความเสี่ยงตัวอย่างขอบเขตที่เหมาะกับ AI
ต่ำdocumentation, local rename, repetitive test fixtureสร้าง diff และหลักฐานได้ โดยคนตรวจความหมายตามปกติ
กลางpublic error mapping, dependency update, cache behavior, concurrent control flowต้องมี contract test, focused review และ rollback ชัด
สูงauthorization, schema migration, retry ของ state-changing operation, money movementใช้ช่วยค้นและเสนอทางเลือก แต่คนที่รับผิดชอบต้องกำหนด contract และอนุมัติทุก decision

ระดับความเสี่ยงไม่ได้ขึ้นกับจำนวนบรรทัดอย่างเดียว การเปลี่ยน boolean condition ใน authorization อาจมีเพียง 1 บรรทัดแต่สำคัญกว่า generated mapper หลายร้อยบรรทัด ให้ใช้ business impact, reversibility, data mutation, external contract และความสามารถในการทดสอบเป็นตัวกำหนด review budget

AI ไม่ใช่ผู้อนุมัติการตัดสินใจเรื่องเงินหรือ Compliance

เงื่อนไข money movement, authorization, retention และ compliance ต้องมาจากเจ้าของที่รับผิดชอบ พร้อมหลักฐานและวันที่ AI ช่วยอ่านเอกสารหรือสร้าง test ได้ แต่ห้ามให้ model คิด policy แทนคน

Feedback Loop ที่บังคับให้ Agent คืนหลักฐาน

Workflow ที่ปลอดภัยไม่ใช่ “prompt แล้วรอ code” แต่เป็น loop ที่หยุดได้หลายจุด:

ถ้า check ล้ม ให้กลับไปแก้ diff โดยยังรักษา task contract เดิม ถ้า reviewer พบว่า requirement ไม่พอ ให้กลับไปแก้ contract แทนการปล่อยให้ agent ขยาย implementation เพื่อเดา intent การย้อนกลับคนละจุดนี้ช่วย แยก implementation defect ออกจาก requirement defect

Fast loop ที่ agent และ developer รันระหว่างทำงานอาจประกอบด้วย:

go fmt ./...
go test ./...
go vet ./...
go mod tidy -diff
go mod verify

Change ที่มีความเสี่ยงสูงขึ้นจึงเพิ่ม check ตาม threat และ build configuration:

go test -race ./...
go tool govulncheck ./...
go fix -diff ./...

ถ้า change แตะ parser หรือ untrusted input และมี fuzz target อยู่แล้ว ให้รัน focused fuzzing ตามเวลาที่ทีม กำหนด ส่วน generated code ต้องสร้างใหม่ใน clean checkout แล้วตรวจว่าไม่มี diff:

go test -fuzz=FuzzDecode -fuzztime=30s ./internal/httpapi
go generate ./...
git diff --exit-code

Compatibility check ต้องรัน module tests บน latest patch ของ Go 1.25 และ Go 1.26 ตาม baseline ของคอร์ส ไม่ใช่เพียง build ด้วย toolchain ที่ agent มีอยู่ในเครื่อง รายละเอียดการออกแบบ fuzz target อยู่ใน Fuzzing and Secure Boundaries

ตัวอย่างนี้สมมติว่า govulncheck ถูก pin เป็น tool dependency ตามบท Tool-Driven Review ส่วน go fix -diff ใช้ Go 1.26 เพื่อ preview modernizers ก่อนแก้ source จริง เอกสาร go fix ระบุว่า LLM มักสร้าง idiom จาก training data รุ่นเก่า แม้ถูกบอกให้ใช้ feature ใหม่ จึงควรให้ analyzer ที่รู้ toolchain version ตรวจแทนการหวังว่า prompt จะชนะ training distribution

อย่ารวม command ทั้งหมดเป็น gate เดียวโดยไม่ดูความเสี่ยง local documentation change ไม่จำเป็นต้องรัน integration environment ทั้งระบบ แต่ change ที่แตะ concurrent state ควรมี race และ cancellation test ส่วน dependency change ต้องตรวจ module graph, license และ vulnerability เพิ่มเติม

Evidence Packet ไม่ใช่คำว่า Done

เมื่อ AI บอกว่า “เรียบร้อยแล้ว” reviewer ยังไม่รู้ว่ามันแก้อะไร รันอะไร และหลีกเลี่ยง path ใด ให้กำหนด handoff contract ที่ตอบคำถามเหล่านี้ในรูปแบบสั้นและตรวจซ้ำได้:

change:
  behavior: "request cancellation ถูกส่งไปถึง batch store"
  files_changed:
    - "internal/settlement/service.go"
    - "internal/settlement/service_test.go"
  assumptions:
    - "store คืน context cancellation โดยไม่แปลง error"
  verification:
    - command: "go test ./internal/settlement"
      result: "passed"
    - command: "go vet ./internal/settlement"
      result: "passed"
  untested_paths:
    - "database driver cancellation ใน integration environment"
  residual_risks:
    - "ยังไม่ได้วัดเวลาที่ connection คืนสู่ pool"
  reviewer_decisions:
    - "store owner ยืนยันว่า change นี้ไม่เพิ่ม retry"
  rollback: "revert change นี้ได้โดยไม่ย้อน schema"

Evidence packet ไม่ใช่หลักฐานด้วยตัวมันเอง เพราะ AI อาจสรุปผิดหรือรายงาน command ที่ไม่ได้ครอบคลุมจริง CI ต้อง rerun mandatory checks ใน environment ที่ทีมควบคุม Reviewer ใช้ packet เป็นแผนที่เพื่อเปิด diff, ดู test oracle และตรวจ residual risk ไม่ใช่ใช้เป็นใบรับรองอัตโนมัติ

ถ้า change มี generated code ให้แนบ source และ generation command ถ้ามี benchmark ให้เก็บ baseline, command, environment และ comparison artifact ถ้ามี migration ให้ระบุ forward, backward compatibility และ rollback limitation หลักฐานต้องเปลี่ยนตามความเสี่ยง ไม่ใช่ template ยาวเท่ากันทุกงาน

Failure Modes ของ AI-Generated Go

Go ลด error surface บางชนิด แต่รูปแบบผิดพลาดต่อไปนี้ยังเกิดได้แม้ code ดู idiomatic:

  • Hallucinated API — compiler จับ method หรือ field ที่ไม่มี แต่จับไม่ได้เมื่อ model เลือก API ที่มีอยู่ จริงแต่มี lifecycle หรือ error semantics คนละแบบ
  • Stale idiom — model สร้าง pattern เก่าจาก corpus จำนวนมาก ให้ analyzer และ versioned docs ช่วยตรวจ แทนการบังคับด้วยคำว่า “modern Go” กว้าง ๆ
  • Dependency invention — model เลือก library ที่จำจาก training data โดยไม่รู้ maintenance, license หรือ version ปัจจุบัน Standard library ลดความจำเป็นบางส่วน แต่ dependency ใหม่ยังต้องมีเหตุผลและ owner
  • Test mirrors implementation — AI อ่าน code แล้วเขียน test ที่ยืนยันทุก branch ตาม implementation เดิม ทำให้ test ผ่านแม้ requirement ผิด Test ที่มีค่าต้องเริ่มจาก observable contract
  • Context detachment — การใช้ context.Background() กลาง request path ทำให้ compile ผ่าน แต่ตัด cancellation และ deadline ออกจาก caller
  • Unowned goroutine — go statement ถูก syntax และ race detector อาจเงียบใน test run แต่ไม่มีเงื่อนไข หยุดหรือช่องทางส่ง error กลับ
  • Helpful refactor — agent เปลี่ยนชื่อ ย้าย package หรือเพิ่ม abstraction ข้างเคียง ทำให้ behavioral diff ถูกซ่อนใน mechanical noise

Pattern เหล่านี้ชี้ว่าคำสั่ง “เขียน idiomatic Go” กว้างเกินไป Repository ต้องมี contract ที่ค้นพบได้ toolchain ต้องรายงาน mechanical evidence และ reviewer ต้องอ่าน call site, failure path, resource ownership และ boundary เหมือน review code ของคน

Human Review ตามระดับความเสี่ยง

Reviewer ไม่ควรตรวจทุกบรรทัดด้วยน้ำหนักเท่ากัน เริ่มจาก task contract แล้วไล่คำถามที่เครื่องมือยังตอบไม่ได้:

  1. Behavior ที่เปลี่ยนตรงกับ goal และมี behavior นอก scope แอบเข้ามาหรือไม่
  2. Invariant ใดได้รับผล และ test พิสูจน์จาก public behavior หรือเพียง mirror implementation
  3. Error, retry, timeout และ cancellation รักษา caller decision เดิมหรือไม่
  4. Resource และ goroutine ทุกตัวมี owner, limit และ cleanup path หรือไม่
  5. Dependency หรือ public API ใหม่เพิ่ม compatibility และ supply-chain commitment อะไร
  6. Change deploy และ rollback ได้โดยไม่ทำให้ data หรือ consumer อยู่ใน state ครึ่งกลางหรือไม่

AI สามารถช่วย reviewer สรุป diff, ค้น call site หรือเสนอ missing tests ได้ แต่ไม่ควรเป็น reviewer คนเดียวของ change ที่มันสร้าง เพราะ model และ review prompt อาจมี blind spot ชุดเดียวกัน สำหรับ high-risk boundary ให้ มี domain owner หรือ security/data owner ตามประเภทของ decision ไม่ใช่เพิ่ม approval ทั่วไปโดยไม่มีคำถามเฉพาะ

หลักง่าย ๆ คือ คน merge เป็นเจ้าของผลลัพธ์ การบอกว่า AI เป็นผู้เขียนไม่ลดความรับผิดชอบต่อ behavior, security, operations หรือ maintenance และ reviewer มีสิทธิ์ขอให้ลด diff หรือเขียน task contract ใหม่เมื่อ change ใหญ่เกินกว่าจะอธิบายได้

วัด Outcome ไม่วัดปริมาณ Code

จำนวน suggestion ที่ accept, token ที่ใช้ หรือบรรทัดที่สร้างวัด activity แต่ไม่ตอบว่าทีมส่งมอบคุณค่าเร็วขึ้น โดยไม่เพิ่มความเสี่ยงหรือไม่ ก่อน pilot ให้เก็บ baseline แยกตามประเภทงานและพิจารณา metric เหล่านี้:

  • cycle time ตั้งแต่รับ task ถึง merge
  • เวลาที่ใช้ review และจำนวนรอบที่ขอแก้
  • rework หลัง merge, revert และ change failure
  • escaped defect หรือ incident ที่เชื่อมกับ change
  • pull request size และ unrelated change rate
  • dependency หรือ public surface ที่เพิ่มขึ้น
  • เวลาที่ developer ใช้ทำความเข้าใจและแก้ output
  • compute, license และ operational cost ของเครื่องมือ

ผลการวิจัยปัจจุบันเตือนว่าไม่มี productivity number เดียว Go Developer Survey 2025 พบว่าผู้ตอบ 53% ใช้ AI development tools ทุกวัน แต่ปัญหาหลักยังเป็น non-functional หรือ low-quality code ขณะที่ Google enterprise RCT ประเมิน speedup ประมาณ 21% ในงานและ environment ที่ศึกษาโดยมี confidence interval กว้าง ส่วน METR early-2025 RCT พบ slowdown 19% สำหรับ experienced open-source developers ในบริบทของงานวิจัยนั้น

ตัวเลขเหล่านี้ไม่ขัดกันเมื่อ population, task, tool และช่วงเวลาต่างกัน METR February 2026 update ยังอธิบายว่าเครื่องมือรุ่นใหม่ อาจช่วยเร็วขึ้น แต่ selection effect ทำให้ประมาณขนาดผลได้ยาก ข้อสรุปที่ใช้ได้จึงเป็นให้ทีมทดลองกับงานจริง เปรียบเทียบ task category ที่ใกล้กัน และยอมรับผลว่า AI อาจคุ้มกับ boilerplate แต่ไม่คุ้มกับ brownfield change บางชนิด

DORA 2025 เรียก AI ว่า amplifier ของระบบองค์กร ถ้า test, platform, documentation และ review loop ดี AI ช่วยขยายความสามารถนั้น แต่ถ้า requirement คลุมเครือ และ deployment feedback ช้า AI จะขยายจำนวน change ที่ต้องรอและจำนวน defect ที่หลุดผ่านไปด้วย

Review Lab: PR ที่ Compile ผ่าน

สมมติ task เดิมเขียนเพียงว่า “เพิ่ม retry ให้ Submit เพื่อให้ทนต่อ store error” และ AI ส่ง code นี้มา:

func (s *Service) Submit(
    ctx context.Context,
    req SubmitRequest,
) (Batch, error) {
    var lastErr error
    for range 3 {
        batch, err := s.store.Create(context.Background(), req)
        if err == nil {
            return batch, nil
        }
        lastErr = err
    }

    return Batch{}, fmt.Errorf("submitting batch: %w", lastErr)
}

Code นี้ compile ได้ และ test ที่ mock ให้ store fail 2 ครั้งก่อนสำเร็จก็ผ่าน แต่ reviewer ยังต้องหยุด merge:

  • parameter ctx ไม่ถูกใช้ จึงทำให้ request deadline ไม่เดินทางไปยัง store
  • Create เป็น state-changing operation แต่ task ไม่บอกว่ามี idempotency key หรือ unique constraint
  • retry ทุก error รวม validation, conflict และ permanent error โดยไม่แยก caller decision
  • mock ที่ fail ก่อน success ไม่จำลองกรณี store commit สำเร็จแต่ response สูญหาย
  • retry count 3 ไม่มี owner, evidence หรือ relationship กับ latency budget

การแก้ที่ถูกไม่ใช่เปลี่ยน context.Background() เป็น ctx แล้ว merge ทันที แต่ต้องย้อนกลับไปเขียน task contract ว่าจะ retry failure ชนิดใด operation มี idempotency guarantee ตรงไหน และ latency budget อนุญาต กี่ attempt ถ้ายังตอบไม่ได้ stop condition ต้องหยุด implementation ไว้ก่อน รายละเอียด error vocabulary อยู่ใน Errors as Public Contracts และการส่ง deadline อยู่ใน Context, Resources and Cancellation

Pilot ก่อนขยายการใช้งาน

เริ่มจากงานที่ขอบเขตชัดและมี feedback เร็ว เช่น documentation, test fixture, local refactor หรือการเพิ่ม validation ที่มี contract test อยู่แล้ว เลือกกลุ่มงานเปรียบเทียบ เก็บ baseline และกำหนด owner ของ incident ก่อนเปิดใช้กับ boundary ที่เสี่ยงสูง

ระหว่าง pilot ให้ทบทวนทั้ง false confidence และ unnecessary friction ถ้า evidence template ยาวกว่างานจริง ให้ลด field ที่ไม่ช่วยตัดสินใจ ถ้า agent มักเปลี่ยนไฟล์นอก scope ให้ทำ allowlist หรือแยก task เล็กลง ถ้า review time เพิ่มแม้ generation time ลด ให้จำกัด batch size และเลือกประเภทงานใหม่

เมื่อขยายการใช้งาน อย่าบังคับเครื่องมือหรือ productivity target เดียวกับทุกทีม ให้กำหนด organizational minimum ที่ตรวจได้ เช่น source ต้องอยู่ใน version control, mandatory CI รันอิสระ, high-risk change มี เจ้าของ decision และ AI-generated change ใช้มาตรฐาน review เดียวกับ human-generated change ส่วน tool, model และ interaction style เปลี่ยนได้ตามงานและข้อจำกัดด้านข้อมูล

Checklist ก่อน Merge AI-Assisted Change

  • task มี goal, non-goals, invariants, acceptance criteria และ stop conditions
  • repository context ชี้ไปยัง contract และ decision ที่เป็นปัจจุบัน
  • diff มี behavioral purpose เดียวหรือแยก mechanical change ออกจากกันแล้ว
  • agent ระบุ assumptions, untested paths, residual risks และ rollback
  • CI rerun checks ที่จำเป็นโดยไม่เชื่อรายงานจาก agent เพียงอย่างเดียว
  • reviewer ตรวจ call site, failure path, context, ownership และ external boundary
  • dependency, generated code และ public API ใหม่มีเหตุผลกับ owner
  • money, authorization, compliance และ migration decision ได้รับอนุมัติจากคนที่รับผิดชอบ
  • metric วัด review, rework และ production outcome ไม่ใช่จำนวน code ที่สร้าง

สรุป

Go เหมาะกับ AI-assisted engineering เพราะมี syntax ที่วิเคราะห์ง่าย รูปแบบมาตรฐาน และ toolchain ที่ให้ feedback ตรวจซ้ำได้ แต่ข้อได้เปรียบจะเกิดขึ้นต่อเมื่อทีมเขียน contract ให้มองเห็น จำกัด change ให้ review ได้ และให้มนุษย์รับผิดชอบความหมายของระบบ AI เป็น contributor ที่เร็ว ไม่ใช่แหล่งความจริงหรือผู้อนุมัติสุดท้าย

อ่านเพิ่ม: go fmt your code, Using go fix to modernize Go code, Go Vulnerability Management และ Measure, Profile and Optimize