diff แสดงว่าแพตช์อ้างว่าจะทำอะไร แต่ไม่ได้แสดงว่าบั๊กหายไปจริงหรือเปล่า แขนงใหม่ของ if เคยถูกรันบ้างไหม หรือการอัปเดต dependency ทำให้ import พังตอนติดตั้งใหม่หรือไม่ ผู้รีวิวรู้เรื่องนี้ดี จึงมีรีวิวจำนวนมากที่จบด้วยคำว่า "LGTM ถ้าเทสต์ผ่าน"
กับแพตช์ที่ AI เขียน ช่องว่างนี้ยิ่งกว้างขึ้น โมเดลผลิตโค้ดที่ดูน่าเชื่อได้อย่างรวดเร็ว และโค้ดที่ดูน่าเชื่อนี่แหละที่หลุดสายตาผู้รีวิวที่เหนื่อยล้า ทางแก้ราคาถูกคือรันการเปลี่ยนแปลงก่อนที่ใครจะอนุมัติ ในที่ที่มันทำอะไรเสียหายไม่ได้
การตรวจ: base, head และเทสต์
หลักฐานที่น่าเชื่อที่สุดที่แพตช์ให้ได้ คือขั้นตอนทำซ้ำที่ล้มบนโค้ดเก่าและผ่านบนโค้ดใหม่ แซนด์บ็อกซ์ทำให้เรื่องนี้กลายเป็นสคริปต์ 20 บรรทัด มันคือ Firecracker microVM ที่มี Python 3.12, Node.js 22, git และ curl เริ่มทำงานในราวหนึ่งวินาที:
import os
from eqvps import Sandbox
REPO, BASE, HEAD = os.environ["REPO_URL"], os.environ["BASE_SHA"], os.environ["HEAD_SHA"]
def repro(sb, ref):
sb.exec(f"cd /root/app && git checkout -q {ref}", timeout=55)
return sb.exec("cd /root/app && python3 /root/repro.py", timeout=55).exit_code
with Sandbox.create(tariff="standard", ttl=1800) as sb:
sb.exec(f"git clone -q {REPO} /root/app", timeout=55)
sb.exec("cd /root/app && pip install -q -r requirements.txt", timeout=55)
sb.upload("/root/repro.py", open("repro.py").read())
before, after = repro(sb, BASE), repro(sb, HEAD)
tests = sb.exec("cd /root/app && python3 -m pytest -q", background=True).wait()
print(f"repro on base: {before}, on head: {after}; tests: {tests.state}, exit {tests.exit_code}")
repro.py คือโค้ดตัวอย่างจากรายงานบั๊ก ถ้ามันจบด้วยโค้ดที่ไม่ใช่ศูนย์บน base และจบด้วยศูนย์บน head แปลว่าแพตช์แก้สิ่งที่อ้างว่าแก้ได้จริง โพสต์บรรทัดนั้นพร้อมสรุปผลเทสต์เป็นคอมเมนต์ใน pull request แล้วผู้รีวิวจะเริ่มจากข้อเท็จจริง
ชุดเทสต์รันเป็นงานเบื้องหลัง เพราะคำสั่งซิงโครนัสหนึ่งคำสั่งจะหยุดที่ 55 วินาที TTL 30 นาทีจำกัดว่าการรันที่ค้างจะคิดเงินคุณได้นานแค่ไหน
agent รีวิวที่รันโค้ด
ไอเดียเดียวกันใช้ได้กับผู้รีวิวที่เป็น AI agent ที่เชื่อมต่อผ่าน เซิร์ฟเวอร์ MCP มีเครื่องมือของแซนด์บ็อกซ์: สร้างแซนด์บ็อกซ์ รันคำสั่ง อัปโหลดและดาวน์โหลดไฟล์ แทนที่จะเขียนว่า "อาจทำให้เข้ากันไม่ได้กับ Python 3.8" มันจะดึง branch มารันโค้ดแล้วยก traceback มาให้ดู หรือรายงานว่าไม่มีปัญหา
ให้ agent แบบนี้มี เพดานค่าใช้จ่าย และโทเค็นแบบอ่านอย่างเดียว แล้วกำหนดว่าเครื่องมือใดเรียกได้โดยไม่ต้องถาม มาตรการป้องกันของ MCP จัดเรียงเครื่องมือทั้งหมดตามระดับความเสี่ยง
แพ็กเกจไหนดี
| Repository | แพ็กเกจ | รอบทั่วไป | ค่าใช้จ่ายโดยประมาณ |
|---|---|---|---|
| ไลบรารีขนาดเล็ก Python หรือ JS ล้วน | small (0.5 vCPU, 1 GB) | 2 นาที | $0.0011 |
| เว็บแอปที่มีชุดเทสต์ | standard (1 vCPU, 2 GB) | 5 นาที | $0.0055 |
| Native extension หรือ dependency ที่ต้องคอมไพล์ | plus (2 vCPU, 4 GB) | 15 นาที | $0.033 |
แซนด์บ็อกซ์ชั่วคราวคิดเงินรายวินาที ขั้นต่ำ 60 วินาที ถ้าผู้รีวิวอยากกลับมาที่สภาพแวดล้อมเดิมตลอดสองสามวัน ให้สร้างเป็น persistent แทน มันจะเก็บดิสก์ไว้ได้นานสูงสุด 30 วันและคิดเงินตามชั่วโมงที่เริ่มใช้ แซนด์บ็อกซ์ standard ที่เก็บไว้สำหรับรีวิวสองวันจึงมีค่าใช้จ่ายราว $3.17 ลบทิ้งเมื่อ pull request ถูก merge แล้ว
ข้อจำกัดที่ควรรู้
- สองคำสั่งพร้อมกันต่อบัญชี เพียงพอสำหรับการรีวิวที่ทำทีละรายการ ถ้าตรวจ pull request หลายสิบรายการพร้อมกัน จะต้องเข้าคิว
- ไม่มีพอร์ตขาเข้า เปิดแอปในเบราว์เซอร์ไม่ได้ ให้รันข้างในแล้วทดสอบด้วย
curl localhostจากคำสั่งที่สอง - ไม่มี Docker ข้างใน เทสต์ที่ต้องเปิดคอนเทนเนอร์ควรอยู่บน runner ใน VPS
- อินเทอร์เน็ตขาออกเปิดอยู่ นั่นคือสิ่งที่ทำให้
pip installใช้ได้ อย่าใส่อะไรลงในแซนด์บ็อกซ์ที่คุณจะไม่ให้กับผู้เขียนแพตช์
เริ่มต้นใช้งาน
บัญชีใหม่ได้เวลาแซนด์บ็อกซ์มูลค่า $1 ซึ่งพอสำหรับรีวิวมากกว่าร้อยรอบบนแพ็กเกจ standard หน้าแซนด์บ็อกซ์ มีแพ็กเกจทั้งหมด เอกสารอ้างอิง SDK มีทุกเมธอดที่ใช้ข้างต้น และ Python SDK ใน 5 นาที อธิบายการตั้งค่า
เกี่ยวข้อง: รันเทสต์ CI แบบแยกส่วน สำหรับทั้ง pipeline และ แซนด์บ็อกซ์สำหรับ AI agent สำหรับ agent ที่เขียนโค้ดตั้งแต่ต้น
ความคิดเห็น
ยังไม่มีความคิดเห็น เป็นคนแรกสิ