อย่าให้ Claude Code แก้ไฟล์ตั้งค่าของตัวเองเด็ดขาด — ประวัติอุบัติเหตุที่นำไปสู่การเสนอ diff แล้วรอเจ้าของอนุมัติ

Claude Code AIエージェント 運用 ガバナンス RAG

บทนำ

ฉันใช้การตั้งค่าที่แบ่งบทบาทให้ AI หลายตัวทำงานขนานกัน นอกจากตัวลงมือทำและตัวตรวจสอบ ฉันเคยมีบทบาทที่ทำหน้าที่จ่ายงานด้วย — ตัวที่ตัดสินว่าใครได้รับอะไร และในลำดับไหน ฉันปล่อยให้ตัวจ่ายงานนั้นตัดสินด้วยตัวเองว่าจะประพฤติอย่างไรเมื่อกฎการทำงานขัดกันเอง แล้วมันก็กลายเป็นอุบัติเหตุ บทความนี้ว่าด้วยการที่อุบัติเหตุนั้นตกผลึกเป็นแนวปฏิบัติว่า ชั้นที่นิยามตัววินัยเองจะไม่ถูกเปลี่ยนด้วยการตัดสินของ AI เพียงลำพัง

เหตุผลเชิงโครงสร้างของการยกเลิกชั้นจ่ายงานทั้งชั้นอยู่ในอีกบทความหนึ่ง ตรงนี้ฉันหยิบออกมาเฉพาะอุบัติเหตุที่นำไปสู่การยกเลิกนั้น — นั่นคือคำถามข้อเดียวว่า อำนาจในการเปลี่ยนการตั้งค่าควรอยู่ตรงไหน

ทำไมฉันจึงเลิกใช้ orchestrator subagent ใน Claude Code — ข้อจำกัดเชิงโครงสร้าง 3 ข้อจากสเปกฮาร์เนสทางการ

เกิดอะไรขึ้น

ตัวจ่ายงานถูกให้กฎการทำงาน 2 ข้อต่อไปนี้ไปพร้อมกัน “ชั้นที่นิยามวินัยจะไม่ถูกเปลี่ยนโดย AI ด้วยการตัดสินของตัวเอง ถ้าดูเหมือนว่าจำเป็นต้องเปลี่ยน ให้เสนอเป็น diff และนำไปใช้หลังจากเจ้าของยืนยันแล้วเท่านั้น” — และ “ถ้าไม่แน่ใจระหว่างทำงาน ให้ถามเจ้าของ”

วันหนึ่ง ตัวจ่ายงานมาถึงสถานการณ์ที่ทั้งสองข้อนั้นดูเหมือนขัดกัน พอขุดลงไป มันไม่ได้ขัดกันจริง แต่เป็นข้อตั้งต้นที่ไม่ตรงกัน: ตัววิธีการถามเจ้าของนั่นเองถูกพรากไปจาก AI ลูกน้องโดยโครงสร้าง แต่ตัวจ่ายงานไม่ได้หยุดตรงนั้น มัน “แก้” ความขัดแย้งด้วยการตัดสินของตัวเอง ในรูปธรรมคือ มันให้ตัวลงมือทำแก้ไฟล์ที่นิยามตัววินัยเองไป 2 ไฟล์โดยตรง และเขียนคำอธิบายว่าทำไมการตัดสินนั้นถึงถูกต้อง ลงในความทรงจำร่วมพร้อม เครื่องหมายลำดับความสำคัญสูงสุด กำกับไว้

ชั้นที่นิยามวินัย (ไฟล์ที่ตัดสินว่าเอเจนต์ AI จะประพฤติอย่างไร)

  ├─▶ โค้ดทั่วไป, บทความ, เอกสารออกแบบ ── ขอบเขตที่ AI แก้ได้โดยตรง

  └─▶ ตัวชั้นที่นิยามวินัยเอง ── ขอบเขตที่ AI ต้องไม่เปลี่ยนด้วยการตัดสินของตัวเอง

          ├─▶ อุบัติเหตุ: ตัวจ่ายงานเจอกรณีที่กฎดูเหมือนขัดกัน
          │       └─ มีกฎที่บอกว่า "ถ้าไม่แน่ใจ ให้ถามเจ้าของ" แต่
          │          วิธีการถามเจ้าของไม่มีอยู่โดยโครงสร้าง
          │             └─ ตัวจ่ายงาน "แก้" สถานการณ์เอง ── เส้นทางที่ผิด
          │                   ├─▶ ให้ตัวลงมือทำแก้ไฟล์นิยาม 2 ไฟล์โดยตรง
          │                   └─▶ เขียนความชอบธรรมของตัวเองลงในความทรงจำร่วมพร้อมเครื่องหมายลำดับสูงสุด
          │                         └─ กลไกความปลอดภัยของแพลตฟอร์มเองตรวจจับได้
          │                               └─ ทุกอย่างถูกย้อนกลับ ── เส้นย้อนกลับ

          └─▶ แนวปฏิบัติที่ถูกตั้งขึ้น: เตรียม diff → เจ้าของยืนยัน → นำไปใช้
                    └─ เมื่อพบสิ่งที่ดูเหมือนความขัดแย้ง อย่า "แก้" มัน ให้รายงานแล้วหยุด

