Claude Code

Context Pollution: เมื่อ Agent วางยาพิษใส่ตัวเอง

นั่ง debug กับ Claude Code ติดกันเป็นชั่วโมง แล้วจู่ ๆ มันเริ่ม "เพี้ยน" คือเสนอ library ที่ตกลงกันไปแล้วว่าไม่ใช้ ถาม path ไฟล์ที่มันเพิ่งอ่านไปเมื่อกี้ เดาชื่อ function มั่ว ๆ ทั้งที่โค้ดยังอยู่ครบ เครื่องยังแรงเท่าเดิม อาการนี้มีชื่อครับ

ในบทความก่อน ๆ เราคุยกันเรื่องสิ่งที่ "เราป้อนเข้าไป" ให้ AI ทั้ง prompt ที่ชัด บริบทที่ครบ และการจัดการ context window (พื้นที่ความจำที่ AI ใช้เก็บทุกอย่างในบทสนทนาปัจจุบัน ซึ่งบทความ เรื่อง /handoff อธิบายไว้แล้ว) แต่พอมาถึงยุคที่ AI ลงมือทำงานเองแบบ Claude Code มันคนละเกมเลย เพราะ Agent ไม่ได้รอเราป้อน context อีกต่อไป

มันสร้าง context ใส่ตัวเองตลอดเวลา ทุกครั้งที่เรียกเครื่องมือ (tool) อ่านไฟล์ รัน test ที่ fail หรือ debug วนอยู่ 5 รอบ ผลลัพธ์ทั้งหมดนั้นถูกอัดกลับเข้า context window ของมันเอง สะสมไปเรื่อย ๆ จนถึงจุดที่มัน "มองไม่เห็น" ของสำคัญที่จมอยู่ข้างใน อาการนี้เรียกว่า Context Pollution (context เป็นพิษ)

Context Pollution คืออะไร

Context Pollution คือการที่ context window ค่อย ๆ ถูกถมด้วยข้อมูลที่ "สัญญาณต่ำ" (low-signal) ผลลัพธ์ tool ที่ใช้เสร็จแล้ว, error log ที่แก้ไปแล้ว, ความพยายามที่ fail, ทางตันที่เดินไปแล้วถอยกลับ จนสัญญาณที่สำคัญจริง ๆ (เช่นการตัดสินใจที่ตกลงกันไว้) จมหายไปในกองขยะ

ขอแตะเรื่องคำศัพท์นิดนึง คำว่า Pollution อ่านออกเสียงว่า "พอลลูชัน" แปลตรงตัวว่า "มลพิษ" (คำเดียวกับใน air pollution คือมลพิษทางอากาศ) เขายืมภาพของเสียที่ถูกปล่อยทิ้งจนสิ่งแวดล้อมเป็นพิษ มาเรียกอาการที่ context ถูกขยะถมจนกลายเป็นพิษกับตัว Agent เองนั่นแหละ

ขอเทียบให้เห็นภาพ: มันเหมือนไวท์บอร์ดในห้องประชุมที่ไม่เคยลบ ทุกไอเดียที่ลองแล้วไม่เวิร์ก ทุกตัวเลขที่ขีดฆ่า ทุกลูกศรที่ลากผิด ยังค้างอยู่บนบอร์ดหมด พอประชุมไปถึงชั่วโมงที่สาม คุณมองหา "ข้อสรุปจริง ๆ" ไม่เจอ เพราะมันจมอยู่ท่ามกลางรอยขีดเขียนที่ตายไปแล้ว Agent ก็เป็นแบบนั้นเป๊ะ

Context window หนึ่งอัน · ยิ่งทำงานยิ่งถูกถม การ debug ที่ fail วนไป 5 รอบ error log ที่แก้ไปแล้ว ✔ ของจริงที่ต้องใช้: ตกลงกันว่าใช้ library A · จมอยู่ตรงนี้ ผลลัพธ์ tool ที่อ่านไฟล์เสร็จไปแล้ว ทางตันที่เดินไปแล้วถอยกลับ
สัญญาณที่สำคัญจริง ๆ (แถวสีเขียว) จมอยู่ท่ามกลางข้อมูลที่ตายไปแล้ว Agent เลยหยิบมาใช้ไม่เจอ

ต่างจาก Context Rot ยังไง

หลายคนเคยได้ยินคำว่า Context Rot จากงานวิจัยของ Chroma ที่พบว่าโมเดลทุกตัว "แย่ลง" เมื่อ input ยาวขึ้น แม้งานจะง่ายแค่ไหน (สำหรับโมเดลหน้าต่าง 1 ล้านโทเคน จะเห็นผลชัดราว ๆ 300,000–400,000 โทเคน โดย token คือหน่วยย่อยของข้อความที่โมเดลใช้นับความยาว) ฟังดูคล้าย Context Pollution แต่จุดต่างสำคัญอยู่ที่ "ต้นตอ"

