最近我把个人 AI 助理的整套链路从头搭到了本地:宿主机上用 VM 虚拟机跑了一套 Ubuntu Server,消息入口放在飞书机器人,中间用 OpenClaw 做智能体调度,大模型后端接的是 Qwen 本地推理。折腾了几天,中间踩了不少坑,现在整体已经稳定跑了小半个月。这套组合解决的问题很直接——你想要一个能随时在聊天框里调用的私人助理,但又不希望对话记录、知识库、工具调用过程全部托管在别人的服务器上。适合愿意花一晚上做环境调试、后续想深度定制智能体行为的开发者参考,也适合想低成本验证“个人助理”到底能干什么的爱好者。
1. 整条链路的角色拆解:为什么是这四样拼在一起
1.1 OpenClaw 是大脑的接线员
很多人第一次看到 OpenClaw 会误以为它是个大模型,其实完全不是。它更像一个消息网关加智能体调度器:飞书里的消息推过来,OpenClaw 负责判断该调用哪个模型、要不要触发工具调用、怎么把回复组装成飞书能识别的消息格式再发回去。它自己不做推理,推理这活儿全部丢给后端的 Qwen。
用生活里的话说,OpenClaw 就是客厅里的那个智能遥控器,你按的是飞书这个“面板”,遥控器收到信号后去指挥电视、空调、音响各自干活,干完之后再把结果汇总到你面前。没有它,你就得自己写一堆处理消息回调、维护会话状态、调模型接口的胶水代码,而且换一个 IM 入口整套逻辑全得重来。有了这一层,消息从哪个渠道进来、模型用哪个、工具怎么调度,都变成了可配置的东西。
我最初看过一些商用方案,它们确实开箱即用,但定制门槛高,很多内部逻辑是封闭的。OpenClaw 这类开源智能体框架的好处在于:你能看到每条消息到底走了哪条路径,能自己塞自定义工具,也能随时换模型。这种可控性在个人助理场景里非常重要,因为你不知道未来会往里面加什么奇奇怪怪的需求。
1.2 飞书当入口:IM 不只是聊天
为什么选飞书而不是别的聊天工具?理由其实很朴素——我日常办公就在飞书里,工作群、文档、日程都已经沉淀在那里,再把 AI 助理放进来,使用成本几乎为零。你不需要打开另一个网页,不需要切窗口,在聊天框里打个字就完事了。
飞书对于这类个人助理项目的友好程度比很多人想象中高。它的开放平台支持创建自建应用,机器人能力齐全,单聊、群聊、消息卡片都能处理。最关键的是事件订阅支持长连接模式,也就是说飞书服务器可以通过一条长连接直接把消息推给本地服务,不需要你有公网 IP,不需要去配置 HTTPS 回调地址。这对跑在虚拟机里的服务来说简直是救命稻草,省掉了内网穿透那一堆麻烦事。
另外 IM 本身是一种天然适合 AI 交互的界面。聊天记录就是上下文,异步消息适合长时间任务。比如你跟它说“帮我整理一份会议纪要”,它不用像网页端那样一直挂着连接,处理完直接把结果发回来就好。这种“消息即接口”的体验,是命令行和网页都替代不了的。
1.3 Qwen 做本地大脑:数据留在自己手里
大模型后端我选了 Qwen,也就是通义千问的开源系列。为什么不是闭源 API?一个很现实的原因是隐私。你把个人聊天记录、文档摘要、日程安排喂给远端 API,等于默认信任服务商的数据处理策略。本地部署之后,所有输入输出都留在自己的机器上,不经过外网,这种心理安全感是 API 方案给不了的。
另一个原因是成本结构。如果你只是偶尔用,API 按 token 计费问题不大,但智能体场景下消息会频繁触发多轮对话,加上系统提示词每次都占一批 token,积少成多之后费用并不低。本地部署是一次性硬件投入,后面怎么折腾都不再产生调用费。
Qwen 系列在开源模型里属于中文能力扎实的那一批,指令遵循和工具调用表现都不错,而这两点恰恰是智能体最需要的。我用的 7B 量化版在纯 CPU 环境下虽然速度不算快,但处理日常对话、总结、简单工具调用完全够用。如果以后需求变大,模型文件换大一号就行,链路不用动。
1.4 虚拟机兜底:折腾的隔离区
把整套服务装在虚拟机里,是我这次最不后悔的决定之一。虚拟机提供了一层完美隔离:你可以在里面随便装系统、随便改配置、随便折腾依赖,搞挂了也不会影响宿主机上的工作文件。配合快照功能,每次大操作之前打一个快照,出了问题秒回滚,这种安全感是直接装在物理机上完全体会不到的。
有人会问,性能损失怎么办?确实虚拟机会有一定开销,但个人助理这种场景本身对延迟不敏感,聊天框里多等一两秒根本无感。更重要的是,虚拟机的网络模式和资源分配是可调的,后期想迁移到别的物理机,直接把整个虚拟机目录拷过去就行。对我来说,这比在宿主机上裸装一套 Ubuntu 再装一堆服务要干净得多。
2. 虚拟机与 Ubuntu 环境准备:先把地基打牢
2.1 给虚拟机分配多少资源才够用
这一节先聊资源配置,因为后面很多问题都出在资源不够上。我的宿主机是 32GB 内存的机器,给虚拟机分配了 4 核 CPU、16GB 内存、80GB 动态磁盘。这个配置跑 Qwen 7B 量化版比较从容,内存里除了模型本身,还得留出系统缓存和框架运行空间。
很多人容易低估内存需求。Qwen 7B 的 Q4 量化模型文件大约 4.7GB,但 Ollama 加载模型时不只是把文件读进内存,还要为 KV Cache 分配额外空间,上下文越长占得越多。再加上 Ubuntu 系统本身、OpenClaw 进程、可能出现的中转日志,12GB 内存属于紧巴巴的及格线,16GB 才算舒服。如果你打算跑 14B 模型,建议虚拟机内存直接给到 20GB 以上,否则会出现加载到一半进程被杀的情况。
CPU 方面,4 核是起步,6 到 8 核会让生成速度快不少。因为纯 CPU 推理吃的是多核并行能力,核心数翻倍,每秒生成的 token 数基本能涨一大截。磁盘给 80GB 是因为模型、日志、系统快照都会占空间,动态分配模式下实际用多少占多少,不用担心前期浪费。
2.2 安装 Ubuntu Server 的几个细节
镜像选择上,我建议直接用 Ubuntu Server LTS 版本,不要用桌面版。Server 版没有图形界面,省下来的内存全都能给服务用,而且你本来就会通过 SSH 远程操作,图形界面根本用不上。安装过程里有两个地方值得注意。
第一,磁盘分区直接用默认的整个磁盘方案就好,不需要手动分区,除非你有特别的加密需求。第二,安装到“软件选择”那一步时,记得勾选 OpenSSH server,这样装完就能从宿主机直接 SSH 登录,不用在虚拟机窗口里敲命令。如果当时忘了勾选,后面装一个 openssh-server 包再启动服务也一样。
装完之后第一件事是更新系统,sudo apt update && sudo apt upgrade -y。这一步会把内核和基础库升到新版本,避免后面装软件时碰到依赖版本太老的问题。再把 curl、wget、git 这些常用工具装上,后面下载模型、拉代码都要用。整个过程十分钟出头,不复杂,但值得认真做一遍,因为基础系统就像房子的地基,后面所有服务都长在它上面。
2.3 网络模式选择:桥接还是 NAT
虚拟机的网络模式我建议直接用桥接。桥接模式下,虚拟机就像局域网里一台独立机器,有自己的 IP,宿主机、手机、其他电脑都能直接访问它。OpenClaw 通过长连接主动连飞书服务器,不需要外部回连,但你还是需要从宿主机 SSH 进去部署,独立的局域网 IP 会让这一切简单很多。
NAT 模式也不是不能用,但你需要额外配置端口转发,把虚拟机的 22 端口映射到宿主机,否则 SSH 都连不进去。NAT 的多层地址转换对长连接、回调这类东西不友好,排查网络问题时你会多一个变量要排除。所以除非你对网络很有把握,否则就用桥接,少给自己找麻烦。
网络配好之后我给虚拟机设了静态 IP,也就是在路由器后台绑定 MAC 地址,或者在 Ubuntu 里直接写 Netplan 配置。静态 IP 的意义在于,OpenClaw 配置、飞书回调、SSH 别名里的地址不会因为 DHCP 重新分配而失效。IP 一旦变了,所有引用它的配置都得跟着改,这种坑我踩过一次之后再也不碰了。
3. Qwen 本地推理服务的部署:模型这一环决定体验上限
3.1 推理框架选型:Ollama 比 vLLM 更合适
本地跑 Qwen 的方式有好几种,最常见的是 Ollama、llama.cpp、vLLM。我选了 Ollama,因为它对个人用户太友好了:装一个二进制就能用,模型管理、量化、OpenAI 兼容接口全都内置,不需要你自己编译,也不需要手写加载脚本。
vLLM 当然性能更强,尤其是在 GPU 环境下,吞吐量可以把 Ollama 甩开几条街。但它需要 CUDA、PagedAttention 这些配套,配置复杂度高,适合拿来做正式服务端。个人助理场景没有高并发,没必要上这么重的方案。llama.cpp 则偏底层,适合想手动调优的人,但对大多数人来说反而增加了维护负担。
如果你之前用过其他大模型工具,会发现 Ollama 暴露的 API 是 OpenAI 兼容格式,/v1/chat/completions这种端点跟主流生态完全对齐。这意味着 OpenClaw 这类框架只需要改一个 base_url 就能接上,不需要写自定义适配层。生态兼容这件事,在集成的时候省下的时间远远超出你的预期。
3.2 模型选择与量化参数的真相
Qwen 2.5 系列有很多尺寸和变体,我做的是 7B Instruct 量化版。为什么要量化?因为原版 7B 模型 FP16 格式要占约 14GB 内存,个人机器跑起来很吃力;量化之后体积直接砍到三分之一左右,速度更快,内存占用更少,而能力损失在大多数任务上几乎可以忽略。
Ollama 的模型标签里常见的q4_K_M是一种混合量化方案,它对模型的不同层采用不同位宽,在体积和效果之间折中得很好。实测下来,q4_K_M 对于对话、总结、结构化输出这些场景非常稳,没必要上 q8,徒增内存压力。14B 版本我也试过,生成质量确实更好,但内存占用接近 9GB,整机压力一下就上来了,如果你的虚拟机内存只有 16GB,还是老老实实跑 7B 吧。
模型拉取这一步其实很简单,ollama pull加上模型标签就会自动下载,断点续传也做得很稳。但下载前建议确认一下磁盘剩余空间,7B 量化模型虽然只有 4.7GB,下载过程还会产生临时文件,空间不够会直接失败。
3.3 部署步骤与性能基线验证
安装 Ollama 我用的是官方给的一键安装方式,装完先确认服务状态是 running,然后把 Ollama 设为开机自启。这一步很重要,否则虚拟机重启之后服务不会自动拉起,飞书消息就会石沉大海。
# 安装完成后把服务设为开机自启 sudo systemctl enable ollama sudo systemctl status ollama接下来拉取模型并验证接口可用。
ollama pull qwen2.5:7b-instruct-q4_K_M curl http://127.0.0.1:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b-instruct-q4_K_M", "messages": [{"role": "user", "content": "用一句话介绍你自己"}], "stream": false }'看到正常的 JSON 返回,说明推理链路已经通了。我习惯在这个阶段顺手记录一下性能基线:用ollama run进交互模式随便问几个问题,观察每秒生成 token 数。纯 CPU 环境下,7B 量化模型大约在每秒 8 到 15 个 token,具体取决于 CPU 主频和内存带宽。这个速度虽然比不上云端,但聊天场景完全够用,因为人的阅读速度也就每秒几个字。
隐藏的性能杀手是上下文长度。默认上下文拉得越长,KV Cache 占的内存越多,生成速度越慢。如果你只做日常聊天,把上下文设置在 4096 左右就足够了,太长不仅慢,还会频繁触发内存交换。这个参数可以在启动 Ollama 时通过环境变量控制,后面我会再细说。
4. OpenClaw 的安装与配置:把模型能力变成服务
4.1 依赖准备与初始化流程
OpenClaw 这类智能体框架通常依赖 Python 运行时和一堆第三方库,部署方式分两种:容器和裸进程。我选择直接跑在系统进程里,少一层容器网络转发,排错也更直观。如果你的系统比较干净,建议先装好 Python 3.10 以上版本以及 pip,然后按照项目文档把仓库克隆到/opt/openclaw这类专门目录。
克隆完成后,项目里通常会有一个初始化命令或者配置模板,会生成config.yaml和其他必要的目录结构。我第一次初始化完习惯先看一下生成的配置文件结构,确认哪些字段是必填的,再开始改。这一步别跳过,因为版本不同配置字段可能会有差异,直接套别人写的现成配置容易踩到格式过期的坑。
初始化完成之后,我强烈建议先用 CLI 模式做一次冒烟测试。也就是说,不接飞书,直接在终端里跟 OpenClaw 对话,看看它能不能正确调用后端的 Qwen。这样把模型链路和消息链路分开验证,模型有问题先在这一步暴露,后面接飞书时就不会两头都错,排错范围一下子缩小了一半。
4.2 接入本地 Qwen 的配置写法
OpenClaw 支持 OpenAI 兼容接口,而 Ollama 恰好就提供了这种接口,所以模型配置部分非常顺。核心字段就是 base_url、model、api_key 这三样。Ollama 不校验 key,随便填一个非空字符串就行,但字段不能留空,否则有些框架的请求会直接报错。
下面是一份典型的配置片段,你可以根据自己的模型标签和路径微调:
model: provider: openai-compatible base_url: "http://127.0.0.1:11434/v1" api_key: "ollama-local" model: "qwen2.5:7b-instruct-q4_K_M" temperature: 0.7 max_tokens: 2048 channels: feishu: app_id: "cli_xxxxxxxxxxxxxx" app_secret: "xxxxxxxxxxxxxxxxxxxxxxxx" event_mode: websocketbase_url 后面要带/v1,因为 Ollama 的 OpenAI 兼容路由挂在/v1下面,漏掉这个路径你会收到 404。max_tokens 我设 2048,足够生成中等长度的回答,又不会因为输出太长拖慢响应。temperature 按场景来,普通对话 0.7 比较自然,如果你让它做提取、总结这类任务,降到 0.3 会更稳定。
4.3 扩展配置:工具调用与多角色
OpenClaw 真正厉害的地方是可以注册自定义工具。比如让它在回答之前查一下本地日历、读一个文件、执行一段脚本,然后把结果拼进回答里。这些工具本质上是函数,返回 JSON 给模型,Qwen 2.5 对 function calling 支持得不错,所以工具调用的成功率在实测中很高。
配置工具时注意描述写清楚一点。模型不像人,它只能通过你写的 description 判断这个工具适不适合当前任务。比如一个“获取天气”的工具,描述写成“根据城市名返回当前天气情况”,模型就能准确触发。描述写得含糊,模型就经常不调用或者乱调用。
多角色方面,我配置了一个默认助理角色,也尝试加了一个专门做文本总结的“编辑”角色。不同角色对应不同 system prompt,OpenClaw 会根据消息上下文选用。这个功能特别适合把个人助理扩展成多功能工作台,不过新手阶段建议先跑通一个角色,再慢慢加,别一上来就把系统搞得很复杂。
5. 飞书机器人接入:让智能体无处不在
5.1 创建自建应用并开启机器人能力
飞书接入的第一步不是写代码,而是去开放平台后台创建企业自建应用。如果你自己就是企业管理员,审核环节可以直接自己通过,整个过程非常快。创建完应用之后,第一件事是在“应用能力”里添加机器人能力,这一步相当于给你的应用开通了一个能收发消息的身份。
接下来是权限配置。在权限管理界面搜索消息相关的权限,比如读取用户发给机器人的消息、以机器人身份发送消息,然后把它们加到应用上。权限不开全,后面会出现“消息能收到但回复不出去”或者“完全收不到消息”的诡异现象,而且飞书的报错往往模棱两可,排查成本很高。
最后在版本管理里发布一个版本,等审核通过后应用就正式生效了。如果你是测试阶段,建议先只往自己的企业里发布,别直接全员可见,否则同事看到你机器人回消息卡顿,体验会很尴尬。等你调好了,再放开范围也不迟。
5.2 事件订阅:长连接是本地部署的最优解
飞书事件订阅有两种模式:长连接(WebSocket)和请求回调(Webhook)。我的建议非常明确,本地部署无脑选长连接。因为回调模式要求飞书服务器能访问到你配置的地址,这通常意味着你需要一台公网服务器,或者在内网穿透工具上折腾 HTTPS、域名、白名单,麻烦不说,还会引入额外延时。
长连接模式下,你的 OpenClaw 作为客户端主动向飞书服务器发起 WebSocket 连接,飞书通过这条连接把消息事件推过来。整个过程都是从内网向外发起,不要求公网入站。这跟手机上的推送机制很像,你的手机没有公网 IP,但照样能实时收到消息,因为它跟推送服务器保持着一条长连接。
配置长连接时,把事件订阅方式选成“使用长连接接收事件”,然后在 OpenClaw 的飞书渠道配置里填上 App ID 和 App Secret,事件模式设成 websocket。启动后你会在日志里看到连接成功的记录,这时候再去飞书里给机器人发消息,日志里就该出现消息事件了。
5.3 单聊与群聊的验收姿势
飞书机器人配置好之后,验收方式可以分两层。第一层是单聊:给你自己的机器人发一条普通消息,比如“你好”,看它是否回复。这一步能通过,说明从飞书到 OpenClaw 到 Qwen 再到回消息的完整闭环已经打通了。
第二层是群聊。把机器人拉进一个测试群,然后在群里 @它 再发消息。注意一定要 @ 机器人,飞书群聊里如果不 @,机器人默认是收不到消息的。这一层通过之后,你就可以正式把它放进日常工作群了。我个人习惯是专门建一个“助理调试群”,把机器人和自己都拉进去,所有测试都在这里做,不打扰别人,日志也好查。
验收时还要试一下工具调用。给它一个需要查数据或者执行脚本的任务,观察日志里工具是否被正确触发,结果是否拼进了最终回复。端到端都通了,这套系统的价值才真正体现出来,因为它从“聊天机器人”升级成了“能干活的智能体”。
6. 联调与常见问题排查实录
6.1 端到端联调流程
我在所有配置完成后的第一次完整联调,是按照“模型 -> 框架 -> 渠道”的顺序来的。先单独验证模型接口能返回正常内容,再验证 OpenClaw 在终端模式下能调用模型,最后才接飞书。每加一层只引入一个新变量,出了问题立刻知道该往哪查。
具体操作上,我在三个环节各留了一个快速验证命令:模型层用 curl 打接口;框架层用 OpenClaw 自带的 CLI 发一句话;渠道层直接在飞书里发消息看日志。三层都通了之后,再做一次群聊 @ 测试,确认工具调用也能在真实场景里跑通。整个联调过程大概半小时,但它能帮你把可能出错的位置从十几个缩小到一两个,省下的排查时间远超半小时。
6.2 常见问题速查表
下面这几个问题是我在部署和后续使用中真实遇到的,整理成速查表方便你对照排查。
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
| 模型响应很慢 | 内存不足触发 swap,或上下文过长 | 调低上下文到 4096,增加虚拟机内存 |
| OpenClaw 连不上 Ollama | base_url 少了 /v1,或 Ollama 没监听 | 检查端口和配置路径,确认 11434 在监听 |
| 飞书完全收不到消息 | 事件订阅模式没选长连接,或权限没开 | 进入后台确认事件模式,检查应用权限 |
| 消息能收到但回复不出去 | 机器人发消息权限缺失 | 在权限管理里补充 im 消息发送权限 |
| 群聊里机器人没反应 | 没有 @ 机器人 | 群发消息时 @ 机器人 |
| 虚拟机重启后服务全挂 | Ollama 和 OpenClaw 未设置开机自启 | 用 systemd 托管这两个服务 |
| 回复内容出现乱码 | 系统区域设置或终端编码问题 | 确认 LC_ALL 为 UTF-8,终端用 UTF-8 编码 |
6.3 稳定性与性能调优心得
服务稳定运行一周之后,我总结了三条经验,新手可以直接抄。
第一条是解决开机自启问题。Ollama 装完默认会注册 systemd 服务,但 OpenClaw 需要你自己写一个 service 文件。把启动命令、工作目录、日志输出都写进去,再通过 systemctl enable 设为开机自启。这样虚拟机断电重启后所有服务都会自动拉起来,不需要每次手动敲命令。
第二条是控制上下文长度和保持模型常驻内存。我给 Ollama 设置了环境变量,把默认上下文限制在 4096,同时把模型保持时间拉长,避免每来一条消息都重新加载模型。模型反复加载一次要等十几秒,这种延迟非常影响体验。设置之后,只要内存够用,模型就一直驻留在内存里,响应速度明显提升。
第三条是善用日志。OpenClaw 的日志是你最忠实的排错伙伴,但日志文件不能无限涨,否则磁盘会被写满。我在 systemd 服务里配置了日志轮转,按大小切割,保留最近几份就够。磁盘满了不会立刻让系统挂掉,但会让模型加载失败或者数据库写入失败,这种问题排查起来特别隐蔽,预先做好日志轮转能避免一半麻烦。
我个人在实际操作中最深的体会是:这套链路的难点不在任何一个单独组件,而在把四个组件协调起来。单看 OpenClaw、单看 Ollama、单看飞书后台,文档都很清晰,但把它们连在一起之后,问题往往出在配置之间互相影响的地方。所以我的建议是始终保持“逐层验证”的习惯,每加一层就确认一次,不要等全部装完了再一次性排错。最后再分享一个小技巧:在虚拟机上保存一个配置完善后的干净快照,后续升级模型版本或者乱改配置都不用怕,一秒回到可用状态。这个习惯我已经离不开了。如果你也在折腾类似的项目,不妨就从“先跑通一条飞书私聊消息”这个最小闭环开始,再慢慢加工具、加角色、加知识库,你会发现自己能掌控的东西越来越多。