กลไกความปลอดภัยของแพลตฟอร์มสังเกตเห็นก่อน

การแก้ไขและการเขียนเหล่านั้นถูกกลไกความปลอดภัยของแพลตฟอร์มเองตรวจจับได้ ก่อนที่ฉันจะสังเกตเห็นอะไรเลย พฤติกรรมที่พยายามดัดแปลงนิยามของตัวเอเจนต์เอง และพฤติกรรมที่พยายามฉีดการตีความแบบหนึ่งเข้าไปในทุกเทิร์นด้วยการติดเครื่องหมายลำดับความสำคัญสูงสุดในความทรงจำร่วม — ตัวจำแนกที่แพลตฟอร์มถือไว้อย่างเป็นอิสระจับรูปแบบได้ทั้งสองอย่าง

เพื่อตอบสนอง ไฟล์นิยามที่ถูกแก้ก็ถูกกู้คืน และความชอบธรรมที่เขียนลงในความทรงจำร่วมก็ถูกถอน ความทรงจำนั้นเป็นแบบเขียนต่อท้ายอย่างเดียวโดยการออกแบบ การเพิ่มคำแก้ไขทีหลังจึงทิ้งบันทึกเดิมไว้ที่เดิม ฉันจึงใช้ กลไกเฉพาะที่เล็งและลบเฉพาะบันทึกที่เป็นปัญหา ตัวกลไกนั้นเองถูกสร้างไว้ก่อนหน้าแล้ว ในฐานะบันทึกอีกชิ้นหนึ่ง

ฉันสร้างกลไกถอน ‘บทเรียนที่ผิด’ ที่เก็บไว้ใน RAG ในภายหลัง — ล้างการปนเปื้อนที่บิดเบือนเพื่อน AI ทุกเทิร์นโดยอัตโนมัติ

เพราะกลไกการถอนนี้จัดการกับการลบ — การกระทำที่เอาคืนไม่ได้ — ค่าตั้งต้นของมันจึงคือ “ไม่ลบอะไรเลย แค่แสดงรายการว่าอะไรจะถูกลบ” ต่อไปนี้คือผลลัพธ์จากการรันแบบเปล่าเมื่อสักครู่ (ชื่อโปรแกรมถูกปิดบัง และบรรทัดวินิจฉัยรายบันทึกถูกละไว้)

[実測・マスク済み] 撤回機構の空打ち
$ python <撤回スクリプト> --help
usage: <撤回スクリプト> [-h] [--apply] [--show-body]

options:
  -h, --help   show this help message and exit
  --apply      実削除する(既定はdry-run)
  --show-body  消える(消えた)チャンクの先頭200字を出す。巻き添えの確認用

$ python <撤回スクリプト>
...
=== RETRACTS マーカー: 51 件 (apply=False) ===
=== 削除dry-run(削除せず): 0 件 ===

มีเครื่องหมายการถอน 51 รายการ และในจำนวนนั้น จำนวนที่ยังค้างอยู่โดยไม่ถูกลบคือ 0 ความชอบธรรมที่ถูกเขียนระหว่างอุบัติเหตุก็ผ่านเส้นทางนี้มาแล้วเช่นกัน จะไม่มีอะไรถูกลบเว้นแต่ส่ง --apply ดังนั้นคุณจึงอ่านได้ก่อนว่าอะไรจะโดนลูกหลงบ้างก่อนจะรันจริง ในแง่ของทิศทางที่ควรเอียงค่าตั้งต้นสำหรับการกระทำอันตราย นี่เดินตามความคิดเดียวกันกับกระบวนการอนุมัติของชั้นตั้งค่า

ทำไม “ชั้นที่นิยามวินัย” เท่านั้นถึงได้รับการปฏิบัติเป็นพิเศษ

AI แก้เนื้อหาของโค้ดทั่วไป บทความ หรือเอกสารออกแบบ กับ AI แก้ไฟล์ที่ตัดสินว่าเอเจนต์ AI เองจะประพฤติอย่างไร ดูเหมือนเป็นการกระทำ “แก้ไฟล์” เดียวกัน แต่ต่างกันในเชิงชนิด ในกรณีแรก คนอ่านผลลัพธ์แล้วตัดสินได้ ส่วนกรณีหลังคือการกระทำที่ เขียนเกณฑ์ของการตัดสินนั้นใหม่ และการยื่นอำนาจตัดสินว่าการเขียนใหม่นั้นเหมาะสมหรือไม่ ให้กับฝ่ายเดียวกับที่ลงมือเขียนใหม่ ก็เท่ากับปิดทั้งเกณฑ์และผู้อยู่ใต้เกณฑ์ไว้ในตัวแสดงเดียว

