- เอเจนต์ LLM แข็งแกร่งในการสร้างโค้ดจากสเปกที่หลวม แต่ยังเปราะบางต่อการปฏิบัติตามข้อจำกัดของสัญญา API, สถาปัตยกรรม, DB และ ORM ที่แบ็กเอนด์ระดับใช้งานจริงต้องการ
- ใช้ สเปก OpenAPI เดียวกันเพื่อตรึงความต้องการด้านฟังก์ชัน และใช้การทดสอบพฤติกรรมชุดเดียวกันกับงานกรีนฟิลด์ 80 งานและงานพัฒนาฟีเจอร์ 20 งานในเว็บเฟรมเวิร์ก 8 ตัว
- ข้อจำกัดที่ไม่ใช่เชิงฟังก์ชันถูกแบ่งเป็น 4 มิติ ได้แก่ การเลือกเฟรมเวิร์ก, รูปแบบสถาปัตยกรรม, แบ็กเอนด์ฐานข้อมูล และการผสานรวม ORM เพื่อแยกผลของความซับซ้อนเชิงโครงสร้าง
- Constraint decay คือปรากฏการณ์ที่ประสิทธิภาพลดลงอย่างรุนแรงเมื่อความต้องการเชิงโครงสร้างสะสมเพิ่มขึ้น โดยในงานที่กำหนดรายละเอียดครบถ้วนและมีการตั้งค่าระดับสูง assertion pass rate ลดลงเฉลี่ย 30 จุด
- แกนหลักของความล้มเหลวคือ ข้อบกพร่องในชั้นข้อมูล โดยการประกอบ query ผิดพลาดและการละเมิดรันไทม์ของ ORM คิดเป็นราว 45% ของความล้มเหลวของตรรกะเอเจนต์
ปัญหาหลักและการตั้งค่าการประเมิน
- เอเจนต์ LLM มีความสามารถสูงในการสร้างโค้ดอัตโนมัติจากสเปกที่หลวม แต่ความสามารถในการปฏิบัติตามข้อจำกัดเชิงโครงสร้างอย่างเข้มงวดที่ซอฟต์แวร์แบ็กเอนด์ระดับใช้งานจริงต้องการนั้นยังไม่ได้รับการประเมินอย่างเพียงพอ
- แบ็กเอนด์ระดับใช้งานจริงต้องตอบสนองไม่เพียงแต่ endpoint ที่เป็นไปตามสัญญา API เท่านั้น แต่ยังต้องรองรับข้อกำหนดนอกเหนือจากฟังก์ชัน เช่น รูปแบบสถาปัตยกรรม การผสานรวมฐานข้อมูล และ ชั้น ORM ที่ระบุไว้
- benchmark เดิมมักให้รางวัลกับวิธีแก้ที่ถูกต้องเชิงฟังก์ชันแต่มีโครงสร้างตามอำเภอใจ จึงยังจับความยากของการพัฒนาแบ็กเอนด์หลายไฟล์ที่มีข้อจำกัดได้ไม่เพียงพอ
- งานวิจัยก่อนหน้านี้มุ่งเน้นหลักไปที่การแก้ปัญหาเฉพาะในโค้ดเบสเดิม การสร้างแบบไม่มีข้อจำกัดจากพรอมป์ธรรมชาติ วิธีแก้แบบไฟล์เดียว และการเติมโค้ด skeleton ให้สมบูรณ์ โดยยังไม่ได้ศึกษาผลของการปรับระดับข้อจำกัดเชิงโครงสร้างอย่างเป็นระบบ
- ใช้ สเปก OpenAPI เดียวกันเพื่อตรึงข้อกำหนดด้านฟังก์ชัน และใช้การทดสอบพฤติกรรม end-to-end ชุดเดียวกันในทุกเงื่อนไขเพื่อแยกผลของความซับซ้อนเชิงโครงสร้าง
- การทดลองประกอบด้วย งานสร้างกรีนฟิลด์ 80 งาน และ งานพัฒนาฟีเจอร์ 20 งาน ครอบคลุมเว็บเฟรมเวิร์ก 8 ตัว
- ข้อจำกัดที่ไม่ใช่เชิงฟังก์ชันถูกแบ่งเป็น 4 มิติ ได้แก่ การเลือกเฟรมเวิร์ก รูปแบบสถาปัตยกรรม แบ็กเอนด์ฐานข้อมูล และการผสานรวม ORM
- ในเงื่อนไขฐานจะให้เพียงสเปก API เดียวกัน ส่วนเงื่อนไขที่มีข้อจำกัดจะเพิ่มข้อกำหนดอย่าง clean architecture, PostgreSQL และ SQLAlchemy
- การประเมินใช้ทั้ง การทดสอบพฤติกรรม แบบ end-to-end และตัวตรวจสอบแบบสถิติควบคู่กัน เพื่อแยกความถูกต้องเชิงฟังก์ชันออกจากการปฏิบัติตามโครงสร้าง
ผลลัพธ์สำคัญและความหมาย
- Constraint decay ได้รับการยืนยันว่าเป็นปรากฏการณ์ที่ประสิทธิภาพของเอเจนต์ลดลงอย่างมากเมื่อข้อกำหนดเชิงโครงสร้างสะสมเพิ่มขึ้น
- แม้แต่การตั้งค่าที่ให้ประสิทธิภาพสูง เมื่อเปลี่ยนจากเงื่อนไขฐานไปสู่งานที่กำหนดรายละเอียดครบถ้วน ค่า assertion pass rate ก็ลดลงเฉลี่ย 30 จุด และบางการตั้งค่าที่อ่อนกว่าลดลงจนเกือบเป็น 0
- แม้ใช้สัญญา API เดียวกัน แต่อัตราความสำเร็จแตกต่างกันมากตามเฟรมเวิร์ก และเอเจนต์ทำงานได้ดีกว่าใน เฟรมเวิร์กที่เบาและชัดเจน อย่าง Flask
- ในสภาพแวดล้อมที่มีธรรมเนียมปฏิบัติมากอย่าง FastAPI และ Django ประสิทธิภาพเฉลี่ยลดลงอย่างมาก
- การวิเคราะห์ข้อผิดพลาดชี้ว่า ข้อบกพร่องในชั้นข้อมูล เป็นสาเหตุหลัก โดยมีตัวอย่างเด่นคือการประกอบ query ผิดพลาดและการละเมิดรันไทม์ของ ORM
- ข้อบกพร่องในชั้นข้อมูลถูกจัดเป็นสาเหตุหลักที่ทำให้ตรรกะเอเจนต์ล้มเหลวประมาณ 45%
- การตอบสนองทั้งข้อกำหนดด้านฟังก์ชันและข้อกำหนดเชิงโครงสร้างพร้อมกัน ยังเป็นโจทย์สำคัญที่ยังไม่ถูกแก้สำหรับเอเจนต์เขียนโค้ด
- pipeline การประเมิน ชุดงาน เส้นทางการรันของเอเจนต์ และสคริปต์วิเคราะห์ เผยแพร่ไว้ที่ constraint-decay
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เดิมทีฉันค่อนข้างไม่เชื่อถือการสร้างโค้ดด้วย LLM แบบสุด ๆ แต่ตอนนี้โค้ดที่ฉันใช้ทำงาน มากกว่า 80% กลายเป็นโค้ดที่ถูกสร้างขึ้นมาแล้ว
แต่ข้อจำกัดก็เริ่มชัดขึ้นมากเช่นกัน และเริ่มปรากฏในบางโปรเจกต์แล้ว ซึ่งบทความนี้ก็ดูเหมือนจะยืนยันข้อสงสัยของฉัน
ยิ่งงานซับซ้อน ก็ยิ่งต้องคอยเพิ่มข้อกำหนดใน Markdown, กฎ, ข้อจำกัดด้านสกิล, style guide, เงื่อนไขขอบเขต, การจัดการข้อผิดพลาด, และแนวทางการปรับแต่งประสิทธิภาพเข้าไปเรื่อย ๆ
จนถึงจุดหนึ่งมันดูเหมือนกับการย้ายความซับซ้อนที่เคยอยู่ในโลกที่เป็นทางการและกำหนดผลได้แน่นอนกว่าของภาษาโปรแกรม ไปอยู่ในโลกของ ภาษาธรรมชาติที่ไม่เป็นทางการและไม่กำหนดผลตายตัว
ความเร็วในการเขียนเพิ่มขึ้นอย่างมหาศาล และแน่นอนว่าฝั่งธุรกิจก็มองว่านี่คือการเพิ่มผลิตภาพ แต่ต้นทุนของมันก็ชัดเจน และดูเหมือนหลายคนจะมองข้ามไป
ไม่มีใครตรวจทาน 100% และถึงตรวจทานก็ยังเป็นเรื่องอัตวิสัยสูงมาก
ความต่างระหว่าง “ให้ยึดแนวทาง RESTful”, “เราใช้ REST ไม่ใช้ GraphQL”, และ “90% ของ endpoint เป็นแบบยึด resource แต่บางส่วนดูเหมือน RPC ก็ไม่ต้องสนใจ” นั้นคลุมเครือมาก
ทั้งหมดนี้ดูค่อนข้างงี่เง่า
ในทางปฏิบัติมันก็เหมือนคอมไพล์โปรแกรมที่เต็มไปด้วย undefined behavior แต่ส่วนใหญ่แค่ “ดูเหมือนจะใช้งานได้”
ที่ฝั่งธุรกิจมองว่านี่คือการเพิ่มผลิตภาพ ทำให้รู้สึกเหมือนเรากำลังย้อนกลับไปสู่ยุคที่วัด “ผลิตภาพ” กันด้วยจำนวนบรรทัดโค้ดต่อวินาทีอีกครั้ง
เมื่อ codebase ไม่สามารถอยู่ในช่วง 20% แรกของ context window และหลุดพ้นจากระดับที่ทำซ้ำได้ทั้งหมดด้วยการอนุมานครั้งเดียว execution harness และเทคนิคการ patch โค้ดจะสำคัญขึ้นมาก
แนวทาง apply_patch ที่ OAI ขัดเกลาให้กับโมเดลดูเหมือนเป็นวิธีที่ดีที่สุดสำหรับ codebase ขนาดใหญ่มาก
วิธีที่อิงกับช่วงบรรทัดหรือการ find-replace แบบง่าย ๆ จะพังตรงขอบ ๆ และการจัดการเคสยากอย่างไฟล์ cshtml ต้องใช้ anchor หลายจุดในหลายพื้นที่
พฤติกรรมแบบ prepare/commit เหมาะมากกับการวนซ้ำบนบริบทกำกวมที่กระจายอยู่ในไฟล์ใหญ่จำนวนมาก แล้วค่อย ๆ ปรับ anchor ให้แม่นขึ้น
LLM ไม่สามารถสร้างสิ่งใหม่ได้
“การศึกษาอย่างเป็นระบบเผยให้เห็นปรากฏการณ์ constraint decay ใน coding agent ที่อิงกับ LLM โมเดลปัจจุบันยอดเยี่ยมมากกับการสร้างแบบไร้ข้อจำกัด แต่เมื่อจำเป็นต้องทำตามกฎสถาปัตยกรรมที่ระบุไว้อย่างชัดเจน ประสิทธิภาพจะลดลง สำหรับผู้ใช้ปลายทาง ความเป็นสองขั้วนี้หมายความว่า agent นั้นเชื่อถือได้สำหรับการทำต้นแบบอย่างรวดเร็ว แต่ยังยากจะไว้วางใจสำหรับการพัฒนา backend ระดับ production”
จุดอ่อนใหญ่ของงานวิจัยนี้คือเพราะข้อจำกัดด้านต้นทุน จึงยังไม่ได้ทดสอบ frontier model อย่างเพียงพอ ดังนั้นควรดูตัวเลขประสิทธิภาพแบบเฉพาะเจาะจงอย่างระมัดระวัง
ถึงอย่างนั้น ข้อสรุปที่ว่าประสิทธิภาพของโมเดลลดลงเมื่อทั้งพฤติกรรมและสถาปัตยกรรมต้องถูกต้องพร้อมกัน ก็ยังน่าสนใจและควรติดตามต่อไป
ถ้ามีแค่ functional requirements ก็เหมือนกำลังทำ program synthesis รูปแบบหนึ่ง และ reinforcement learning ก็สามารถ optimize สิ่งนี้ได้แรงมาก
แต่เมื่อ functional requirements กับ non-functional requirements ปะปนกัน เท่ากับว่าเรากำลังให้สเปกที่ไม่สมบูรณ์กับโมเดล และโมเดลก็ต้องเดาเจตนาของผู้ใช้บางส่วนเพื่อเติมช่องว่าง
นี่ก็เป็นเหตุผลว่าทำไมการใส่ตัวอย่างรูปแบบโค้ดที่ต้องการลงในพรอมป์ต์จึงทรงพลังมาก
ยิ่งมีเนื้อหาให้อ้างอิงมากขึ้นเท่าไร มันก็ยิ่งพึ่งการพูดซ้ำสิ่งที่มาก่อนหน้ามากขึ้น
เป็นไปได้เหมือนกันว่าผู้เขียนใส่ใจน้อยลงและลงแรงตัดต่อน้อยลงเมื่อไปถึงบทท้าย ๆ
Amazon มีหนังสือออกมาปริมาณมหาศาล แต่ LLM ยังไม่ถึงขั้นเขียนหนังสือได้ดี
ถ้ามันเสนอวิธีแก้ที่เข้ากันไม่ได้ แล้วเราเติมบริบทและข้อกำหนดเพิ่มเข้าไป มันจะมีแนวโน้ม ยึดติด กับสถาปัตยกรรมเดิมและปรับตัวยาก
บางครั้งถึงขั้นพยายามแอบสอดการเปลี่ยนแปลงที่เอื้อกับแผนเดิมเข้ามา
ดูเหมือนว่าก้อนใหญ่ ๆ ของพื้นที่คำตอบที่เป็นไปได้จะเข้าถึงไม่ได้
ตัวอย่างเช่น เมื่อราวหนึ่งปีก่อน พอใส่ guardrails ให้กับเครื่องสร้างภาพ คนทุกคนก็เริ่มหน้าตาคล้าย ๆ กัน และเครื่องสร้างเรื่องเล่าก็เริ่มใช้ชื่อมาตรฐานอยู่ไม่กี่ชื่อ
ฉันสงสัยว่าแม้แต่ frontier model ตอนนี้ก็ยังเกิดเรื่องแบบนี้อยู่หรือเปล่า
ฉันไม่ได้สนใจการวิเคราะห์จุดอ่อนของโมเดลประเภทนี้มากนัก จากประสบการณ์ของฉัน เมื่อโมเดลเก่งขึ้นและเพิ่ม effort ในการใช้เหตุผล จุดอ่อนหลายอย่างจะหายไปหมด
โดยเฉพาะเมื่อบอกพฤติกรรมที่ต้องการให้ชัดเจน และก็ไม่น่าแปลกใจที่อัตราความล้มเหลวจะสูงขึ้นเมื่อ acceptance criteria เพิ่มขึ้น
สถานการณ์จริงแย่กว่านั้นอีก agent ไม่ได้แค่ลำบากขึ้นภายใต้ “ข้อจำกัดเชิงโครงสร้าง” เท่านั้น แต่จะยิ่งแย่หนักเมื่อ ข้อจำกัดเชิงโครงสร้างนั้นเองต้องเปลี่ยน
ตอนออกแบบระบบหรือคอมโพเนนต์ เราจะตั้งแนวคิดบางอย่างให้เป็น invariant
invariant บางอย่างมีขนาดใหญ่เท่ากับสถาปัตยกรรมทั้งชุด และบางอย่างก็เล็กเท่ากับการเลือก data structure
แต่สุดท้ายก็มักมีช่วงเวลาที่เราอยากเพิ่มฟีเจอร์ซึ่งชนกับ invariant นั้น
ตอนนั้นโดยทั่วไปมีทางเลือกอยู่สามแบบ: ไม่เพิ่มฟีเจอร์, เพิ่มฟีเจอร์ทับบน invariant แบบไม่สวยงามหรือไม่มีประสิทธิภาพ, หรือย้อนกลับไปแก้ invariant เอง
โดยมากจะมีแค่หนึ่งทางที่ถูก และอย่างน้อยหนึ่งทางก็ผิดแบบร้ายแรงจนก่อผลเสีย
agent นั้นแย่มากในการสังเกตว่า ถึงเวลาที่ต้องเปลี่ยนข้อจำกัดแล้ว แม้แต่ในกรณีที่มันยังพอทำตามข้อจำกัดได้อยู่ก็ตาม
นี่คือหนึ่งใน เส้นแบ่งระหว่างการรู้จำรูปแบบกับการให้เหตุผล และต่างจากคำโฆษณาเรื่องกระบวนการคิด LLM ไม่ได้ให้เหตุผลเลยแม้แต่น้อย
ความพยายามทุกอย่างที่จะทำให้มันดูเหมือนกำลังให้เหตุผล สำหรับฉันแล้วก็ใกล้เคียงกับความพยายามแบบ recursive containment ของ harness ที่พยายามจับสายฟ้าใส่ขวด
ทำให้นึกถึงงานวิจัยล่าสุดที่มอบหมายงานแก้ไขเอกสารในหลายสาขาให้ LLM https://arxiv.org/abs/2604.15597
ในงานนั้นมองว่าโดเมนเดียวที่ LLM ส่วนใหญ่สามารถทำ งานระยะยาว ได้โดยไม่สะสมข้อผิดพลาดและไม่ทำเอกสารพัง คือการเขียนโปรแกรม
งานนี้ฉันยังอ่านแค่บทคัดย่อ แต่ดูเหมือนว่าจะซูมเข้าไปที่การเขียนโปรแกรมอย่างละเอียดขึ้นและแสดงปรากฏการณ์คล้ายกัน
เพียงแต่มันดูใกล้เคียงกับ “ขอบเขตสไตล์ระยะยาว” ต่อชุดข้อจำกัดเชิงโครงสร้างที่ใหญ่กว่า มากกว่าจะเป็นงานระยะยาว
การอภิปรายที่เกี่ยวข้อง: https://news.ycombinator.com/item?id=48073246
เป็นงานวิจัยที่น่าสนใจมากและเห็นด้วยทั้งหมด แต่ไม่คิดว่าเป็นเรื่องใหม่
มันเบี่ยงจากความคาดหวังช่วงแรกไปนิดหน่อย ที่คิดว่าแค่โยนโซลูชันการเขียนโค้ดแบบเอเจนต์ลงในโปรเจกต์แล้วส่งรายการงานให้ มันจะปฏิบัติตามข้อจำกัดที่กำหนดไว้ล่วงหน้าของโปรเจกต์อย่างน่าอัศจรรย์
ฉันไม่เชื่อว่าชุดสแต็กการเขียนโค้ดแบบเอเจนต์ใด ๆ จะทำสิ่งนี้ได้ในสภาพตั้งต้น
ยังต้องมี กลไก ที่เหมาะสมเพื่อให้เอเจนต์เข้าใจบริบท ข้อจำกัด และเป้าหมายได้อย่างเสถียร และเมื่อดูจากการที่แล็บ AI หลัก ๆ ยังอัปเดตเครื่องมือ·สกิล·กระบวนการกันต่อเนื่อง ก็ชัดว่านี่ยังเป็นพื้นที่ที่กำลังพัฒนา
ชั้นเพิ่มเติมนี้อาจทำกำไรได้มากกว่าตัวโมเดลล้วน ๆ และการใช้โทเค็นเสียอีก
แม้แต่โมเดลเปิดที่ดูเหมือนถูกทดสอบอยู่ตอนนี้ ถ้ารันอย่างเหมาะสมก็สร้าง โค้ดโปรดักชัน ที่ทำตามข้อจำกัดที่ต้องการได้แล้ว
ช่วงไม่กี่เดือนที่ผ่านมา โค้ดโปรดักชันของพวกคุณเป็นอย่างไรกันบ้าง
ฉันทดลองการเขียนโค้ดแบบเอเจนต์ระยะยาวมาพอสมควร https://medium.com/@vishvananda/i-spent-2-billion-tokens-wri... และก็เห็นเหมือนกันว่าการบังคับใช้แพตเทิร์นสถาปัตยกรรมบางแบบทำให้ประสิทธิภาพของเอเจนต์แย่ลง
ถ้าใส่ข้อจำกัดเข้าไประหว่างทางแทนที่จะค่อยเติมทีหลัง มันจะดีขึ้นเล็กน้อย
มีผลข้างเคียงอย่างหนึ่งที่ฉันเรียกว่า การกลายเป็นหินปูน คือพอแพตเทิร์นบางอย่างเริ่มปรากฏในโค้ดเบส เอเจนต์จะไหลตามแพตเทิร์นนั้นจนมันครอบงำบริบทและเสริมตัวเอง
ในโค้ดเบสที่มีอยู่เดิม สิ่งนี้อาจเป็นได้ทั้งจุดแข็งหรือจุดอ่อนขึ้นอยู่กับคุณภาพของโค้ด
น่าจะได้อินไซต์มากขึ้นเมื่อการรันโค้ดเบสใหม่ที่มีแนวทางสถาปัตยกรรมตั้งแต่แรกเริ่มเสร็จสิ้น
อีกอย่าง โมเดลมักทำ modularization ได้พอใช้เมื่อมีพื้นที่ให้ “วางแผน” การนำไปใช้จริง แต่แทบไม่ค่อยตัดสินเองว่าควรทำ abstraction เพิ่มภายหลัง
ยิ่งเห็นชัดหลังทำซ้ำหลายรอบในโค้ดเบสใหม่ หรือเมื่อถูกปล่อยลงไปในโค้ดเบส legacy ซึ่งมักลงเอยเป็น ไฟล์ขนาดยักษ์
ถ้าผู้ใช้ชี้ให้เห็น โมเดลจะวิจารณ์ได้ถูกต้อง แต่พอเป็นโค้ดที่ตัวเองเขียนกลับดูตลกทีเดียว
ฟังดูเหมือนอีกเวอร์ชันของ “ยิ่งแชตยาว guardrail ก็ยิ่งเลือน”
เหตุผลที่ใช้ context window ไม่ได้ทั้งหมดก็เพราะช่วงท้าย ๆ เอาต์พุตจะไม่ยึดตามข้อจำกัดหรือ guardrail
แต่ถ้าจะสร้างโค้ดระดับโปรดักชันอย่างเสถียร โมเดลก็ต้องมีการรับรู้ที่กว้าง และนั่นทำให้ context window เต็มอย่างรวดเร็ว
มันคล้ายกับการบอกว่า “ให้คิดถึงทุกอย่างใน 6 ไดเรกทอรีนี้แล้วทำการเปลี่ยนแปลงนี้” ซึ่งแค่การคิดถึงทุกอย่างก็ทำให้ context window เต็มจนเสียความสามารถในการทำตามข้อจำกัดแล้ว
แต่ถ้าเป็นแบบนั้น รูปแบบความล้มเหลวก็น่าจะกลายเป็นการหมกมุ่นกับการทำให้ผ่าน linter แล้วค่อย ๆ ลืม requirement ไป
การลองผิดลองถูกซ้ำ ๆ ก็คงไม่ดีกับบริบทเลย
งานวิจัยนี้ใช้ภาษาแบบ dynamic type อย่าง Python และ JS
จากประสบการณ์ของฉัน โค้ดเบสแบบ static type ดูแลรักษาง่ายกว่าสำหรับคน ดังนั้นอาจง่ายกว่าสำหรับเอเจนต์ด้วย
ตอนใช้ Codex หรือ Claude Code กับโค้ด Go ฉันเห็นเอเจนต์แก้ไข รันบิลด์ หา error แล้วกลับไปแก้อย่างนี้นับครั้งไม่ถ้วน
ทุกวันนี้โมเดลจัดการ Python type ได้ค่อนข้างดี
ใน Python มีตัวเลือก static type ที่แข็งแรงมาหลายปีแล้ว และมันควรเป็นค่าเริ่มต้นได้แล้ว
เขาบอกว่าเป็น “งานที่ครอบคลุม 8 web framework” เลยสงสัยว่ามีใครรู้สึกเหมือนกันไหมว่า LLM ทำ HTML+CSS+JS ล้วน ๆ ได้ดีกว่าการทำงานกับ framework ที่มีอยู่
ชุดผสมที่น่าทึ่งที่สุดที่ฉันเห็นล่าสุดคือ Razor Pages พร้อม progressive enhancement ด้วย JavaScript
ในโครงแบบนี้ โมเดลรุ่นใหม่ตัดสินได้ค่อนข้างดีว่าอะไรควรเกิดฝั่งเซิร์ฟเวอร์ (cshtml) และอะไรควรเกิดฝั่งไคลเอนต์ (js)
แนะนำให้ใช้เวลาเกลาบางส่วนของโค้ดเบสให้เป็นรูปแบบที่เป็นสำนวนมาตรฐานก่อน แล้วกำหนดไฟล์พวกนั้นด้วย @ เป็น ไฟล์ตัวอย่าง
มันได้ผลดีกว่าการพยายามบังคับด้วย Markdown มาก
สำหรับอย่าง FastAPI ถือว่าโอเคพอสมควร แต่ JavaScript ดูแย่ที่สุด
ต่อให้ให้ทั้งคำสั่งและตัวอย่าง มันก็ยังมีแนวโน้มจะอินไลน์โค้ดที่ไม่จำเป็นกองโต แทนที่จะใช้ API ที่ระบุ