Mac mini M4 + Gemma 4:16GB 内存搭建纯本地 AI 中文知识库

0 阅读23分钟

Mac mini M4 + Gemma 4:16GB 内存搭建纯本地 AI 中文知识库

硬件:Mac mini M4 · 16GB 统一内存

系统:macOS 15 (Sequoia) 及以上

前提:已安装 OpenClaw(本教程不涉及 OpenClaw 安装步骤)

网络:国内网络,需配置国内镜像源


为什么要做这件事

Google 最近开源了 Gemma 4 系列模型,其中 E4B 变体经过 MXFP4 混合精度量化后,仅需约 6.6GB 显存即可运行——这意味着它不仅能跑在 Mac mini 这样的消费级设备上,甚至连手机都能带得动。看到这个消息后,我决定在自己的 Mac mini M4(16GB)上动手搭一套完全本地化的知识库系统。

最直接的原因是数据安全——工作中有些内部文档不太方便丢到云端去跑,本地部署的话所有东西都留在自己机器上,断网照样能用,心里踏实。验证一下其他博主的一个省钱小妙招:OpenClaw 的心跳机制平时会持续消耗云端 token,把心跳交给本地模型处理之后,这部分开销就省下来了,长期算算也不少。

这篇教程就是把自己折腾的过程记录下来,踩过的坑也写了进去,希望能帮到有类似想法的朋友。


目录


1. 项目简介与架构总览

我们要做什么

在 Mac mini M4 (16GB) 上搭建一套完全本地的 LLM 知识库问答系统。数据不出机,零 API 费用,支持中文。

核心组件

组件模型 / 工具作用
对话模型Gemma 4 E4B IT (MXFP4)理解用户问题,生成自然语言回答
嵌入模型BGE-M3 MLX 4bit将文本转换为向量,用于语义检索
重排序模型BGE-Reranker-v2-m3对检索结果精排,提高回答准确度
推理框架MLXApple 专为自家芯片设计的机器学习框架
推理服务oMLX (Osaurus)本地模型管理与 OpenAI 兼容 API 服务
知识库入口OpenClawAI Agent 运行时,提供记忆、检索和对话能力

架构图

用户提问
│
▼
OpenClaw (Agent)
│
├─① memory_search ──▶ BGE-M3 (嵌入) ──▶ 向量检索召回 Top-K
│ │
├─② omlx_rerank ───▶ BGE-Reranker-v2-m3 ────▶ 精排 Top-N
│ │
└─③ 生成回答 ──────▶ Gemma 4 E4B ────────────▶ 输出答案
▲
│
oMLX (本地 API 服务, 端口 8000)

1架构图.jpg

内存预算(16GB)

组件预估占用
macOS 系统~3-4 GB
Gemma 4 E4B MXFP4 (含 KV cache)~3-4 GB
BGE-M3 MLX 4bit~0.5 GB
BGE-Reranker-v2-m3~2.2 GB
OpenClaw Gateway + SQLite 索引~0.5-1 GB
合计~9-12 GB

剩余 4-7 GB 留给系统缓存和临时峰值,可正常运行。


2. 前置条件与国内镜像源配置

2.1 系统要求

  • Mac mini M4(或其他 Apple Silicon 设备)

  • macOS 15 (Sequoia) 及以上

  • 16GB 统一内存(MacMini丐版+)

  • 已安装 OpenClaw 并能正常运行

2.2 安装基础工具

Homebrew 在国内可能下载缓慢,可使用清华镜像加速安装:

# 使用清华镜像安装 Homebrew

/bin/bash -c "$(curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/misc/homebrew-install.sh)"

安装完成后,配置 Homebrew 使用国内源:

# 替换 Homebrew 源为清华镜像
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"
export HOMEBREW_API_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api"
export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"


# 写入 ~/.zshrc 使其永久生效
cat >> ~/.zshrc << 'EOF'


# === Homebrew 清华镜像 ===
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"
export HOMEBREW_API_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api"
export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"

EOF

source ~/.zshrc

然后安装基础工具:

# 安装 Python 3.11(MLX 推荐版本)
brew install python@3.11

# 安装 Git(如未安装)
brew install git

2.3 配置 pip 国内镜像源

# 配置 pip 使用清华 PyPI 镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn

验证

pip config list
# 预期输出包含:
# global.index-url='https://pypi.tuna.tsinghua.edu.cn/simple'

2.4 配置 Hugging Face 国内镜像

模型下载依赖 Hugging Face Hub,国内直连很慢甚至超时。配置 HF 镜像:

# 写入 ~/.zshrc
cat >> ~/.zshrc << 'EOF'

# === Hugging Face 国内镜像 ===
export HF_ENDPOINT="https://hf-mirror.com"
EOF

source ~/.zshrc

验证

