AIDive

Gói video

Claude Code Mods: thử nghiệm fail-open, số đo, checklist và nguồn

10 phút đọc

TL;DR

  • Một Claude Code Mod gồm ba file: .claude-plugin/plugin.json, hooks/hooks.json chứa {"modules":["./index.ts"]}, và một module TypeScript export register(on). Chỉ cần vậy là Mod được nạp.
  • Trên build 2.1.272, bộ type do /plugin-types ghi ra là 11,783 dòng claude-code.d.ts: 84 tên event hoặc call trên 23 noun. fs.readFile không còn, noun giờ là fs.read và fs.write.
  • Một hook tool.call dài 42 dòng khiến model đọc API_KEY=[REDACTED] thay cho key thật, ở cả tool Read lẫn tool Bash, với 27.9 ms mỗi hop khi chạy bình thường và khoảng 0 token thêm vào session.
  • Hook ngủ quá ngưỡng 10 s hoặc ném lỗi sẽ bị bỏ qua và lệnh bên dưới vẫn chạy. Log có báo, nhưng hiệu quả là bị bypass: một Mod làm guard sẽ fail open.
  • Đường sinh tự động chạy được: một câu mô tả tạo ra Mod 190 dòng cộng 53 dòng test trong khoảng 4 phút với $1.23, qua claude plugin validate không có cảnh báo và claude plugin test đạt 4 pass / 0 fail.
  • Có một điều không tái lập được: Mod nạp được dưới claude -p nhưng im lặng trong REPL tương tác chạy qua pty, qua hai lần thử. Hãy coi việc nạp trong REPL là chưa được xác minh cho đến khi bạn thử trên terminal thật.

Các phép đo cho thấy gì

Mọi thứ dưới đây chạy trên Claude Code 2.1.272 với CLAUDE_CODE_ENABLE_FUNCTION_HOOKS được bật, trên một Mod viết tay tên redact-secrets và ba Mod dùng một lần được dựng để phá nó. Bản thân tính năng được theo dõi trong issue đề xuất Function Hooks, hiện vẫn là thứ gần nhất với một spec chính thức s3.

Công cụ có trước tài liệu. Build 2.1.272 đi kèm claude plugin validate, test, eval và details; test chạy được dù plugin --help không liệt kê nó trong khối lệnh s3. Chạy /plugin-types trong một session ghi ra 11,783 dòng vào .claude/types/claude-code.d.ts, cộng thêm claude-code-mcp.d.ts dài 3,438 dòng phủ 150 tool MCP từ 7 server s3. Đếm các type được sinh ra cho 84 tên event hoặc call trải trên 23 noun, và file này đổi tên một thứ bạn có thể đã đọc trong các bài tháng 9: fs.readFile không còn tồn tại, bề mặt là fs.read và fs.write s9. Cũng theo các type này, một hook tool.call trả về { result, context? } hoặc { deny }; text và ref đến từ core và không thuộc phần trả lời của hook, nên bạn viết lại result, không phải text s3.

claude plugin validate in ra footprint trước khi Mod chạy lần nào: ./index.ts hooks: tool.call và ./index.ts calls: $.ui.toast, hoặc calls: nothing on $ khi module không đụng đến năng lực nào của host s4. Dòng tĩnh này là cách duy nhất một thư mục như awesome-claude-code-mods có thể tự động kiểm tra hiện nay, điều này quan trọng khi bạn đọc đoạn tiếp theo.

Việc redact hoạt động ở chế độ -p. Hook 42 dòng chặn tool.call, và model nhận API_KEY=[REDACTED] ở chỗ file và output của shell chứa sk-test1234567890abcdef, cho cả tool Read lẫn tool Bash s3. Log debug đo một hop bình thường là 27.9 ms khứ hồi, gồm hop sang worker và next() s3. claude plugin details tính Mod này thêm khoảng 0 token vào mỗi session: Mod là code chạy trong process, không phải văn bản prompt, và đó là lập luận chính của những người ủng hộ Mod so với shell hook và skill s7.

Guard fail open. Một Mod slow-guard ngủ 15 s bị cắt ở ngưỡng 10 s với thông báo hook failed: slow-guard: exceeded 10000ms budget (tool.call; skipped; what is below it ran in its place), và echo hi vẫn chạy s3. Một Mod throw-guard ném lỗi cũng bị bỏ qua theo cách tương tự, hook failed: throw-guard: boom (tool.call; skipped; what is below it ran in its place), báo 574.2 ms s3. Ồn ào trong log, bị bypass trong thực tế. Mọi Mod có nhiệm vụ chặn thứ gì đó đều phải được đọc với điều này trong đầu: lỗi trong guard là một lỗ hổng, không phải một cú crash.