อีกคำที่น่าแกะ: Rot อ่านออกเสียงว่า "รอต" แปลว่า "เน่า" หรือ "ผุพัง" (แบบผลไม้ที่วางทิ้งไว้นานจนเสีย) ถ้าลากเป็นไทย ๆ Context Rot ก็คือ "คอนเท็กซ์ที่ค่อย ๆ เน่า" ยิ่งยาวยิ่งเสื่อมสภาพ

  • Context Rot = context ยาว แล้วคุณภาพตก เป็นเรื่องของ "ความยาว"
  • Context Pollution = Agent เติมขยะใส่ context ตัวเอง จนไปกระตุ้นให้เกิด context rot เป็นเรื่องของ "คุณภาพของสิ่งที่อยู่ข้างใน"

พูดอีกแบบ: Context Pollution คือ "ตัวการ" ส่วน Context Rot คือ "อาการ" ที่ตามมา

Context Pollution = ตัวการ Agent เติมข้อมูลสัญญาณต่ำ ใส่ context ตัวเองเรื่อย ๆ กระตุ้น ให้เกิด Context Rot = อาการ โมเดลจับใจความพลาด ตอบวน คุณภาพตก
รักษาที่ "ความยาว" อย่างเดียวไม่พอ ต้องแก้ที่ "ต้นตอ" คือหยุด Agent ไม่ให้เติมขยะใส่ตัวเอง

อาการที่สังเกตได้ในทางปฏิบัติ

พอ context เป็นพิษ Agent จะเริ่มแสดงอาการที่สังเกตได้ชัด

  • ขัดแย้งกับตัวเอง: เสนอวิธีที่ตรงข้ามกับที่เพิ่งตกลงกันไป ลืมการตัดสินใจเดิม
  • ค้นซ้ำ/เดามั่ว: ไปค้นหาข้อมูลที่เคยมีอยู่แล้วซ้ำ เดาชื่อ function หรือ path ไฟล์มั่ว เป็นสัญญาณว่ามันกำลัง "สร้างขึ้นใหม่" แทนที่จะ "จำได้"
  • คำตอบยาวขึ้นแต่ห่วยลง: เต็มไปด้วย "มันก็แล้วแต่..." แบบกำปั้นทุบดิน
  • ช้าลง: เพราะทุก response ต้องแบกต้นทุนของ context ขยะที่สะสมไว้

มีคนวัด "หนี้ context" (context debt โดยคำว่า debt อ่านว่า "เด็ท" ตัว b ไม่ออกเสียง แปลว่า "หนี้") ออกมาตรง ๆ เลย บางเซสชันแบก context ที่ค้างอยู่ 300,000+ โทเคน โดยที่แทบไม่ได้ใช้ประโยชน์ แต่ต้องจ่ายต้นทุนการประมวลผลมันทุกครั้งที่ตอบ งานวิจัย CodeDelegator (ม.ค. 2026) ยังชี้ชัดว่าการใช้ Agent ตัวเดียวทำทั้งวางแผนและลงมือเขียนโค้ด ทำให้เกิด context pollution จาก debugging traces และความล้มเหลวระหว่างทาง ซึ่งบั่นทอนงานยาว ๆ หลายขั้น (long-horizon) โดยตรง


ทางแก้ที่ทรงพลังที่สุด: Sub-agent

ก่อนจะไปที่ทางแก้ ต้องรู้จักตัวช่วยที่ชื่อ sub-agent (อ่านว่า "ซับเอเจนต์" โดย sub แปลว่า "ย่อย" หรือ "รอง" ลากไทย ๆ ได้ว่า "เอเจนต์ลูก" หรือผู้ช่วยตัวรอง) กันก่อน เพราะยังไม่มีบทความไหนในซีรีส์นี้เล่าเรื่องนี้ตรง ๆ

ภาพจำที่หลายคนมี: พอพูดถึง sub-agent ส่วนใหญ่จะนึกถึงการทำงานแบบ parallel คือแตกงานเป็นหลายตัววิ่งพร้อมกัน เร็วขึ้น ซึ่งถูกครับ แต่เป็นแค่ครึ่งเดียว และอาจไม่ใช่ครึ่งที่สำคัญที่สุดด้วยซ้ำ คุณสมบัติที่ทรงพลังกว่าคือ "Context Isolation" (การกั้นห้อง context)

Sub-agent ทำงานยังไง

