)
文档教程技术博客大模型人工智能【免费下载链接】one-small-step这是一个简单的技术科普教程项目主要聚焦于解释一些有趣的前沿的技术概念和原理。每篇文章都力求在 5 分钟内阅读完成。项目地址https://gitcode.com/gh_mirrors/on/one-small-step点击查看免费下载本文是 one-small-step 仓库中 OpenClaw 教程专题的实战篇讲解如何在 Mac 上让个人 AI 助手框架 OpenClaw 接入本地推理引擎mlx_lm / mlx_vlm跑起来的 Qwen3.5 系列 9B 等中小模型实现零成本、无隐私顾虑的本地 Agent 体验。读完你将掌握适合 OpenClaw 的本地模型选型思路、共享 venv pm2 管理推理服务的完整命令、OpenClawconfig.json接入本地 provider 的配置方法以及用仓库自带的 mlx-proxy.py 代理脚本桥接 OpenClaw 与 mlx 推理引擎的整套实战方案。背景为什么让 OpenClaw 接本地模型OpenClaw 是个人 AI 助手框架可以接各种大模型 API。本文的目标是让它接上 Mac 上用 mlx_vlm 跑的本地模型Qwen3.5 系列这样既不用花钱也不用担心隐私。推理框架用的是 mlx_lm 或 mlx_vlm针对 Qwen3.5 系列两者都提供 OpenAI 兼容的 HTTP API理论上配个baseUrl就能接入。实际验证下来在 OpenClaw 接入的情况下无论是多模态的图片输入还是工具调用都挺流畅而复杂场景比如连续工具调用更推荐 GLM-4.7-flash全能型或 kimi-linear线性注意力特别适合处理长文本prefill 和推理速度快且模型召回能力好。需要说明的是这篇文章准确的讲是给你的 AI 看的如果配置卡住了让 AI 看这篇文章帮你配置即可即使本地没有 OpenClaw也可以本地开一个 claude code让它参考本文帮你在 Mac 上部署。模型选型哪些本地模型适合 OpenClawQwen 新推出的 Qwen3.5 9B、35B-A3B、27B 模型都支持一定程度的工具调用模型能力对日常任务来说也够用作为 OpenClaw 使用的模型是可以的。以下是几个候选模型的对比模型参数量-激活参数量优势劣势建议量化版本GLM-4.7-flash30B-A3B全能型且 Agent 能力突出特别适合搭配 OpenClaw 使用长文本召回能力会比 kimi-linear 差一些8bit不要低于 4bitkimi-linear48B-A3B线性注意力prefill 和推理速度巨快且长文本召回能力很强很适合处理大量文本的工作Agent 能力较 GLM-4.7-flash 差一些8bit不要低于 4bitQwen3.5-35B-A3B35B-A3B支持多模态输入激活参数量小所以速度很快Agent 能力适中mlx_vlm 的 prefill 速度很慢且 mlx 没有提供 mlx_lm 直接使用的版本8bit不要低于 4bitQwen3.5-27B27B支持多模态输入Agent 能力体感比 Qwen3.5-35B-A3B 好一些dense 模型会慢一些mlx_vlm 的 prefill 速度很慢且 mlx 没有提供 mlx_lm 直接使用的版本5bitQwen3.5-9B9B支持多模态输入显存/统一内存占用小Agent 能力是这几个里面垫底的mlx_vlm 的 prefill 速度很慢且 mlx 没有提供 mlx_lm 直接使用的版本8bit不要低于 5bit几点解读A3B 是 MoE 的激活参数量例如 30B-A3B 表示总参数量 30B、每次推理只激活 3B 参数激活参数量小意味着速度快、内存占用相对可控可参考仓库中 什么是 MoE 模型 一文理解原理。dense 与 MoE 的取舍Qwen3.5-27B 是 dense 模型能力更均衡但推理更慢MoE 模型A3B 后缀速度快但 Agent 能力相对弱一些。多模态差异Qwen3.5 三个尺寸都支持多模态输入GLM-4.7-flash 与 kimi-linear 主要面向文本 Agent 任务。量化建议表中给出了各模型的最低量化底线4bit/5bit通常 8bit 是兼顾效果与占用推荐值量化原理可参考仓库中 什么是大语言模型量化。推理引擎差异Qwen3.5 系列用 mlx_vlm多模态GLM-4.7-flash / kimi-linear 用 mlx_lm纯文本这直接影响后面代理脚本的参数选择。第零步下载模型直接去 Hugging Face 的 mlx-community 组织下载模型例如mlx-community/Qwen3.5-9B-8bit这个 8bit 量化版本如果 Mac 内存比较小也可以考虑 4bit 版本。如果你是 Windows 或 Linux 环境则改用 GGUF 格式搭配 llama.cpp 来跑可参考仓库中 如何本地运行 GGUF 格式的 LLM 模型 和 什么是 GGUF。模型下载后是一组独立的权重文件后面部署时通过--model参数指定其路径即可。第一步创建共享 venv多个 Qwen3.5 模型可以共用一个 venv不用把 20G 的依赖复制三份。venv 里装的是推理框架模型权重是独立的文件通过--model参数指定就行。# 示例中模型放在 /Volumes/WORK_2/models可根据实际情况调整 python3 -m venv /Volumes/WORK_2/models/Qwen3.5-venv source /Volumes/WORK_2/models/Qwen3.5-venv/bin/activate pip install githttps://github.com/Blaizzy/mlx-vlm.gitmain # 这里一定要用 GitHub 上的最新版本PyPI 上的版本还不支持 tool call pip install torch torchvision # 这两个都要装是 mlx-vlm 必须的库踩坑venv 不能复制Python venv 里的脚本pip、python3 等都硬编码了原始路径的 shebang。把.venv文件夹复制到别的地方后里面的 pip 仍指向旧路径装的包会全部装到旧位置。表面上(.venv)提示符亮着实际上which pip指向的是系统 Python。解决办法永远在目标位置重新python3 -m venv创建别复制。第二步用 pm2 管理模型服务先检查是否安装了 node.js 环境如果没有先安装 node.jspm2 依赖它运行。关键技巧不需要source activate直接用 venv 里的 Python 完整路径pm2 start /Volumes/WORK_2/models/Qwen3.5-venv/bin/python3 \ --name qwen3.5-api \ --interpreter none \ -- -m mlx_vlm.server \ --model /Volumes/WORK_2/models/Qwen3.5-9B-8bit \ --host 0.0.0.0 --port 10012 --trust-remote-codesource activate本质就是把 venv 的 bin 目录加到 PATH 前面直接用完整路径调 Python 效果完全一样。用 pm2 管理的好处是进程意外退出会自动拉起日志统一收集且pm2 savepm2 startup可实现开机自启。这里--host 0.0.0.0表示监听所有网卡局域网内其他设备也能访问--trust-remote-code用于加载模型仓库中的自定义代码。第三步配置 OpenClaw在 OpenClaw 的config.json里添加 local provider{ models: { mode: merge, providers: { local: { baseUrl: http://10.0.6.26:10012, apiKey: DEADBEEF, api: openai-completions, models: [ { id: /Volumes/WORK_2/models/Qwen3.5-9B-8bit, name: Qwen 3.5 9B, reasoning: false, input: [text, image], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768 } ] } } }, agents: { defaults: { models: { local//Volumes/WORK_2/models/Qwen3.5-9B-8bit: { alias: qwen3.5-9b, streaming: false } }, timeoutSeconds: 600 } } }几个注意点apiKey设成DEADBEEF或其他随机字符串即可本地模型不需要鉴权这样设置是为了防止 OpenClaw 对留空的兼容性问题。model id 就是模型权重的完整路径因为 mlx_vlm 的 API 用路径来区分模型。streaming: false关掉流式传输避免 SSE 兼容性问题导致超时打开应该也没事。timeoutSeconds: 600给本地模型 10 分钟响应时间防止长推理被 OpenClaw 超时掐断。模型引用格式是local//Volumes/...第一个/是 provider 和 model id 的分隔符第二个/是路径本身。contextWindow: 262144与maxTokens: 32768需与模型实际能力对齐这里按 Qwen3.5 系列的上下文与最大输出配置cost全为 0 表示本地推理零成本。第四步使用代理脚本过滤 mlx 不支持的字段由于 OpenClaw 发起的请求有很多特殊字段而 mlx_lm / mlx_vlm 不支持这些字段仓库为此提供了一个代理脚本 mlx-proxy.py。可以让 OpenClaw 请求这个脚本脚本负责 rewrite 或 strip 掉特殊字段让推理引擎正常运行。整个链路为OpenClaw → mlx-proxy.py代理如 10012 端口→ mlx_vlm / mlx_lm上游推理服务如 10002 端口。代理监听对外端口OpenClaw 只认这个地址再把清洗后的请求转发给真正的推理服务。对于 Qwen3.5 系列使用 mlx_vlm 推理引擎的模型使用默认参数启动即可python3 mlx-proxy.py --host 0.0.0.0 --port 10012 --upstream http://127.0.0.1:10002当然可以使用 pm2 管理服务pm2 start /Volumes/WORK_2/models/mlx-venv/bin/python3 \ --name mlx-vlm-proxy \ --interpreter none \ -- mlx-proxy.py \ --host 0.0.0.0 --port 10012 \ --upstream http://127.0.0.1:10002对于 GLM-4.7-flash 或 kimi-linear 等使用 mlx_lm 推理引擎的模型需要去除掉 model 字段python3 mlx-proxy.py --host 0.0.0.0 --port 10014 --upstream http://127.0.0.1:10004 --strip-model同样可以用 pm2 管理服务pm2 start /Volumes/WORK_2/models/mlx-venv/bin/python3 \ --name mlx-lm-proxy-glm-4.7-flash \ --interpreter none \ -- mlx-proxy.py \ --host 0.0.0.0 --port 10014 \ --upstream http://127.0.0.1:10004 \ --strip-model源码剖析代理脚本内部是怎么工作的从 mlx-proxy.py 的实现看它本质是一个基于http.server的轻量级转发代理核心逻辑集中在ProxyHandler.do_POSTmlx-proxy.py完整记录原始请求每个 POST 请求都会打印 headers 和 JSON body含字段摘要出问题时可直观看到 OpenClaw 到底发了什么按开关清洗请求体根据启动参数决定是否 strip / rename / normalize / strip-model转发上游把清洗后的 JSON 原样 POST 到上游推理服务超时设置为 600 秒forward 函数并把上游响应含错误码原样回传。代理脚本定义了四组可独立开关的处理逻辑默认值如下开关对应 CLI 参数默认作用--strip-fields关闭删除 STRIP_FIELDS 集合里的不支持字段--rename-fields开启把max_completion_tokens改名为max_tokens--normalize-messages关闭对 messages 做归一化兼容 mlx_vlm--strip-model关闭删除请求体中的model字段mlx_lm 场景必需STRIP_FIELDS 集合定义在 mlx-proxy.py共 16 个字段tools、tool_choice、parallel_tool_calls、response_format、logprobs、top_logprobs、n、presence_penalty、frequency_penalty、logit_bias、user、seed、service_tier、store、metadata、stream_options。这些正是 OpenAI 风格 API 里 mlx 推理引擎无法解析的字段删掉后请求才能过校验。RENAME_FIELDS 只做一条映射max_completion_tokens→max_tokensmlx-proxy.py。因为 OpenClaw 按较新 OpenAI 协议发送max_completion_tokens而 mlx_vlm/mlx_lm 只认max_tokens这也是 Qwen3.5mlx_vlm场景用默认参数即可的原因——重命名开关默认就是开的。normalize_messagesmlx-proxy.py则负责消息层兼容主要包括content为null时补成空字符串content为数组多模态块格式时提取所有text块拼接为纯文本role为tool的消息改写成user并在内容前加[Tool result from {name} (call_id: {id})]前缀把工具结果语义保留给模型assistant 消息只有tool_calls而没有内容时转成[Tool calls: name(args), ...]文本只保留role/content/name三个字段剔除其余字段连续多条 user 消息自动合并mlx_vlm 可能拒绝连续的 user 消息。代理脚本的全部 CLI 参数速查参数默认值说明--port10010代理监听端口--host0.0.0.0代理绑定地址--upstreamhttp://127.0.0.1:10012上游推理服务地址--strip-fields/--no-strip-fields关闭是否删除 STRIP_FIELDS 字段--rename-fields/--no-rename-fields开启是否执行字段改名--normalize-messages/--no-normalize-messages关闭是否归一化 messages--strip-model/--no-strip-model关闭是否删除model字段第五步可能的 Discord 权限配置问题如果你运行/model命令返回 You are not authorized to use this command这不是 Discord Bot 权限问题而是 OpenClaw 的鉴权。即使groupPolicy设成openslash 命令仍然需要在 guild 配置里明确授权你的 User ID{ channels: { discord: { groupPolicy: open, guilds: { 你的SERVER_ID: { requireMention: false, users: [你的USER_ID] } } } } }User ID 和 Server ID 在 Discord 开启开发者模式后右键复制即可获得。调试技巧如果报错 HTTP 422大概率是你用的 mlx-vlm 不够新——请使用 GitHub 版本而不是 pip 安装的旧版PyPI 版本还不支持 tool call。如果不知道具体是什么问题可以按照下面的思路 debug用 socat 抓 OpenClaw 发出的原始请求pm2 stop qwen3.5-api # 先释放端口 socat -v TCP-LISTEN:10012,reuseaddr,fork \ SYSTEM:cat; echo -e HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\choices\:[{\message\:{\role\:\assistant\,\content\:\ok\}}]}这样 OpenClaw 发往 10012 的请求会被原样打印出来并且直接得到一段假装模型的响应可以借此确认 OpenClaw 侧发出的请求格式。用 curl 逐个字段排查哪个触发 422# 基础测试 curl -X POST http://10.0.6.26:10012/chat/completions \ -H Content-Type: application/json \ -d {model:...,messages:[{role:user,content:hi}],stream:false} # 加上 tools 测试 curl -X POST ... -d {model:...,messages:[...],stream:false,tools:[]} # 加上 content 数组格式测试 curl -X POST ... -d {model:...,messages:[{role:user,content:[{type:text,text:hi}]}],stream:false}依次加入tools、content数组等字段就能定位是哪个字段不被 mlx 推理引擎接受从而决定是升级 mlx-vlm、还是用代理脚本的--strip-fields/--strip-model开关把它过滤掉。另外代理脚本本身会把每个请求的字段摘要打印到日志里配合pm2 logs mlx-vlm-proxy查看也是一个很高效的排查手段。总结整个部署链路可以归纳为下载 mlx 量化模型 → 建共享 venv 装 mlx_vlm → pm2 拉起推理服务 → 用 mlx-proxy.py 桥接 OpenClaw → 处理 Discord 鉴权。核心难点不在模型本身而在 OpenClaw 与 mlx 推理引擎之间的协议差异——代理脚本正是解决这一层的钥匙--rename-fields处理 token 字段名、--strip-model处理 mlx_lm、--strip-fields兜底过滤不支持的 OpenAI 扩展字段。最后给个实用建议遇到问题不要自己闷头折腾把现象和上面的调试思路一起丢给 AI让它参照本文帮你定位能省下大量时间。赞分享文档教程技术博客大模型人工智能【免费下载链接】one-small-step这是一个简单的技术科普教程项目主要聚焦于解释一些有趣的前沿的技术概念和原理。每篇文章都力求在 5 分钟内阅读完成。项目地址https://gitcode.com/gh_mirrors/on/one-small-step点击查看免费下载相关推荐三大秘诀GLM-4-9B大模型本地部署的终极指南三大秘诀GLM 4 9B大模型本地部署的终极指南 想要在自己的服务器上部署一个强大的AI助手吗GLM 4 9B作为智谱AI推出的最新一代多模态对话模型凭借大模型深度学习tbox跨编译器支持GCC、Clang与MSVC的兼容性处理tbox跨编译器支持GCC、Clang与MSVC的兼容性处理 1. 编译器碎片化挑战与tbox的解决方案 在C语言开发中编译器碎片化Compiler Fr文档教程技术博客大模型人工智能FlashAI通义千问大模型本地部署完整指南FlashAI通义千问大模型本地部署完整指南 还在为复杂的AI模型安装而头疼吗FlashAI通义千问大模型整合包让你零基础也能轻松上手无需任何技术背景只需大模型AI 应用上一篇NanoClaw v1 → v2 迁移收尾实战指南migrate-from-v1 技能全解析下一篇在终端用 OpenCLI 读取幕布Mubu文档doc / docs / notes / recent / search 适配器完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考