echo $HF_ENDPOINT
# 预期输出:https://hf-mirror.com

# 测试镜像是否可访问
curl -I https://hf-mirror.com
# 预期:返回 HTTP 200

2.4配置国内镜像源.png

2.5 配置 Git 加速(可选)

如果 GitHub 访问缓慢,可配置 Git 使用国内镜像:

# 使用 ghproxy 加速 GitHub(可选)
git config --global url."https://ghproxy.com/https://github.com/".insteadOf "https://github.com/"

提示:如果后续某个步骤下载失败,优先检查对应的镜像源是否配置正确。

2.6 镜像源汇总

资源国内镜像用途
Homebrewmirrors.tuna.tsinghua.edu.cnbrew 安装软件包
PyPIpypi.tuna.tsinghua.edu.cnpip 安装 Python 包
Hugging Facehf-mirror.com下载模型权重
GitHubghproxy.com(可选)克隆仓库

3. 安装 MLX 推理环境

MLX 是 Apple 官方的机器学习框架,专为 Apple Silicon 的统一内存架构设计,GPU/CPU 共享同一块内存,无需数据搬运,推理效率远高于 PyTorch。

3.1 创建 Python 虚拟环境

# 创建专用虚拟环境
python3.11 -m venv ~/mlx311-env

# 激活环境
source ~/mlx311-env/bin/activate

# 升级 pip
pip install --upgrade pip

3.2 安装 MLX 及相关包

pip install mlx mlx-lm huggingface_hub

3.3 验证

python -c "import mlx.core as mx; print(f'MLX 版本: {mx.__version__}'); print(f'默认设备: {mx.default_device()}')"

预期输出:

MLX 版本: x.x.x
默认设备: Device(gpu, 0)

如果显示 gpu,说明 MLX 已正确识别 Apple Silicon GPU。

3.3验证MLX推理环境.png


4. 安装 oMLX (Osaurus)

oMLX (Osaurus) 是 macOS 原生的 AI 推理服务,用 Swift 编写,提供模型管理、OpenAI 兼容 API、嵌入和重排序等能力。它是连接 OpenClaw 与本地模型的桥梁。

4.1 安装

# 方式一:Homebrew(推荐)
brew install --cask osaurus

# 方式二:从官网下载 DMG
# 访问 https://omlx.org 下载安装

4.1 安装oMLX.png

4.2 启动 oMLX

安装完成后,从「应用程序」中打开 Osaurus。首次启动会初始化配置目录 ~/.omlx/

4.3 验证

# 检查 oMLX API 服务是否运行(默认端口 8000)
curl -s http://127.0.0.1:8000/v1/models -H "Authorization: Bearer 123456"

预期返回 JSON 格式的模型列表(首次可能为空)。如果连接被拒绝,确认 Osaurus 应用已打开。

说明:oMLX 的 API Key 需自行设置。在 ~/.omlx/settings.jsonauth.api_key 中填写你自定义的密钥(本教程以 123456 为示例),后续所有涉及 Authorization: BearerapiKey 的地方都需要与此保持一致。


5. 下载对话模型 — Gemma 4 E4B IT MXFP4

Gemma 4 是 Google 开源的第四代多模态模型,支持文本、图像、音频和视频输入。E4B 是该系列的一个规格变体,采用 42 层 Transformer 架构,支持 128K 上下文窗口。IT 表示经过指令微调(Instruction Tuned)。MXFP4 是混合精度量化格式——大部分层使用 4bit,关键层(前几层 MLP)保留 8bit 以保护生成质量,在 Apple Silicon 上推理效率高。

名字拆解gemma4-e4b-it-mxfp4

  • gemma4 — Gemma 第 4 代(不是 4B 参数的意思)
  • e4b — Google 的模型规格代号
  • it — Instruction Tuned(指令微调版)
  • mxfp4 — MX Floating Point 4-bit 混合精度量化

5.1 通过 oMLX Admin 下载

  1. 打开浏览器,访问 oMLX Admin 面板(通常在 Osaurus 应用内或 http://127.0.0.1:8000

  2. 进入 Models 页面

  3. 搜索 gemma4-e4b-it-mxfp4

  4. 点击下载,等待完成

5.1通过oMLX Admin下载Gemma 4.png

5.2 验证

# 确认模型文件存在
ls ~/.omlx/models/gemma4-e4b-it-mxfp4/

# 预期看到:config.json, model.safetensors (或分片文件), tokenizer.json 等
# 通过 API 测试对话
curl -s http://127.0.0.1:8000/v1/chat/completions \
-H "Authorization: Bearer 123456" \
-H "Content-Type: application/json" \
-d '{
"model": "gemma4-e4b-it-mxfp4",
"messages": [{"role": "user", "content": "你好,请用中文介绍一下你自己"}],
"max_tokens": 200
}'