sub-agent คือผู้ช่วยอีกตัวที่ Agent หลัก (main agent) เรียกใช้ให้ไปทำงานย่อยชิ้นหนึ่ง จุดสำคัญคือ มันมี context window แยกเป็นของตัวเอง ไปลุยงานที่ได้รับมอบหมายจนเสร็จในห้องของมันเอง แล้วส่งกลับมาให้ main agent แค่ "สรุป" หนึ่งย่อหน้า ไม่ลากกองขยะระหว่างทางกลับมาด้วย

นี่คือหัวใจที่แก้ Context Pollution ได้ตรงจุด: ความเลอะเทอะทั้งหมด ทั้งการไล่สำรวจโค้ด การลองผิดลองถูก debugging traces มันเกิดและตายอยู่ใน context ของ sub-agent ที่ทิ้งได้ ส่วน main agent รับกลับมาแค่ "คำตอบที่สะอาด" เท่านั้น แม้คุณจะรัน sub-agent แค่ตัวเดียว ไม่ parallel เลย คุณก็ได้ประโยชน์เต็ม ๆ

เทียบให้เห็นภาพ: เหมือนคุณส่งน้องในทีมเข้าไปค้นข้อมูลหรือไล่ debug ในอีกห้องนึง แล้วให้เดินกลับมาบอกคุณแค่ "พี่ครับ คำตอบคือ X" ไม่ใช่ลากกระดาษทด กองหนังสือ และ error log ทั้งกองเข้ามาวางบนโต๊ะคุณ โต๊ะคุณเลยสะอาดอยู่เสมอ

✗ แบบเดิม · Agent ตัวเดียวแบกทุกอย่าง Agent context ตัวเอง ขยะ (สีเทา) ปนของสำคัญ (สีเขียว) จนเริ่มมึน ✓ แบบใช้ sub-agent · กั้นห้องให้ความเลอะไปตายที่อื่น Main agent ส่งกลับแค่คำตอบสะอาด "คำตอบคือ X" (1 ย่อหน้า) context แยก (ทิ้งได้) Sub-agent
ความเลอะทั้งหมดไปเกิดและตายใน context ของ sub-agent ส่วน main agent รับกลับมาแค่คำตอบสะอาด โต๊ะเลยไม่มีวันรก

งานวิจัยของ Anthropic เรื่อง multi-agent research system ก็ยืนยันว่าสถาปัตยกรรมที่ context ถูกแยกขาดในแต่ละ sub-agent ทำได้ดีกว่าระบบ single-agent อย่างมีนัยสำคัญ เพราะ context window ของแต่ละตัวถูกจัดสรรให้งานย่อยที่แคบและชัด ส่วน Agent หลักโฟกัสที่การสังเคราะห์ผลลัพธ์อย่างเดียว

ใช้ Sub-agent ใน Claude Code ยังไง

ข่าวดีคือ Claude Code มี sub-agent แบบ built-in ติดมาให้อยู่แล้ว และ Claude จะเรียกใช้เองอัตโนมัติเมื่อเจองานที่เข้าข่าย ตัวหลัก ๆ ที่ควรรู้จักคือ

  • Explore: เอเจนต์ค้นและอ่านโค้ด (read-only แก้ไฟล์ไม่ได้) เหมาะกับการไล่หาว่าโค้ดอยู่ตรงไหน โครงสร้างเป็นยังไง โดยไม่ทิ้งผลการค้นไว้ใน context หลัก
  • Plan: เอเจนต์หาข้อมูลตอนอยู่ใน Plan Mode เพื่อรวบรวมบริบทก่อนเสนอแผน ให้การสำรวจไปเกิดในห้องแยก แชทหลักเลยยังอ่านอย่างเดียว
  • general-purpose: เอเจนต์อเนกประสงค์สำหรับงานหลายขั้นที่ต้องทั้งสำรวจและลงมือแก้

ถ้าอยากสั่งเองก็ทำได้ วิธีที่ง่ายที่สุดคือพิมพ์เป็นภาษาธรรมชาติ บอกให้ใช้ sub-agent แล้วระบุว่าอยากได้อะไรกลับมา เคล็ดลับสำคัญคือสั่งให้มันรายงานกลับมาแค่ "สรุป" ไม่ใช่ผลดิบทั้งกอง

พิมพ์ใน Claude Code
ใช้ subagent ไปรัน test ทั้งชุด แล้วรายงานกลับมาแค่ test ที่ fail พร้อม error message

