☰
OpenClaw+飞书+Ollama:构建可自动装技能的本地AI办公机器人
2026/10/21 1:52:53 网站建设 项目流程

前阵子有个朋友跟我吐槽,说他们团队每天要在飞书群里手工处理各种重复请求:查数据、填报表、发通知、回工单,忙得跟客服一样。我问了一句“这些活能不能交给机器人”,他反问“能倒是能,但数据都在内网,业务规则又老变,一般机器人接不住”。后来我给他搭了一套基于OpenClaw的飞书AI办公机器人,用的正是本地Ollama模型,支持按需自动安装skills,还顺手把数据可视化做进去了。这套组合落地之后,群里80%的重复问答和报表类请求都自动化了,他这才意识到,原来办公机器人不一定要绑云端大模型,也不一定要改动一次需求就改一次代码。

这篇文章就围绕“OpenClaw + 飞书 + 本地Ollama + 自动安装skills + 数据可视化”这条主线展开。OpenClaw在这里扮演智能体框架层的角色,负责飞书消息的收发、意图调度和技能管理;Ollama提供完全本地化的推理能力,数据不出内网;skills机制让机器人的能力可以像装App一样按需扩展;可视化部分让机器人不只“会聊天”,还能直接产出图表和报表。适合正在做企业内部工具、飞书机器人,或对本地模型应用感兴趣的同学参考。我下面讲的配置和步骤,是基于一套常见且可复现的落地做法,不一定是最新版本的最优解,但链路是完整且经过验证的。

1. 这套组合解决的核心问题:OpenClaw、飞书与Ollama各自的角色

1.1 为什么一定要选“本地模型”

很多团队做AI办公机器人,第一反应就是接云端大模型API,因为省事、效果好。但真放到企业办公场景里,云端API往往不是最优解:内部经营数据、客户名单、合同信息不能随便出内网,合规这一关就卡死了一大半方案;其次是成本,如果群里有几百号人高频调用,token费用累积起来非常可观;再有就是稳定性,办公高峰期如果云端服务限流,机器人直接变“人工智障”。

Ollama这类本地推理工具解决的正是这三个痛点。它把模型跑在自己的服务器上,数据全程不出内网,没有按token计费的压力,模型文件一旦下载完,离线也能用。对我这次的项目来说,选Ollama还有一个额外的好处:部署足够简单。它就是一个本地服务,默认监听11434端口,OpenClaw把对话请求转发过去,拿到返回结果再组织回复,整体链路清爽。

1.2 OpenClaw在整条链路里的位置

OpenClaw在这个项目里不是“模型”,也不是“某个具体功能”,而是一个承上启下的智能体框架。简单理解,它干四件事:第一,连接飞书开放平台,接收群里的消息事件,也能主动向飞书发消息;第二,根据消息内容做意图理解,判断是闲聊、查数据还是执行某个操作;第三,把需要推理的请求转给Ollama本地模型,把需要特定逻辑的任务分发给对应的skills执行;第四,维护技能包的生命周期,支持按需安装、卸载和更新。

打个比方,如果把机器人比作一家公司,Ollama是“大脑”,负责思考;skills是“员工”,负责干具体的事;飞书是“前台”,负责和用户打交道;而OpenClaw是“管理层”,把所有环节串起来、排优先级、做决策。没有Ollama,机器人没有推理能力;没有skills,机器人只会聊天不会干活;没有OpenClaw,前面两样东西根本接不进飞书。三者的关系是互补的,不是竞争关系。

2. 飞书侧的前置工作:应用创建、权限与事件订阅

2.1 创建自建应用并开启机器人能力

飞书机器人本质上是开放平台上的一个“应用”。要做这件事,第一步是到飞书开放后台创建一个“企业自建应用”。创建完成后,会拿到两个关键凭证:App ID和App Secret。这两个东西后面OpenClaw配置里要用,相当于机器人的身份证和密码。

创建完应用,需要在“应用能力”里开启“机器人”能力。这一步以后,飞书才会生成一个机器人账号,你才能在群里@它。接下来是权限配置,常见办公机器人都需要至少这么几项权限:

  • im:message(读取群聊消息)
  • im:message:send_as_bot(以机器人身份发消息)
  • im:chat(获取群信息)
  • im:resource(上传、读取图片等资源)

