Apple Silicon 本地 RAG:毫秒级响应,无需后端
开源方案实现在本地 M 系列 Mac 运行毫秒级 RAG 检索,完全离线无依赖,代码极简可直用。
开源方案实现在本地 M 系列 Mac 运行毫秒级 RAG 检索,完全离线无依赖,代码极简可直用。
为你的 AI agent 赋予永不遗忘的记忆。一个文件。零云。在 Apple Silicon 上闪电般快速的召回。
English · Español · Français · 日本語 · 한국어 · Português · 中文
Wax 是一个面向 AI agent 的 Swift 原生内存引擎。它在一个完全驻留于你设备上的单个 .wax 文件中存储文档、embedding 和结构化知识。
无服务器。无 API 密钥。无 Docker。就是一个文件,你可以通过 AirDrop、同步或备份的方式使用,就像其他任何文档一样。
import Wax
let memory = try await Memory(at: url)
try await memory.save("The user prefers dark mode and uses Vim keybindings.")
let results = try await memory.search("What editor does the user like?")
// → "The user prefers dark mode and uses Vim keybindings."
持久化聊天机器人 — 你的助手在整个会话中记住每次对话、偏好和决策。
具有长期记忆的编码 agent — Claude Code 或 Cursor 可以回忆你的代码库模式、架构决策和上周的 TODO。
个人知识库 — 对你的笔记、文档和网页剪辑进行语义搜索。提问"我读过什么关于 HNSW 的?",得到确切的段落。
设备上 RAG — 在你的 iOS 或 macOS 应用中部署 AI 功能,无需调用云服务。
Wax 能够适应你所在的位置。选择与你构建内容相匹配的路径:
Swift Package Manager
// Package.swift
dependencies: [
.package(url: "https://github.com/christopherkarani/Wax.git", from: "0.1.8")
]
或在 Xcode 中:File → Add Package Dependencies → https://github.com/christopherkarani/Wax.git
import Foundation
import Wax
let url = URL.documentsDirectory.appending(path: "agent.wax")
// Open a memory store
let memory = try await Memory(at: url)
// Save something
try await memory.save("The user is building a habit tracker in SwiftUI.")
// Recall it later — works even if the app was killed
let results = try await memory.search("What is the user building?")
if let best = results.items.first {
print("Found: \(best.text)")
// → "Found: The user is building a habit tracker in SwiftUI."
}
try await memory.close()
import SwiftUI
import Wax
struct ContentView: View {
@State private var result = "Searching…"
var body: some View {
Text(result)
.task {
do {
let url = URL.documentsDirectory.appending(path: "agent.wax")
let memory = try await Memory(at: url)
try await memory.save("The user is building a habit tracker in SwiftUI.")
let context = try await memory.search("What is the user building?")
result = context.items.first?.text ?? "Nothing found"
try await memory.close()
} catch {
result = "Error: \(error.localizedDescription)"
}
}
}
}
import Foundation
import Wax
@main
struct AgentMemory {
static func main() async throws {
let url = URL.documentsDirectory.appending(path: "agent.wax")
let memory = try await Memory(at: url)
try await memory.save("The user is building a habit tracker in SwiftUI.")
let results = try await memory.search("What is the user building?")
if let best = results.items.first {
print("Found: \(best.text)")
}
try await memory.close()
}
}
想要存储持久化事实和长期推理?参见 Structured Memory。
# Build from source (requires Swift 6+)
git clone https://github.com/christopherkarani/Wax.git
cd Wax
swift build -c release
# The binary is now at .build/release/wax-cli
cp .build/release/wax-cli /usr/local/bin/
# Save a memory
wax-cli remember "An automobile needs periodic maintenance."
# Search it back
wax-cli search "car service" --mode hybrid --topK 3
# Simple text-only search (no setup required)
wax-cli search "car service" --mode text
对于长时间运行的会话,启动守护进程:
wax-cli daemon --store-path ~/.wax/memory.wax
然后发送 JSON 行命令:
{"id":"1","command":"remember","content":"An automobile needs periodic maintenance."}
{"id":"2","command":"search","query":"car service","mode":"hybrid","topK":3}
{"id":"3","command":"shutdown"}
向量搜索需要 embedder。如果不可用,hybrid/vector 命令会显式失败而不是无声地回落到纯文本模式。
为你的 AI 编码助手(Claude Code、Cursor、Windsurf)提供跨会话存活的持久记忆。
npx -y waxmcp@latest mcp install --scope user
这会在本地暂存 Wax 运行时,向 Claude Code 注册 wax-mcp,并在 ~/.local/share/waxmcp/skills/wax-mcp 下暂存 wax-mcp operator skill(然后在可用时尝试调用 claude install-skill)。npx 仅用于一次性安装。
MCP 服务器还在每次工具连接时通过生命周期指令进行传递,因此 agent 即使没有单独的 skill 安装也能接收 remember/recall/handoff playbook。
# Preferred: staged local copy after mcp install
claude install-skill ~/.local/share/waxmcp/skills/wax-mcp
# Or from GitHub
claude install-skill https://github.com/christopherkarani/Wax/tree/main/Resources/skills/public/wax-mcp
这是 agent operator skill(会话生命周期、remember/recall、handoff)。
Use the Wax MCP server for persistent memory in this repo.
Workflow rules:
- At session start, call `handoff_latest` first to load prior context, then call `session_start` once and keep the returned `session_id`.
- Use `remember` to store decisions, discoveries, and short factual notes. If the memory is session-scoped, pass `session_id` as a top-level argument. Do not put `session_id` inside `metadata`.
- Use `recall` for assembled context and `search` for raw ranked hits.
- Prefer `mode: "hybrid"` when semantic retrieval helps. Use `mode: "text"` when I want a fast or deterministic lexical lookup.
- Do not manage `SESSION_STORE`, `--store-path`, or `flush` in normal agent flows. The broker owns long-term memory and virtual session stores.
- Use `handoff` near the end of the session with `content`, optional `project`, and `pending_tasks`, then call `session_end`.
- Use `corpus_search` only when you need cross-session retrieval across broker-managed session history with provenance metadata.
- Use structured memory tools (`entity_upsert`, `fact_assert`, `fact_retract`, `facts_query`, `entity_resolve`) for stable entities and facts, not transient debugging notes.
Behavior expectations:
- Read existing handoffs and recall results before asking me to restate prior context.
- Keep memory writes concise, factual, and scoped to the task.
- When a cross-session result looks relevant, cite the provenance metadata so we know which session store it came from.
完整的 Claude Code 设置流程,参见 Resources/docs/wax-mcp-setup.md。
在 Swift 应用中使用 Wax 框架?这是一个不同的 skill:claude install-skill https://github.com/christopherkarani/Wax/tree/main/Resources/skills/public/wax
对于远程或团队托管的部署,wax-mcp 还支持 HTTP 传输:
./.build/debug/wax-mcp --no-embedder --transport http --http-host 127.0.0.1 --http-port 3000
索引任何仓库并使用自然语言查找代码或提交。
# From within any git repo
wax-repo index
wax-repo search "where did we implement the WAL?"
大多数 RAG 设置最终都会有一个数据库、一个向量存储和一个文件服务器。Wax 通过将文档、元数据和索引打包到一个二进制文件中来保持活动部件更少。
更少的设置 — 没有 Docker 栈,也没有单独的数据库需要照看。
便于移动 — 使用 AirDrop、iCloud 或你已经使用的任何同步层移动文件。
原子性 — 备份、复制或删除一个文件,而不是在服务之间追踪状态。
Wax 为 M 系列硬件和本地召回进行了优化。
下面越好。以毫秒为单位测量。
Wax (Hybrid) |██ 6.1ms
SQLite (Text) |████ 12ms
Cloud RAG |██████████████████████████████████████████████████ 150ms+
下面越好。以毫秒为单位测量。
Wax |███ 9.2ms
Traditional |██████████████████████████████████████ 120ms+
Wax 在 M3 Max 上以完整混合索引处理 85.9 docs/s。完整基准报告:Resources/docs/benchmarks/2026-03-06-performance-results.md
Wax 使用基于框架的容器格式,并在主文件内嵌入它需要的搜索引擎:用于文本的 SQLite FTS5 和用于向量的 Metal 加速 HNSW 索引。
┌──────────────────────────────────────────────────────────────────────────┐
│ Dual Header Pages (A/B) │
│ (Magic, Version, Generation, Pointers to WAL & TOC, Checksums) │
├──────────────────────────────────────────────────────────────────────────┤
│ WAL (Write-Ahead Log) │
│ (Atomic ring buffer for crash-resilient uncommitted mutations) │
├──────────────────────────────────────────────────────────────────────────┤
│ Compressed Data Frames │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Frame 0 (LZ4) │ │ Frame 1 (LZ4) │ │ Frame 2 (LZ4) │ ... │
│ │ [Raw Document] │ │ [Metadata/JSON] │ │ [System Info] │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
├──────────────────────────────────────────────────────────────────────────┤
│ Hybrid Search Indices │
│ ┌──────────────────────────────┐ ┌──────────────────────────────┐ │
│ │ SQLite FTS5 Blob │ │ Metal HNSW Index │ │
│ │ (Text Search + EAV Facts) │ │ (Vector Search) │ │
│ └──────────────────────────────┘ └──────────────────────────────┘ │
├──────────────────────────────────────────────────────────────────────────┤
│ TOC (Table of Contents) │
│ (Index of all frames, parent-child relations, and engine manifests) │
└──────────────────────────────────────────────────────────────────────────┘
原子弹性 — 双头和 WAL 即使进程在写入中间死亡时也能保持存储一致。
统一检索 — 一个查询同时扇出到 BM25 文本索引和 HNSW 向量索引。
结构化知识 — 内置的 EAV(Entity-Attribute-Value)存储处理持久化事实和长期推理。
Wax 提供一个一级的 Model Context Protocol(MCP)服务器。将你的本地记忆连接到 Claude Code 或任何兼容 MCP 的 agent。
npx -y waxmcp@latest mcp install --scope user
关于推荐的 Claude Code 提示和设置流程,参见 Resources/docs/wax-mcp-setup.md。对于本仓库中使用的 OpenClaw 适配器验证通过,运行 scripts/verify-openclaw-adapter.sh。对于本地内存 operator 指南、验证器和基准扫描,参见 docs/openclaw-native-memory.md。
MCP 表面现在支持带有 markdown_export / markdown_sync 的托管 Markdown 往返,包括 MEMORY.md、每日笔记和 DREAMS.md 提升审查。markdown_sync 也支持 dry_run,OpenClaw 导向的提升阈值可以在 session_synthesize / memory_promote 上覆盖或通过环境变量。
对于远程或团队托管的部署,wax-mcp 还支持 HTTP 传输:
./.build/debug/wax-mcp --no-embedder --transport http --http-host 127.0.0.1 --http-port 3000
Q: 我需要互联网连接吗? A: 不需要。Wax 100% 在设备上。无云 API,无网络调用。
Q: .wax 文件会变多大? A: 这取决于你的数据,但文件由于 LZ4 压缩而保持紧凑。典型用途:数千个文档只需几 MB。
Q: 我可以在设备之间同步 .wax 文件吗? A: 可以。它是一个单一文件。iCloud Drive、Dropbox、AirDrop — 任何你已经使用的。
Q: 如果应用在写入期间崩溃会怎样? A: Wax 使用 write-ahead log(WAL)和双头。存储在下一次打开时自动恢复。
Q: Wax 在 Intel Mac 上工作吗? A: Wax 针对 Apple Silicon(M 系列)进行了优化。它可能通过 Rosetta 在 Intel 上运行,但向量加速需要 Metal 性能着色器,这在 Apple Silicon 上最受支持。
Q: 使用混合搜索时我得到"embedder unavailable"。 A: 混合和向量搜索需要本地 embedding 模型。确保 WaxEmbedder 目标被链接,或为纯文本搜索回落到 --mode text。
💬 讨论与问答:GitHub Discussions
🐛 bug 报告:GitHub Issues
⭐ Star 仓库以关注发布
📖 完整文档:Resources/docs
Wax 在 Apache License 2.0 下发布。详见 LICENSE。