Sinh Mod rất rẻ. Từ một câu, model viết ra một Mod chạy được 190 dòng cộng 53 dòng test trong khoảng 4 phút, 34 turn và $1.23 (19,053 output token, 497,282 cache-read, 8,357 thinking) s3. Mod đó qua claude plugin validate không có cảnh báo và claude plugin test đạt 4 pass / 0 fail trong 0.31 s, và che các key ngay khi chạy s3. Với Mod viết tay, claude plugin test chạy không cần API key và không gọi model: 1 pass trong 0.25 s s3. Đã có sẵn một skill dạy agent viết Mod nếu bạn muốn lặp lại thử nghiệm với một template s12.

Điều không tái lập được: $.ui.toast không bao giờ hiển thị vì Mod không nạp trong REPL chạy qua pty qua 2 lần thử; trong -p, thứ tương đương chỉ hiện ra như một dòng debug. Quan sát được ngược lại với tuyên bố "chỉ REPL" đang lan trên X, và nguyên nhân gốc chưa được cô lập s8. Heartbeat 5 s của worker bị treo cũng chưa được kiểm tra; chỉ đo ngưỡng await 10 s và đường ném lỗi.

Bảng đo

Trường hợp Mod làm gì Kết quả Thời gian
redact-secrets, tool Read Viết lại result trên tool.call Model thấy API_KEY=[REDACTED] 27.9 ms mỗi hop
redact-secrets, tool Bash Cùng hook, output của shell Model thấy API_KEY=[REDACTED] 27.9 ms mỗi hop
slow-guard Ngủ 15 s trong tool.call Bị bỏ qua, echo hi chạy cắt ở 10000 ms
throw-guard Ném boom trong tool.call Bị bỏ qua, lệnh chạy 574.2 ms
Mod được sinh 190 dòng + 53 dòng test từ một câu validate: không cảnh báo; test: 4 pass / 0 fail ~4 phút, 34 turn, $1.23
claude plugin test trên redact-secrets Không API key, không gọi model 1 pass 0.25 s
claude plugin details Chi phí session của Mod ~0 token thêm vào n/a

Quy trình: Claude Code 2.1.272, function hook được bật bằng biến môi trường. Mỗi Mod là một thư mục plugin gồm plugin.json, hooks/hooks.json và một index.ts. Các lần chạy dùng claude -p với debug log bật; một file được đặt sẵn và một lệnh shell đều chứa sk-test1234567890abcdef. Các trường hợp fail open được điều khiển bằng một Mod ngủ 15 s và một Mod ném lỗi, với echo hi là lệnh được canh giữ. REPL tương tác được điều khiển qua pty và không nạp Mod trong hai lần thử.

Việc làm vào thứ Hai

  • Chạy /plugin-types trong một session và mở .claude/types/claude-code.d.ts: tìm fs.read và tool.call trước khi tin bất kỳ đoạn code nào từ bài tháng 9.
  • Viết bộ khung Mod ba file (plugin.json, hooks/hooks.json với {"modules":["./index.ts"]}, index.ts export register(on)) và chạy claude plugin validate trên nó: đọc các dòng footprint hooks: và calls:.
  • Chuyển shell hook bạn dùng nhiều nhất sang một handler tool.call viết lại result, rồi so thời gian hop trong log debug với bản shell.
  • Thêm một file claude plugin test cạnh Mod để guard chạy được không cần API key trong CI.
  • Bọc mọi handler của guard trong try/catch trả về { deny } khi lỗi: trên build này, một exception hoặc một lần đứng 10 s sẽ khiến guard bị bỏ qua và lệnh được đi qua.
  • Test Mod dưới claude -p và trong terminal tương tác thật của bạn riêng biệt, và ghi lại cái nào đã nạp được nó.
  • Trước khi cài một Mod của bên thứ ba, chạy claude plugin validate trên nó và từ chối mọi Mod có dòng calls: nêu tên những năng lực host mà Mod không có lý do gì để dùng.

