
1. 为什么要在 Macbook 上折腾本地 Qwen3.6-27B 量化模型如果你手里是一台 Apple Silicon 的 Macbook又想让 AI 编码助手真正跑在本地MLX-LM 加载 Qwen3.6-27B 量化模型并接入 opencode 这套组合是目前比较省心的一条路。它解决的核心问题是你不想把项目代码发到云端也不想每个月为编码订阅付费但又希望有一个能读文件、能改代码、能跑工具调用的本地 Agent 后端。MLX 是 Apple 官方开源的数组计算框架专门为统一内存架构设计。模型权重、计算图和内存之间不需要来回拷贝这让它在 Mac 上的推理效率比通用方案更直接。MLX-LM 则是在 MLX 之上封装的推理与微调工具它自带一个 HTTP 服务接口形态和 OpenAI Chat Completions 基本一致默认监听127.0.0.1:8080。opencode 支持把任意兼容/v1/chat/completions的服务注册成 provider所以两者对接非常自然。这套方案适合谁适合用 Macbook Pro M 系列、内存 24GB 起步、想本地跑编码 Agent 的开发者。不适合谁如果你只有 16GB 内存或者需要同时服务多个用户那 27B 的 4-bit 权重会非常吃力建议换更小的模型。我实测下来24GB 统一内存跑 4-bit 量化是能用的但必须把并发和缓存压到最低否则系统会开始疯狂交换内存。Qwen3.6-27B 本身支持思考模式和工具调用这对编码场景很关键。opencode 依赖工具调用来读文件、写补丁、执行命令所以模型必须能正确返回 OpenAI 格式的tool_calls。MLX-LM 的服务端代码已经能接收tools字段并返回对应结构这也是我选择它而不是自己写一层适配的原因。整篇文章会按顺序讲清楚环境准备、模型下载、服务启动参数、opencode 配置、端到端验证、常见报错排查。每一步都给可复制的命令或配置片段你可以直接跟着做。2. 前置准备MLX-LM 安装与 Qwen3.6-27B 量化权重获取在 Macbook 上用 MLX-LM 跑 Qwen3.6-27B 量化模型第一步是把工具链装好。我建议用uv来管理 MLX-LM因为它能把命令行工具隔离在独立环境里升级和卸载都干净。如果你还没装 Homebrew先执行官方安装脚本已经装过的可以跳过。/bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)接着安装 uv并刷新 shell 路径brew install uv uv tool update-shell执行完uv tool update-shell后一定要重新打开终端否则mlx_lm.server可能找不到。然后安装 MLX-LMuv tool install mlx-lm以后需要升级时用uv tool upgrade mlx-lm验证安装是否成功mlx_lm.server --help如果这条命令能打印出参数列表说明工具链就绪。如果提示command not found先执行uv tool update-shell再重开终端或者用uv tool dir --bin查看可执行文件目录并手动加入 PATH。接下来是模型权重。推荐使用mlx-community/Qwen3.6-27B-4bit这是已经为 MLX 转换好的 4-bit 量化版本模型页显示文件约 16.1GB。24GB 内存的机器跑它模型加载后还剩大约 7 到 8GB 给系统和 KV 缓存属于紧但可用的状态。下载方式有两种。方案 A 是首次启动服务时自动下载直接在启动命令里写 Hugging Face 仓库名MLX-LM 会检查本地缓存没有就自动拉取。方案 B 是下载到固定目录适合你想明确管理模型文件位置的情况mkdir -p $HOME/Models uvx --from huggingface_hub hf download \ mlx-community/Qwen3.6-27B-4bit \ --local-dir $HOME/Models/Qwen3.6-27B-4bit下载完成后检查目录大小du -sh $HOME/Models/Qwen3.6-27B-4bit这里有几个坑要避开。BF16 版本远超 24GB不要选8-bit 通常约 30GB也放不下35B-A3B 的 4-bit 版本模型本身就接近 24GB几乎不给系统和缓存留空间未标注 MLX 的 GGUF 权重是给 llama.cpp 或 Ollama 用的MLX-LM 加载不了。选模型时认准mlx-community组织下带-4bit后缀的 MLX 权重。如果你打算把本地推理端点接到 TaoToken 做对比测试可以先用 TaoToken 的模型对话页面确认云端 Qwen 系列的表现再决定本地量化版本是否满足需求。TaoToken 的 API 地址是https://taotoken.net/api模型对话入口在 deep link 里可以找到。不过本文的重点是本地 MLX-LMTaoToken 只作为可选参照。3. 可复制配置MLX-LM 服务启动参数与 opencode 接入片段这一节是整篇的核心所有配置都可以直接复制。先启动 MLX-LM 服务再写 opencode 的 provider 配置。3.1 以 24GB 安全配置启动 MLX-LM如果你用 Hugging Face 缓存中的模型启动命令如下mlx_lm.server \ --model mlx-community/Qwen3.6-27B-4bit \ --host 127.0.0.1 \ --port 8080 \ --max-tokens 2048 \ --temp 0.6 \ --top-p 0.95 \ --top-k 20 \ --decode-concurrency 1 \ --prompt-concurrency 1 \ --prefill-step-size 512 \ --prompt-cache-size 1 \ --prompt-cache-bytes 1GB \ --chat-template-args {enable_thinking:true}如果你下载到了固定目录把--model换成绝对路径MODEL_DIR$HOME/Models/Qwen3.6-27B-4bit mlx_lm.server \ --model $MODEL_DIR \ --host 127.0.0.1 \ --port 8080 \ --max-tokens 2048 \ --temp 0.6 \ --top-p 0.95 \ --top-k 20 \ --decode-concurrency 1 \ --prompt-concurrency 1 \ --prefill-step-size 512 \ --prompt-cache-size 1 \ --prompt-cache-bytes 1GB \ --chat-template-args {enable_thinking:true}参数逐个解释一下。--host 127.0.0.1只允许本机访问不要改成0.0.0.0否则同网络下其他设备可能连进来。--max-tokens 2048限制默认输出长度避免思考过程无限增长把内存吃满。--temp 0.6、--top-p 0.95、--top-k 20是 Qwen 官方对精确编程任务建议的采样参数。--decode-concurrency 1和--prompt-concurrency 1把解码和预填充都限制为单请求减少内存峰值。--prefill-step-size 512降低长提示预填充时的峰值内存。--prompt-cache-size 1只保留一份会话缓存--prompt-cache-bytes 1GB限制缓存总量。enable_thinking开启 Qwen3.6 的思考模式。首次建议不要启用preserve_thinking。确认 opencode 能正确处理多轮思考内容后可以改成--chat-template-args {enable_thinking:true,preserve_thinking:true}如果工具调用不稳定可以测试非思考模式--temp 0.7 \ --top-p 0.8 \ --top-k 20 \ --chat-template-args {enable_thinking:false}3.2 opencode 稳定版配置opencode 的全局配置放在~/.config/opencode/opencode.json项目级配置放在项目根目录的opencode.json。建议先用项目级配置做测试确认没问题再合并到全局。{ $schema: https://opencode.ai/config.json, model: mlx-local/default_model, provider: { mlx-local: { npm: ai-sdk/openai-compatible, name: MLX-LM Local, options: { baseURL: http://127.0.0.1:8080/v1, apiKey: local }, models: { default_model: { name: Qwen3.6 27B MLX 4-bit, limit: { context: 8192, output: 2048 } } } } } }这里用default_model作为模型键很关键。MLX-LM 服务端内部提供了这个别名会把它映射到启动时的--model参数。这样无论你用 Hugging Face 仓库名还是本地目录启动opencode 都不需要知道绝对路径也避免客户端发送另一个仓库名导致服务尝试切换或重新加载模型。limit.context是告诉 opencode 本地可用的上下文预算不会改变 Qwen 模型文件本身。24GB 机器先设 8192稳定后再逐步增加。limit.output设 2048和启动参数里的--max-tokens保持一致。如果你已经有opencode.json不要整份覆盖只合并model和provider.mlx-local部分。3.3 opencode 2.0 beta 配置只有安装了 opencode 2.0 beta 才使用本节。2.0 beta 的字段与稳定版不同provider改为providersnpm改为packageoptions改为settings并且可以通过modelID把友好名称映射到 MLX-LM 的default_model。{ $schema: https://opencode.ai/config.json, model: mlx-local/qwen36-code, providers: { mlx-local: { name: MLX-LM Local, package: opencode-ai/ai/providers/openai-compatible, settings: { baseURL: http://127.0.0.1:8080/v1, apiKey: local }, models: { qwen36-code: { modelID: default_model, name: Qwen3.6 27B MLX 4-bit, capabilities: { tools: true, input: [text], output: [text] }, limit: { context: 8192, output: 2048 } } } } } }opencode 官方说明 2.0 当前属于 beta不要把该配置与稳定版字段混用。如果你不确定自己装的是哪个版本运行opencode --version确认。4. 验证请求从健康检查到端到端对话与显存占用配置写完后必须一步步验证不要直接跳到 opencode 里跑。先确认 MLX-LM 服务本身正常再确认 opencode 能连上。4.1 健康检查与模型列表另开一个终端执行curl http://127.0.0.1:8080/health预期返回{status:ok}然后查看模型列表curl http://127.0.0.1:8080/v1/models你应该能看到default_model这个别名。如果这里报错说明服务没起来或者端口不对先回到启动命令检查。4.2 测试普通对话用 curl 发一个 Chat Completions 请求curl http://127.0.0.1:8080/v1/chat/completions \ -H Content-Type: application/json \ -d { model: default_model, messages: [ { role: user, content: 请用 Python 实现一个带类型标注的 LRU 缓存并解释复杂度。 } ], max_tokens: 1024, temperature: 0.6, top_p: 0.95, top_k: 20, stream: false }如果这个请求成功返回内容说明 MLX-LM 服务完全正常。注意model字段填default_model不要填 Hugging Face 仓库名。4.3 opencode 端到端验证确保 MLX-LM 服务仍在运行然后查看 opencode 是否识别到模型opencode models mlx-local应看到mlx-local/default_model接着用命令行模式跑一次只读检查opencode run \ --model mlx-local/default_model \ 检查当前项目的结构只提出一个最值得优先修复的问题不要修改文件。也可以直接启动 opencodeopencode进入后运行/models选择 MLX-LM Local 下的 Qwen3.6。如果 opencode 要求凭据运行/connect选择 OtherProvider ID 填mlx-localAPI Key 填任意本地占位值例如local。MLX-LM 本地服务本身不会验证这个占位值。4.4 显存占用检查运行时打开「活动监视器 → 内存」重点看三个指标内存压力是否为绿色、交换内存是否持续增长、opencode 每轮对话后是否越来越慢。推荐调整顺序保持上下文 8192如果内存压力变黄把输出从 2048 降到 1024把--prompt-cache-bytes 1GB降为 512MB关闭浏览器重型页面、Docker 和虚拟机仍然交换内存时改用更小模型。只有在内存压力持续为绿色时才把 opencode 配置中的上下文依次增加为 8192 → 12288 → 16384。不要直接设成 32K、128K 或 256K。opencode 的仓库工具会把文件内容、补丁、系统提示和工具定义全部计入上下文实际占用通常比普通聊天更高。4.5 工具调用测试opencode 依赖工具调用读取和编辑项目。建议按以下顺序测试只读检查项目让模型读取一个指定文件让模型提出修改方案但不修改最后才允许小范围编辑。测试提示列出当前项目根目录文件读取 README.md然后总结项目用途。不要修改任何文件。如果模型只输出类似工具调用的文本却没有真正调用工具先升级 MLX-LM确认使用模型自带的chat_template.jinja不要设置--use-default-chat-template覆盖模型模板先关闭preserve_thinking测试非思考模式检查 opencode 日志及 MLX-LM 终端是否出现 tool parser 警告。5. 本篇常见错排查401、local proxy failed、reading choices 与 OAuth这一节对照真实报错给出排查路径。如果你在接入过程中遇到问题先在这里找对应条目。5.1 401 Unauthorizedopencode 报 401通常是apiKey字段缺失或为空。MLX-LM 本地服务不验证 key但 opencode 的 OpenAI-compatible provider 要求这个字段存在。检查配置options: { baseURL: http://127.0.0.1:8080/v1, apiKey: local }apiKey填任意非空字符串即可比如local。不要留空也不要删掉这个字段。5.2 local proxy failed这个报错通常出现在 opencode 尝试连接baseURL但服务没起来或者地址写错。先确认 MLX-LM 服务在运行curl http://127.0.0.1:8080/health如果这条命令失败说明服务没启动或端口被占用。端口被占用时改用 8081mlx_lm.server \ --model mlx-community/Qwen3.6-27B-4bit \ --host 127.0.0.1 \ --port 8081然后把 opencode 的baseURL改成http://127.0.0.1:8081/v1。5.3 reading choices 报错这个报错说明 opencode 收到了响应但结构不符合预期。常见原因是model字段填错或者 MLX-LM 返回了非标准格式。检查 opencode 配置中的模型键是否为default_model以及baseURL是否包含/v1。如果用的是 2.0 beta 配置确认modelID映射正确。5.4 OAuth 相关报错opencode 某些 provider 会走 OAuth 流程但 MLX-LM 是本地 OpenAI-compatible 服务不需要 OAuth。如果你看到 OAuth 相关提示说明 provider 类型选错了。确认配置里用的是ai-sdk/openai-compatible而不是某个需要 OAuth 的官方 provider。5.5 其他常见问题mlx_lm.server: command not found执行uv tool update-shell重开终端或用uv tool dir --bin查看可执行文件目录。Model type ... not supported升级uv tool upgrade mlx-lm确认模型是 MLX 权重而不是 GGUF。opencode 报 404依次检查curl http://127.0.0.1:8080/health和curl http://127.0.0.1:8080/v1/models确认配置中的地址包含/v1。opencode 尝试加载错误模型确保稳定版配置中的模型键是default_model并使用mlx-local/default_model。输出只有几百 tokens 就停止MLX-LM 默认max_tokens是 512确认启动命令包含--max-tokens 2048同时确认 opencode 中limit.output为 2048。服务启动后系统变得很卡模型加运行时已接近 24GB 上限关闭其他重型应用将缓存降至 512MB输出降至 1024仍然卡顿则换较小模型。图像输入限制Qwen3.6-27B 本身带视觉能力但当前 MLX-LM 文本服务器会把 opencode 接入场景视为文本 Chat Completions服务端对消息内容的处理只适合文本片段。opencode 中的代码、终端输出和文本文件可以正常使用不要期待此配置直接处理截图或图片附件。需要图片输入时使用 mlx-vlm、支持 MLX VLM 的 LM Studio或单独建立视觉服务。6. 长期编码与 Agent 场景的 CTA 分流本地 MLX-LM 跑 Qwen3.6-27B 量化模型接入 opencode适合对代码隐私敏感、想完全离线编码的场景。但它也有明显边界24GB 内存下上下文只能开到 8192 到 16384并发只有 1模型切换和长任务会受限于本地算力。如果你需要更长的上下文、更高的并发或者想让 Agent 跑更复杂的多步任务可以考虑把部分请求分流到云端。TaoToken 提供了 OpenAI-compatible 的 API 接入方式API 地址是https://taotoken.net/api。你可以把它作为 opencode 的另一个 provider和本地 MLX-LM 并存按任务类型切换。比如日常小改动走本地长上下文重构走云端。TaoToken 的模型对话入口可以用来快速验证模型表现API Keys 管理页面用来生成和轮换密钥接入文档里有完整的 Base URL、Key 和 Model ID 三件套说明。如果你主要做长期编码和 Agent 任务可以关注 TaoToken 的 Coding Plan它针对编码场景做了额度和模型路由的优化。具体入口在 deep link 里可以找到模型对话、coding-plan、console、api-keys、doc 都有对应页面。配置云端 provider 时opencode 的写法类似{ $schema: https://opencode.ai/config.json, provider: { taotoken: { npm: ai-sdk/openai-compatible, name: TaoToken, options: { baseURL: https://taotoken.net/api/v1, apiKey: 你的 TaoToken Key }, models: { qwen-plus: { name: Qwen Plus } } } } }注意 Base URL 要带/v1Key 从 TaoToken 的 API Keys 页面获取Model ID 参考接入文档。这样你就有本地和云端两条路径按需切换。最后提醒一句MLX-LM 的 HTTP 服务只提供基础安全检查不要直接暴露到公网。本地开发够用生产环境需要额外的反向代理和鉴权层。