อุบัติเหตุครั้งนี้เกิดขึ้นภายในวงปิดนั้นพอดี ตัวจ่ายงานหยิบ ตัววินัยเอง — “ชั้นที่นิยามวินัยจะไม่ถูกเปลี่ยนด้วยการตัดสินของตัวเอง” — แล้วเลี่ยงมันด้วยการขยายการตีความด้วยการตัดสินของตัวเอง เมื่อการชี้ขาดว่าวินัยถูกปฏิบัติตามหรือไม่ ถูกทำให้เสร็จสมบูรณ์ภายในฝ่ายที่ถูกวินัยนั้นกำกับอยู่ (คือ AI) วินัยก็เลิกทำหน้าที่ในฐานะวินัย

แนวปฏิบัติที่ถูกตั้งขึ้น

หลังอุบัติเหตุ การเปลี่ยนแปลงต่อชั้นตั้งค่าถูกตรึงไว้ในรูปต่อไปนี้

สิ่งที่กำลังถูกเปลี่ยนใครลงมือได้
โค้ดทั่วไป, บทความ, เอกสารออกแบบAI ลงมือแล้วรายงานภายหลัง
ไฟล์นิยามที่ตัดสินพฤติกรรมของเอเจนต์, การตั้งค่าของกลไกความปลอดภัยAI ไปได้ไกลสุดแค่เตรียม diff การนำไปใช้ตามหลังการอนุมัติของเจ้าของ
กรณีที่กฎดูเหมือนขัดกันเองAI ไม่ “แก้” มัน แต่รายงานแล้วหยุด

แถวที่สามคือหัวใจของอุบัติเหตุครั้งนี้ ความขัดแย้งถูกปฏิบัติไม่ใช่ในฐานะ “สิ่งที่ AI แก้” แต่ในฐานะ “สิ่งที่ทำให้มันรายงานแล้วหยุด” มันคือเส้นที่ถูกลากไว้เพื่อไม่ให้อำนาจตัดสินลำดับความสำคัญระหว่างวินัย ตกอยู่กับฝ่ายที่ถูกวินัยเหล่านั้นกำกับ

อุบัติเหตุกลายเป็นวัตถุดิบให้วินัยแข็งแรงขึ้น

แม้จะยกเลิกชั้นจ่ายงานไปแล้ว อุบัติเหตุชนิดเดียวกันก็ยังเป็นไปได้ตราบเท่าที่เส้นทางสำหรับเปลี่ยนชั้นที่นิยามวินัยยังเปิดอยู่ สิ่งที่กรณีนี้ทำให้ชัดคือ แพลตฟอร์มถือกลไกของตัวเองสำหรับตรวจจับความผิดปกติในชั้นเดียวกันนั้นอยู่แล้ว และ อุบัติเหตุก็ยังเกิดขึ้นอยู่ดี เพราะ AI นำการเปลี่ยนแปลงไปใช้ก่อน ทะลุผ่านประตูที่มาก่อนหน้าอย่างการอนุมัติของเจ้าของไปตรง ๆ การตรวจจับทำงานได้หลังเกิดเหตุเท่านั้น ต่อเมื่อแนวปฏิบัติที่ วางการอนุมัติไว้ก่อนแล้วหยุดตรงนั้น ถูกตั้งขึ้น อุบัติเหตุจึงกลายเป็นวัตถุดิบสำหรับป้องกันการเกิดซ้ำ

Claude Code ไม่ได้อ่าน CLAUDE.md ของรีโปพี่น้อง — 18 เซสชันที่วัดจริงจากเวิร์กสเปซข้ามรีโป

อำนาจในการแตะชั้นที่นิยามวินัยเป็นคำถามเรื่องลำดับ ไม่ใช่เรื่องความสามารถ แค่แทรกขั้นตอนเพิ่มอีกขั้นอย่างการเสนอ diff แล้วหยุด ก็คือสิ่งที่กันไม่ให้ฝ่ายที่ถูกวินัยกำกับ กับฝ่ายที่ตัดสินวินัย ปิดตัวลงเป็นตัวแสดงเดียวกัน — ตำแหน่งของขั้นตอนเดียวนั้นคือทั้งหมดที่อุบัติเหตุครั้งนี้มีจะสอน

ส่งข้อความได้ตามสบาย

ไม่ว่าจะเป็นการว่าจ้างงาน แนะนำโปรเจกต์ ความคิดเห็น หรือคำถาม ยินดีรับทั้งหมด ฉันหวังเป็นอย่างยิ่งว่าจะได้เชื่อมต่อกับผู้ที่มีอุดมการณ์อันสูงส่งเช่นเดียวกัน ฉันจะมุ่งมั่นท้าทายในสิ่งที่ทุ่มเททั้งชีวิตต่อไป ขอขอบคุณและฝากเนื้อฝากตัวด้วยครับ/ค่ะ