
เฟรมเวิร์กเอเจนต์ส่วนใหญ่ในปัจจุบันถูกออกแบบมาสำหรับเดสก์ท็อป ผู้ใช้หนึ่งคน เครื่องหนึ่งเครื่อง กระบวนการหนึ่งกระบวนการ เอเจนต์จะทำงานในขณะที่เปิดแล็ปท็อป เขียนข้อมูลลงในระบบไฟล์ในเครื่อง เก็บคีย์ API ไว้ในตัวแปรสภาพแวดล้อม และจะหยุดทำงานเมื่อปิดเทอร์มินัล เมื่อเกิดข้อผิดพลาด ผู้ใช้ก็ลองใหม่ เมื่อเอเจนต์ต้องการแพ็กเกจ ก็ใช้ pip install ลงใน Python ของผู้ใช้ สถานะ ความลับ และวงจรชีวิตทั้งหมด อยู่ภายในขอบเขตที่เชื่อถือได้เพียงขอบเขตเดียว
โครงสร้างพื้นฐานของคลาวด์เอเจนต์ไม่มีสิทธิพิเศษเหล่านั้นเลย
เอเจนต์ทำงานบนแซนด์บ็อกซ์ที่บูตเครื่องใหม่หมด บนฮาร์ดแวร์ที่ใช้ร่วมกับคนแปลกหน้า ถูกเรียกใช้โดยผู้เรียกที่ผู้ใช้ไม่เคยรู้จัก: กำหนดการ, คำขอ HTTP, หรือเอเจนต์ตัวอื่น ผู้ใช้มักจะกำลังหลับอยู่ตอนที่รัน โค้ดภายในแซนด์บ็อกซ์อาจเป็นปฏิปักษ์ได้ ระบบไฟล์ต้องอยู่รอดผ่านการ Deploy หลายครั้ง ข้อมูลรับรองไม่สามารถอยู่ที่เดียวกับที่เอเจนต์อยู่ การรับประกันทุกอย่างที่เดสก์ท็อปมอบให้คุณได้โดยไม่ต้องลงทุนอะไรเลย เช่น ความคงทน อัตลักษณ์ ความน่าเชื่อถือของเครือข่าย การลองใหม่ ล้วนต้องถูกสร้างขึ้นใหม่เป็นระบบที่ชัดเจน
เราใช้เวลาสองสามเดือนที่ผ่านมาในการทำให้เลเยอร์นั้นแข็งแกร่งขึ้นที่ CREAO มีบทเรียนสองข้อที่ได้เรียนรู้ หากคุณเคย Deploy เอเจนต์บนเดสก์ท็อปและสงสัยว่าจะเปลี่ยนแปลงอะไรบ้างเมื่อมันย้ายไปยังคลาวด์ นี่คือสิ่งที่เปลี่ยนแปลง
บทเรียนที่ 1: แยกสิ่งที่เปลี่ยนแปลงช้าออกจากสิ่งที่เปลี่ยนแปลงเร็ว