预期返回包含中文回答的 JSON 响应。

5.2验证Gemma 4.png


6. 下载嵌入模型 — BGE-M3 MLX 4bit

BGE-M3 是 BAAI(北京智源研究院)开源的多语言嵌入模型,支持 100+ 语言,能将文本转换为 1024 维向量用于语义检索。MLX 4bit 版本针对 Apple Silicon 优化,仅占约 0.5GB 内存。

6.1 通过 oMLX Admin 下载

  1. 在 oMLX Admin 的 Models 页面搜索 bge-m3-mlx-4bit
  2. 点击下载

6.2 验证

# 确认模型文件存在
ls ~/.omlx/models/bge-m3-mlx-4bit/

# 预期看到:config.json, model.safetensors, tokenizer.json, modules.json 等
# 通过 API 测试嵌入
curl -s http://127.0.0.1:8000/v1/embeddings \
-H "Authorization: Bearer 123456" \
-H "Content-Type: application/json" \
-d '{
"model": "bge-m3-mlx-4bit",
"input": "这是一段测试文本"
}'

预期返回包含 1024 维浮点数组的 JSON 响应。


7. 下载重排序模型 — BGE-Reranker-v2-m3

BGE-Reranker-v2-m3 是 BGE-M3 的配套重排序模型,使用 cross-encoder 架构,将 query 和候选文档拼接后直接输出相关性分数。相比初次向量检索,重排序能显著提高结果精度。

关键优势(相比旧版 bge-reranker-base):

  • 参数量 0.6B(base 为 0.3B),精度更高
  • 最大输入 8192 tokens(base 仅 512),不会截断长文档
  • 多语言能力强,中文效果明显更好
  • 与 BGE-M3 嵌入模型同系列,语义空间对齐

7.1 通过 oMLX Admin 下载

在 oMLX Admin 的 Models 页面搜索 bge-reranker-v2-m3,如果能找到则直接下载。

如果 oMLX 模型库中未收录,使用命令行手动下载:

# 激活虚拟环境
source ~/mlx311-env/bin/activate

# 创建模型目录
mkdir -p ~/.omlx/models/bge-reranker-v2-m3

# 从 Hugging Face 下载(排除冗余的 ONNX 和 PyTorch bin 文件)
python -c "
from huggingface_hub import snapshot_download
snapshot_download(
repo_id='BAAI/bge-reranker-v2-m3',
local_dir='$HOME/.omlx/models/bge-reranker-v2-m3',
ignore_patterns=['*.onnx', 'onnx/*', '*.bin']
)
print('下载完成')
"

国内网络提示:如果下载缓慢或失败,确认第 2 步中的 Hugging Face 镜像已配置:

echo $HF_ENDPOINT
# 应输出:https://hf-mirror.com

如未生效,运行 source ~/.zshrc 后重试。

7.2 补充 oMLX 元数据

手动下载的模型需要添加 oMLX 识别所需的元数据文件:

# 创建 configuration.json
echo '{"framework": "pytorch", "task": "text-classification", "allow_remote": true}' \
> ~/.omlx/models/bge-reranker-v2-m3/configuration.json

# 创建版本标记
echo 'Revision:main,CreatedAt:1713052800' \
> ~/.omlx/models/bge-reranker-v2-m3/.mv

7.3 重启 oMLX

退出并重新打开 Osaurus 应用,让它重新扫描 models 目录。

7.4 验证

7.4oMLX运行本地模型.png

# 确认模型文件完整
ls -lh ~/.omlx/models/bge-reranker-v2-m3/

# 预期看到:
# config.json (~800B)
# configuration.json (刚创建的)
# model.safetensors (~2.1GB)
# sentencepiece.bpe.model (~4.8MB)
# tokenizer.json (~16MB)
# tokenizer_config.json
# .mv
# 通过 API 测试重排序
curl -s http://127.0.0.1:8000/v1/rerank \
-H "Authorization: Bearer 123456" \
-H "Content-Type: application/json" \
-d '{
"model": "bge-reranker-v2-m3",
"query": "什么是人工智能",
"documents": [
"人工智能是计算机科学的一个分支,致力于创建能模拟人类智能的系统",
"今天天气晴朗,适合户外运动",
"机器学习是人工智能的核心技术之一"
]
}'

预期返回:第 1 和第 3 条文档的 relevance_score 远高于第 2 条。

首次调用较慢(约 20 秒)是正常的,MLX 需要编译 Metal kernel。后续调用会降到毫秒级。

# 查看 oMLX 日志确认模型加载成功
tail -20 ~/.omlx/logs/server.log

# 预期看到:
# Loading model: bge-reranker-v2-m3
# Reranker model loaded successfully: ...bge-reranker-v2-m3 (compiled=True)
# Loaded model: bge-reranker-v2-m3 (estimated: 2.22GB, total: ...)

