เหตุผลที่มองไม่เห็นการสิ้นเปลืองโทเค็น เป็นเพราะมันไม่ใช่ความล้มเหลว แต่เป็นความซ้ำซ้อน เช่น อ่านไฟล์เดิมสองครั้ง, ลองใหม่ด้วยอาร์กิวเมนต์เดิม, เรียกใช้เครื่องมือเดิมซ้ำ ดังนั้นผมจึงสร้าง CLI ที่อ่านเทรซหลังงานจบ แล้วชี้ให้เห็นว่าสเต็ปไหนทำสิ่งที่ทำไปแล้วซ้ำอีกครั้ง!
[ลองใช้]
pip install "clew-custos[detect]"
python -m clew analyze ~/.claude/projects/<slug>/<uuid>.jsonl --out report.md
รันบนเครื่องโลคัลได้โดยไม่ต้องสมัคร และไม่ดึง torch มาด้วย ดังนั้นติดตั้งเสร็จได้ในไม่กี่วินาที รองรับ Python 3.12 ขึ้นไป ไฟล์เซสชันของ Claude Code อยู่ใต้ ~/.claude/projects/
นี่คือผลลัพธ์จริงที่รันกับเซสชัน Claude Code สาธารณะ (258 เทิร์น):
Result: WASTE DETECTED
- category breakdown: 0 error_repeat, 0 side_effect, 1 idempotent, 0 unclassified
1. requery — Read on .../boot.ts
- turns: turn 50 → re-run at turn 58 (of 258 total)
- state: No modification of this file in between — re-read output is unchanged.
- re-consumed across 200 subsequent turns (≈439 tokens/turn → 87800 amplification tokens)
- estimated cost impact: $0.026340 ~ $0.263400 (cache-hit to cache-miss)
[ตัดสินอย่างไร]
มันไม่ได้เก็บและทำ visualization ของเทรซแบบ Langfuse หรือ Phoenix แต่จะอ่านเทรซที่จบแล้วและชี้เฉพาะความสิ้นเปลือง
มี 2 ขั้นตอน ขั้นแรกคือจัดกลุ่มการเรียกใช้เครื่องมือเดียวกันด้วยอาร์กิวเมนต์เดียวกัน จากนั้นตรวจดูว่า sha256 ของเอาต์พุตตรงกันทุกประการหรือไม่ ถ้าเอาต์พุตต่างกัน แสดงว่าสถานะเปลี่ยนไป ก็จะไม่ถูกจับ
ไม่มีการตัดสินโดย LLM ใส่เทรซเดิมเข้าไปก็จะได้ผลลัพธ์เดิมเสมอ
ความสิ้นเปลืองที่พบจะถูกจัดเป็น 4 ประเภท: การทำซ้ำของข้อผิดพลาด (ลองใหม่ทั้งที่ยังไม่แก้สาเหตุของ error เดิม), การรันซ้ำที่มีผลข้างเคียง (เรียกเครื่องมือที่เปลี่ยนสถานะซ้ำด้วยอาร์กิวเมนต์เดิม), พื้นที่สีเทา (การทำซ้ำแบบอ่านอย่างเดียว — ไม่มีผลข้างเคียงแต่ใช้โทเค็น), และตัดสินไม่ได้ เครื่องมืออย่าง Bash หรือ PowerShell ที่ผลลัพธ์อาจต่างกันโดยสิ้นเชิงตามเนื้อหาอาร์กิวเมนต์ จะไม่ตัดสินจากชื่อเพียงอย่างเดียว และจะจัดเป็นตัดสินไม่ได้
[พบอะไรจากข้อมูลสาธารณะ]
เมื่อนำไปรันตรง ๆ กับ benchmark Toolathlon (โมเดล frontier 22 ตัว × รัน 3 ครั้ง, 6,780 เทรซ, tool span 176,270 รายการ) พบการเรียกซ้ำ 8,042 ครั้ง
แต่ถ้าใช้ตัวเลขนี้ตรง ๆ จะถือว่าเกินจริง เพราะ 47% เป็นพื้นที่สีเทา (เช่น ประกาศงานเสร็จซ้ำ, สร้างไดเรกทอรีที่มีอยู่แล้วซ้ำ) เมื่อตัดออกจะเหลือ 4,251 ครั้ง คิดเป็น 2.41% ของ tool span
สิ่งที่สะดุดตาคือมีการรันซ้ำของเครื่องมือที่เปลี่ยนสถานะ 1,343 ครั้ง และในนั้นมีการส่งอีเมลซ้ำด้วยอาร์กิวเมนต์เดิม 459 ครั้ง อย่างไรก็ตาม สิ่งที่ตรวจจับได้คือ "เครื่องมือเดียวกันถูกเรียกสองครั้งด้วยอาร์กิวเมนต์เดิม" เท่านั้น จากเทรซอย่างเดียวไม่สามารถยืนยันได้ว่าอีเมลถูกส่งออกไปซ้ำจริงหรือไม่
[สิ่งที่คาดไม่ถึง]
ตัว Claude Code เองมีประสิทธิภาพมากกว่าที่คิด ผมวัด candidate pattern อย่างการอ่านไฟล์ซ้ำหรือการลองใหม่แบบไร้ความหมายอยู่หกครั้ง แต่ห้าครั้งแทบไม่พบในเซสชันจริงของ CC เลย ดูเหมือนว่ามันป้องกันไว้แล้วด้วย caching และการคง context
ฝั่งที่มีความสิ้นเปลืองหนากว่าคือสภาพแวดล้อมที่ต่อ MCP server หลายตัวเข้าด้วยกัน โดย CC ที่มีเครื่องมือ 20 ตัว (0.80%) กับ Toolathlon ที่มี 523 ตัว (2.41%) ต่างกันถึง 3 เท่า
[ข้อจำกัด]
ตอนนี้ยังไม่มีกรณีลดค่าใช้จ่ายที่วัดผลได้ แม้จะตรวจจับและประเมินได้ แต่ยังไม่มีข้อมูลเลยว่ามีใครดูผลนี้แล้วไปแก้บางอย่างจนบิลลดลงจริง
47% ที่เป็นพื้นที่สีเทาจะไม่ถูกกรองทิ้ง แต่จะแสดงให้เห็นในรูปแบบการจัดประเภทเท่านั้น เพราะการทำซ้ำแบบอ่านอย่างเดียวจะเป็นความสิ้นเปลืองจริงหรือไม่นั้นขึ้นอยู่กับบริบทการรัน ซึ่งเป็นส่วนที่ผมตัดสินแทนไม่ได้
ยังไม่รองรับ Cursor และ Codex
ตัวตรวจจับที่ตรวจสอบความถูกต้องไม่ผ่านจะถูกทิ้ง ผมเคยสร้างตัวตรวจจับการอ่านไฟล์ซ้ำ แต่จากตัวอย่าง 30 รายการมันมี precision ต่ำกว่าเกณฑ์ 70% มาก (มองแบบผ่อนปรนยังได้แค่ 3.3%, ถ้าเข้มงวดคือ 0%) เลยยกเลิกไป และได้ทิ้งทั้งคำคาดการณ์และผลลัพธ์ไว้ในเอกสาร preregistration แล้ว
[สรุป...]
ผมตั้งใจจะวิจัยและตรวจสอบในด้านนี้ต่อไป!
ต้องขออภัยที่ readme ยังเป็นภาษาอังกฤษ.. T_T
ถ้าได้ลองใช้แล้ว อยากให้ปรับปรุงหรือเพิ่มส่วนไหน ก็อยากได้รับฟีดแบ็กครับ!
ต่อจากนี้ก็ฝากติดตาม clew กันเยอะ ๆ ด้วยนะครับ ขอบคุณครับ...!!
1 ความคิดเห็น
[เผื่อว่าอ่านยาก ผมเลยเขียนคำแปลภาษาเกาหลีของ README ไว้ให้แล้ว!]
Clew
ตัวตรวจจับแบบกำหนดผลลัพธ์แน่นอนสำหรับค้นหางานที่สูญเปล่าใน agent trace
Clew จะอ่าน trace ของการรัน AI agent ที่เสร็จสมบูรณ์แล้ว แล้วค้นหาสต็ปที่ทำงานซ้ำกับที่ทำไปแล้ว — เรียกเครื่องมือเดิมซ้ำด้วยอาร์กิวเมนต์เดิม, ลองเรียกที่ล้มเหลวซ้ำด้วยอาร์กิวเมนต์เดิม, ดึงข้อมูลที่มีอยู่ในคอนเท็กซ์แล้วกลับมาอีกครั้ง — โดยทำงานได้โดยไม่ต้องมีการตัดสินจาก LLM ดังนั้นถ้าใส่ trace เดิมเข้าไป ก็จะได้ผลลัพธ์เดิมเสมอ
pip install "clew-custos[detect]"python -m clew analyze ~/.claude/projects/<slug>/<uuid>.jsonl --out report.mdตัวอย่างเอาต์พุตจริงจากการรันกับเซสชัน Claude Code แบบสาธารณะ:
Result: WASTE DETECTED
1. requery — Read on
.../boot.tsทำไมเรื่องนี้จึงสำคัญ
ในเซสชัน AI coding agent ความสูญเปล่าจะโผล่มาให้เห็นแค่ในบิลเท่านั้น เครื่องมือทุกตัวคืนค่า 200 และไม่มีอะไรแจ้ง error เลย จึงมองไม่เห็นความสูญเปล่าด้วยตาเปล่า แต่ภายใน trace จะเห็นว่า agent อ่านไฟล์เดิมสองครั้ง, ลองเรียกที่ล้มเหลวซ้ำด้วยอาร์กิวเมนต์เดิม, และเรียกเครื่องมือเดิมซ้ำด้วย payload เดิม
เพราะงานอ่าน (read) ในเซสชัน coding agent กินโทเค็นถึง 65~90% ความสูญเปล่าแบบนี้จึงค่อย ๆ สะสมโดยไม่ทันสังเกต เครื่องมือ observability แสดง trace ให้ดูได้ แต่ไม่บอกว่าสเต็ปไหนเป็นงานซ้ำซ้อน
ตรวจจับอะไรบ้าง
Clew มองหารูปแบบความซ้ำซ้อน 3 แบบ:
repeat — เรียกเครื่องมือ/โหนดเดิมซ้ำ
requery — เรียกเครื่องมือเดิมซ้ำด้วยอินพุตเดิม (เอาต์พุตเหมือนเดิม)
pingpong — agent สองตัวส่งต่อเนื้อหาที่แทบจะเหมือนกัน (multi-agent)
แต่ละสิ่งที่พบจะถูกจัดเป็น 4 ประเภท:
error_repeat — เอาต์พุตเป็น error แต่ยังเรียกแบบเดิมซ้ำ
side_effect — รันเครื่องมือที่เปลี่ยนสถานะ (ส่ง/เขียน/สร้าง ฯลฯ) ซ้ำ
idempotent — ทำซ้ำกับเครื่องมือแบบอ่านอย่างเดียว/เชิงประกาศ (ไม่มีผลข้างเคียง แต่กินโทเค็น)
unclassified — เครื่องมือที่ไม่มีในแมปปิง ไม่อนุมานจากชื่อเครื่องมืออย่างเดียวเพราะผลลัพธ์ขึ้นกับ payload (เช่น Bash/PowerShell)
[ทำงานอย่างไร]
เป็นแคสเคด 2 ขั้น:
โครงสร้างเกต — จัดกลุ่มการเรียกเครื่องมือเดียวกันด้วยอาร์กิวเมนต์เดียวกัน (ที่ผ่านการทำ normalization แล้ว)
เกตความเหมือนกัน — ตรวจว่า sha256 ของเอาต์พุตตรงกันทุกประการหรือไม่ ถ้าไม่ตรงแปลว่าสถานะเปลี่ยน จึงไม่ถูกแฟล็ก
การตรวจโครงสร้างที่ต้นทุนต่ำจะคัดผู้ต้องสงสัยก่อน แล้วการตรวจเชิงความหมายที่แพงกว่า (embedding+cosine) จะรันเฉพาะเมื่อจำเป็น เนื่องจากไม่มีการตัดสินจาก LLM ผลลัพธ์จึงเป็นแบบกำหนดแน่นอน — จุดนี้สำคัญถ้าคุณอยากใส่มันเข้า CI
[รูปแบบอินพุต]
Claude Code — วิเคราะห์ session JSONL ได้โดยตรง
LangGraph — ตรวจจับ chain ซ้ำจาก trace
LangChain·CrewAI·AutoGen·LlamaIndex ฯลฯ — พาร์ส trace ที่ทำ instrumentation ตามฟอร์แมตมาตรฐาน OpenTelemetry/OpenInference (รองรับในระดับฟอร์แมต แต่การตรวจวัดจริงรายเฟรมเวิร์กยังอยู่ระหว่างดำเนินการ)
trace benchmark สาธารณะ (Toolathlon, RedundancyBench)
ตอนนี้ยังไม่รองรับเซสชัน Cursor และ Codex — กำลังตรวจดูฟอร์แมตภายในอยู่
[ผลการตรวจสอบ]
benchmark สาธารณะ (Toolathlon, 6,780 trace, 176,270 tool span):
ตรวจพบการเรียกซ้ำ 8,042 ครั้ง ในจำนวนนั้น 47% เป็นพื้นที่สีเทา (การทำงานแบบ idempotent, การประกาศว่าเสร็จแล้ว) เมื่อตัดส่วนนั้นออกจะเหลือ 4,251 ครั้ง (2.41% เทียบกับ tool span) สูงกว่าเซสชัน Claude Code (0.80%) ราว 3 เท่า
พบการรันซ้ำของเครื่องมือที่เปลี่ยนสถานะ 1,343 ครั้ง รวมถึงการส่งอีเมลซ้ำด้วยอาร์กิวเมนต์เดิม 459 ครั้ง อย่างไรก็ตาม นี่เป็นเพียงการตรวจพบว่ามีการเรียกเครื่องมือเดียวกันซ้ำด้วยอาร์กิวเมนต์เดิม ไม่ได้ยืนยันว่าเกิดผลข้างเคียงจริงหรือไม่
benchmark แบบติดป้ายกำกับ (RedundancyBench):
precision 0.826 (ค่าประมาณขอบล่างสำหรับความซ้ำภายในไฟล์) ป้ายกำกับ RB จำนวนมากเป็นความซ้ำข้ามไฟล์ (cross-file) ซึ่งอยู่นอกขอบเขตของการออกแบบที่วิเคราะห์ระดับเซสชัน recall อยู่ที่ 0.157 ซึ่งค่อนข้างต่ำ
[ขอบเขตความตรงไปตรงมา]
ยังไม่มีกรณีที่วัดการประหยัดได้จริง ตอนนี้ตรวจจับและประเมินได้ แต่ยังมีข้อมูล before/after จากผู้ใช้จริงที่แก้อะไรบางอย่างแล้วบิลลดลงจริงอยู่ 0 กรณี
47% ของสิ่งที่ถูกแฟล็กใน benchmark เป็นพื้นที่สีเทา (การรันซ้ำแบบ idempotent) มันกรองทิ้งไม่ได้ มีแค่จัดประเภทไว้ — เพราะการที่การรันซ้ำแบบอ่านอย่างเดียวจะถือว่าสูญเปล่าหรือไม่ ขึ้นอยู่กับบริบทที่มองไม่เห็น
เพราะกำหนดให้ sha256 ต้องตรงกันทุกประการ ถ้าเอาต์พุตต่างกันแม้เพียงเล็กน้อยก็จะไม่ถูกแฟล็ก นี่คือเหตุผลที่ recall ต่ำ และเป็นการออกแบบที่เอนเอียงไปทาง precision
Claude Code ถูกปรับแต่งมาดีเป็นพิเศษ ผมวัดรูปแบบความสูญเปล่าที่น่าจะเป็นไปได้ 6 แบบในเซสชัน CC จริง แต่ 5 แบบไม่พบในนั้น ความสูญเปล่าที่น่าสนใจกลับไปปรากฏในสภาพแวดล้อม MCP แบบหลายเครื่องมือ ไม่ใช่ใน CC เอง
การประเมินต้นทุน (amplification) เป็นการประมาณ ไม่ใช่การวัด และทำได้เฉพาะในฟอร์แมต Claude Code เท่านั้น
สิ่งที่ยังไม่ผ่านการตรวจสอบจะถูกทิ้ง
ผมเคยสร้างตัวตรวจจับการอ่านไฟล์ซ้ำ แต่จากการใส่คำอธิบายกำกับโดยมนุษย์กับตัวอย่าง 30 กรณี precision ต่ำกว่าเกณฑ์ที่ preregistered ไว้อย่างมาก (70%) — มองแบบผ่อนปรนก็แค่ 3.3% ถ้าเข้มงวดคือ 0% — จึงเลิกใช้ไปแล้ว ทั้งการคาดการณ์และผลลัพธ์ถูกเก็บไว้ด้วยกันในเอกสาร preregistration