บนเดสก์ท็อป สภาพแวดล้อมของผู้ใช้และรันไทม์ของเอเจนต์คือสิ่งเดียวกัน อัปเดตในจังหวะเดียวกัน โดยคนคนเดียวกัน ในคลาวด์ สิ่งเหล่านี้ไม่ใช่สิ่งเดียวกัน
แอปพลิเคชันเอเจนต์จะสะสมสถานะไว้บนฝั่งแพลตฟอร์ม นักวิเคราะห์หุ้นติดตั้ง matplotlib ดาวน์โหลดข้อมูลตลาด เขียนสคริปต์สร้างแผนภูมิ สภาพแวดล้อมนั้นคือความจำของกล้ามเนื้อของเอเจนต์ เราจะแช่แข็งมันไว้เป็นสแนปช็อตของแซนด์บ็อกซ์ทันทีที่ผู้ใช้พอใจ และเราจะเก็บสแนปช็อตนั้นไว้จนกว่าผู้ใช้จะแก้ไขสภาพแวดล้อมอีกครั้ง ทุกครั้งที่รันจะบูตจากอิมเมจเดียวกัน แพ็กเกจเดียวกัน ไฟล์เดียวกัน เวอร์ชันเดียวกัน การรันในวันจันทร์จะเหมือนกับการรันในวันศุกร์ เพราะไม่มีอะไรด้านล่างที่ขยับไปไหน
นี่คือคุณสมบัติที่เฟรมเวิร์กบนเดสก์ท็อปไม่สามารถมอบให้คุณได้ฟรี การ pip install เมื่อหกเดือนก่อนจะแก้ไขเป็นเวอร์ชันที่แตกต่างกันในวันนี้ สแนปช็อตบนคลาวด์จะแก้ไขเป็นไบต์เดียวกันตลอดไป ความสามารถในการทำซ้ำได้เป็นสิ่งที่แพลตฟอร์มเป็นหนี้ผู้ใช้ และสแนปช็อตที่ถูกแช่แข็งคือวิธีที่ถูกที่สุดในการส่งมอบมัน
จากนั้นปัญหาการเชื่อมโยงก็ปรากฏขึ้น
อิมเมจเดียวกันที่แช่แข็งสภาพแวดล้อมของผู้ใช้ ยังมีโค้ดของ Runner ซึ่งเป็นไลบรารีตัวช่วยขนาดเล็กที่เราพัฒนาขึ้นเพื่อจัดการเอเจนต์ในแต่ละการรัน ผู้ใช้ต้องการให้สภาพแวดล้อมของพวกเขาหยุดนิ่ง เราต้องการให้ Runner ของเราสามารถ Deploy ได้หลายครั้งต่อวัน สิ่งประดิษฐ์ชิ้นเดียว แต่มีความต้องการที่ตรงกันข้ามกันสองอย่าง
การแก้ไขครั้งแรกของเราค่อนข้างทื่อ เมื่อบูต ให้ตรวจสอบว่า Runner ภายในสแนปช็อตตรงกับเวอร์ชันที่เราเพิ่ง Deploy หรือไม่ ถ้าไม่ตรง ให้ทิ้งสแนปช็อตนั้นแล้วบูตจากเทมเพลตที่สะอาด มันใช้ได้ และไม่มีใครบ่น ความเสียหายเกิดขึ้นเฉพาะการรันครั้งแรกหลังการ Deploy เท่านั้น
การรันแบบไม่ต้องมีคนดูแลทำให้การป้องกันนั้นใช้ไม่ได้ผล การทำงาน Cron Job เวลา 9 โมงเช้าวันจันทร์ไม่ควรสูญเสียสภาพแวดล้อมไปเพราะเรา Deploy ตอน 8:55 น. สัญญาที่เรากำลังละเมิดอย่างเงียบ ๆ คือ "สภาพแวดล้อมของคุณจะถูกแช่แข็งจนกว่าคุณจะเปลี่ยนแปลงมัน"
การแก้ไขใช้เวลานานกว่าที่ควรจะคิดได้ สภาพแวดล้อมของผู้ใช้และโค้ด Runner เปลี่ยนแปลงในอัตราที่แตกต่างกันอย่างสิ้นเชิง ผู้ใช้แก้ไขเอเจนต์ของตนเมื่อพวกเขาเลือกที่จะทำ เราปรับใช้แพลตฟอร์มหลายครั้งต่อวัน การปฏิบัติต่อพวกมันเป็นสิ่งประดิษฐ์ชิ้นเดียว บังคับให้เราต้องเลือกในการ Deploy ทุกครั้ง: เก็บโค้ด Runner ที่ล้าสมัยไว้ หรือทำลายสภาพแวดล้อมที่ถูกแช่แข็งซึ่งผู้ใช้ขอให้เราเก็บรักษาไว้อย่างชัดเจน
โมเดลที่เราลงเอยด้วยนั้นยืมมาจากวิธีการที่ระบบปฏิบัติการจัดการกับการอัปเดต เคอร์เนลเปลี่ยนไป โฮมไดเรกทอรีของคุณไม่เปลี่ยน คุณจะไม่ล้างดิสก์เพื่อติดตั้งแพตช์รักษาความปลอดภัย
เราวาดขอบเขตเดียวกันนั้น แซนด์บ็อกซ์บูตจากสแนปช็อตที่ถูกแช่แข็งของผู้ใช้โดยไม่ถูกแตะต้อง จากนั้นเราจะสลับเฉพาะ Runner แบบ Hot-Swap ลำดับคือ:
- จัดเตรียม Runner ตัวใหม่ในไดเรกทอรีชั่วคราวภายในแซนด์บ็อกซ์
- ตรวจสอบความถูกต้องด้วย
node --checkเพื่อจับข้อผิดพลาดทางไวยากรณ์ก่อนที่จะแตะต้องสิ่งใดที่กำลังทำงานอยู่ - สลับมันแบบอะตอมมิก: ปลดล็อกแอตทริบิวต์ Immutable บน Runner เก่า คัดลอกตัวใหม่เข้าไป ล็อคอีกครั้งด้วย
chattr +iจากนั้นซ่อนไบนารีchattrเองเพื่อให้โค้ดในแซนด์บ็อกซ์ไม่สามารถย้อนกลับการล็อคได้ - ล้าง V8 compile cache (
/home/user/.cache/v8-compile-cache/*) เพื่อให้ไฟล์ใหม่โหลดจริง ๆ แทนที่จะรัน bytecode ที่เก่า - หากขั้นตอนใดล้มเหลว ให้ฆ่าแซนด์บ็อกซ์แล้วลองใหม่ด้วยอันใหม่ จะไม่มีสถานะที่อัปเกรดครึ่งทางไปรันเอเจนต์เด็ดขาด
การสลับทั้งหมดใช้เวลาประมาณ 300 มิลลิวินาที เราจะทำสแนปช็อตใหม่หลังจากการรันที่สำเร็จเฉพาะเมื่อมีการสลับโค้ด Runner เท่านั้น โดยอบโค้ดที่อัปเดตลงในอิมเมจของผู้ใช้ เพื่อให้การรันครั้งถัดไปข้ามการสลับไปเลย การ Deploy แพลตฟอร์มจะไม่ทิ้งสถานะของผู้ใช้ แต่จะรวม Runner ใหม่เข้าไปในนั้น แพ็กเกจ ไฟล์ และการปรับแต่งของผู้ใช้จะถูกส่งต่อโดยไม่เปลี่ยนแปลง
หากคุณจะจำอะไรสักอย่างจากบทเรียนนี้ นั่นคือคำถามเพื่อการวินิจฉัย สำหรับสิ่งใดก็ตามที่คุณคงอยู่ในแพลตฟอร์มคลาวด์ ให้ถาม: ใครเป็นผู้ควบคุมจังหวะการเปลี่ยนแปลงของสิ่งประดิษฐ์นี้? หากทั้งผู้ใช้และแพลตฟอร์มเป็นเจ้าของมันร่วมกัน ในที่สุดคุณจะต้องจ่ายค่าการเชื่อมโยงนั้น แบ่งสิ่งประดิษฐ์ตามแนวการเป็นเจ้าของ และปล่อยให้แต่ละฝ่ายอัปเดตตามนาฬิกาของตนเอง
บทเรียนที่ 2: เก็บความลับออกจากขอบเขตการทำงาน

นี่คือบทเรียนที่แยกโครงสร้างพื้นฐานของคลาวด์เอเจนต์ออกจากทุกสิ่งทุกอย่าง
เอเจนต์บนเดสก์ท็อปทำงานในฐานะผู้ใช้ มันใช้คีย์ของผู้ใช้ บนเครื่องของผู้ใช้ กับเครือข่ายของผู้ใช้ เอเจนต์บนคลาวด์ทำงานในฐานะไม่มีใครเลย บนฮาร์ดแวร์ที่ใช้ร่วมกัน กับอินเทอร์เน็ตเปิด โดยเรียกใช้โค้ดที่ LLM เขียนจากพรอมต์ที่อาจเป็นปฏิปักษ์ โมเดลความปลอดภัยต้องสมมติว่าโค้ดภายในแซนด์บ็อกซ์ถูกบุกรุกไปแล้ว ไม่ใช่แค่หวังว่ามันจะไม่เกิดขึ้น
กฎที่เรายึดถือนั้นง่ายมาก ไม่มีข้อมูลรับรองที่มีอายุยืนยาวใด ๆ อาศัยอยู่ภายในแซนด์บ็อกซ์
เมื่อเอเจนต์จำเป็นต้องเรียกใช้บริการที่ต้องรับรองความถูกต้อง เช่น Slack, GitHub, API ของผู้ใช้เอง มันจะไม่เก็บโทเคนไว้ มันจะส่งคำขอ HTTP ในเครื่องไปยังสะพานเชื่อม API ที่ทำงานอยู่นอกแซนด์บ็อกซ์ สะพานเชื่อมจะแนบ OAuth token ไว้บนฝั่งโฮสต์และส่งต่อการเรียก คำตอบจะกลับมาโดยที่โทเคนไม่เคยเข้าสู่หน่วยความจำหรือสภาพแวดล้อมของแซนด์บ็อกซ์
ส่วนที่น่าสนใจคือ สะพานเชื่อมรู้ได้อย่างไรว่าแซนด์บ็อกซ์ได้รับอนุญาตให้ถาม มีการตรวจสอบสองขั้นตอน ซ้อนกันโดยเจตนา
ประการแรก IP allowlist สะพานเชื่อมจะยอมรับการเชื่อมต่อจากช่วงเครือข่ายภายในที่โฮสต์แซนด์บ็อกซ์ของเราอาศัยอยู่เท่านั้น การเรียกจากที่อื่นใด เช่น แล็ปท็อปของนักพัฒนา URL ที่รั่วไหล หรืออินเทอร์เน็ตสาธารณะ จะถูกทิ้งที่เลเยอร์เครือข่าย ก่อนที่โค้ดแอปพลิเคชันใด ๆ จะทำงาน สิ่งนี้จะยึดสะพานเชื่อมไว้กับโครงสร้างพื้นฐานทางกายภาพชิ้นเดียว และทำให้มันไร้ประโยชน์สำหรับใครก็ตามที่อยู่นอกนั้น
ประการที่สอง JWT อายุสั้นที่สร้างขึ้นต่อการรันหนึ่งครั้ง เมื่อแซนด์บ็อกซ์บูต แพลตฟอร์มจะเซ็นโทเคนที่กำหนดขอบเขตเฉพาะการรันนั้น: ผู้ใช้คนใด แอปใด เซสชันใด โดยมีวันหมดอายุที่ครอบคลุมช่วงเวลาการรันเท่านั้น แซนด์บ็อกซ์จะนำเสนอโทเคนนี้ทุกครั้งที่มีการเรียกสะพานเชื่อม สะพานเชื่อมจะตรวจสอบลายเซ็น ตรวจสอบวันหมดอายุ จากนั้นจึงแก้ไขข้อมูลรับรองที่เก็บไว้ของผู้ใช้และแนบไปทางฝั่งเซิร์ฟเวอร์ หากแซนด์บ็อกซ์ถูกยึด ผู้โจมตีจะได้รับโทเคนที่หมดอายุพร้อมกับการรัน และอนุญาตเฉพาะการเรียกที่กำหนดขอบเขตไว้กับเซสชันนั้นเท่านั้น ไม่มีข้อมูลรับรองหลักให้ขโมย
สะพานเชื่อมเดียวกันนี้ยังนำการหักค่าใช้จ่าย บันทึก และเมตริกออกไป ดังนั้นมันจึงเป็นอินเทอร์เฟซเดียวที่ข้ามขอบเขตแซนด์บ็อกซ์ในทั้งสองทิศทาง ทุกสิ่งอย่างอื่นภายในแซนด์บ็อกซ์จะถูกถือว่าถูกบุกรุกตามค่าเริ่มต้น
หากพรอมต์อินเจคชันทำให้เอเจนต์ทิ้ง process.env ไปยัง Webhook ในวันพรุ่งนี้ ผู้โจมตีจะได้ JWT อายุสั้นที่ใช้ได้จากภายในเครือข่ายของเราเท่านั้นและหมดอายุพร้อมกับการรัน คุณสมบัตินั้นคือสิ่งที่ทำให้เราสามารถรันโค้ดผู้ใช้ที่ไม่น่าเชื่อถือบนโครงสร้างพื้นฐานที่ใช้ร่วมกันได้ โดยไม่ต้องกังวล
รูปแบบที่อยู่เบื้องล่าง
โครงสร้างพื้นฐานของคลาวด์เอเจนต์ที่เชื่อถือได้และปลอดภัยไม่ใช่ระบบที่แปลกใหม่ มันคือคุณสมบัติไม่กี่ข้อที่ยึดถือโดยไม่มีข้อยกเว้น:
- สถานะอยู่ในแซนด์บ็อกซ์ ถูกแช่แข็งจนกว่าผู้ใช้จะเปลี่ยนแปลงมัน
- โค้ดสามารถสลับแบบ Hot-Swap ได้ เป็นอิสระจากสถานะ
- ข้อมูลรับรองอยู่ฝั่งโฮสต์ ไม่เคยอยู่ภายในเอเจนต์
- ไพพ์ไลน์การทำงานหนึ่งชุดให้บริการแก่ผู้เรียกทุกคน ไม่ว่าตัวกระตุ้นจะเป็นมนุษย์ ตัวกำหนดเวลา หรือซอฟต์แวร์อื่น
คุณสมบัติสุดท้ายคือประเด็นสำคัญของการออกแบบทั้งหมด ฟังก์ชัน executeAgent เดียวกันจัดการการคลิก UI การรันตามกำหนดเวลา และการเรียก API ระบบการเรียกเก็บเงิน บันทึกการหักเครดิต สัญญาณการสังเกตการณ์ ทั้งหมดเหมือนกัน ไม่ว่ามนุษย์จะคลิก Run, Cron Job จะทำงาน หรือสคริปต์จะเรียก API การเพิ่มพื้นผิวตัวกระตุ้นใหม่คือการเปลี่ยนแปลงการกำหนดเส้นทาง ไม่ใช่การเปลี่ยนแปลงสถาปัตยกรรม ตัวเอเจนต์เองไม่รู้หรือสนใจว่าใครเป็นคนดึงไกปืน
นั่นคือสิ่งที่เฟรมเวิร์กบนเดสก์ท็อปไม่สามารถให้คุณได้ และสิ่งที่ทำให้เวอร์ชันคลาวด์คุ้มค่าที่จะสร้าง เอเจนต์บนแล็ปท็อปผูกติดอยู่กับแล็ปท็อป เอเจนต์ในคลาวด์คือฟังก์ชันที่ส่วนอื่น ๆ ใน Stack ของคุณสามารถเรียกใช้ได้ ผู้ใช้เขียนมันครั้งเดียว แพลตฟอร์มทำให้มันอยู่รอดผ่านการ Deploy ทำงานได้อย่างปลอดภัยบนฮาร์ดแวร์ที่ใช้ร่วมกัน และยอมรับผู้เรียกที่ผู้ใช้ไม่เคยคาดคิดมาก่อน
เอเจนต์คือฟังก์ชันที่มีอินเทอร์เฟซภาษาธรรมชาติ การนำไปใช้งานเป็นของผู้ใช้ พื้นผิวตัวกระตุ้น รันไทม์ ขอบเขตความปลอดภัย เป็นของแพลตฟอร์ม ระเบียบวินัยคือการสร้างเลเยอร์เพื่อให้แต่ละส่วนวิวัฒนาการตามนาฬิกาของตัวเอง และใช้เวลาในการหารอยร้าวระหว่างระบบก่อนที่คนอื่นจะเจอมัน
นั่นคือสิ่งที่ทำให้พื้นผิวถัดไปมีราคาถูกและปลอดภัยที่จะ Deploy





