2026-03-198 phút đọcVI
- 1.AI Agent cá nhân KHÔNG phải multi-tenant — Vì sao điều đó thay đổi mọi thứ
- 2.8 lớp bảo mật tool — Làm sao để AI bot không rm -rf /
- 3.Kiến trúc mở rộng — Skills, Plugins, và Hooks (Chọn đúng cái)(bài này)
- 4.Secrets, Memory, và nghệ thuật không để lộ mọi thứ
- 5.Từ bot cá nhân đến platform cho team — Playbook thực tế
Kiến trúc mở rộng — Skills, Plugins, và Hooks (Chọn đúng cái)
English title: Extension Architecture — Skills, Plugins, and Hooks (Pick the Right One)
Khi bạn cần dạy AI agent làm điều gì mới, bản năng đầu tiên thường là: fork framework, sửa code, rebuild. Đừng.
Framework tốt không cần bạn fork. Chúng cung cấp extension mechanisms — cách mở rộng mà không đụng vào core code. Vấn đề là: thường có 3-4 cơ chế khác nhau, mỗi cái phục vụ mục đích riêng. Chọn sai = tốn công, tốn token, hoặc tạo tech debt.
Bài này chia sẻ cách tôi phân biệt và chọn giữa Skills, Plugins, và Hooks khi mở rộng AI agent framework.
Hierarchy: Skills > Plugins > Hooks > Config
Đây là thứ tự ưu tiên khi quyết định dùng cơ chế nào:
| Mechanism | Format | Runtime | Token Cost | Khi nào dùng |
|---|---|---|---|---|
| Skills | Markdown (SKILL.md) | System prompt + on-demand read | ~24 tok/skill | Dạy agent task mới — ALWAYS TRY FIRST |
| Plugins | TypeScript | In-process (trusted code) | 0 (code, not prompt) | Custom tools, channel integrations, auth flows |
| Hooks | TS/Config | Event-driven | 0 | React to events (commands, messages, lifecycle) |
| Config | JSON5 | Behavioral overrides | 0 | Tune existing behavior |
Rule: Bắt đầu từ Skills. Chỉ dùng Plugins khi Skills không đủ. Hooks cho automation. Config cho tuning.
Skills — "Dạy, không code"
Concept
Skill là một folder chứa file SKILL.md — hướng dẫn bằng Markdown cho agent biết phải làm gì trong tình huống cụ thể. Không phải code executable. Là hướng dẫn.
~/.openclaw/workspace/skills/
└── report-generator/
└── SKILL.md
---
name: report-generator
description: Generate weekly status reports from conversation history
---
# Report Generator
## When to Use
When user asks for "weekly report", "báo cáo tuần", or "status summary".
## Instructions
1. Read memory files for the last 7 days
2. Extract: decisions made, action items, blockers
3. Format as structured report with sections
4. Keep under 1000 words
## Output Format
### Weekly Report: {date range}
- **Decisions:** ...
- **Action Items:** ...
- **Blockers:** ...
## Constraints
- Do not include personal DM content in group reports
- Do not fabricate information not in memoryCách nó hoạt động (behind the scenes)
- Load time: Framework scan folders, đọc SKILL.md frontmatter
- System prompt: Inject danh sách skills (name + description + path) — ~24 tokens mỗi skill
- On demand: Khi agent quyết định cần skill, nó dùng tool
readđể đọc SKILL.md đầy đủ - Execution: Agent follow instructions trong SKILL.md
Quan trọng: Skill instructions KHÔNG nằm trong prompt mọi lúc. Chỉ danh sách (name + description) được inject. Agent chỉ đọc chi tiết khi cần. Đây là thiết kế tiết kiệm token.
3 location, precedence rõ ràng
| Location | Precedence | Scope |
|---|---|---|
<workspace>/skills/ | Highest | Per-agent |
~/.openclaw/skills/ | Medium | Shared across agents |
| Bundled (shipped with install) | Lowest | Everyone |
Name conflict → workspace wins. Nghĩa là bạn có thể override bundled skill bằng workspace version.
Gating — skill chỉ hiện khi phù hợp
---
name: image-gen
description: Generate images via Gemini
metadata: { "openclaw": { "requires": { "env": ["GEMINI_API_KEY"], "bins": ["uv"] } } }
---Nếu GEMINI_API_KEY chưa set hoặc uv chưa cài → skill tự động ẩn. Không lỗi, không warning cho user. Clean.
Token budget — vấn đề ít ai nghĩ tới
Mỗi skill trong danh sách tốn ~24 tokens. 10 skills = 240 tokens. Nghe ít, nhưng cộng với bootstrap files (AGENTS.md, SOUL.md, TOOLS.md — mỗi file có thể tới 5000 tokens), total overhead lên 15,000-55,000 tokens trước khi conversation bắt đầu.
Rule: giữ workspace skills ≤ 15, mỗi SKILL.md dưới 5000 chars.
Plugins — "Khi Markdown không đủ"
Concept
Plugin là TypeScript module chạy in-process với gateway. Plugin có thể đăng ký tools, HTTP routes, CLI commands, background services, và channel integrations.
Plugin = trusted code. Nó chạy cùng process với gateway, có access tới mọi thứ gateway có. Install plugin = trust plugin.
Khi nào cần Plugin thay vì Skill
| Tình huống | Skill đủ? | Cần Plugin? |
|---|---|---|
| Dạy agent viết báo cáo | ✅ | ❌ |
| Thêm custom tool (API call) | ❌ | ✅ |
| Integrate messaging channel mới | ❌ | ✅ |
| Inject context vào mỗi prompt | ❌ | ✅ (hook API) |
| Auth flow cho model provider | ❌ | ✅ |
| Background service (polling) | ❌ | ✅ |
Plugin hooks — inject vào agent lifecycle
Plugin có thể hook vào lifecycle events:
api.on("before_prompt_build", (event, ctx) => {
return {
prependSystemContext: "Always respond in Vietnamese."
};
});Hai hooks quan trọng nhất:
before_model_resolve— override model/provider trước session loadbefore_prompt_build— inject context sau session load (messages available)
Exclusive slots — chỉ 1 plugin per category
Một số categories chỉ chấp nhận 1 plugin active:
- Memory:
memory-core(default) hoặcmemory-lancedb - Context Engine:
legacy(default) hoặc custom
Nếu 2 plugins cùng claim memory slot → chỉ slot winner load.
Gotcha: Plugins run in-process
Plugin crash = gateway crash. Plugin malicious = gateway compromised. Đây không phải sandbox — đây là trusted extension.
Recommendation: chỉ install plugins bạn đọc source code. Dùng plugins.allow allowlist.
Hooks — "Khi X xảy ra, làm Y"
Concept
Hook là script nhỏ chạy khi event xảy ra. Không phải tool (agent không gọi hooks). Không phải skill (không nằm trong prompt). Hook là automation — "khi /new được gọi, backup session".
Events
| Event | Trigger |
|---|---|
command:new | User gọi /new |
command:reset | User gọi /reset |
command:stop | User gọi /stop |
agent:bootstrap | Trước khi inject workspace files |
gateway:startup | Gateway khởi động xong |
message:received | Tin nhắn đến |
message:sent | Tin nhắn gửi đi |
Ví dụ: Audit log
// hooks/audit-log/handler.ts
const handler = async (event) => {
if (event.type !== "command") return;
const entry = {
timestamp: event.timestamp.toISOString(),
action: event.action,
sessionKey: event.sessionKey,
senderId: event.context.senderId,
};
await appendFile("logs/audit.jsonl", JSON.stringify(entry) + "\n");
};
export default handler;Hooks vs Plugins — ranh giới mờ
Plugins cũng có hooks (api.on("before_prompt_build", ...)). Vậy khi nào dùng standalone hook vs plugin hook?
| Standalone Hook | Plugin Hook |
|---|---|
| Lightweight, 1 file | Part of larger plugin |
CLI manageable (openclaw hooks enable/disable) | Enable/disable with plugin |
| Best for: logging, backup, notifications | Best for: integrated features |
Decision Framework
Cần dạy agent task mới?
└── Yes → SKILL (SKILL.md)
Cần custom tool, channel, hoặc auth flow?
└── Yes → PLUGIN (TypeScript)
Cần react to events (logging, backup)?
└── Yes → HOOK (handler.ts)
Cần tune existing behavior?
└── Yes → CONFIG (openclaw.json)
Anti-pattern: "Plugin cho mọi thứ"
Tôi từng muốn viết plugin cho mọi tính năng mới. Sai. Phần lớn use cases giải quyết bằng SKILL.md — 10 phút viết markdown thay vì 2 giờ viết TypeScript + debug + maintain.
Anti-pattern: "Fork framework"
Framework AI agent release hàng tuần. Fork = diverge = miss security patches = technical debt. Extend qua Skills + Plugins + Hooks = sustainable path.
Bài học
1. Skills trước, code sau
Khi cần tính năng mới, viết SKILL.md trước. Nếu 3 ngày sau vẫn đủ dùng → bạn đã tiết kiệm 1 plugin. Nếu không đủ → bạn có spec rõ ràng cho plugin.
2. Token cost là real cost
15 skills × 24 tokens = 360 tokens mỗi turn chỉ cho skills list. Cộng bootstrap files = 20,000+ tokens overhead. Nhân 100 messages/ngày × $3/MTok = vài chục USD/tháng chỉ cho overhead.
Giữ skills lean. Delete skills không dùng.
3. Hooks = invisible infrastructure
Hook tốt nhất là hook bạn quên nó tồn tại. Audit log chạy im lặng. Session backup tự động. Memory sync nightly. Không cần user interaction.
4. Đừng fork
Framework tốt cung cấp đủ extension points. Nếu bạn thấy cần fork — trước tiên hỏi: "Có skill/plugin/hook nào giải quyết được không?" Hầu hết lần, câu trả lời là có.
Pillar: 1. Content type: lesson-note. Engine: ACE-LDK-claire-personal-branding-engine.