Đọc thêm

  • Đọc toàn bộ issue đề xuất, kể cả PDF kiến trúc đính kèm trong phần comment: đó là bản hợp đồng duy nhất bằng văn bản cho register(on), các ngưỡng thời gian và hop sang worker s3.
  • So với thiết kế Command Code Mods, chạy TypeScript trên một ModApi trong process host: hai hệ thống có chung hình dạng và cùng cơ chế early access s2.
  • Bản preview của claudefa.st được viết khi tính năng còn là đề xuất: hữu ích để thấy cái gì đã đổi giữa bản văn ngày 3 tháng 9 và binary 2.1.272 s9.
  • Note tweet của Prathkum là phát biểu ngắn gọn rõ nhất về lý do hook trong process thắng shell hook về token và độ trễ s7.
  • cc-mod-waitwhat là một Mod đầu tiên tốt để đọc: UI phía trên prompt, không ghi gì vào transcript s11.
  • cc-arcade cho thấy $.ui với tới đâu: game được render phía trên prompt từ một Mod s5.
  • Tài liệu tham chiếu hooks vẫn mô tả mô hình shell; hãy mở sẵn để ánh xạ từng event cũ sang tên noun.event mới s1.
  • Những người hoài nghi trên X cho rằng plugin đã làm được việc này và bề mặt sẽ vỡ ở mỗi bản phát hành; việc noun fs bị đổi tên là một dữ kiện ủng hộ họ s23.

Nguồn

  • Function Hooks proposal (issue #91870), GitHub, anthropics/claude-code. Vì sao nên đọc: văn bản duy nhất giống một spec cho Mod, kèm PDF kiến trúc và lịch sử phát hành trong phần comment.
  • Hooks reference, Claude Code docs. Vì sao nên đọc: mô hình shell hook bạn đang chuyển đi, từng event một.
  • Command Code Mods documentation, Command Code. Vì sao nên đọc: tiền lệ có cùng hình dạng TypeScript trong process, giúp nhận ra Anthropic đã sao chép hay tránh điều gì.
  • awesome-claude-code-mods, GitHub, karanb192. Vì sao nên đọc: thư mục Mod công khai được quét tự động, với footprint của validate là cách kiểm duyệt duy nhất.
  • cc-arcade, GitHub, sezaakgun. Vì sao nên đọc: bản demo đã làm tính năng này hiện hữu, và một chuyến tham quan $.ui.
  • Boris Cherny announcement tweet, X, Boris Cherny. Vì sao nên đọc: lời công bố ra mắt từ một kỹ sư Anthropic, vì không có bài blog nào.
  • Prathkum: Function Hooks explained, X, Prathkum. Vì sao nên đọc: lời giải thích ngắn tốt nhất về hook so với Mod cho người đã viết shell hook.
  • shipnotesai reaction thread, X, shipnotesai. Vì sao nên đọc: nơi tuyên bố "chỉ REPL" lan truyền, và lần chạy của chúng tôi đã mâu thuẫn với nó.
  • Claude Code Function Hooks: Preview Behind a Flag, claudefa.st. Vì sao nên đọc: bài giải thích trước khi phát hành, tốt để đối chiếu đề xuất với binary.
  • cc-mod-waitwhat, GitHub, GGGODLIN. Vì sao nên đọc: một Mod nhỏ dễ đọc, ghi vào UI chứ không vào transcript.
  • claude-mods-skill, GitHub, BeLazy167. Vì sao nên đọc: một skill để sinh Mod, nếu bạn muốn lặp lại thử nghiệm một câu.
  • AxialisSoftware reaction, X, AxialisSoftware. Vì sao nên đọc: lập luận hoài nghi, gói trong một tweet.

FAQ

Mod có thay thế shell hook của tôi ngay bây giờ không?

Chưa, với bất cứ thứ gì phải chặn được. Trên 2.1.272, một hook ném lỗi hoặc đứng quá 10 s sẽ bị bỏ qua và lệnh vẫn chạy. Shell hook vẫn hoạt động, nên hãy giữ các hook chặn ở đó cho đến khi có cơ chế catch khai báo hoặc tùy chọn fail closed.

Nếu Mod chạy ổn thì validate còn quan trọng ở đâu?

Vì các dòng hooks: và calls: của nó là góc nhìn tĩnh duy nhất về những gì một Mod chạm vào trên $. Với Mod của bạn, nó xác nhận footprint; với Mod của bên thứ ba, đó là toàn bộ bước review bạn có trước khi code chạy trong process của bạn.

Một Mod tốn bao nhiêu mỗi session?

claude plugin details báo khoảng 0 token thêm vào. Mod là code chạy trong engine, không phải văn bản trong prompt, đó là lợi thế chính so với skill hoặc một quy tắc trong CLAUDE.md.

Vì sao Mod nạp được trong -p nhưng không nạp trong REPL?

Chưa rõ. Hai lần thử qua pty im lặng trong khi claude -p nạp và áp dụng hook. Nguyên nhân có thể nằm ở môi trường pty hơn là tính năng, nên hãy test trên terminal của bạn trước khi dựa vào bất kỳ chiều nào.