8. 配置 OpenClaw 对接 oMLX

OpenClaw 通过 openclaw.json 配置文件连接到 oMLX 的 OpenAI 兼容 API。

8.1 设计思路:独立知识库 Agent

OpenClaw 支持创建多个 Agent,每个 Agent 有独立的工作区、模型和记忆。我们的策略是:

  • 主 Agent(main):日常使用,可对接云端模型(如 OpenRouter),处理通用任务
  • 知识库 Agent(gemma4):专门对接本地 oMLX,负责知识库问答

这样做的好处:

  1. 互不影响:知识库 Agent 的配置、记忆、工作区与主 Agent 完全隔离,调试知识库不会干扰日常使用
  2. 节省 Token 费用:将 OpenClaw 的心跳(定时会话保活)切换到知识库 Agent,心跳消耗的 Token 走本地 Gemma 4 而不是云端付费模型,长期可节省不少费用
  3. 灵活切换:在 OpenClaw 中可随时切换 Agent,知识库问答用 gemma4 Agent,其他任务用主 Agent

8.2 编辑 OpenClaw 配置

编辑 ~/.openclaw/openclaw.json,以下是完整的关键配置:

{
  "models": {
    "mode": "merge",
    "providers": {
      // ---- 云端模型(主 Agent 使用,示例为 GPT-5.4) ----
      "openai": {
        "baseUrl": "https://api.openai.com/v1",
        "api": "openai-completions",
        "apiKey": {
          "source": "env",
          "provider": "default",
          "id": "OPENAI_API_KEY"
        },
        "models": [{
          "id": "gpt-5.4",
          "name": "GPT-5.4",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": {
            "input": 2.5,
            "output": 10,
            "cacheRead": 1.25,
            "cacheWrite": 2.5
          },
          "contextWindow": 200000,
          "maxTokens": 32768
        }]
      },
      // ---- 本地模型(知识库 Agent + 心跳使用) ----
      "omlx": {
        "baseUrl": "http://127.0.0.1:8000/v1",
        "api": "openai-completions",
        "apiKey": {
          "source": "env",
          "provider": "default",
          "id": "OMLX_API_KEY"
        },
        "models": [{
          "id": "memorySearch",
          "name": "BGE M3 Embedding",
          "reasoning": false,
          "input": ["text"],
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          },
          "contextWindow": 8192,
          "maxTokens": 8192
        }, {
          "id": "gemma4-e4b-it-mxfp4",
          "name": "Gemma 4 on oMLX",
          "reasoning": true,
          "input": ["text"],
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          },
          "contextWindow": 32768,
          "maxTokens": 32768
        }]
      }
    }
  },
  "agents": {
    // ---- 默认配置 ----
    // defaults.model.primary 决定心跳走哪个模型
    // 设为本地模型 → 心跳零费用
    "defaults": {
      "model": {
        "primary": "omlx/gemma4-e4b-it-mxfp4"
      },
      "memorySearch": {
        "provider": "openai",
        "model": "bge-m3-mlx-4bit",
        "sync": {
          "watch": true
        },
        "query": {
          "minScore": 0.20,
          "maxResults": 8
        },
        "extraPaths": ["./knowledge"],
        "remote": {
          "apiKey": "123456",
          "baseUrl": "http://127.0.0.1:8000/v1"
        }
      },
      "models": {
        "openai/gpt-5.4": {
          "alias": "GPT-5.4"
        },
        "omlx/gemma4-e4b-it-mxfp4": {
          "alias": "Gemma 4"
        }
      },
      "workspace": "/Users/<你的用户名>/.openclaw/workspace"
    },
    "list": [
      // ---- 主 Agent:使用云端 GPT-5.4,处理通用任务 ----
      // 没有 heartbeat 块 → 不跑心跳,不产生云端费用
      {
        "id": "main",
        "name": "main",
        "workspace": "/Users/<你的用户名>/.openclaw/workspace",
        "model": {
          "primary": "openai/gpt-5.4"
        }
      },
      // ---- 知识库 Agent:使用本地模型,独立工作区 + 承担心跳 ----
      {
        "id": "gemma4",
        "name": "gemma4",
        "workspace": "/Users/<你的用户名>/.openclaw/workspace-gemma4",
        "model": {
          "primary": "omlx/gemma4-e4b-it-mxfp4",
          "fallbacks": []
        },
        "heartbeat": {
          "every": "30m",
          "model": "omlx/gemma4-e4b-it-mxfp4"
        }
      }
    ]
  }
}

注意:云端模型 provider 以 GPT-5.4 为示例,你可以替换为任何 OpenAI 兼容的服务(如 OpenRouter、Anthropic 等),按需修改 baseUrlapiKeymodels

8.3 关键配置说明

Provider 配置(两套并行)

