blog.dopana

Back

Đ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()   │
     └──────────┘
plaintext

13 Subsystem, 13 Interface#

SubsystemInterfaceMặc địnhExtension
ProviderAI Model50+ providercustom:https://api.cty.com
ChannelGiao tiếpTelegram, Discord, Signal, Nostr…API bất kỳ
MemoryLưu trữSQLite hybrid searchClickHouse, Redis, PostgreSQL
ToolCông cụshell, file, web, git, GPIO…Bất kỳ capability
ObserverObservabilityLog, File, MultiPrometheus, OTel
RuntimeAdapterRuntimeNative, Docker, WASMBất kỳ sandbox
SandboxBảo mậtLandlock, Firejail, DockerTự động detect
TunnelKết nốiCloudflare, Tailscale, ngrokCustom tunnel
PeripheralHardwareSerial, Arduino, RPi GPIO, STM32Bất kỳ thiết bị
IdentityConfigIdentityOpenClaw, AIEOS JSONFormat khác
EmbeddingProviderEmbeddingOpenAI, customNoop
SkillKiến thứcTOML/YAML manifestsCommunity packs
SchedulerCronCron expressionsJSON 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 state
text

Cấu hình hybrid search:

{
  "memory": {
    "backend": "sqlite",
    "vector_weight": 0.7,
    "keyword_weight": 0.3,
    "hygiene_enabled": true
  }
}
json

Ví 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" }
    }
  }
}
json

Tạ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.

Tài liệu tham khảo#