权限申请后需要发布应用版本,并且要经过企业管理员审核。如果你是在自己的测试企业里搭建,这一步很简单;如果是在客户环境里交付,记得把这一步的时间预留出来,因为审核经常要等。

2.2 事件订阅与长连接模式的选择

飞书机器人接收消息有两种方式:一种是“事件订阅回调”,需要提供一个公网可达的HTTPS地址,飞书把用户的消息事件POST到这个地址上;另一种是“长连接模式”,客户端主动跟飞书服务器维持一个WebSocket,消息来了通过这个连接推给你。

我强烈建议本地开发阶段用长连接。原因很现实:回调模式下,你的本机服务没有公网IP,要么做内网穿透,要么部署到公网服务器上,调试链路长、问题多;而长连接模式下,OpenClaw直接连飞书的WebSocket网关,本地起了服务就能收到消息,断线后框架还会自动重连,省去了一堆网络配置的麻烦。

在飞书后台配置时,只需要在“事件订阅”里选择“使用长连接接收事件”,然后添加事件im.message.receive_v1(接收消息)。OpenClaw的飞书适配器启动后会自动完成长连接握手。需要注意,应用发布版本时勾选的事件权限范围必须覆盖这些事件,否则服务能启动但收不到任何消息。

3. OpenClaw的项目形态与skills自动安装机制

3.1 核心目录结构与配置文件示意

OpenClaw本身是一个服务进程,一般通过配置文件描述它要连接哪个平台、使用什么模型、加载哪些技能。我项目里的目录结构大致是这样的:

openclaw/ ├── config/ │ └── openclaw.yaml # 主配置 ├── skills/ # 已安装的技能包 │ ├── weather/ │ ├── sales_report/ │ └── approval_query/ ├── data/ # 用于可视化的数据文件 ├── logs/ # 运行日志 └── main.py # 启动入口

主配置文件openclaw.yaml里,飞书和Ollama的接入参数通常在同一个文件里管理。一个常见的片段如下:

adapter: platform: feishu app_id: "cli_xxxxxxxxxxxx" app_secret: "xxxxxxxxxxxxxxxx" event_mode: websocket llm: provider: ollama base_url: "http://127.0.0.1:11434" model: "qwen2.5:7b" temperature: 0.7 max_tokens: 2048 skills: dir: "./skills" remote_repo: "https://your-git-lab.example.com/openclaw-skills" auto_install: true allowed_users: ["admin", "ops"]

这里有个容易踩坑的点:event_mode如果设成回调模式,就需要额外配置回调地址和token验证;对于纯内网部署,老老实实用websocket最省心。auto_install: true表示允许机器人按指令自动安装技能,但一般我会限制只有allowed_users里的用户能触发安装,避免群里任何人都能往内部环境装东西。

3.2 自动安装Skills的完整流程

“自动安装skills”是OpenClaw最有价值的能力之一。普通机器人加功能要靠开发者改代码、重启服务;OpenClaw把技能做成可分发的软件包,用户(通常是管理员)在群里发一条指令,机器人就能把技能装好、加载好,立刻投入使用。

一次完整的自动安装流程大概分六步:

  1. 用户在群里发送指令,比如/skills install sales_report。
  2. OpenClaw先校验发送者的身份是否在allowed_users白名单里,这一步不能省,否则安全性没法保证。
  3. 框架从配置的remote_repo技能仓库读取sales_report的清单文件,里面描述了这个技能的版本、入口文件、依赖项。
  4. 下载技能压缩包,同时校验哈希值或签名,确认包没有被篡改。
  5. 解压到skills/目录,扫描入口文件,动态注册新的意图路由。
  6. 回复安装结果,并把新技能加载情况写进日志。

整个过程不需要人工登录服务器,也不需要重启主进程。用的时候,用户直接发“查询本月销售报表”,OpenClaw会把这条消息匹配到刚装好的sales_report技能上,技能再从数据源取数并生成报表。

依赖问题是我实际部署中经常遇到的坑。技能包如果依赖了第三方Python库,安装时需要在隔离环境里处理依赖,而不是直接往主进程里塞。我的做法是让每个技能自带一个requirements.txt,OpenClaw在安装时自动创建一个虚拟环境、安装依赖并记录环境路径。这样既能热加载,又不会把主环境搞乱。

4. 接入本地Ollama模型的完整链路