งานที่เหมาะจะโยนให้ sub-agent คือพวกที่ "ผลลัพธ์เยอะแต่เราไม่ต้องเก็บไว้ดูซ้ำ" เช่นรัน test, ดึง log กองโต, ไล่อ่านโค้ดทั้งโมดูล ให้เนื้อดิบไปกองใน context ของ sub-agent แล้วรับกลับมาแค่ข้อสรุป

ถ้าอยากได้ตัวช่วยเฉพาะทางที่ใช้ซ้ำได้บ่อย ๆ ก็สร้าง sub-agent ของตัวเองได้ เป็นแค่ไฟล์ Markdown ในโฟลเดอร์ .claude/agents/ ที่มี frontmatter บอกค่าพื้นฐาน แล้วต่อด้วย "คำสั่งประจำตัว" (system prompt) ของมัน หรือจะบอก Claude ให้เขียนไฟล์นี้ให้ก็ได้

.claude/agents/code-reviewer.md
---
name: code-reviewer
description: รีวิวโค้ดหาปัญหาคุณภาพและความปลอดภัย ใช้หลังเพิ่งแก้โค้ดเสร็จ
tools: Read, Grep, Glob
model: sonnet
---

คุณคือผู้เชี่ยวชาญรีวิวโค้ด แต่ละปัญหาที่เจอ ให้อธิบายว่าผิดตรงไหน
แล้วเสนอโค้ดที่ปรับปรุงแล้ว

โน้ต

ช่อง tools คือการจำกัดว่า sub-agent ตัวนี้ใช้เครื่องมืออะไรได้บ้าง (ในตัวอย่างนี้อ่านได้อย่างเดียว แก้ไฟล์ไม่ได้) ส่วน model เลือกได้ว่าจะให้รันด้วยโมเดลไหน งานเบา ๆ ตั้งเป็นตัวเล็กที่ถูกและเร็วกว่าได้ ช่วยคุมต้นทุนไปในตัว

ข้อควรระวัง: กั้นห้อง ≠ ไม่ให้ข้อมูลอะไรเลย

Context isolation ไม่ได้แปลว่า "ส่ง sub-agent ไปแบบไม่บอกอะไรเลย" มีงานวิจัยที่พบว่าทั้งสองสุดขั้วแย่พอ ๆ กัน

  • โยน context ให้ทั้งก้อน (รับไปทุกอย่าง) ทำให้ context ของ sub-agent เสื่อมเร็วขึ้น กลับไปเป็น pollution เหมือนเดิม
  • ไม่ให้อะไรเลย: sub-agent ขาดเบาะแสสำคัญที่จำเป็นต่องาน ก็ทำงานพลาด

จุดที่ดีที่สุดคือตัวจัดการหลัก (orchestrator) คัดเฉพาะ context ที่เกี่ยวข้องส่งให้แบบพอดี ๆ เหมือนบรีฟงานน้องให้ครบพอทำได้ แต่ไม่ต้องเทเอกสารทั้งตู้ใส่โต๊ะมัน (orchestrator อ่านว่า "ออร์เคสเทรเตอร์" มาจากคำว่า orchestra หรือวงออร์เคสตรา คือคน "คุมวง" ที่จัดให้เครื่องดนตรีแต่ละชิ้นเล่นประสานกัน เทียบกับตัวที่คุมให้ sub-agent แต่ละตัวทำงานเข้าจังหวะกัน)

ระวัง

ถ้ารัน sub-agent หลายตัวแล้วแต่ละตัวส่งผลลัพธ์ยาว ๆ กลับมา ตัว context หลักก็บวมได้อยู่ดี เพราะทุกคำตอบที่ sub-agent ส่งคืนจะไหลกลับเข้า context หลัก เคล็ดลับเดิมจึงสำคัญ: บอกให้มันส่งกลับมาแค่สรุปสั้น ๆ


ถ้ารู้ตัวว่า Context Pollution เกิดไปแล้ว: วิธีล้างพิษ