Provider用途费用
openai主 Agent 对话(GPT-5.4 示例)按 Token 付费
omlx知识库 Agent 对话 + 嵌入 + 心跳本地零费用

模型与 API 配置

配置项说明
models.providers.openai.baseUrlhttps://api.openai.com/v1云端 API 地址(可替换为 OpenRouter 等)
models.providers.omlx.baseUrlhttp://127.0.0.1:8000/v1本地 oMLX API 地址
agents.defaults.model.primaryomlx/gemma4-e4b-it-mxfp4全局默认模型,未指定 Agent 时的 fallback
memorySearch.provideropenai使用 OpenAI 兼容协议连接 oMLX
memorySearch.modelbge-m3-mlx-4bit嵌入模型名称
memorySearch.remote.baseUrlhttp://127.0.0.1:8000/v1嵌入 API 地址
memorySearch.remote.apiKey123456oMLX API Key(自行设置,需与 ~/.omlx/settings.json 中一致)
memorySearch.query.minScore0.20最低相关性分数阈值
memorySearch.query.maxResults8最多返回结果数
memorySearch.extraPaths["./knowledge"]额外索引的知识库目录(可按需添加子目录路径)

Agent 配置(两个 Agent 分工)

Agent模型心跳用途费用
main(主 Agent)openai/gpt-5.4不跑心跳日常通用任务按 Token 付费
gemma4(知识库 Agent)omlx/gemma4-e4b-it-mxfp4每 30 分钟知识库问答 + 心跳保活零费用

8.4 创建知识库 Agent 的工作区

mkdir -p ~/.openclaw/workspace-gemma4/knowledge
mkdir -p ~/.openclaw/workspace-gemma4/memory

8.5 心跳只走本地模型(节省 Token 费用)

OpenClaw 的心跳机制会定期运行 Agent turn 以保持会话活跃,每次心跳都会消耗 Token。如果心跳走云端付费模型,费用会日积月累。

关键规则:OpenClaw 中,如果任何 agents.list[] 定义了 heartbeat 块,则只有那些 Agent 会运行心跳。没有 heartbeat 块的 Agent 不会跑心跳。

利用这个规则,我们的配置策略是:

main Agent → 没有 heartbeat 块 → 不跑心跳 → GPT-5.4 零心跳消耗
gemma4 Agent → 有 heartbeat 块 → 每 30 分钟跑一次 → 走本地 Gemma 4,零费用

省钱小妙招

场景走哪个模型费用
心跳保活gemma4 Agent → 本地 Gemma 4
知识库问答gemma4 Agent → 本地 Gemma 4
日常通用任务main Agent → GPT-5.4按 Token 付费

整个系统只有一个心跳,且走本地模型。main Agent 不跑心跳,云端模型只在你主动对话时才消耗 Token。

8.6 设置环境变量

# 在 ~/.zshrc 中添加(替换为你自己的 Key)
cat >> ~/.zshrc << 'EOF'

# === OpenClaw API Keys ===
export OMLX_API_KEY="123456" # oMLX 本地服务 Key(自行设置)
export OPENAI_API_KEY="sk-your-key-here" # OpenAI Key(主 Agent 使用,如不用云端可跳过)

EOF

source ~/.zshrc

8.7 重启 OpenClaw Gateway

openclaw gateway restart

8.8 验证

# 检查 OpenClaw 是否正常连接 oMLX
openclaw memory status

# 预期看到:嵌入 provider 已配置,索引状态正常

8.8验证openclaw memory status.png

验证知识库 Agent 独立工作区:

# 确认两个工作区独立存在
ls ~/.openclaw/workspace/
ls ~/.openclaw/workspace-gemma4/

9. 配置 Reranker 插件

OpenClaw 通过插件机制调用 oMLX 的重排序 API。我们需要创建一个 omlx-reranker 插件。

9.1 创建插件目录

mkdir -p ~/.openclaw/plugins/omlx-reranker

9.2 创建插件描述文件

cat > ~/.openclaw/plugins/omlx-reranker/openclaw.plugin.json << 'EOF'
{
  "id": "omlx-reranker",
  "name": "oMLX Reranker",
  "description": "使用本地 oMLX bge-reranker-v2-m3 进行结果重排序",
  "version": "1.0.0",
  "author": "local",
  "runtime": "node",
  "format": "openclaw",
  "entry": "index.ts",
  "permissions": [
    "network:127.0.0.1:8000"
  ],
  "configSchema": {
    "type": "object",
    "properties": {},
    "additionalProperties": false
  }
}
EOF

9.3 创建插件代码

