Claude Code สำหรับข้อผิดพลาด CI: ให้พรอมต์ให้อ้างบรรทัดที่ล้ม แนะนำการแก้ที่เล็กที่สุด และเพิ่ม regression test เพื่อป้องกันไม่ให้เกิดซ้ำ

go test ./..., npm test, flutter test, golangci-lint run)\n- พาธไฟล์ที่อ้างถึงใน error และคอนฟิกที่เกี่ยวข้อง (test config, linter config, build scripts)\n- อะไรเปลี่ยนไปเมื่อเร็ว ๆ นี้: สรุป diff ของ PR, การ bump dependency, แก้ CI config\n- มัน flaky ไหม: ถ้ามีการรันสองสามครั้งล้มและหนึ่งครั้งผ่าน ให้บอก\n\nเพิ่มข้อจำกัดด้วยคำง่าย ๆ ถ้าคุณต้องการการแก้เล็ก ๆ ให้บอก: ห้าม refactor, ห้ามเปลี่ยนพฤติกรรมถ้าไม่จำเป็น, จำกัดแพตช์เฉพาะจุดที่ล้ม\n\nตัวอย่างง่าย: CI ล้มที่ขั้น lint หลังจาก bump dependency แปะ lint output เริ่มจากคำเตือนแรก ใส่คำสั่งที่ CI ใช้ และบอกการเปลี่ยนเวอร์ชันของแพ็กเกจเพียงรายการเดียว พอให้แนะนำการปรับคอนฟิกบรรทัดเดียวหรือการเปลี่ยนโค้ดเล็ก ๆ แทนการปรับฟอร์แมตทั้งรีโพ\n\nถ้าคุณต้องการสิ่งที่คัดลอกไปแปะได้ โครงสร้างนี้มักเพียงพอ:\n\ntext\nCI command:\n\nFailing output (full):\n\nRecent changes:\n\nConstraints (smallest fix, no refactor):\n\nFlaky? (runs attached):\n\n\n## พรอมต์กฎที่บังคับให้มันอ่านข้อความที่ล้ม\n\nเมื่อโมเดลพลาดเป้าบนการแตกของ CI มักเป็นเพราะพรอมต์ให้มันเดา หน้าที่คุณคือทำให้มันแสดงกระบวนการโดยใช้ผลลัพธ์ที่ล้มจริง ๆ แล้วยึดการเปลี่ยนแปลงที่เล็กที่สุดที่ทำให้งานผ่าน\n\n### กฎที่ทำให้โมเดลตรงไปตรงมา\n\nบังคับหลักฐานและแผนเล็ก ๆ พรอมต์ที่ดีบังคับห้าข้อ:\n\n- อ้างบรรทัดที่ล้มจาก CI log (errors, stack trace, file:line) และระบุว่า "ฉันกำลังใช้บรรทัดเหล่านี้"\n- ให้การวินิจฉัยเป็นประโยคเดียว ไม่มีการอ่อนๆ\n- เสนอแผนแพตช์เล็กที่สุด 1–3 แก้ไข โดยระบุไฟล์ที่จะแตะจริง ๆ\n- ห้ามเปลี่ยนที่ไม่เกี่ยวข้อง (ห้ามฟอร์แมต, rename, refactor, bump dependency) เว้นแต่คุณอนุญาต\n- ระบุสิ่งที่ไม่แน่ใจและข้อมูลเดียวที่จะยืนยันการวินิจฉัย\n\nความไม่แน่นอนเป็นเรื่องปกติ แต่การไม่เปิดเผยความไม่แน่นอนคือสิ่งที่เสียเวลา\n\n### เฟรกเมนต์พรอมต์พร้อมวาง\n\nวางส่วนนี้ไว้บนสุดของคำถาม CI ของคุณ:\n\ntext\nUse ONLY the evidence in the CI output below.\n1) Quote the exact failing lines you are using.\n2) Give ONE sentence: the most likely cause.\n3) Propose the smallest fix: 1-3 edits, with file paths.\n4) Do NOT do formatting/renames/refactors or "cleanup".\n5) List uncertainties + the one extra detail that would confirm the diagnosis.\n\n\nถ้า log บอก "expected 200, got 500" พร้อม stack trace ไปที่ user_service.go:142 โครงสร้างนี้จะผลักให้คำตอบไปที่ฟังก์ชันนั้นและแก้เล็ก ๆ เช่น guard หรือจัดการ error แทนการออกแบบใหม่ของ endpoint\n\n## เท็มเพลตพรอมต์คัดลอก-วางสำหรับความล้มเหลว CI\n\nพรอมต์ที่เร็วที่สุดคือพรอมต์ที่บังคับให้อ้าง log อยู่ในขอบเขต และหยุดเมื่อขาดข้อมูล\n\ntext\nYou are helping me fix a CI failure.\n\nRepo context (short):\n- Language/framework:\n- Test/build command that failed: <PASTE THE EXACT COMMAND>\n- CI environment (OS, Node/Go/Python versions, etc.):\n\nFailing output (verbatim, include the first error and 20 lines above it):\n<PASTE LOG>\n\nConstraints:\n- Propose the smallest possible code change that makes CI pass.\n- Do NOT rewrite/refactor unrelated code.\n- Do NOT touch files you do not need for the fix.\n- If behavior changes, make it explicit and justify why it is correct.\n\nStop rule (no guessing):\n- If the log is incomplete or you need more info (missing stack trace, config, versions, failing test name), STOP and ask only the minimum questions needed.\n\nYour response format (follow exactly):\n1) Evidence: Quote the exact log lines that matter.\n2) Hypothesis: Explain the most likely cause in 2-4 sentences.\n3) Smallest fix: Describe the minimal change and why it addresses the evidence.\n4) Patch: Provide a unified diff.\n5) Follow-up: Tell me the exact command(s) to rerun locally to confirm.\n\nThen, write ONE regression test (or tweak an existing one) that would fail before this fix and pass after it, to prevent the same failure class.\n- Keep the test focused. No broad test suites.\n- If a test is not feasible, explain why and propose the next-best guardrail (lint rule, type check, assertion).\n\n\nสองรายละเอียดที่ลดการคุยซ้ำ:\n\n- ใส่คำสั่งที่ล้มและข้อผิดพลาดแรกให้ชัดเจน (ไม่ใช่แค่สรุปสุดท้าย)\n- ถ้ามีหลายความล้ม ให้บอกว่าจะแก้อันไหนก่อน (ปกติคือความล้มครั้งแรกใน log)\n\n## วิธีผลักให้ได้การแก้เล็ก ๆ ไม่ใช่การเขียนใหม่หมด\n\nวิธีที่เร็วที่สุดที่จะเสียเวลา คือยอมรับการเปลี่ยนแปลงแบบ "cleanup" ที่แก้หลายจุดพร้อมกัน นิยาม "เล็กที่สุด" ล่วงหน้า: แพตช์เล็กที่สุดที่ทำให้งานที่ล้มผ่าน และมีความเสี่ยงต่ำสุดและตรวจสอบเร็วที่สุด\n\nกฎง่าย ๆ ที่ใช้ได้: แก้ symptom ก่อน แล้วค่อยพิจารณา refactor ถ้าจำเป็น ถ้า log ชี้ไปที่ไฟล์เดียว ฟังก์ชันเดียว import หาย หรือกรณีพิเศษ ให้มุ่งไปที่จุดนั้น หลีกเลี่ยงการแก้แบบ "ในเมื่อทำแล้ว"\n\nถ้าต้องการทางเลือก ให้ขอแค่สองแบบ: "แก้ที่ปลอดภัยที่สุดแบบ minimal" vs "แก้ที่เร็วที่สุดแบบ minimal" คุณต้องการ tradeoff ไม่ใช่เมนู\n\nยังบังคับการตรวจสอบท้องถิ่นให้ตรงกับ CI: ขอคำสั่งเดียวกับที่ pipeline รัน (หรือเทียบเท่าที่ใกล้เคียง) เพื่อยืนยันภายในไม่กี่นาที:\n\nbash\n# run the same unit test target CI runs\nmake test\n# or the exact script used in CI\nnpm test\n\n\nถ้าคำตอบเสนอการเปลี่ยนใหญ่ ให้ตอบกลับว่า: "แสดงแพตช์เล็กที่สุดที่แก้ assertion ที่ล้ม โดยไม่เปลี่ยนฟอร์แมตหรือชื่อไฟล์ที่ไม่เกี่ยวข้อง"\n\n## การพรอมต์สำหรับเทสต์ติดตามผลที่ป้องกันการเกิดซ้ำ\n\nการแก้โดยไม่มีเทสต์คือการเดิมพันว่าจะไม่เจอปัญหาเดิมอีกเสมอ ขอเทสต์ติดตามผลเสมอที่ล้มก่อนแพตช์และผ่านหลังแพตช์\n\nเจาะจงว่า "ดี" คืออะไร:\n\n- ถ้าล้มเพราะ unit test crash ให้เขียนเทสต์ใหม่หรือเสริม assertion ที่เข้มขึ้น\n- ถ้าล้มเพราะ build, lint หรือ formatting ให้เพิ่มเช็คที่บังคับกฎนั้นไว้\n\nรูปแบบที่มีประโยชน์: ระบุให้ครบ 4 อย่าง: ที่วางเทสต์, ชื่อไฟล์เทสต์, พฤติกรรมที่ครอบคลุม, และบันทึกสั้น ๆ ว่าทำไมเทสต์นี้ป้องกันการเกิดซ้ำ\n\nคัดลอกเพื่อเพิ่มเติม:\n\n- เขียน regression test หนึ่งรายการที่ล้มบน branch main ปัจจุบันและผ่านหลังแก้\n- ให้มันครอบคลุมคลาสของความล้ม ไม่ใช่แค่บรรทัดเดียวที่แตก\n- วางเทสต์ใน: <path or folder> ตั้งชื่อตาม convention ของคุณ\n- ถ้าเป็นกฎ lint/build ให้เพิ่มหรือตั้งกฎที่บังคับมัน\n- เพิ่ม 2–3 ประโยค: ทำไมเทสต์นี้จะจับบั๊กที่คล้ายกันได้ในอนาคต\n\nตัวอย่าง: CI แสดง panic เมื่อ handler API ได้ ID ว่าง อย่าขอแค่ "เทสต์บรรทัดนี้" ให้ขอเทสต์ที่ครอบ ID ไม่ถูกต้อง (ว่าง, whitespace, รูปแบบผิด) แพตช์เล็กที่สุดอาจเป็น guard clause ที่คืน 400 เทสต์ติดตามผลควรตรวจพฤติกรรมสำหรับ input ไม่ถูกต้องหลายแบบ เพื่อให้การ refactor parsing ในอนาคตทำให้ CI ล้มทันที\n\nถ้าโปรเจกต์มี convention ของเทสต์ ให้บอกมัน หากไม่มี ให้ขอให้ทำตามเทสต์ที่อยู่ใกล้เคียงในแพ็กเกจ/โฟลเดอร์เดียวกัน และให้เทสต์ใหม่เรียบง่ายอ่านง่าย\n\n## เวิร์กโฟลว์ขั้นตอนที่นำกลับมาใช้ซ้ำได้\n\n### 1) ให้มันรับความล้มเดิมโดยตรง\n\nแปะส่วนของ log ที่มีข้อผิดพลาดและ ~20–40 บรรทัดด้านบน พร้อมคำสั่งที่ CI รันและรายละเอียดสภาพแวดล้อมสำคัญ (OS, เวอร์ชัน runtime, flags สำคัญ)\n\nแล้วขอให้มันสรุปเป็นภาษาเรียบง่ายและชี้บรรทัดใน output ที่พิสูจน์ ถ้ามันไม่สามารถอ้าง log ได้ แปลว่ามันยังไม่ได้อ่านจริง\n\n### 2) บังคับให้แพตช์เล็กที่สุดก่อน\n\nขอการเปลี่ยนโค้ดที่เล็กที่สุดที่ทำให้คำสั่งล้มผ่าน ดันกลับทุกการ refactor ก่อนนำไปใช้ ให้มันระบุ:\n\n- ไฟล์ที่จะถูกแตะ\n- พฤติกรรมที่เปลี่ยนแปลงอย่างชัดเจน\n- สิ่งที่จะไม่เปลี่ยน\n\n### 3) รันคำสั่งเดียวกันอีกครั้ง รักษา loop ให้แคบ\n\nใช้แพตช์และรันคำสั่งที่ล้มแบบเดียวกับ CI ในเครื่องของคุณ (หรือในงาน CI เดิมถ้านั่นเป็นทางเดียว) ถ้ายังล้ม ให้แปะ output ใหม่และทำซ้ำ การรักษาขอบเขตบริบทเล็กช่วยให้คำตอบโฟกัส\n\n### 4) เพิ่ม regression test สำหรับคลาสของความล้ม\n\nเมื่อผ่าน ให้เพิ่มเทสต์ติดตามผลหนึ่งรายการที่ล้มก่อนแพตช์และผ่านหลังแพตช์ จำกัดเทสต์: หนึ่งเทสต์, หนึ่งเหตุผล\n\nรันคำสั่งอีกครั้งพร้อมเทสต์ใหม่เพื่อยืนยันว่าคุณไม่ได้แค่ปิดเสียง error\n\n### 5) ปิด PR ด้วยชุดข้อมูลที่ชัดเจน\n\nขอข้อความ commit สั้น ๆ และคำอธิบาย PR ที่รวมว่าอะไรล้ม, อะไรเปลี่ยน, คุณยืนยันอย่างไร, และเทสต์อะไรที่ป้องกันการเกิดซ้ำ รีวิวจะเร็วขึ้นเมื่อเหตุผลชัดเจน\n\n## ตัวอย่างสมจริง: จาก log ที่ล้มถึงการแก้และเทสต์\n\nความล้มที่พบบ่อย: ทุกอย่างทำงานในเครื่อง แต่การเปลี่ยนเล็ก ๆ ทำให้เทสต์ล้มบน runner CI ตัวอย่างนี้มาจาก Go API ที่ handler เริ่มรับค่า date-only (2026-01-09) แต่โค้ดยัง parse เฉพาะ RFC3339 เต็มรูปแบบ\n\nนี่คือตัวอย่างสั้น ๆ ที่ควรแปะ (เก็บให้สั้นแต่ใส่บรรทัด error):\n\ntext\n--- FAIL: TestCreateInvoice_DueDate (0.01s)\n invoice_test.go:48: expected 201, got 400\n invoice_test.go:49: response: {\"error\":\"invalid due_date: parsing time \\\"2026-01-09\\\" as \\\"2006-01-02T15:04:05Z07:00\\\": cannot parse \\\"\\\" as \\\"T\\\"\"}\nFAIL\nexit status 1\nFAIL\tapp/api\t0.243s\n\n\nใช้พรอมต์ที่บังคับหลักฐานและแพตช์เล็ก ๆ ดังนี้:\n\ntext\nYou are fixing a CI failure. You MUST use the log to justify every claim.\n\nContext:\n- Language: Go\n- Failing test: TestCreateInvoice_DueDate\n- Log snippet:\n<PASTE LOG>\n\nTask:\n1) Quote the exact failing line(s) from the log and explain the root cause in 1-2 sentences.\n2) Propose the smallest possible code change (one function, one file) to accept both RFC3339 and YYYY-MM-DD.\n3) Show the exact patch.\n4) Add one regression test that fails before the fix and passes after.\nReturn your answer with headings: Evidence, Minimal Fix, Patch, Regression Test.\n\n\nคำตอบที่ดีจะชี้ไปที่ mismatch ของ layout ที่ใช้ parse แล้วทำการเปลี่ยนเล็ก ๆ ในฟังก์ชันหนึ่ง (เช่น parseDueDate ใน invoice.go) ให้ลอง parse RFC3339 ก่อนแล้ว fallback ไปที่ 2006-01-02 ไม่ต้อง refactor หรือเพิ่มแพ็กเกจใหม่\n\nเทสต์ติดตามคือรั้วป้องกัน: ส่ง due_date: "2026-01-09" และคาดว่า 201 หากใครต่อใคร later ลบ fallback การเปลี่ยน parsing CI จะล้มทันทีด้วย class เดิม\n\n## ความผิดพลาดทั่วไปที่เสียเวลา (และวิธีหลีกเลี่ยง)\n\nวิธีที่เร็วที่สุดจะเสียชั่วโมงคือให้มุมมองปัญหาที่ครอบตัดเกินไป Log CI มีเสียงรบกวน แต่ส่วนที่มีประโยชน์มักอยู่ 20 บรรทัดขึ้นไปเหนือข้อผิดพลาดสุดท้าย\n\nกับดักหนึ่งคือแปะแค่บรรทัดแดงสุดท้าย (เช่น "exit 1") ขณะที่สาเหตุจริงอยู่ก่อนหน้า (env var หาย เทสต์ snapshot ล้ม หรือเทสต์แรก crash) วิธีแก้: รวมคำสั่งที่ล้มและหน้าต่าง log ที่มีข้อผิดพลาดแรก\n\nกับดักอื่นคือให้โมเดล "tidy up" ระหว่างทาง การเปลี่ยนฟอร์แมต, bump dependency, หรือ refactor ทำให้รีวิวยากและเสี่ยงที่จะทำอย่างอื่นพัง วิธีแก้: ล็อกขอบเขตเป็นการเปลี่ยนเล็กที่สุดและปฏิเสธสิ่งที่ไม่เกี่ยวข้อง\n\nรูปแบบที่ควรระวัง:\n\n- แปะแค่บรรทัดสุดท้าย: ให้รวมคำสั่งที่ล้มและข้อผิดพลาดแรก\n- ให้มันแก้ dependencies หรือไฟล์ที่ไม่เกี่ยว: กำหนด minimal diff และเหตุผลสำหรับทุกไฟล์ที่แตะ\n- ยอมรับการแก้ที่ไม่ได้ตรวจกับคำสั่ง CI: ให้รันคำสั่งเดียวกันเพื่อตรวจสอบ\n- เขียนเทสต์ที่ยังผ่านเมื่อบั๊กกลับมา: ขอเทสต์ที่ล้มบนโค้ดเก่าและผ่านบนโค้ดแก้\n- ผสม flaky กับ regression จริง: ตัดสินว่ามันเป็น nondeterministic หรือ logic ที่คงที่ แล้วจัดการตามนั้น\n\nถ้าคาดว่า flaky อย่าปิดด้วย retry แต่เอาความสุ่มออก (เวลา, RNG, temp dirs แยก) เพื่อให้สัญญาณชัด\n\n## ตรวจสอบด่วนก่อน push แพตช์\n\nก่อน push ให้ทำ sanity pass สั้น ๆ เป้าหมายคือยืนยันว่าสิ่งที่เปลี่ยนจริง เล็ก และทำซ้ำได้ ไม่ใช่แค่ผ่านด้วยโชค\n\n- Evidence: คำอธิบายอ้างบรรทัดข้อผิดพลาดจริงหรือไม่?\n- Scope: การเปลี่ยนจำกัดอยู่ในสิ่งที่จำเป็นหรือไม่?\n- Causality: อธิบายได้ไหมว่าทำไมการเปลี่ยนนี้ทำให้ผ่าน?\n- Repro: รันคำสั่ง CI เดิมหรือไม่ (flag, working dir เหมือนกัน)?\n- Regression: เทสต์ใหม่ล้มก่อนแก้และผ่านหลังแก้หรือไม่?\n\nสุดท้าย รันชุดคำสั่งที่กว้างขึ้นเล็กน้อยกว่างานที่ล้มเดิม (เช่น lint + unit tests) แพตช์ที่ผ่านงานเดิมแต่ทำให้เป้าหมายอื่นพังเป็นกับดักทั่วไป\n\n## ขั้นตอนถัดไป: ทำให้เวิร์กโฟลว์นี้เป็นนิสัย\n\nถ้าต้องการให้มันประหยัดเวลาเป็นสัปดาห์ต่อสัปดาห์ ให้ถือพรอมต์และโครงสร้างคำตอบเป็นกระบวนการทีม เป้าหมายคือลงอินพุตที่ทำซ้ำได้ ผลลัพธ์ที่ทำซ้ำได้ และข้อผิดพลาดน้อยลง\n\nแปลงพรอมต์ที่ดีที่สุดของคุณเป็นสแนิปต์ในรีโพและปักหมุดในแชททีม กฎง่าย ๆ ที่ใช้ได้:\n\n- เซฟพรอมต์เป็นสแนิปต์รีโพและปักไว้ในแชททีม\n- แบ่ง CI failures ตามประเภท (lint, unit, integration, packaging, deploy)\n- เมื่อป้ายซ้ำ ให้เพิ่มเทสต์หรือเช็คที่ควรจับมันก่อนหน้า\n- เก็บการทดลองที่เสี่ยงให้ย้อนกลับได้ง่ายเพื่อถอยทันที\n\nถ้าคุณชอบเวิร์กโฟลว์แบบ chat-first ในการสร้างและวนซ้ำแอป คุณสามารถใช้ลูปแก้-ทดสอบเดียวกันใน Koder.ai ใช้สแนปชอตระหว่างทดลอง และส่งออกซอร์สเมื่อพร้อมผสานกลับเข้าผลิตจริงเริ่มจากข้อผิดพลาดตัวจริงตัวแรก ไม่ใช่ exit 1 สุดท้าย
บอกให้มันพิสูจน์ว่ามันอ่านข้อความใน log จริง ๆ
ใช้ข้อจำกัดเช่น:
โดยทั่วไปคือแพตช์ที่เล็กที่สุดซึ่งทำให้ขั้นตอนที่ล้มเหลวผ่าน
โดยมากหมายถึง:
หลีกเลี่ยงการ "ทำความสะอาด" จนกว่า CI จะผ่าน
ใส่บริบทพอให้สร้างซ้ำความล้มเหลวได้ ไม่ใช่แค่บรรทัดแดงสุดท้าย
รวม:
go test ./..., , , ฯลฯ)ได้—ระบุข้อจำกัดด้วยภาษาตรงไปตรงมาและย้ำมัน
ตัวอย่างข้อจำกัด:
แก้ failure ที่เกิดก่อนเป็นอันดับแรก
ถ้าไม่แน่ใจ ให้ให้โมเดลระบุขั้นตอนแรกที่ล้มใน log แล้วยึดตามนั้น
ถือว่า flaky เป็นสัญญาณให้เอาความสุ่มออก ไม่ใช่เพิ่ม retry
ตัวช่วยปกติ:
เมื่อ deterministic แล้ว การแก้ที่เล็กที่สุดจะชัดเจนขึ้น
ขอคำสั่งที่ CI รันเป๊ะ ๆ แล้วรันคำสั่งนั้นในเครื่องของคุณ
ถ้า local reproduce ยาก ให้ขอ minimal repro ในรีโพ (เทสต์หรือ target เดียว) ที่กระตุ้นข้อผิดพลาดเดียวกัน
เขียนเทสต์ regression เดียวที่ล้มก่อนแพตช์และผ่านหลังแพตช์
เป้าหมายที่ดีได้แก่:
ถ้าเป็น lint/build ให้เพิ่มหรือตั้งกฎ lint ที่เข้มขึ้นเป็นรูปแบบ "เทสต์"
ใช้ snapshot/rollback เพื่อทำให้การทดลองย้อนกลับได้
ลูปปฏิบัติได้จริง:
หากใช้ Koder.ai สแนปชอตช่วยให้ทดลองเร็วโดยไม่ปนกับแพตช์สุดท้ายที่จะแปะกลับ
npm testflutter test