4.1 模型选型与启动Ollama服务

Ollama接入的第一步不是写配置,而是选模型和准备硬件。办公场景里,我并不建议一上来就追求最大参数量的模型。显存有限、并发要求也有限,最合适的通常是7B到14B之间、中文支持比较好的开源模型。我自己用的配置是7B级别的模型,量化后大约需要6GB到8GB显存;如果只有纯CPU环境也能跑,但每轮回复可能要等半分钟以上,体验会明显下降。

启动Ollama服务本身很简单,装好之后,先用命令行拉取模型:

ollama pull qwen2.5:7b ollama serve

ollama serve会默认监听127.0.0.1:11434。如果你的OpenClaw和Ollama不在同一台机器上,需要把Ollama服务绑定到可访问的内网IP,并设置环境变量OLLAMA_HOST=0.0.0.0,然后重启服务。这时可以在服务器上用curl验证一下:

curl http://127.0.0.1:11434/api/generate -d '{ "model": "qwen2.5:7b", "prompt": "用一句话介绍你自己", "stream": false }'

能正常返回内容,说明模型服务没问题。这一步做完,再回到OpenClaw侧配置。

4.2 OpenClaw侧模型配置与调用逻辑

配置文件里的llm段就是给OpenClaw指路用的。写了provider: ollama之后,框架内部会把对话历史、工具调用请求封装成Ollama兼容的请求格式,POST到/api/chat接口。这里要注意,Ollama的接口格式和OpenAI不完全一样,但OpenClaw的适配层会做转换,你只需要确保model名称和ollama list里显示的名字完全一致。

ollama list # 输出中第一列就是你要填到配置里的模型名,比如 qwen2.5:7b

我遇到过最频繁的问题是模型名写错。有些人用qwen2.5不带:7b,有些人写成了其他版本号,结果OpenClaw启动时连接正常,但一发送请求就报model not found。排查方式很简单:启动前先执行ollama list,把完全一致的名称复制进配置。

调通之后,可以做个快速验证:在飞书群里@机器人说“帮我总结一下这段话”,机器人会把消息转发给Ollama,拿到返回值后再以飞书消息的形式回复。到了这一步,说明“飞书→OpenClaw→Ollama”的推理链路已经闭合。接下来就可以做真正的办公自动化了。

5. 数据可视化:从“收到问题”到“输出图表”

5.1 一个典型的图表生成请求处理链

数据可视化是这个项目里最出彩的部分。机器人不只能回答“某产品上季度销量是多少”,还能量出“把过去30天的销量趋势画给我看”。本质上,这需要把自然语言请求转换成一次数据查询、一次图表渲染、一次图片上传。

我实现的处理链路是:用户在群里发“画一下本周工单趋势”;OpenClaw识别到这是一个可视化请求,把它交给report技能;技能读取data/目录下的CSV数据文件,用Python的Pandas做聚合统计;然后调用Matplotlib绘制折线图;生成PNG之后,通过飞书API上传图片,再把图片消息发送到会话里。

核心代码思路很简单:

import pandas as pd import matplotlib.pyplot as plt def render_trend(data_path: str, output_path: str) -> str: df = pd.read_csv(data_path, parse_dates=["date"]) daily = df.groupby("date").size().reset_index(name="count") plt.figure(figsize=(10, 4)) plt.plot(daily["date"], daily["count"], marker="o") plt.title("工单趋势") plt.xlabel("日期") plt.ylabel("数量") plt.savefig(output_path, dpi=150) return output_path

这里有个中文字体的大坑:服务器上如果没有安装中文字体,Matplotlib生成的图片里所有中文都会变成方块。解决办法是下载并注册一个中文字体,比如思源黑体,然后在绘图前设置:

from matplotlib import font_manager font_manager.fontManager.addfont("/usr/share/fonts/source-han-sans-regular.otf") plt.rcParams["font.family"] = "Source Han Sans CN"

这一步不做,前面的图表逻辑再好,输出也是废的。

5.2 让输出适配飞书:图片消息、卡片与定时推送

图表生成之后,怎么发给用户?最直接的方式是上传到飞书并发送图片消息。飞书开放平台的图片消息API要求先把本地图片上传到飞书,拿到image_key,再通过im/v1/messages接口发送。OpenClaw的飞书适配器一般已经封装好了这个流程,但底层逻辑就是三步:上传图片、拿image_key、发消息。