cat > ~/.openclaw/plugins/omlx-reranker/index.ts << 'PLUGINEOF'
const OMlxRerankerTool = (ctx) => ({
  name: "omlx_rerank",
  description: "使用本地 oMLX 的 bge-reranker-v2-m3 模型对检索结果进行精排。使用 cross-encoder 重新评估 query 和文档的相关性,支持 100+ 语言和 8192 token 长文本。适用于 memorySearch 返回结果后的二次排序。",
  inputSchema: {
    type: "object",
    properties: {
      query: {
        type: "string",
        description: "用户查询/问题"
      },
      documents: {
        type: "array",
        items: {
          type: "string"
        },
        description: "需要重新排序的文档数组"
      }
    },
    required: ["query", "documents"]
  },
  execute: async (args) => {
    const {
      query,
      documents
    } = args;
    try {
      const response = await fetch("http://127.0.0.1:8000/v1/rerank", {
        method: "POST",
        headers: {
          "Authorization": "Bearer 123456",
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          model: "bge-reranker-v2-m3",
          query: query,
          documents: documents
        })
      });
      if (!response.ok) {
        throw new Error(`oMLX reranker API error: ${response.status}`);
      }
      const data = await response.json();
      const results = data.results.map((item) => ({
        index: item.index,
        relevance_score: item.relevance_score,
        document: item.document.text || item.document
      }));
      return {
        result: "success",
        details: {
          reranked_results: results,
          model: data.model,
          original_count: documents.length,
          returned_count: results.length
        }
      };
    } catch (error) {
      return {
        result: "error",
        error: `Reranker 调用失败: ${error.message}`,
        details: {
          documents_count: documents.length
        }
      };
    }
  }
});
const plugin = {
  id: "omlx-reranker",
  name: "oMLX Reranker",
  description: "使用本地 oMLX bge-reranker-v2-m3 进行结果重排序",
  register(api) {
    api.registerTool(OMlxRerankerTool, {
      name: "omlx_rerank"
    });
    api.logger.info("oMLX reranker tool registered");
  }
};

export default plugin;
PLUGINEOF

9.4 在 OpenClaw 中注册插件

编辑 ~/.openclaw/openclaw.json,在 plugins 部分添加:

{
  "plugins": {
    "load": {
      "paths": [
        "/Users/<你的用户名>/.openclaw/plugins/omlx-reranker"
      ]
    },
    "entries": {
      "omlx-reranker": {
        "enabled": true
      }
    }
  }
}

9.5 重启 OpenClaw Gateway

openclaw gateway restart

9.6 验证

# 查看 OpenClaw 日志,确认插件加载
# 预期看到:oMLX reranker tool registered

# 直接测试 reranker API
curl -s http://127.0.0.1:8000/v1/rerank \
-H "Authorization: Bearer 123456" \
-H "Content-Type: application/json" \
-d '{
"model": "bge-reranker-v2-m3",
"query": "如何配置代理",
"documents": [
"在 .zshrc 中设置 HTTP_PROXY 环境变量即可配置系统代理",
"苹果公司发布了新款 MacBook Pro",
"Clash 是一款常用的代理工具,支持多种协议"
]
}'

预期:第 1 和第 3 条得分高,第 2 条得分低。

9.6 验证Reranker插件.png


10. 构建知识库与索引

OpenClaw 的知识库基于 Markdown 文件,存放在工作区目录中。

10.1 工作区目录结构

OpenClaw 工作区下有三个核心目录,各有分工:

~/.openclaw/workspace-gemma4/ # 知识库 Agent 的工作区
├── MEMORY.md # 长期记忆(核心知识、偏好、决策)
├── IDENTITY.md # Agent 身份描述
├── TOOLS.md # 可用工具说明
├── HEARTBEAT.md # 心跳配置
│
├── knowledge/ # 知识库文档(手动维护)
│ ├── tech-docs.md # 技术文档、参考资料
│ ├── project-notes.md # 项目笔记
│ └── policies/ # 规范、策略类文档
│     └── ...
│
├── memory/ # 对话记忆(自动 + 手动)
│ ├── 2026-04-13.md # 每日对话摘要(OpenClaw 自动生成)
│ └── ...
│
└── state/ # Agent 运行状态(自动管理)
    └── ... # OpenClaw 内部使用,无需手动修改

三个目录的区别

