Nửa đầu năm cộng đồng agent toàn cãi nhau về model. Model nào code khoẻ hơn. Model nào sống được context dài. Model nào tool-call không bị "tự kỷ". Khoảng tháng 4, cuộc cãi đó âm thầm đổi chủ đề. Các thread Reddit, các talk, các channel agent-shop-talk không còn so Sonnet vs Opus vs GPT-5 nữa — họ chuyển sang chủ đề khác: skills. Những workflow artifact tái sử dụng được, biến một coding agent generic thành một operator chuyên biệt cho một domain cụ thể.
Bọn mình viết skill được chín tháng rồi. Cụ thể là viết cho pipeline AI video tên FLOW KIT — hơn hai mươi file Markdown trong skills/ để drive Veo 3.1 qua Claude Code. Video là chỗ stress-test mô hình skill rất tàn — mỗi lỗi là một call Veo $0.50 thật hoặc 30 phút polling đi tong. Có pattern sống sót production. Có pattern ngày một nhìn rất sang, sáu tuần sau bị xoá. Bài này kể lại cái nào là cái nào.

Một Claude Code skill thực sự là cái gì
Bóc hết lớp hype thì một skill chỉ là một file Markdown trong thư mục skills/, kèm header YAML ngắn. Header có name, description, đôi khi có cả list tool được phép dùng. Body là một recipe viết cho agent reader — không phải human reader — bằng ngôn ngữ tự nhiên, nói rõ làm gì, theo thứ tự nào, verify gì trước khi đi tiếp. Claude Code tự nhặt file lên khi CLAUDE.md của bạn trỏ tới skills/, rồi expose mỗi skill thành một native slash command (/your-skill-name) ngay trong terminal.
Cơ chế chỉ có vậy. Không SDK, không runtime, không plugin manifest. Skill theo design là agent-CLI-agnostic: Codex CLI và Gemini CLI đọc cùng file thông qua entry point của riêng họ. Cái bạn nhận lại là một workflow primitive portable, reviewable, và grep-able. Một skill cùng lúc là recipe để agent execute, doc để contributor đọc, diff để reviewer comment — tất cả trong một artifact duy nhất.
Lý do format này hợp với video là vì pipeline video thật chứa rất nhiều quyết định vận hành dạng long-tail: bao nhiêu Veo call concurrent thì throttle, xử lý sao khi media_id hết hạn, khi nào fallback từ i2v sang t2v. Hardcode mấy quyết định đó vào code là khoá chúng lại. Code hoá chúng vào skill thì agent vẫn còn đường đi vòng khi thực tế đổi. Sáu tháng qua bọn mình thay nhiều Python procedural bằng skill prose hơn hai năm trước thay Python bằng TypeScript.
Vì sao AI video là chỗ stress-test đúng
Ba đặc tính khiến AI video là chỗ test xem mô hình skill có sống sót không.
Đa bước. Một project đi qua tám phase có tên rõ ràng: project, video, scenes, reference images, scene images, video generation, narration, concat. Mỗi phase có success criteria riêng, retry semantics riêng, failure mode riêng. Prompt kiểu "do the thing" không sống nổi với bề mặt đó.
Async và đắt. Một call scene-image trả trong vài giây. Một call Veo render trả trong 2–5 phút, và tốn tiền thật trên Flow plan đã trả phí. Nếu skill mất chỗ giữa một run 25 scene thì restart tốn tiền thật và thời gian thật. Resumable không phải tính năng nice-to-have.
Có nhánh. Có project muốn 1 timeline chính. Có project muốn 1 hero scene cộng 3 cutaway. Có project muốn narration trước rồi concat. Có project muốn concat trước rồi trim sau. Skill ship 1 sequence hardcoded sẽ chết ngày thứ hai.
Nếu mô hình skill của bạn sống sót video, hầu như mọi thứ khác đều sống sót được.
Anatomy của skill trong FLOW KIT
Bề mặt user-visible của FLOW KIT là một bộ ổn định các command /fk-*. Năm cái đầu phủ phần lớn một lần chạy production; phần còn lại lo các case biên.
| Command | Việc trong một câu |
|---|---|
/fk-create-project | Đọc story, draft entity và scene, ghi project shell |
/fk-gen-refs | Generate một reference image per entity, block tới khi mọi UUID resolve |
/fk-gen-images | Generate scene image với đúng reference đã apply |
/fk-gen-videos | Submit Veo i2v job, poll tới khi từng clip về máy |
/fk-concat-fit-narrator | Trim mỗi scene clip theo track narrator rồi concat ra final cut |
Xem /fk-gen-videos như worked example. File skill của nó khoảng 90 dòng Markdown. Phần mở đầu set khung cho agent: "Bạn đang xử lý một danh sách scene để generate video. Mỗi scene có scene image. Việc của bạn là submit một GENERATE_VIDEO per scene, poll tới khi clip xong, download nó, mark scene complete trong project manifest. Đừng skip scene đã có clip trên đĩa. Đừng retry quá ba lần cho cùng một scene." Phần giữa là shape của API — bản copy của route FastAPI và schema response. Phần cuối là checklist post-condition: mọi scene đều có mp4 local, manifest được update, không media_id nào còn dangling.
Agent đọc rồi chạy. Không có state machine nội bộ, không scheduler, không event bus. Skill chính là state machine, biểu đạt bằng prose, và Claude Code là runtime.
Pattern 1 — một skill, một verb
Quyết định design lớn nhất là cưỡng lại cám dỗ viết /fk-do-everything — một skill tạo project, generate tất cả, upload tất cả. Sẽ là một command rất gọn. Cũng sẽ là một command không debug nổi.
Thay vào đó mỗi bước là một slash command riêng, và mỗi cái sở hữu đúng một verb. /fk-gen-refs chỉ generate reference. /fk-gen-images chỉ generate scene image. Chúng share project manifest trên đĩa và đều từ chối chạy nếu prerequisite chưa có. Agent — hoặc human — compose chúng tại run time.
Lợi từ ràng buộc đó không hề tinh tế:
- Idempotency cho không. Mỗi skill check manifest trước, skip phần đã xong. Re-run
/fk-gen-videossau khi crash sẽ pick up tại scene đầu tiên chưa có clip. Re-run cả chain sau khi xoá thì chỉ regenerate phần thiếu. - Resumable tự động. Vì mọi skill thao tác trên cùng manifest trên đĩa, project là single source of truth. Không có in-memory pipeline state để corrupt. Restart Claude Code, restart laptop — slash command tiếp theo cứ vậy chạy tiếp.
- Debug rẻ. Khi có lỗi, call duy nhất bạn cần re-run là cái fail. Một nửa chi phí của bug AI video là xác định lỗi xảy ra ở stage nào. Atomic skill nói cho bạn ngay lập tức.
Pattern 2 — skill compose, agent orchestrate
Bọn mình không hardcode thứ tự thao tác vào bất kỳ skill nào. Skill gọi skill khác sẽ couple hai mảnh pipeline mà bọn mình cố tình muốn tách rời. Thay vào đó agent — Claude — orchestrate. User (hoặc một skill cấp cao hơn) gõ chain /fk-create-project … /fk-gen-refs … /fk-gen-images … /fk-gen-videos … /fk-concat-fit-narrator và agent chạy theo thứ tự đó, surface output tại từng biên.
Nghe như khác biệt nhỏ. Đó là toàn bộ lý do bọn mình có thể thêm stage mới mà không phải viết lại thế giới. Khi thêm /fk-gen-chain-videos cho frame chaining start-end mượt, không skill cũ nào phải đổi. Chain skill slot vào giữa /fk-gen-images và /fk-concat-fit-narrator khi user yêu cầu. Khi thêm /fk-insert-scene để chèn cutaway vào chain có sẵn, một lần nữa không skill cũ nào phải đổi.
Mental model là Unix philosophy áp dụng vào agent workflow. Mỗi skill là một chương trình nhỏ, làm một việc. Agent là dấu pipe.
Pattern 3 — skill trên API, không thay API
Skill là chỗ rất tốt để mô tả làm gì. Skill là chỗ rất tệ để nhét polling loop của Veo dưới dạng prose thuần. Nên bọn mình kẻ một đường cứng: skill là recipe, còn heavy lifting nằm trong một FastAPI service nhỏ ở 127.0.0.1:8100 mà skill gọi qua HTTP. API biết về throttling, exponential back-off, expiry của media_id, và plumbing WebSocket của Chrome extension. Skill chỉ biết khi nào hỏi API và làm gì với câu trả lời.
Cú split đó là lý do file skill giữ được tầm 90 dòng Markdown thay vì biến thành bash script 500 dòng. Cũng là lý do contributor có thể đọc hết bề mặt user-facing của FLOW KIT trong một buổi chiều bằng cách lướt skills/ — implementation detail nằm ở agent/ và họ chỉ phải đào sâu nếu muốn.
Quy tắc tương tự áp dụng khi bạn viết skill chống lưng một API bên thứ ba. Giữ skill mang tính mô tả ("call POST /v1/clips với fields này, retry 429 kèm back-off, fail loud trên 422"), giữ phép tính retry ra ngoài. Markdown rất dở số học; agent không nên làm phép trong dòng.
Pattern 4 — skill chính là doc
Thứ đầu tiên một contributor mới mở trong repo của bọn mình là skills/, không phải README. Mỗi file /fk-* là cùng một document cho hai audience: agent execute nó, và human cần hiểu nó. Frontmatter description là thứ hiện trong slash-command picker. Body là thứ chạy tại execution time và là thứ được đọc tại review time.
Sự đồng bộ đó loại bỏ nguyên một loại doc rot. Skill không thể drift xa khỏi cách hệ thống thực sự hành xử, vì skill chính là cách hệ thống hành xử. Khi muốn đổi một invariant — ví dụ "đừng try upscale trên tài khoản Tier One" — bọn mình đổi trong skill, và thay đổi đó đồng thời là behavior change, doc update, và diff cho reviewer ký. Một edit, ba artifact.
Cái không work — ba anti-pattern bọn mình đã gỡ
Không phải pattern nào thử cũng sống. Một danh sách ngắn những pattern viết ra rồi xoá, vì nhìn đẹp mà già nhanh.
Skill có state sống lâu. Bản iteration thứ hai cố cho mỗi skill một file JSON sidecar — chỗ nhớ scene đang xử lý giữa các run. Chạy ổn cho tới khi hai skill bất đồng xem ai sở hữu file. Bọn mình xoá hết sidecar và đặt project manifest làm state-of-record duy nhất. Skill cần biết cái gì xong thì đọc manifest. Skill cần mark cái gì xong thì ghi manifest.
Skill hỏi quá nhiều. Bản đầu của /fk-create-project hỏi user từng entity name, từng scene number, từng camera angle theo kiểu interactive. Nhìn rất kỹ. Cũng mất 20 phút để bootstrap một project. Bản hiện tại hỏi đúng một lần, lấy story, và infer phần còn lại từ nội dung story — surface kế hoạch đã infer thành một block duy nhất user có thể edit trước khi commit gì. Một vòng edit ăn đứt hai mươi vòng hỏi.
Skill "thông minh" skip step. Có lúc bọn mình thử một /fk-gen-images tự phát hiện scene image "gần đủ giống" cái trước và skip regenerate để tiết kiệm call Flow. Tiết kiệm token thật. Cũng tạo ra những run mà một scene xài stale image từ project cũ. Bọn mình gỡ heuristic đó, quay về dumb-but-correct: regenerate mọi image được yêu cầu, mọi lần, trừ khi manifest nói nó đã xong trên project này.
Pattern phía dưới các anti-pattern đều giống nhau: skill nên ngắn và predictable. Clever thuộc về agent, không thuộc về recipe.
Cách viết skill video đầu tiên của bạn
Nếu bạn đang ngồi trên một workflow nửa-script nửa-Slack — generate vài ảnh, đẩy qua một model, batch upload đâu đó — bạn có thể viết skill hữu ích đầu tiên trong một tiếng. Cái shape sống sót với bọn mình là:
- Chọn một verb. "Generate references." "Concat the cut." Nếu không mô tả được skill bằng ba chữ, hãy tách đôi.
- Viết frontmatter. Một
name, mộtdescriptionđúng một câu, và list tool agent được phép dùng khi chạy. Giữ list tool gọn. - Khai báo precondition. Cái gì phải có sẵn trên đĩa hoặc trong manifest để skill này chạy. Nếu precondition không thoả, fail loud và nói rõ user cần chạy skill nào trước.
- Khai báo công việc. Một list đánh số ngắn. Hai tới bảy bước. Dài hơn là hai skill.
- Khai báo postcondition. Thế giới trông như thế nào khi skill xong. Path file mới, field manifest, log line — bất cứ thứ gì skill sau hoặc human sau có thể verify.
- Chạy. Xem agent đã làm gì. Sửa prose. Đây là phần làm người ta ngạc nhiên. Skill iterate y hệt như prompt — đọc trace, siết câu chữ, re-run.
skills/ trong repo FLOW KIT là reference thực tế. Skill ngắn (/fk-thumbnail, /fk-youtube-seo) là chỗ dễ đọc nhất để bắt đầu; skill dài (/fk-gen-chain-videos, /fk-insert-scene) cho bạn thấy format trông sao khi workflow phức tạp.
Vì sao chuyện này quan trọng lúc này
Lý do cộng đồng agent đột nhiên nói về skill là vì bottleneck đã dịch. Năng lực model frontier không còn là yếu tố giới hạn việc một workflow domain-specific có chạy end-to-end hay không. Yếu tố giới hạn là đã có ai chịu ngồi xuống và encode cái domain đó chưa. Skill là đơn vị của việc encode đó. Đủ nhỏ để viết trong một buổi chiều, đủ tái dùng để share, và legible đủ để review — đặc tính cuối cùng khiến agent workflow trở thành thứ team có thể ship cùng nhau thay vì thứ cá nhân hack một mình.
Bọn mình build FLOW KIT để ship video YouTube. Bonus không lường trước là cách build nó — Markdown recipe trên một lớp HTTP mỏng — hoá ra lại là một template general-purpose. Pipeline tiếp theo bọn mình wire không phải video. Nó sẽ theo cùng anatomy.
Thử FLOW KIT
Repository ở github.com/crisng95/flowkit. Muốn đọc skill trước khi cài thì skills/ là directory đáng đọc nhất repo. Nếu bạn muốn version canvas trực quan cho workflow e-commerce dạng branching, bài đi kèm là FLOWBOARD — cùng hướng Chrome-bridge, ergonomic khác, triết lý skill bên dưới giống nhau.
Cả hai project nằm dưới ISEMI open-source. Nếu bạn viết một skill trên FLOW KIT cho domain bọn mình chưa đụng — clean narration, alternate uploader, thumbnail theo vùng — mở issue hoặc thả output vào nhóm cộng đồng. Vòng cải tiến tiếp theo chạy theo cái team thật thật sự cần.