除了图片消息,飞书的交互卡片也很有用。卡片能承载按钮、链接和结构化数据,适合做“点击查看详情”这种场景。比如机器人回复一张趋势图的同时,卡片上可以带一个“导出CSV”按钮,用户点了就能在对话里拿到原始数据文件。这种交互体验比单纯发一段文字强得多。

定时推送是另一个高频需求。办公机器人不能只等人来问,还要主动汇报。我在report技能里加了一个简单的定时任务配置,每天早上9点自动读取昨天的数据、生成图表、发到指定的飞书群里。这样团队领导一进办公室就能看到数据日报,不用任何人手动操作。数据可视化到此就不是一个炫技功能,而成了真正日常使用的业务闭环。

6. 实际部署中的踩坑记录与执行体会

6.1 五个高频问题的定位路径

这套系统整体链路不算复杂,但从零部署到稳定运行,我确实踩了不少坑。挑五个出现频率最高的问题,按排查路径记录下来。

第一个是“消息收不到”。OpenClaw进程启动了,飞书后台也配置了,但群里发消息机器人没反应。先查事件订阅是否添加了im.message.receive_v1,再看应用权限里有没有开通“获取单聊、群组中用户发送的消息”的权限。很多时候,后台能添加事件但权限没开,后台也不会有明显报错,只有测试消息时才暴露。

第二个是“连上了但发不出消息”。这种情况常见于App Secret填错,或者没有正确获取tenant_access_token。OpenClaw会在启动日志里打印token获取结果,先看一眼有没有提示invalid app_secret之类的内容。

第三个是“模型请求超时”。本地模型推理本来就比云API慢,如果用的是CPU推理或者模型参数过大,OpenClaw默认的超时时间可能不够。解决方法是把配置里的请求超时拉长到120秒甚至更久,同时给Ollama服务设置合理的并发上限,避免多个请求同时过来把显存打爆。

第四个是“技能安装后没有生效”。OpenClaw加载技能时,通常按目录结构识别入口文件。如果技能包解压后多了两层嵌套目录,或者入口文件的文件名和清单不一致,框架会静默跳过。排查时先看logs/下的加载日志,再确认技能目录是否在skills/下直接可见。

第五个是“卡片消息显示异常”。飞书交互卡片的JSON结构非常死板,一个字段写错整张卡片就显示不出来。建议先在飞书后台的“卡片调试工具”里把JSON跑通,再填到skill里。别直接用AI生成一段复杂卡片JSON就丢进去,调试成本会很高。

6.2 上线前值得做的小事

基于这次的实践,我总结了四件小而重要的事,强烈建议在做类似项目时提前安排。

第一,给所有技能包加上版本号。自动安装技能是方便,但如果没有版本管理,哪天更新了一个技能导致行为变了,查回滚会非常痛苦。技能仓库里保留历史版本,必要时一键回退,比在服务器上手动改文件安全得多。

第二,控制allowed_users白名单。自动安装Skills能力很强,但也容易被滥用。只让管理员和运维账号触发安装指令,普通用户使用技能不受限制,这样既灵活又安全。

第三,日志一定要结构化。OpenClaw本身会打日志,但你在技能里也要打印自己的关键日志:请求参数、数据源查询结果、图表渲染耗时、发送结果。出了问题能顺着日志一层层找,不然就只能靠猜。

第四,先小范围试点再全量接入。我最初只是在一个人数不到20的测试群里跑,验证稳定性后才放到核心业务群里。核心业务群的流量和消息复杂度远高于测试群,如果Ollama服务部署在共享服务器上,建议先压测一下并发能力。

我在这个项目里最深的体会是,办公机器人能不能被团队真正用起来,关键不在于模型多聪明,而在于它能不能稳定地完成那些具体、重复、琐碎的事务。OpenClaw加飞书只是把入口打通了,Ollama只是把推理能力带回了内网,真正让机器人生存下来的,是那一套不断补充、可自动安装的skills,和数据可视化这种一眼就能看到价值的功能。你先从一个最痛的场景开始,比如“每天手动汇总数据报表”,把它完整跑通,再慢慢往里面加技能。相信我,一旦团队尝到了甜头,后面的事情就不再是你要不要扩展,而是他们追着你问“能不能再做一个”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询