目录谁写入存放什么是否被索引
knowledge/你手动维护技术文档、参考资料、规范策略等静态知识(.md / .txt是(通过 extraPaths 配置)
memory/OpenClaw 自动生成每日对话摘要、上下文笔记,也可手动添加是(OpenClaw 内置索引)
state/OpenClaw 自动管理Agent 运行时状态数据否(内部使用)

重要knowledge/ 及其子目录中只能存放纯文本文件(.md.txt)。图片、PDF 等二进制文件会导致索引报错(EISDIR / 读取失败),应存放在 knowledge/ 之外(如 assets/ 目录)。

简单理解knowledge/ 是你喂给 Agent 的「教材」,memory/ 是 Agent 自己的「笔记本」,state/ 是 Agent 的「工作台」。

10.2 创建知识库目录

memory/state/ 由 OpenClaw 在 Agent 首次运行时自动创建,无需手动操作。只需创建 knowledge/ 目录用于存放你的知识文档:

mkdir -p ~/.openclaw/workspace-gemma4/knowledge

10.3 添加知识文档

将你的知识内容以 Markdown 格式放入 knowledge/ 目录。例如:

cat > ~/.openclaw/workspace-gemma4/knowledge/example.md << 'EOF'

# MLX 框架简介
MLX 是 Apple 为自家芯片设计的机器学习框架。
它利用 Apple Silicon 的统一内存架构,GPU 和 CPU 共享同一块内存,无需数据搬运。

## 主要特点
- 原生支持 Apple Silicon (M1/M2/M3/M4)
- 统一内存,无需 GPU 显存管理
- 支持自动微分
- 惰性计算,按需执行
EOF

10.4 构建索引

# 检查索引状态
openclaw memory status

# 强制重建索引(首次或大规模变更后)
openclaw memory index --force

# 测试搜索
openclaw memory search "MLX 是什么"

10.4强制重建索引.png

10.5 验证

# 搜索应返回刚才添加的文档片段
openclaw memory search "Apple Silicon 机器学习"

# 预期:返回 knowledge/example.md 中的相关片段,附带文件路径和行号

11. 全链路验证

所有组件就绪后,进行端到端测试。

11.1 检查所有服务状态

# 1. oMLX 服务
curl -s http://127.0.0.1:8000/v1/models \
-H "Authorization: Bearer 123456" | python -m json.tool
# 预期:列出 gemma4-e4b-it-mxfp4, bge-m3-mlx-4bit, bge-reranker-v2-m3

# 2. OpenClaw Gateway
openclaw memory status

# 3. 查看 oMLX 模型发现与内存占用(日志按天轮转,需搜索当天或历史日志)
grep "Discovered model\|Loaded model" ~/.omlx/logs/server.log*
# 预期看到类似:
# Discovered model: bge-m3-mlx-4bit (type: embedding, engine: embedding, size: 0.31GB)
# Discovered model: bge-reranker-v2-m3 (type: reranker, engine: reranker, size: ...)
# Discovered model: gemma4-e4b-it-mxfp4 (type: vlm, engine: vlm, size: 6.59GB)
# Loaded model: gemma4-e4b-it-mxfp4 (estimated: 6.59GB, total: 6.59GB)

11.2 测试知识库问答

步骤一:打开日志监控(新开一个终端窗口)
tail -f ~/.omlx/logs/server.log

保持这个窗口可见,后续操作时实时观察日志输出。

步骤二:确认 Gateway 运行并向知识库 Agent 提问

教程配置了两个 Agent:main(GPT-5.4 云端)和 gemma4(本地知识库)。测试知识库时需要指定 gemma4 Agent。

# 确认 Gateway 已在运行
openclaw gateway start

方式 A:命令行单次提问(推荐用于快速验证)

openclaw agent --agent gemma4 --message "knowledge 目录下有哪些文档?请总结一下主要内容"

--agent gemma4 指定使用知识库 Agent,消息会经过完整的 RAG 链路处理后返回结果。

方式 B:TUI 交互界面(适合持续对话)

TUI 默认连接 main session(即 GPT-5.4 主 Agent)。要让 TUI 路由到 gemma4,需要先为其绑定一个 session:

# 为 gemma4 Agent 绑定 session
openclaw agents bind --agent gemma4 --bind tui

# 启动 TUI 并指定 session 连接到 gemma4
openclaw tui --session gemma4

进入 TUI 后直接输入问题即可,所有对话都会路由到本地 Gemma 4 模型。

11.2测试知识库问答.png

步骤三:提问并观察完整 RAG 流程

无论使用方式 A 还是方式 B,输入一个知识库中已有的问题,例如:

knowledge 目录下有哪些文档?请总结一下主要内容

如果你已在 ~/.openclaw/workspace-gemma4/knowledge/ 中放入了自己的文档,可以针对文档内容提问,效果更明显。

验证:完整 RAG 链路应依次触发

提问后,观察 OpenClaw 的输出和 oMLX 日志窗口,确认以下三步依次发生:

步骤触发动作oMLX 日志关键字说明
1. 向量检索OpenClaw 自动调用 memory_searchEmbedding: 1 inputs, 1024 dims, N tokens in ...sBGE-M3 将问题编码为向量,在知识库中混合检索召回候选文档
2. 精排重排OpenClaw 调用 omlx_rerank 工具Rerank: N docs, ... tokens in ...sBGE-Reranker-v2-m3 对候选文档按相关性重新排序
3. 生成回答OpenClaw 将精排结果作为上下文发给 LLMChat completion: ... tokens in ...sGemma 4 E4B 基于精排后的上下文生成最终回答

验证要点:

  • 如果日志中只出现 Embedding 而没有 Rerank,说明 reranker 插件未正确加载,检查 ~/.openclaw/plugins/omlx-reranker/ 配置

  • 如果日志中没有 Chat completion,说明 Gemma 4 模型未被调用,检查 Agent 的 model.primary 是否指向 omlx/gemma4-e4b-it-mxfp4

  • 如果 OpenClaw 回复"未找到相关记忆",说明 knowledge/ 目录为空或文档尚未被索引,确认已放入 .md / .txt 文件并等待索引完成

补充:直接通过 API 测试各组件(可选)

如果想单独验证某个组件是否正常工作,可以用 curl 直接调用 oMLX API:

# 测试嵌入模型
curl -s http://127.0.0.1:8000/v1/embeddings \
-H "Authorization: Bearer 123456" \
-H "Content-Type: application/json" \
-d '{"model":"bge-m3-mlx-4bit","input":"测试文本"}' | python -m json.tool
# 预期:返回 1024 维向量数组

# 测试重排序模型
curl -s http://127.0.0.1:8000/v1/rerank \
-H "Authorization: Bearer 123456" \
-H "Content-Type: application/json" \
-d '{"model":"bge-reranker-v2-m3","query":"什么是RAG","documents":["RAG是检索增强生成","今天天气很好","RAG结合了检索与生成"]}' | python -m json.tool
# 预期:返回按相关性排序的结果,RAG 相关文档得分最高

# 测试对话模型
curl -s http://127.0.0.1:8000/v1/chat/completions \
-H "Authorization: Bearer 123456" \
-H "Content-Type: application/json" \
-d '{"model":"gemma4-e4b-it-mxfp4","messages":[{"role":"user","content":"你好,请用一句话介绍自己"}],"max_tokens":100}' | python -m json.tool
# 预期:返回 Gemma 4 的回复

12. 性能优化与常见问题

12.1 性能优化

控制上下文长度

16GB 内存下,Gemma 的 KV cache 会随上下文增长而膨胀。建议在 oMLX 设置中限制:

// ~/.omlx/settings.json
{
  "sampling": {
    "max_context_window": 32768,
    "max_tokens": 32768
  }
}

大批量索引时错峰运行

导入大量 Markdown 文件时,嵌入模型会密集运算。建议:

  • 先在 oMLX Admin 中卸载 Gemma 对话模型

  • 运行 openclaw memory index --force

  • 索引完成后重新加载对话模型

关闭不必要的后台应用

16GB 统一内存紧张时,关闭浏览器、IDE 等内存大户,把资源留给模型推理。

12.2 常见问题

问题排查方向
oMLX API 无响应确认 Osaurus 应用已打开;检查端口 lsof -i :8000
下载模型超时确认 echo $HF_ENDPOINT 输出 https://hf-mirror.com;或从 ModelScope 国内源下载
memory_search 无结果运行 openclaw memory status 检查索引;openclaw memory index --force 重建
memory_search 只有关键词匹配无语义确认嵌入 provider 配置正确;检查 memorySearch.remote.baseUrl 指向 oMLX
Reranker 首次调用慢(~20s)正常现象,MLX 首次编译 Metal kernel;后续调用毫秒级
内存不足 / 系统卡顿查看活动监视器「内存压力」;减少并发;降低 max_context_window
oMLX Admin 看不到手动下载的模型检查是否有 configuration.json.mv 元数据文件;重启 Osaurus
Reranker 插件未生效检查 openclaw.jsonplugins.entries.omlx-reranker.enabledtrue;重启 gateway

12.3 文件清单速查

文件路径用途
oMLX 配置~/.omlx/settings.json服务端口、API Key、采样参数
oMLX 日志~/.omlx/logs/server.log模型加载、请求日志
oMLX 模型目录~/.omlx/models/所有本地模型存放位置
OpenClaw 主配置~/.openclaw/openclaw.json模型、记忆、插件、网关配置
OpenClaw 工作区~/.openclaw/workspace/知识库 Markdown 文件
Reranker 插件~/.openclaw/plugins/omlx-reranker/重排序插件代码

附录:模型信息汇总

模型规格磁盘占用运行时内存格式
Gemma 4 E4B IT MXFP442 层多模态,128K 上下文~3 GB~3-4 GBMLX safetensors
BGE-M3 MLX 4bit0.6B,1024 维嵌入~0.5 GB~0.5 GBMLX safetensors
BGE-Reranker-v2-m30.6B,8192 最大输入~2.1 GB~2.2 GBsafetensors (FP32)
合计~5.6 GB~6-7 GB

本教程基于 Mac mini M4 (16GB) + macOS 15 实际部署验证。