NullClaw: Kiến Trúc Vtable Và Hệ Thống Plugin Linh Hoạt
Khám phá kiến trúc vtable-driven của NullClaw — 13 subsystem dạng interface, swap implementation chỉ bằng config, không cần sửa code.
Điểm khác biệt lớn nhất của NullClaw so với các framework AI agent khác không chỉ nằm ở kích thước binary, mà còn ở kiến trúc vtable-driven — nơi mọi subsystem đều là một interface có thể thay thế.
Vtable Là Gì?#
Trong Zig, vtable là một bảng con trỏ hàm — tương đương interface trong OOP, nhưng không có runtime overhead, không có GC, và hoàn toàn tĩnh.
ptr: *anyopaque + vtable
┌──────────┐
│ init() │
│ deinit() │
│ query() │
│ send() │
└──────────┘plaintext13 Subsystem, 13 Interface#
| Subsystem | Interface | Mặc định | Extension |
|---|---|---|---|
| Provider | AI Model | 50+ provider | custom:https://api.cty.com |
| Channel | Giao tiếp | Telegram, Discord, Signal, Nostr… | API bất kỳ |
| Memory | Lưu trữ | SQLite hybrid search | ClickHouse, Redis, PostgreSQL |
| Tool | Công cụ | shell, file, web, git, GPIO… | Bất kỳ capability |
| Observer | Observability | Log, File, Multi | Prometheus, OTel |
| RuntimeAdapter | Runtime | Native, Docker, WASM | Bất kỳ sandbox |
| Sandbox | Bảo mật | Landlock, Firejail, Docker | Tự động detect |
| Tunnel | Kết nối | Cloudflare, Tailscale, ngrok | Custom tunnel |
| Peripheral | Hardware | Serial, Arduino, RPi GPIO, STM32 | Bất kỳ thiết bị |
| IdentityConfig | Identity | OpenClaw, AIEOS JSON | Format khác |
| EmbeddingProvider | Embedding | OpenAI, custom | Noop |
| Skill | Kiến thức | TOML/YAML manifests | Community packs |
| Scheduler | Cron | Cron expressions | JSON persistence |
Memory Stack Đa Tầng#
Điểm đặc biệt là hệ thống memory của NullClaw hoàn toàn tự xây dựng, không dependency ngoài:
Vector Search: Embedding → BLOB in SQLite → Cosine similarity
Keyword Search: FTS5 → BM25 scoring
Hybrid Merge: Weighted vector + keyword
Embeddings: EmbeddingProvider vtable (OpenAI/custom/noop)
Hygiene: Auto archive + purge
Snapshots: Export/import full statetextCấu hình hybrid search:
{
"memory": {
"backend": "sqlite",
"vector_weight": 0.7,
"keyword_weight": 0.3,
"hygiene_enabled": true
}
}jsonVí Dụ: Thêm Provider Mới#
Mở rộng NullClaw không cần sửa core — chỉ cần thêm implementation:
// src/providers/my_provider.zig
const Provider = @import("../root.zig").Provider;
pub const MyProvider = struct {
pub fn init(config: *Config) !void { ... }
pub fn query(self: *Self, req: Request) !Response { ... }
pub fn deinit(self: *Self) void { ... }
};zigĐăng ký vào factory, config chạy ngay:
{
"models": {
"providers": {
"my-provider": { "api_key": "...", "base_url": "https://api.myprov.com" }
}
}
}jsonTại Sao Lại Là Vtable?#
- Zero-cost abstraction — không runtime dispatch overhead ngoài con trỏ hàm
- Testable — mock interface dễ dàng, 5,300+ tests
- Swap without rebuild — đổi backend chỉ bằng config JSON
- Isolation — mỗi subsystem độc lập, bug không lan
Kết Luận#
Kiến trúc vtable của NullClaw là lý do nó có thể gói 50+ provider, 19 channel, 35+ tool vào một binary 678 KB mà vẫn mở rộng được. Đây là mẫu thiết kế xuất sắc cho các hệ thống cần vừa nhẹ vừa linh hoạt.