วิธีแชร์ Agent Skills ข้าม Repository ไม่ให้โค้ดเพี้ยน
หยุดคัดลอกไฟล์ Agent Skills ไปวางซ้ำในหลายโปรเจกต์จนเกิดปัญหาโค้ดไม่ตรงกัน เปลี่ยนมาจัดการด้วยระบบ Dependency ที่มีการระบุเวอร์ชันและทำ Smoke Test เพื่อควบคุมคุณภาพอย่างเป็นระบบ
วิธีการแชร์ทักษะของ Agent ข้าม Repository
หากต้องการแชร์ทักษะของ Agent ข้าม Repository ให้หยุดการคัดลอกไฟล์และเปลี่ยนมาใช้วิธีการอ้างอิงแทน โดยให้คง Repository ของทักษะไว้ที่เดียว ทำการ tag เวอร์ชัน และให้แต่ละโปรเจกต์ระบุเวอร์ชันผ่าน tag นั้น จากนั้นให้เพิ่ม smoke test สำหรับแต่ละทักษะ และตรวจสอบการอัปเดตเวอร์ชันทุกครั้งเช่นเดียวกับการตรวจสอบการอัปเดต Dependency
กระบวนการนี้ประกอบด้วย 4 ส่วน ได้แก่ แหล่งข้อมูลหลักที่ใช้ร่วมกัน, การระบุเวอร์ชันที่แน่นอนในแต่ละ Repository, การทำ smoke test สำหรับแต่ละทักษะ และขั้นตอนการตรวจสอบ เนื้อหาด้านล่างนี้จะอธิบายถึงเหตุผลที่ต้องมีแต่ละส่วน สิ่งที่เครื่องมือที่ปล่อยออกมาในปี 2026 ช่วยจัดการในเรื่องนี้ และวิธีการสร้างระบบทั้งหมดบน git remote ที่คุณโฮสต์เองโดยไม่ต้องพึ่งพาบริการภายนอก
ทักษะของ Agent คือโฟลเดอร์ที่เก็บไฟล์ SKILL.md รวมถึงสคริปต์และไฟล์อ้างอิงที่จำเป็น หากหน่วยข้อมูลนี้เป็นสิ่งใหม่ โปรดอ่าน ทักษะของ Agent คืออะไรและ SKILL.md ทำงานอย่างไร ก่อน หน้าเว็บนี้จะกล่าวถึงห่วงโซ่อุปทานที่เกี่ยวข้องกับหน่วยข้อมูลดังกล่าว
แหล่งที่เก็บทักษะและเหตุผลที่การแบ่งปันเป็นเรื่องยาก
Claude Code โหลดทักษะจากสามแหล่ง ซึ่ง เอกสารประกอบเกี่ยวกับทักษะ ได้ระบุพาธของแต่ละแหล่งไว้ดังนี้
~/.claude/skills/<skill-name>/SKILL.mdเป็นส่วนตัว ทักษะนี้จะถูกโหลดในทุกโปรเจกต์ของคุณเท่านั้น ไม่ส่งผลต่อผู้อื่น.claude/skills/<skill-name>/SKILL.mdเป็นระดับโปรเจกต์ ทักษะนี้จะถูกโหลดสำหรับทุกคนที่ checkout repository นั้นๆ<plugin>/skills/<skill-name>/SKILL.mdมาพร้อมกับปลั๊กอิน ทักษะนี้จะถูกโหลดทุกที่ที่มีการเปิดใช้งานปลั๊กอินนั้น
แหล่งที่สองมีประโยชน์ที่สุดสำหรับทีม เพราะมีการ commit เข้าสู่ระบบและทุกคนที่ clone repository จะได้รับทักษะนี้ไปใช้งานด้วย แต่นี่คือจุดที่ปัญหาเริ่มต้นขึ้น ทักษะที่อยู่ใน .claude/skills/ จะผูกติดอยู่กับ repository เดียว หากคุณมีแปด repository ทักษะดังกล่าวก็จะถูกคัดลอกไปถึงแปดครั้ง
ส่วน frontmatter ไม่ได้ช่วยแก้ปัญหานี้ ข้อกำหนด Agent Skills อนุญาตให้ใช้คีย์ได้หกรายการ และพาธการกระจายทักษะที่บังคับใช้ข้อกำหนดนี้จะแสดงรายการคีย์ออกมาเมื่อคุณพยายามใช้คีย์อื่น:
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, nameสังเกตสิ่งที่ขาดหายไป: ไม่มีคีย์ version อยู่เลย ไม่มีข้อมูลใดภายในไฟล์ที่บันทึกว่าสำเนาใดใหม่กว่ากัน ซึ่งเป็นเรื่องสมเหตุสมผลเนื่องจากทักษะเป็นเพียงเอกสารไม่ใช่แพ็กเกจ แต่นั่นหมายความว่าการจัดการเวอร์ชันจะต้องมาจากเลเยอร์ที่ครอบไฟล์ไว้อีกชั้นหนึ่ง และเลเยอร์นั้นคือหน้าที่ของคุณ
ปัญหาที่หนึ่ง: สำเนาแปดชุดที่ค่อยๆ แตกต่างกัน
การคัดลอกและวางทำงานได้ในวันแรก แต่จะล้มเหลวในวันที่หกสิบ มีคนแก้ไขคำสั่งที่ผิดพลาดใน repo payments แต่ไม่ได้แตะต้องอีกเจ็ดชุดที่เหลือ อีกคนหนึ่งเพิ่มกฎเกี่ยวกับการแบ่งหน้าใน orders ตอนนี้ชื่อทักษะเดียวกันให้ผลลัพธ์ที่ต่างกันสองแบบ ขึ้นอยู่กับว่า agent เริ่มทำงานในไดเรกทอรีใด และไม่มีนักพัฒนาคนไหนทราบเรื่องนี้
ความล้มเหลวนี้เงียบเชียบเพราะไม่มีสถานะข้อผิดพลาด ทักษะคือข้อความ คำสั่งที่ล้าสมัยจะสร้างคำตอบที่มั่นใจแต่ผิดพลาด ซึ่งเป็นความผิดพลาดที่มีราคาแพง ไม่มีสิ่งใดใน agent ที่เปรียบเทียบสำเนาของคุณกับของคนอื่น ดังนั้นสัญญาณเดียวที่จะพบคือการที่มีคนสังเกตเห็นว่า repo สองแห่งไม่ตรงกัน
ปัญหาที่สอง: ไม่มีการระบุเวอร์ชันที่แน่นอน
แม้ว่าทีมจะเก็บทักษะไว้ในที่เดียวกัน แต่วิธีการแบ่งปันที่ใช้กันทั่วไปคือการคัดลอกไฟล์ ไม่ว่าจะเป็นสคริปต์ติดตั้ง, บรรทัด curl ในเอกสารแนะนำพนักงานใหม่ หรือ shell alias ที่ใช้ซิงค์โฟลเดอร์ วิธีการเหล่านี้ล้วนติดตั้งสิ่งที่อยู่บนสุดของ branch ในขณะนั้นทั้งสิ้น
นั่นหมายความว่านักพัฒนาสองคนที่ทำงานบน commit เดียวกันของแอปพลิเคชันเดียวกัน อาจกำลังรันคำสั่งที่แตกต่างกัน เพราะพวกเขาทำการซิงค์ในวันที่ต่างกัน นอกจากนี้ยังหมายความว่าคุณไม่สามารถตอบคำถามสำคัญหลังจากที่ agent ทำงานผิดพลาดได้ว่า: ทักษะเวอร์ชันใดที่สร้างผลลัพธ์นี้ขึ้นมา? หากไม่มีการบันทึก revision ไว้ การรันนั้นจะไม่สามารถทำซ้ำได้ ส่งผลให้รายงานข้อผิดพลาดไม่สามารถนำไปดำเนินการแก้ไขต่อได้
ปัญหาที่สาม: ไม่มีใครทราบว่าทักษะยังคงทำงานได้ตามปกติหรือไม่
ทักษะ (skill) ไม่มีคอมไพเลอร์ เนื่องจากเป็นชุดคำสั่งที่มุ่งเน้นไปที่โมเดล จึงสามารถหยุดทำงานได้อย่างถูกต้องแม้ว่าไฟล์จะยังคงเหมือนเดิมทุกประการในระดับไบต์ การอัปเกรดโมเดลอาจเปลี่ยนระดับความแม่นยำในการปฏิบัติตามคำสั่งที่ยาวเหยียด เครื่องมือบรรทัดคำสั่งที่ทักษะเรียกใช้งานอาจมีการเปลี่ยนชื่อ flag หรือ URL ในไฟล์อ้างอิงอาจเริ่มส่งค่า 404 กลับมา ทำให้เอเจนต์ทำงานโดยอ้างอิงจากหน้าแสดงข้อผิดพลาดแทน
ไม่มีสิ่งใดแจ้งเตือนความล้มเหลวอย่างชัดเจนในกรณีเหล่านี้ เอเจนต์ยังคงตอบกลับได้ตามปกติ เพียงแต่คำตอบนั้นมีคุณภาพแย่ลงกว่าเมื่อเดือนที่แล้ว ซึ่งเป็นสิ่งที่สังเกตได้ยากหากพิจารณาเพียงทีละ pull request
สิ่งที่เครื่องมือที่เปิดตัวในปี 2026 เข้ามาแก้ไข
ขณะนี้มีคำตอบหลายรูปแบบปรากฏขึ้น ซึ่งยังมีความเห็นไม่ตรงกันว่าควรเก็บข้อมูลเวอร์ชันไว้ที่ใด
Lockfiles. เครื่องมือบรรทัดคำสั่ง skills จาก Vercel Labs (vercel-labs/skills, สัญญาอนุญาต MIT, เวอร์ชัน 1.5.22 ณ วันที่ 5 สิงหาคม 2026) จะติดตั้ง skill จาก git repository ลงในไดเรกทอรีที่ agent ของคุณกำหนดไว้ โดยเครื่องมือนี้รองรับโครงสร้างของ agent มากกว่า 70 รายการ npx skills add <repo> ใช้สำหรับติดตั้ง, npx skills update ใช้สำหรับอัปเกรด และ npx skills list ใช้สำหรับแสดงรายการที่คุณมี บันทึกสิ่งที่ติดตั้งจะถูกเก็บไว้ต่อผู้ใช้หนึ่งรายแทนที่จะเก็บต่อหนึ่ง repository ทั้งนี้มีคำร้องขอในโปรเจกต์ดังกล่าว (issue 283) ที่ต้องการคำสั่ง skills install เพื่อติดตั้ง skill ทั้งหมดที่ถูกติดตามจาก lock file ใหม่ เพื่อให้เครื่องที่สองมีชุด skill ที่เหมือนกัน ให้ถือว่าคำร้องขอนั้นเป็นรายงานสถานะ แนวคิดเรื่อง lockfile นั้นได้ข้อสรุปแล้ว แต่ส่วนที่ทำงานต่อโปรเจกต์นั้นยังอยู่ในระหว่างการพัฒนา
Specs และการทดสอบ. SkillSpec มองในมุมที่ต่างออกไป โดยมองว่า SKILL.md เป็นสัญญาที่ต้องตรวจสอบแทนที่จะเป็นเพียงข้อความที่ต้องเชื่อถือ โดยมีเป้าหมายที่ระบุไว้คือการทำให้ skill "ติดตามได้ ทดสอบได้ และพิสูจน์ได้" skillspec doctor <path> จะรายงานจุดที่ agent มีแนวโน้มจะทำ thread หลุด skillspec boundary map <path> จะรายงานสิ่งที่ skill สามารถเข้าถึงได้ และ skillspec boundary assess <path> จะจัดอันดับสิ่งที่พบตามระดับความเสี่ยง เครื่องมือนี้เป็น Rust crate ที่ใช้สัญญาอนุญาตแบบคู่คือ MIT หรือ Apache 2.0 ที่เวอร์ชัน 0.2.2 ณ วันที่ 29 กรกฎาคม 2026 ให้ติดตั้งเวอร์ชันที่ระบุไว้แทนเวอร์ชันล่าสุด:
cargo install skillspec --version 0.2.2 --locked
skillspec --version--locked จะสร้างไฟล์โดยใช้เวอร์ชันของ dependency เดียวกับที่ crate นั้นถูกเผยแพร่ เพื่อไม่ให้การ build เปลี่ยนแปลงไปจากเดิม skillspec --version ควรแสดงผลเป็น 0.2.2 หากได้ตัวเลขอื่น แสดงว่า binary เวอร์ชันเก่าที่อยู่ใน PATH ของคุณกำลังถูกเรียกใช้งานแทน
แนวปฏิบัติในการทำ Vendor. Google ได้อธิบายวิธีการสร้าง skill ใน google/skills ผ่านบทความเรื่อง วิธีการสร้าง ทดสอบ และขยายขนาด skill ของ agent หากตัดเรื่องการขยายขนาดออกไป กลไกที่เหลือก็คือการทำ continuous integration (CI) ตามปกติ Skill ทุกตัวต้องผ่านการตรวจสอบด้วย linter สำหรับ metadata ในส่วน frontmatter, จำนวนบรรทัด, โครงสร้างไดเรกทอรี และการตั้งชื่อก่อนที่จะทำการ merge ตัวตรวจสอบลิงก์จะทำให้การ build ล้มเหลวหากพบ URL ใดที่ส่งค่า 404 ซึ่งช่วยตรวจจับลิงก์ที่ agent สร้างขึ้นมาเอง ผู้เขียนต้องจัดเตรียมชุดคำสั่งประเมินผล (evaluation prompt suite) และเกณฑ์การให้คะแนนควบคู่ไปกับ skill นั้นๆ จากนั้นงานประเมินผลตามกำหนดการจะทำงานทุกสัปดาห์กับคลัง skill ทั้งหมดเพื่อตรวจจับการถดถอยของประสิทธิภาพ และ skill ทุกตัวจะมีเจ้าของที่ระบุชื่อไว้ ซึ่งคาดหวังว่าจะต้องเข้ามาแก้ไขเมื่อคุณภาพลดลง
รูปแบบที่อยู่ภายใต้คำตอบทั้งสามประการ
คุณไม่จำเป็นต้องเลือกเพียงข้อใดข้อหนึ่งจากตัวเลือกเหล่านั้น เพราะภายใต้คำตอบเหล่านั้นมีรูปแบบเพียงหนึ่งเดียว และ git แบบมาตรฐานก็มอบทุกสิ่งที่คุณต้องการให้แล้ว
- แหล่งข้อมูลเดียวที่เชื่อถือได้ (One source of truth): ทักษะหนึ่งอย่างจะมีที่เก็บเพียงแห่งเดียว และทุก repository จะอ้างอิงไปยังที่เก็บนั้นแทนการเก็บสำเนาไว้
- การระบุเวอร์ชันที่แน่นอนต่อ repository: แต่ละโปรเจกต์จะบันทึก revision ที่ใช้งานจริงไว้ ดังนั้นการอัปเกรดจึงเป็นเพียงการทำ commit ในโปรเจกต์นั้นพร้อมระบุผู้เขียนและวันที่
- การทดสอบเบื้องต้นต่อหนึ่งทักษะ (Smoke test): การตรวจสอบที่รันได้จริงหนึ่งรายการเพื่อพิสูจน์ว่าทักษะนั้นยังคงให้ผลลัพธ์ตามที่ระบุไว้
- เส้นทางการตรวจสอบ (Review path): การเปลี่ยนแปลงทักษะที่ใช้ร่วมกันจะต้องผ่านการตรวจสอบ และผู้ใช้งานทุกคนจะเห็นความแตกต่าง (diff) ก่อนที่จะนำไปใช้
นั่นคือรูปแบบของการจัดการ dependency เนื่องจากทักษะต่างๆ กลายเป็นสิ่งที่ถูกนำมาใช้ร่วมกันเร็วกว่าที่เครื่องมือจะพัฒนาตามทัน ดังนั้นเครื่องมือที่คุณไว้วางใจอยู่แล้วจึงเป็นสิ่งที่ปลอดภัยที่สุดในการเลือกใช้
โครงสร้างสำหรับทีมขนาดเล็กบน Git remote ที่โฮสต์เอง
ที่เก็บข้อมูล (repository) หนึ่งแห่งจะเก็บทักษะความรู้เอาไว้ โดยไม่มีข้อมูลอื่นปะปน ประวัติการแก้ไขจึงอ่านได้เสมือนเป็นบันทึกการเปลี่ยนแปลง (changelog) ของคำแนะนำต่างๆ
agent-skills/
skills/
api-review/
SKILL.md
release-notes/
SKILL.md
tests/
api-review.sh
release-notes.sh
CHANGELOG.mdการปล่อยซอฟต์แวร์ (releases) ให้ใช้การทำ tag โดยแนะนำให้ใช้ annotated tags เนื่องจากมีข้อความและวันที่กำกับอยู่ ให้เขียนข้อความอธิบายถึงเหตุผลที่ผู้ใช้งานควรทำการอัปเดตเวอร์ชันนั้นๆ:
git tag -a v1.4.0 -m "api-review: require pagination on list endpoints"
git push origin v1.4.0หาก remote ของคุณคือ Gitea, Forgejo, GitLab หรือเป็น bare repository ที่ใช้งานผ่าน SSH บน VPS ของคุณเอง เนื้อหาต่อจากนี้จะไม่มีการเปลี่ยนแปลงใดๆ ทุกอย่างในที่นี้คือการทำงานของ git ร่วมกับการใช้ symlink
การตรึงเวอร์ชันด้วย git submodule
Submodule จะบันทึก commit ที่เจาะจงของ repository อื่นไว้ภายใน repository ของคุณ บันทึกดังกล่าวคือการตรึงเวอร์ชัน (pin) ในแต่ละโปรเจกต์ที่เรียกใช้งาน:
git submodule add https://git.example.com/team/agent-skills.git vendor/agent-skills
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills checkout v1.4.0
mkdir -p .claude/skills
ln -s ../../vendor/agent-skills/skills/api-review .claude/skills/api-review
git add .gitmodules vendor/agent-skills .claude/skills/api-review
git commit -m "Pin shared agent skills to v1.4.0"Symlink คือส่วนที่ทำให้กลไกนี้ทำงานได้ รายการ skill ในระดับโปรเจกต์อาจเป็น symlink ที่ชี้ไปยังไดเรกทอรีอื่นบนดิสก์ ซึ่ง Claude Code จะติดตาม symlink นั้นไปอ่าน SKILL.md จากปลายทาง ทำให้ skill โหลดเข้ามาเป็น skill ปกติของโปรเจกต์ ในขณะที่ข้อมูลจริงถูกเก็บไว้ใน submodule ณ commit ที่คุณเลือก
ตรวจสอบการตรึงเวอร์ชัน:
git submodule statusบรรทัดที่ถูกต้องจะขึ้นต้นด้วยช่องว่าง ตามด้วย commit, path และ tag ล่าสุด:
4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602 vendor/agent-skills (v1.4.0)หากขึ้นต้นด้วย - หมายความว่า submodule ยังไม่ได้ถูก initialised ทำให้ .claude/skills/api-review ไม่ชี้ไปยังที่ใดและ skill จะไม่โหลดโดยไม่มีการแจ้งเตือน แก้ไขปัญหานี้ด้วย git submodule update --init หากขึ้นต้นด้วย + หมายความว่า commit ที่ checkout อยู่ไม่ตรงกับที่บันทึกไว้ ซึ่งหมายความว่านักพัฒนารายนั้นกำลังรันคำสั่งที่ไม่มีใครใช้ การ clone ใหม่จำเป็นต้องใช้ git clone --recurse-submodules และควรระบุคำสั่งนี้ไว้ใน README เพราะการ clone ปกติจะทำให้ vendor/agent-skills ว่างเปล่าและไม่มีการแสดงข้อผิดพลาด
การอัปเกรดเป็นสิ่งที่ต้องทำโดยเจตนา ซึ่งเป็นหัวใจสำคัญของวิธีนี้:
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills diff v1.4.0 v1.5.0 -- skills/
git -C vendor/agent-skills checkout v1.5.0
git add vendor/agent-skills
git commit -m "Bump shared agent skills to v1.5.0"บรรทัด diff คือเส้นทางการตรวจสอบ (review path) ซึ่งจะแสดงการเปลี่ยนแปลงเดียวกันกับที่ repository อื่นๆ ที่เรียกใช้งานจะเห็น และสามารถรวมไว้ใน pull request ได้
การตรึงเวอร์ชันด้วย Marketplace ของปลั๊กอินแทน
หากคุณไม่ต้องการให้ผู้พัฒนาทุกคนต้องเรียนรู้วิธีใช้ submodules ระบบปลั๊กอินของ Claude Code จะช่วยจัดการการแจกจ่ายให้คุณ และสามารถทำงานร่วมกับรีโมทที่โฮสต์เองได้ ให้วางแคตตาล็อกไว้ที่ .claude-plugin/marketplace.json ในที่เก็บข้อมูล skills:
{
"name": "acme-agents",
"owner": { "name": "Platform team", "email": "platform@example.com" },
"plugins": [
{
"name": "team-skills",
"description": "Shared review and release skills",
"version": "1.4.0",
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0",
"sha": "4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602"
}
}
]
}มีแหล่งที่มาสองแหล่งที่เกี่ยวข้องในที่นี้ และการสับสนระหว่างสองแหล่งนี้เป็นข้อผิดพลาดที่พบบ่อย แหล่งที่มาของ marketplace ซึ่งหมายถึงตำแหน่งที่แคตตาล็อกถูกดึงมานั้น รองรับ ref สำหรับ branch หรือ tag แต่ไม่รองรับ sha ส่วนแหล่งที่มาของปลั๊กอินภายในแคตตาล็อกรองรับทั้งสองอย่าง และเมื่อมีการตั้งค่าทั้งคู่ sha จะเป็นค่าที่ใช้ในการตรึงเวอร์ชัน ดังนั้นการตรึงด้วย exact-commit จึงต้องระบุไว้ในรายการของแคตตาล็อก
จากนั้นแต่ละ repository ที่ใช้งานจะประกาศ marketplace ไว้ในไฟล์ .claude/settings.json ที่ถูก commit ไว้:
{
"extraKnownMarketplaces": {
"acme-agents": {
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0"
}
}
},
"enabledPlugins": {
"team-skills@acme-agents": true
}
}เพื่อนร่วมทีมที่เชื่อถือโฟลเดอร์โปรเจกต์จะได้รับแจ้งให้ติดตั้ง marketplace และปลั๊กอินจะถูกเปิดใช้งานให้โดยอัตโนมัติโดยไม่ต้องมีหน้า wiki คอยบอกให้ทำ จากนั้นทักษะต่างๆ จะตอบสนองต่อ /team-skills:api-review เนื่องจากทักษะของปลั๊กอินจะถูกแยก namespace ตามชื่อปลั๊กอินและไม่สามารถทับซ้อนกับทักษะของโปรเจกต์ที่มีชื่อเดียวกันได้ หลังจากที่คุณ push tag ใหม่ ผู้ใช้งานจะอัปเดตด้วย /plugin marketplace update acme-agents จากนั้นให้รัน /reload-plugins หากสรุปการติดตั้งแจ้งเตือนให้ทำเช่นนั้น
การเขียน smoke test สำหรับหนึ่งทักษะ
Smoke test คือการรันสคริปต์ผ่านเอเจนต์โดยใช้ fixture ที่มีข้อผิดพลาดที่ทราบแน่ชัดร่วมกับการตรวจสอบ (assertion) หนึ่งรายการ Claude Code ทำงานแบบ non-interactive ด้วย -p และทักษะที่เรียกใช้โดยผู้ใช้จะทำงานในโหมดนี้: ให้ใส่ /skill-name ลงในสตริงของ prompt แล้วระบบจะขยายค่าดังกล่าวก่อนการรันจะเริ่มต้น
#!/usr/bin/env bash
set -euo pipefail
claude -p "/api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--allowedTools "Read" \
--output-format json \
--json-schema '{"type":"object","properties":{"rule_ids":{"type":"array","items":{"type":"string"}}},"required":["rule_ids"]}' \
| jq -e '.structured_output.rule_ids | index("pagination-required")' > /dev/nullfixtures/orders-api.md เป็นไฟล์ขนาดสั้นที่มีข้อผิดพลาดที่จงใจใส่ไว้หนึ่งจุด การตรวจสอบคือทักษะดังกล่าวต้องระบุชื่อไฟล์นั้น jq -e จะ exit ด้วยค่าที่ไม่ใช่ศูนย์เมื่อตัวกรองสร้าง null ดังนั้นทักษะใดที่หยุดตรวจจับข้อผิดพลาดที่ใส่ไว้จะทำให้สคริปต์ล้มเหลว claude จะ exit ด้วยค่าที่ไม่ใช่ศูนย์เมื่อการรันล้มเหลว และ set -euo pipefail จะเปลี่ยนความล้มเหลวทั้งสองกรณีให้กลายเป็นการทดสอบที่ล้มเหลว
โมเดลจะปรับเปลี่ยนคำตอบระหว่างการรันแต่ละครั้ง ดังนั้นห้ามตรวจสอบ (assert) ทั้งประโยค ให้ตรวจสอบที่ตัวระบุ (identifier) ที่ทักษะควรจะแสดงออกมา หรือตรวจสอบที่ฟิลด์ของ schema ที่คุณร้องขอ และรักษาขนาดของ fixture ให้เล็กเพื่อให้การรันมีค่าใช้จ่ายต่ำ
ใน CI ให้เพิ่ม --bare หากไม่มีค่านี้ claude -p จะโหลดบริบทเดียวกับที่เซสชันแบบโต้ตอบใช้งาน ซึ่งรวมถึง hooks, plugins และ CLAUDE.md จากเครื่องที่รันอยู่ ดังนั้นการตั้งค่าส่วนตัวของเพื่อนร่วมทีมอาจส่งผลต่อผลลัพธ์ได้ โหมด bare จะข้ามการค้นหาอัตโนมัติทั้งหมด ซึ่งหมายความว่าจะข้ามทักษะที่คุณกำลังทดสอบด้วย ดังนั้นต้องโหลดทักษะนั้นอย่างชัดเจน โหมด bare จะไม่อ่านข้อมูลการเข้าสู่ระบบสมาชิกของคุณด้วย ดังนั้นให้ตั้งค่า ANTHROPIC_API_KEY ใน environment ไว้ก่อน:
claude --bare -p "/team-skills:api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--plugin-dir vendor/agent-skills \
--allowedTools "Read" \
--output-format jsonด้วย --output-format stream-json เหตุการณ์แรกของการรันจะรายงานว่าปลั๊กอินใดถูกโหลดบ้างและจะแสดงอาร์เรย์ plugin_errors สำหรับปลั๊กอินที่ไม่ถูกโหลด ให้ทำให้งาน CI ล้มเหลวหาก plugin_errors ไม่ว่างเปล่า วิธีนี้จะช่วยตรวจจับการระบุเวอร์ชัน (pin) ที่ชี้ไปยัง revision ที่ไม่มีอยู่แล้ว ซึ่งหากไม่ตรวจสอบ จุดนี้จะปรากฏเป็นเอเจนต์ที่เพิกเฉยต่อกฎที่คุณตั้งไว้โดยไม่มีการแจ้งเตือนใดๆ
ทักษะที่แชร์กันคือชุดคำสั่งที่ทำงานได้จริง
มีคุณสมบัติสองประการที่ทำให้สิ่งนี้เป็นจริง และทั้งสองประการมีความสำคัญเมื่อไฟล์มาจากทีมอื่น
ประการแรก SKILL.md สามารถรันคำสั่งเชลล์ก่อนที่โมเดลจะอ่านเนื้อหาใดๆ บรรทัดลักษณะนี้ในเนื้อหาถือเป็นการประมวลผลล่วงหน้า:
- Current branch: !`git rev-parse --abbrev-ref HEAD`คำสั่งจะทำงานบนเครื่องที่โหลดทักษะนั้น และผลลัพธ์จะเข้ามาแทนที่ตัวยึดตำแหน่งในข้อความที่โมเดลได้รับ บล็อกที่ล้อมรอบด้วยเครื่องหมาย backtick สามตัวตามด้วย ! จะรันคำสั่งหลายรายการในลักษณะเดียวกัน ไม่มีใครตรวจสอบสิ่งเหล่านี้ในขณะรันไทม์ การอ่านทักษะที่แชร์กันจึงหมายถึงการอ่านคำสั่งที่ถูกแทนที่เหล่านั้นด้วย
ประการที่สอง ส่วน frontmatter สามารถอนุมัติเครื่องมือล่วงหน้าได้ allowed-tools จะอนุญาตให้ใช้เครื่องมือที่ระบุโดยไม่ต้องแสดงข้อความแจ้งขออนุญาตสำหรับการโต้ตอบที่เรียกใช้ทักษะนั้น สำหรับทักษะระดับโปรเจกต์ การอนุญาตนี้จะมีผลเมื่อมีคนยอมรับกล่องโต้ตอบความเชื่อมั่นของ workspace สำหรับโฟลเดอร์นั้น เอกสารประกอบของ Claude Code ระบุผลลัพธ์ไว้อย่างชัดเจนว่า: ให้ตรวจสอบทักษะของโปรเจกต์ก่อนที่จะเชื่อถือ repository เพราะทักษะสามารถอนุญาตให้ตนเองเข้าถึงเครื่องมือในวงกว้างได้
ดังนั้น ให้จัดการกับการอัปเดตทักษะเช่นเดียวกับการอัปเดต dependency ให้ระบุเวอร์ชันด้วย commit ที่แน่นอนทุกครั้งที่กลไกอนุญาต เนื่องจาก tag สามารถถูกย้ายได้และ branch ก็มีการเปลี่ยนแปลงโดยนิยาม สำหรับเครื่องที่ถูกจำกัดสิทธิ์ "disableSkillShellExecution": true ในการตั้งค่าจะแทนที่การเรียกใช้คำสั่งทั้งหมดด้วยข้อความตัวอักษร [shell command execution disabled by policy] แทนที่จะรันคำสั่งนั้น และหากมีการบังคับใช้ผ่านการตั้งค่าที่มีการจัดการ ผู้ใช้จะไม่สามารถยกเลิกได้ ทักษะที่มาพร้อมกับระบบและทักษะที่มีการจัดการจะได้รับการยกเว้นจากการตั้งค่านี้
ความระมัดระวังเดียวกันนี้ใช้กับสิ่งที่ทักษะอ่าน ทักษะที่รัน env หรือเปิดไฟล์ config จะดึงข้อมูลทุกอย่างที่พบเข้าสู่บริบทของโมเดล ซึ่งเป็นความล้มเหลวที่ครอบคลุมอยู่ใน การเก็บความลับให้พ้นจากเอเจนต์ที่คุณรัน ทักษะที่ดึงหน้าเว็บหรือรัน query คือการเปิดเผยข้อมูลในลักษณะเดียวกันที่ชี้ออกไปยังภายนอก เนื่องจากข้อความที่ดึงมาจะปรากฏในบริบทเหมือนกับคำสั่งที่คุณเขียนไว้ทุกประการ ซึ่งเป็นขอบเขตที่ควรศึกษาให้เข้าใจก่อนที่คุณจะ ชี้เอเจนต์ไปยัง instance ของ SearXNG ของคุณเองเพื่อการค้นหาเว็บ
สิ่งที่ควรตรวจสอบเมื่อมีการปรับเวอร์ชัน
- ผลต่าง (diff) ของเนื้อหาใน
SKILL.mdทุกส่วน เนื่องจากข้อความดังกล่าวคือคำสั่งที่เอเจนต์ของคุณจะปฏิบัติตาม - การแทนที่คำสั่ง (command substitution) ทุกรายการ เนื่องจากคำสั่งเหล่านี้จะทำงานบนเครื่องของคุณเมื่อโหลดทักษะ (skill) นั้น
- การเปลี่ยนแปลงใดๆ ใน
allowed-toolsเนื่องจากบรรทัดดังกล่าวเป็นการให้สิทธิ์การเข้าถึงเครื่องมือโดยไม่ต้องแจ้งเตือน - การทดสอบที่อยู่เบื้องหลังแท็ก หาก repository ที่ใช้ร่วมกันมีการรัน smoke test ใน CI แท็กที่คุณอ้างอิงถึงควรมีสถานะการรันที่ผ่าน (green run)
ผู้ตรวจสอบที่ไม่สามารถอ่านผลต่างทั้งหมดได้ภายใน 10 นาที แสดงว่าทักษะดังกล่าวมีขนาดใหญ่เกินไป ควรแยกส่วนทักษะออก เช่นเดียวกับเอกสารใน repository ที่เอเจนต์ของคุณอ่าน ควรเก็บกฎที่คงทนไว้ในไฟล์ที่อธิบายไว้ใน การแยกไฟล์ AGENTS.md และ HUMAN.md และเก็บเหตุผลเชิงสถาปัตยกรรมไว้ใน ไฟล์ DESIGN.md ที่เขียนสำหรับเอเจนต์ เพื่อให้ทักษะต่างๆ ยังคงเป็นขั้นตอนการทำงานที่เฉพาะเจาะจงและไม่ซับซ้อน
เมื่อการเปลี่ยนแปลงของโมเดลหรือเครื่องมือทำให้ทักษะใช้งานไม่ได้
มีหลายสิ่งที่เปลี่ยนแปลงไปภายใต้ทักษะโดยที่ไม่มีใครเข้าไปแก้ไข การอัปเกรดโมเดลส่งผลต่อความน่าเชื่อถือในการปฏิบัติตามคำสั่งที่ยาวเหยียด ดังนั้นทักษะที่เคยพึ่งพาการที่โมเดลทำงานไปจนถึงขั้นตอนที่ 9 อาจหยุดทำงานก่อนถึงขั้นนั้น เครื่องมือบรรทัดคำสั่ง (command line tool) เปลี่ยนชื่อ flag ทำให้เอเจนต์รันด้วย flag เก่า อ่านข้อผิดพลาดที่เกิดขึ้น แล้วพยายามแก้ไขปัญหาเฉพาะหน้า URL ที่อ้างอิงเริ่มส่งค่า 404 กลับมา หรือตัวควบคุมเอเจนต์ (agent harness) เปลี่ยนวิธีการเลือกทักษะ ทำให้ description ที่เคยถูกเลือกใช้งานกลับไม่ถูกเลือกอีกต่อไป เมื่อกระบวนการเริ่มจบลงก่อนกำหนดเช่นนี้ การปรับเวอร์ชัน (version bump) ไม่สามารถแก้ไขปัญหาได้ และตัวคำสั่งเองจำเป็นต้องมีโครงสร้างที่บังคับให้ทำขั้นตอนสุดท้ายให้สำเร็จ ซึ่งเป็นแนวทางเบื้องหลัง ทักษะที่ไม่ขี้เกียจและวิธี Depth Tree
นี่คือเหตุผลที่การทดสอบแบบ smoke test มีความสำคัญอย่างยิ่งในระบบนี้ ให้รันการทดสอบของแต่ละทักษะตามตารางเวลาและทุกครั้งที่มีการ push โค้ด Google รันงานประเมินผลรายสัปดาห์กับไลบรารีทั้งหมดด้วยเหตุผลนี้ และการตั้ง cron job รายสัปดาห์บน VPS ขนาดเล็กก็เพียงพอสำหรับทีมที่มีทักษะประมาณ 10 รายการ นี่เป็นวิธีเดียวที่คุณจะทราบถึงปัญหาที่เกิดขึ้นก่อนที่นักพัฒนาจะพบเอง
ความสามารถในการพกพา (portability) ก็มีส่วนช่วยเช่นกัน ข้อกำหนด Agent Skills จำกัดส่วน frontmatter ไว้ที่ 6 คีย์ ดังนั้นทักษะที่เขียนตามข้อกำหนดนั้นจะสามารถโหลดใช้งานในเครื่องมืออื่นนอกเหนือจากที่เขียนไว้ในตอนแรกได้ ในขณะที่คีย์เฉพาะของ harness แต่ละตัวที่คุณเพิ่มเข้าไปเปรียบเสมือนการเดิมพันกับผู้ให้บริการรายใดรายหนึ่ง การเขียนทักษะให้รองรับการเปลี่ยนโมเดลถือเป็นทักษะเฉพาะทาง ซึ่งครอบคลุมอยู่ใน การทำให้ทักษะทำงานได้บนทุกโมเดล
FAQ
ฉันจะแชร์ทักษะของ agent หนึ่งรายการข้ามหลาย repository ได้อย่างไร
ให้เก็บทักษะไว้ใน git repository แยกต่างหาก ทำการ tag release ในนั้น และให้โปรเจกต์ที่เรียกใช้ทำการอ้างอิงที่ tag แทนการคัดลอกไฟล์ มีสองกลไกที่ใช้งานได้จริง ได้แก่ git submodule ซึ่งจะบันทึก commit ที่เจาะจงไว้ และการสร้าง symlink จาก .claude/skills/<name> เข้าไปยัง submodule เพื่อให้โหลดทักษะเสมือนเป็นทักษะปกติของโปรเจกต์ หรือใช้ plugin marketplace ซึ่งทำงานในลักษณะเดียวกันผ่าน /plugin โดยระบุเวอร์ชันที่ต้องการใน .claude/settings.json ของ repository ที่เรียกใช้ ทั้งสองวิธีจะบันทึกเวอร์ชันไว้ในประวัติของ git ทำให้คุณสามารถตรวจสอบได้ว่าชุดคำสั่งใดที่ถูกนำไปใช้ในการรัน agent ครั้งนั้นๆ
ฉันสามารถล็อกเวอร์ชัน (pin) ของทักษะ agent ให้เป็นเวอร์ชันที่เจาะจงได้หรือไม่
ไม่สามารถทำได้จากภายใน SKILL.md เนื่องจาก frontmatter ดังกล่าวไม่มีคีย์ version การล็อกเวอร์ชันต้องทำจากเลเยอร์ภายนอกไฟล์ โดย git submodule จะล็อกที่ commit ที่เจาะจงโดยธรรมชาติ สำหรับ Claude Code plugin marketplace นั้น แหล่งที่มาของ plugin จะรองรับ ref สำหรับ branch หรือ tag และ sha สำหรับ commit ที่เจาะจง โดยที่ sha จะถูกนำมาใช้หากมีการระบุทั้งสองค่า ส่วนตัว marketplace เองจะรองรับเฉพาะ ref เท่านั้น แนะนำให้เลือกใช้การล็อกที่ commit เพราะ tag อาจถูกแก้ไขหรือย้ายตำแหน่งได้หลังจากที่คุณตรวจสอบไปแล้ว
การทดสอบ smoke test ของทักษะควรตรวจสอบสิ่งใด
ควรตรวจสอบสิ่งที่คงที่ ให้รันการทดสอบทักษะแบบ non-interactive กับ fixture ที่มีข้อผิดพลาดที่ทราบแน่ชัด จากนั้นตรวจสอบว่ามีตัวระบุเฉพาะปรากฏในผลลัพธ์หรือไม่ เช่น rule id ที่ทักษะควรจะรายงานออกมา การเรียกขอผลลัพธ์แบบ structured output ด้วย --output-format json และ --json-schema จะช่วยให้การตรวจสอบแม่นยำขึ้น และ jq -e จะทำให้สคริปต์ล้มเหลวหากไม่พบค่าที่ต้องการ ห้ามตรวจสอบจากประโยคเต็ม เพราะโมเดลอาจเรียบเรียงคำตอบใหม่ในแต่ละครั้งที่รัน
การติดตั้งทักษะที่แชร์จาก repository ของทีมอื่นมีความปลอดภัยหรือไม่
ให้ปฏิบัติต่อทักษะดังกล่าวเสมือนเป็น code dependency เพราะมันคือชุดคำสั่งที่สามารถรันได้ โดย SKILL.md สามารถรันคำสั่ง shell ในขณะโหลดผ่านรูปแบบ command substitution ของ ! และฟิลด์ allowed-tools ใน frontmatter สามารถอนุมัติเครื่องมือล่วงหน้าโดยไม่ต้องแจ้งเตือนผู้ใช้ ให้ตรวจสอบ diff ทุกครั้งที่มีการอัปเดตเวอร์ชัน ล็อกไว้ที่ commit ที่เจาะจงแทนการใช้ branch และเลือกใช้แหล่งที่มาที่ทีมของคุณควบคุมเอง สำหรับเครื่องที่ถูกจัดการโดยองค์กร การตั้งค่า "disableSkillShellExecution": true จะช่วยหยุดการทำงานของ command substitution ทั้งหมดได้
ทักษะที่แชร์จะทำงานใน agent อื่นที่ไม่ใช่ Claude Code ได้หรือไม่
ขึ้นอยู่กับว่าคุณใช้ frontmatter ใด ข้อกำหนด Agent Skills ระบุคีย์ไว้ 6 รายการ ได้แก่ name, description, license, compatibility, metadata และ allowed-tools ทักษะที่จำกัดอยู่เพียงคีย์เหล่านี้จะสามารถโหลดได้ในเครื่องมือที่รองรับข้อกำหนดดังกล่าว และยังสามารถโหลดใน Claude Code ได้โดยไม่ต้องแก้ไขใดๆ ส่วนคีย์เฉพาะของแต่ละระบบและฟีเจอร์ในส่วนเนื้อหาที่นอกเหนือจากข้อกำหนดจะถูกละเว้นหรือปฏิเสธการทำงานในระบบอื่น ดังนั้นควรหลีกเลี่ยงการใช้ฟีเจอร์เหล่านั้นในทักษะที่คุณต้องการแชร์ในวงกว้าง