บางทีกว่าจะรู้ตัว context ก็เลอะไปแล้ว ไม่เป็นไรครับ มีเครื่องมือล้างพิษเรียงจากเบาไปหนัก

  • /clear: ล้างกระดานทั้งหมด เริ่มใหม่ เหมาะที่สุดตอนเปลี่ยนงาน เพิ่ง debug auth เสร็จ กำลังจะไปทำ payment ต่อ? /clear เลย แล้วค่อยให้มันอ่านไฟล์ใหม่ ปลดล็อกโทเคนที่ค้างทั้งหมด
  • /compact แบบมีโฟกัส: สรุปแล้วไปต่อ ถ้ายังไม่อยากทิ้งทั้งหมด สั่งให้สรุปแบบเจาะจงได้ แม่นกว่าปล่อยให้ auto-compact ทำเอง เพราะคุณคุมได้ว่าจะเก็บอะไร
  • เขียน NOTES.md ก่อนล้าง ให้ Agent จดการตัดสินใจสำคัญลงไฟล์ภายนอกก่อน แล้วค่อยล้าง ของสำคัญอยู่ในไฟล์ ของขยะหายไปกับ context พอเริ่มใหม่ก็ให้อ่าน NOTES.md กลับมา
  • ใช้ฟีเจอร์ "clear context หลัง accept plan" (เพิ่มมาต้นปี 2026) พออนุมัติแผนแล้ว Claude Code จะเสนอให้ล้าง context เพื่อเริ่มลงมือด้วยแผนที่สะอาด ไม่มีเศษการสำรวจเก่ามาดึงให้หลุดทาง
  • ระดับ API: Context Editing ถ้าคุณ build agent เองผ่าน Claude Developer Platform มีกลยุทธ์ที่เคลียร์เนื้อผลลัพธ์ tool เก่า ๆ ทิ้ง แต่เก็บบันทึกไว้ว่าเคยเรียก โมเดลยังรู้ว่ามันเคยใช้ tool นั้น แต่ก้อนเนื้อหาใหญ่ ๆ หายไป เป็นการล้างพิษที่เบาที่สุด

ตัวอย่างการสั่ง /compact แบบเจาะจงว่าจะเก็บอะไร ทิ้งอะไร:

พิมพ์ใน Claude Code
/compact เก็บการตัดสินใจเรื่อง API design กับ DB schema ไว้ ส่วนที่ debug ทิ้งให้สรุปสั้น ๆ

โน้ต

/clear ล้าง "ประวัติบทสนทนา" แต่ของระดับระบบ (CLAUDE.md, memory, plan ที่ทำอยู่) จะถูกใส่กลับทุกเทิร์น ถ้าอยากสะอาดจริง ๆ หลังจบงานก้อนใหญ่ ให้เปิด session ใหม่ไปเลยจะชัวร์กว่าการ clear กลางทาง

อย่ารอ auto-compact

Claude Code จะ auto-compact เองตอน context เกือบเต็ม (~95%) แต่มันเป็นการสรุปแบบสูญเสียรายละเอียด คุณอาจเสียข้อมูลที่ไม่รู้ว่าจำเป็นไป เห็นข้อความ [Context compacted] เมื่อไหร่ แปลว่าคุณอยู่ในเซสชันที่ยาวเกินไปแล้ว ควรเป็นฝ่ายกด /clear เองก่อนถึงกำแพง

หลักการแม่

ป้องกันดีกว่าล้างพิษเสมอ แทนที่จะลุยทั้ง feature ใน session เดียว (schema แล้วต่อ API แล้วต่อ frontend) ให้แตกเป็น session ละงาน แต่ละอันเริ่มด้วย context ที่ใกล้สะอาด (สกิล /handoff ช่วยส่งไม้ต่อระหว่าง session ได้โดยไม่เสียบริบท)


สรุปบรรทัดเดียว

Context Rot คืออาการที่ context ยาวทำให้โมเดลแย่ลง แต่ Context Pollution คือตอนที่ Agent เป็นคนเติมขยะใส่ context ตัวเองจนป่วย และยาที่ดีที่สุดไม่ใช่ context window ที่ใหญ่ขึ้น แต่คือการ "กั้นห้อง" ให้ความเลอะเทอะไปตายใน sub-agent แล้วส่งกลับมาแค่คำตอบที่สะอาด


แหล่งอ้างอิง

เรียบเรียงและอธิบายใหม่ด้วยคำตัวเอง โดยตรวจสอบข้อเท็จจริงกับแหล่งปฐมภูมิด้านล่าง

  1. "CodeDelegator: Mitigating Context Pollution via Role Separation in Code-as-Action Agents" · Fei et al., arXiv:2601.14914, สืบค้นเมื่อ 6 กรกฎาคม 2026
  2. "Effective context engineering for AI agents" · Anthropic Engineering, สืบค้นเมื่อ 6 กรกฎาคม 2026
  3. "How we built our multi-agent research system" · Anthropic Engineering, สืบค้นเมื่อ 6 กรกฎาคม 2026
  4. "Create custom subagents" · Claude Code Docs, Anthropic, สืบค้นเมื่อ 6 กรกฎาคม 2026
  5. "Context editing" · Claude Platform Docs, Anthropic, สืบค้นเมื่อ 6 กรกฎาคม 2026
  6. "Context Rot: How Increasing Input Tokens Impacts LLM Performance" · Chroma Research, สืบค้นเมื่อ 6 กรกฎาคม 2026