在配备oMLX的Mac上运行本地编码代理:磁盘支持的KV缓存详解
oMLX在SSD上缓存提示词前缀,从而使基于Apple Silicon的本地编码工具保持高速运行。安装该工具后,再将Claude Code、Codex、Cursor和OpenCode与之连接即可。
来源: oMLX is Quietly Becoming the Best Way to Run Local AI Agents On a Mac
编码会话开始12分钟后,本地模型就不再表现得像一个智能体,而开始像传真机一样运行。早期的工具调用两秒内就能得到响应,但现在每次处理需要30秒,有时甚至90秒。任务本身并未改变,只是上下文内容变得愈发冗长,导致本地服务器每次收到请求时都不得不从头重新计算整个对话内容。
这种启动缓慢但处理速度正常的现象,正是小型苹果芯片项目oMLX要解决的。它既不是模型也不是智能体,而是一台推理服务器,其唯一功能就是:无论智能体已经读取了什么内容,都会被缓存下来,即便会话持续进行,第12次的响应依然会像第1次一样迅速。真正的测试标准并非华丽的演示,而是它在实际硬件上进行的真实工作会话中,第40次处理时的表现如何。
为何Mac在处理编码智能体时表现不佳
从理论上讲,Apple Silicon是用于本地推理的强大平台。统一内存为CPU和GPU提供了共享内存池,因此量化后的模型可以存储在RAM中而无需通过总线传输,而苹果的MLX框架正是为这类工作负载设计的。
问题出现在聊天任务转变为智能体任务时。一个编程智能体几乎在每一轮都会重新读取大部分之前的上下文,调用某个工具,接收附加在提示语后的结果,然后重复这一过程数十次。提示语的开头部分几乎与上一轮完全相同,仅在末尾多了一个新的工具处理结果。
大多数本地服务器会将这种近似匹配视为完全不匹配,从而丢弃键值缓存并从零开始重新计算。在短时间请求下,人们不会察觉差异。但在20,000个标记的会话中,它会导致两秒的响应与九十秒的响应产生区别。该项目的创建者在苹果的MLX讨论板上明确指出,这就是其设计的动机:编码代理发送的请求前缀会发生变化,而每当出现这种情况时,现有的MLX服务器都会使缓存失效并重新计算所有内容。
什么是oMLX
oMLX是一款基于苹果的MLX和mlx-lm开发的开源推理服务器。它既可作为macOS原生菜单栏应用使用,也可作为Python命令行工具使用。该工具由名为Jun Kim的开发者创建,目前存储在GitHub上,项目名为jundot/omlx,采用Apache 2.0许可证。在撰写本文时,该项目已有约18,600个星标、1,600个分支以及两千多次提交记录。
这些都无法证明其可靠性。评分反映的是关注度而非成熟度,而一个每月发布多个候选版本的项目仍在摸索中。受欢迎程度只是测试的依据,不能替代真正的测试。
同一个流程可支持两种API风格:兼容OpenAI的聊天补全功能,以及原生Anthropic风格的/v1/messages接口,还包括补全、嵌入和重排序功能。它能够同时加载语言模型、视觉语言模型、OCR模型及重排序器,并通过LRU策略和模型级固定机制进行管理。对于智能体而言,重要的是其内部运作机制。
前缀会被保存到磁盘,而非内存缓冲区
普通的MLX推理仅在前缀匹配时将对话缓存存储在GPU内存中。oMLX的核心设计则是采用双层缓存机制,能够应对前缀偏移及系统重启的情况。频繁使用的代码块会保留在内存的高频层中;当该层满载后,这些代码块会以safeensors格式被写入SSD上的低频层,通过前缀共享和写时复制机制逐块进行管理。如果后续的提示语与之前已写入磁盘的某个前缀匹配,系统就会直接读取这些代码块而无需重新计算。
这就好比图书馆员不会重新整理你最近借过的书。即便图书馆重新开放后你再次询问,那本书依然会放在服务台上。
SSD并非RAM,因此恢复大量缓存仍需要实际时间,不过这比重新计算每个标记要便宜得多。对于之前描述的那种代理模式——即长度较长、大部分内容重复、仅在末尾有少量变化的文本——这种方法的收益最为显著。服务器还会通过mlx-lm的BatchGenerator实现连续批处理,同时处理多个请求而非将它们排队,其级别可通过命令行或管理面板进行配置。
有两个数值最为重要。第一个标记出现的时间指的是内容开始流回所需的时间;生成速度则是指一旦开始生成,标记出现的快慢。缓存复用机制会在处理完第一个标记后应用,而不会影响第二个标记。生成速度慢的模型会一直保持慢速生成,但会更快开始响应。
在Apple Silicon上安装
系统要求为 macOS 15(Sequoia)或更高版本,Python 版本需在 3.11 到 3.13 之间,芯片则需为 M1、M2、M3 或 M4 系列。共有三种使用方式,其中第一种最适合大多数人。
推荐的方式是通过 macOS 应用程序。从 GitHub Releases 下载已签名并经过公证的 .dmg 文件,将其拖放到“应用程序”文件夹中并启动。欢迎界面会引导用户选择模型目录、启动服务器并开始首次下载,同时该应用还会安装一个小型命令行接口程序。
使用 Homebrew 的方法:
brew tap jundot/omlx https://github.com/jundot/omlx
brew install omlx
omlx start
来源:
git clone https://github.com/jundot/omlx.git
cd omlx
pip install -e . # core
pip install -e ".[mcp]" # optional MCP support
任何打算使用 GLM-5.2、MiniMax M3 或 Qwen3.5 的人都应知道,仅通过 pip install 安装会跳过这些模型自带的定制内核,从而导致相关模型被迫使用速度慢得多的替代路径。该项目称,其融合预填充内核在 M3 Ultra 上的使用速度大约快30倍。而构建这些内核需要完整的 Xcode,而不仅仅是命令行工具,这便是制作 DMG 文件的最简单理由。
在连接任何设备之前,请先确认服务器处于正常运行状态:
curl -s http://localhost:8000/v1/models
如果尚未设置模型目录,空列表也是可以的。
加载第一个模型
oMLX会自动检测指定目录中的语言模型、视觉语言模型、嵌入模型以及重排器。它还会直接读取现有的Hugging Face缓存和LM Studio文件夹,因此无需重复下载任何内容。
omlx serve --model-dir ~/models
模型的大小应根据机器的内存来确定,而非可用的最大文件大小。应为 macOS 留出四到五GB 的空闲空间,其余空间则用于存储模型权重及缓存扩展。4 位格式下的 9B 模型适合 16 到 32GB 内存的机器;30 到 40B 级别的模型则需要 64GB 及以上的存储空间。该项目基准测试中最大的模型甚至需要超过 400GB 内存的 Mac Studio。
可以从管理控制台内置的 Hugging Face 浏览器 http://localhost:8000/admin 获取模型,也可以使用任何现有的针对模型目录的 hf 下载流程来获取。一个基本的请求形式与普通的 OpenAI 聊天回复请求类似:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "your-model-name", "messages": [{"role": "user", "content": "Say hi in five words."}]}'
如果返回了完成结果,说明该端点正常工作。
连接 Claude Code、Codex、Cursor 和 OpenCode
oMLX 有两种方式可以与智能体连接,具体使用哪种方式取决于智能体存储配置的方式,而非其支持的完善程度。
具有配置文件的工具
OpenClaw、OpenCode、Codex 和 Pi 会读取 oMLX 可直接访问的配置文件,前两者为 JSON 格式,Codex 为 TOML 格式。集成适配器会向该文件写入数据,而管理控制台的“集成”选项卡会提供一个命令:
omlx-cli launch codex --model your-model-name --api-key your-key
omlx-cli launch opencode --model your-model-name --api-key your-key
omlx-cli launch pi --model your-model-name --api-key your-key
运行该命令可一步完成工具配置的更新及代理的启动。任何现有的配置都会首先被备份为带有时间戳的.bak文件,这样一旦出现异常情况便可恢复原状。
Hermes Agent与Copilot条目
二者均出现在README的一键启动列表中,Hermes Agent的官方文档也单独对其进行了说明:设置向导提供了自定义的兼容OpenAI的端点选项,可用于指定任何本地服务器,包括oMLX。若想跳过控制面板,可直接手动将其指向http://localhost:8000/v1。
在依赖 Copilot 之前,值得再仔细审视一下。GitHub 真正的 Copilot Chat 是通过 OAuth 对 api.githubcopilot.com 进行身份验证的,并非设计用于接受任意的本地基础 URL。因此,一键式 Copilot 集成要么针对的是名称相同的另一款工具,要么使用了官方文档未予确认的机制。在认为其功能如标签所示之前,请直接查看“集成”选项卡。
Claude Code
Claude Code 在启动时会从 ANTHROPIC_BASE_URL 环境变量中读取服务器地址,而非从 oMLX 可编辑的文件中读取,所以这一过程仍需手动操作。由于 oMLX 本身就提供原生的 /v1/messages 接口,因此无需翻译代理:
export ANTHROPIC_BASE_URL="http://localhost:8000"
export ANTHROPIC_AUTH_TOKEN="local"
export ANTHROPIC_DEFAULT_SONNET_MODEL="your-model-name"
export ANTHROPIC_DEFAULT_OPUS_MODEL="your-model-name"
claude
oMLX 还提供了专为 Claude Code 设计的功能。上下文扩展功能会显示令牌数量,从而确保在较小的本地上下文窗口下自动压缩功能能正确触发;而 SSE 保持连接功能则可避免在长时间预填充过程中出现读取超时问题。这些都是针对特定智能体的详细功能,而非通用的兼容性选项。
光标
Cursor的本地模型设置位于其图形界面中,因此没有可供oMLX写入的文件。在“设置”中的“模型”选项下找到“OpenAI API”部分,然后开启“覆盖基础URL”开关。Cursor此前曾更改过该开关的名称,因此不同版本上的标签可能有所不同。在“基础URL”字段中输入http://localhost:8000/v1,在“API密钥”字段中输入任意非空字符串,因为本地主机上的服务器不会校验该密钥。将从oMLX加载的模型以其确切名称添加到“自定义模型”中,并禁用Cursor的默认模型,这样它就不会尝试向OpenAI的服务器进行验证。
验证其是否真正正常工作
在真实会话中,管理控制台的热缓存与冷缓存面板应持续积累数据块,而不应在每次调用时重置。每次都重置通常意味着系统提示或工具结构的内容在多次调用之间被重新排序,从而导致前缀结构被破坏。
区分热缓存与冷缓存
无需直接采信供应商的宣传内容,可以在本地进行测试。统一调整所有工具的模型、量化参数、上下文长度以及提示词,然后记录冷启动时间、生成第一个标记所需的冷缓存时间、使用相同前缀时生成第一个标记所需的热缓存时间、稳定的生成速度、峰值内存使用情况、模拟15到20次智能体操作后的行为表现、设置时间,以及在整个会话过程中工具调用是否仍能正确解析。
该项目公布的测试数据表明,使用配备512GB存储且为原厂设备的M3 Ultra芯片,8位版本的Qwen3-Coder-Next在上下文长度从1k到32k不同时,每秒的生成速度约为45到59个标记。当同时处理8个请求而非1个请求时,连续批处理可使生成速度提升约4.14倍。这一数值是顶级硬件所能达到的上限,16GB版的MacBook Air无法达到这样的性能。
有一篇独立文章称,使用普通MLX模型处理8,700个标记的上下文大约需要20秒,而利用预热缓存则能迅速得到结果,以至于作者又重复进行了测试以确认。这是第三方提供的测试结果,并非受控实验,因此在相信之前有必要重新进行验证。
由于尚无可重用的内容,从启动到生成第一个标记的冷启动时间与原始MLX模型并无显著差异。其真正优势体现在那些重复前缀的暖启动对话中,这类对话占据了编码智能体会话的大部分时间。
服务器操作
可通过终端启动、停止和重启,前台模式会直接在终端中运行:
omlx start # background service, auto-restarts on crash
omlx stop
omlx restart
omlx serve --model-dir ~/models # foreground, attached to this terminal
确认其正在运行并提供模型服务:
curl -s http://localhost:8000/v1/models
避免内存使用与系统其他部分产生冲突:
omlx serve --model-dir ~/models --memory-guard safe
omlx serve --model-dir ~/models --memory-guard-gb 48
直接调整双层缓存:
omlx serve --model-dir ~/models --paged-ssd-cache-dir ~/.omlx/cache
omlx serve --model-dir ~/models --hot-cache-max-size 20%
当多个代理同时访问服务器时,提高并发处理能力:
omlx serve --model-dir ~/models --max-concurrent-requests 16
Homebrew 安装的程序可通过 brew services 实现相同的生命周期管理:
brew services start omlx
brew services stop omlx
brew services info omlx