openclaw基于飞书群聊中减少机器人大模型调用次数

飞书多机器人场景下的消息智能过滤方案:减少大模型调用次数的实践

一、背景

在飞书群聊中,我们部署了多个 AI 助手机器人(DevBot、QABot、PMBot、PjMBot)。每个机器人都有自己独立的 Agent 配置,通过飞书开放平台接入群聊。

当用户在群里发送消息时,系统会判断是否需要调用大模型进行回复。然而,在实际运行中发现以下问题:

问题 1:所有机器人都响应同一条消息

例如用户发送"大家周末有什么安排",所有 4 个机器人都认为与自己相关,纷纷调用大模型生成回复。这不仅造成了大量重复调用,而且用户体验很差------用户收到 4 条相似的回复。

问题 2:无关消息也触发大模型调用

群聊中大量消息是项目相关的讨论,但与当前 Bot 的身份无关。例如:

  • DevBot(开发工程师)不该响应"测试报告什么时候出"
  • QABot(测试工程师)不该响应"代码审查通过了"
  • PMBot(产品经理)不该响应"这个 bug 怎么修"

这些消息虽然与项目相关,但与当前 Bot 的身份职责无关,仍被传入大模型处理,浪费 API 调用次数。

问题 3:飞书多账号架构下的重复判断

每个机器人账号独立判断同一批消息,即使使用相同的过滤逻辑,也无法共享判断结果。

核心诉求:在保证与当前 Bot 相关的消息能被正确响应的前提下,减少不必要的远程大模型调用次数。


二、解决方案概述

技术选型:本地小模型 + 智能过滤

采用"本地小模型预判 + 远程大模型处理"的二层架构:

复制代码
┌─────────────────────────────────────────────────────────┐
│                     群聊消息                            │
└─────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│              Smart Filter(本地小模型)                 │
│              gemma2-cpu:latest (~2B 参数)             │
└─────────────────────────────────────────────────────────┘
                           │
              ┌────────────┴────────────┐
              ▼                         ▼
     ┌──────────────┐           ┌──────────────┐
     │   不相关      │           │    相关      │
     │  仅记录历史   │           │ 调用大模型   │
     │  不回复       │           │  正常处理    │
     └──────────────┘           └──────────────┘

三、技术方案详解

3.1 模型选择与测试

测试了多个本地模型,结果如下:

模型 参数量 正确率 平均响应时间 推荐度
gemma2-cpu:latest 2.6B 90% ~1000ms ⭐⭐⭐⭐⭐
gemma2:2b 2.6B 90% ~1000ms ⭐⭐⭐⭐
qwen3:1.7b 2B 90% ~17s ⭐⭐⭐
qwen3:0.6b 0.6B 35% ~1500ms ⭐
stablelm2:1.6b 1.6B 35% ~2500ms ⭐

结论 :选择 gemma2-cpu:latest,在准确率和速度之间取得了最佳平衡。

3.2 消息判断标准

每个 Bot 都有自己明确的身份定位(来自 IDENTITY.md),消息过滤必须结合 Bot 身份进行判断。

以 DevBot(开发工程师)为例:

相关消息:

  • 直接 @ 或提及 DevBot
  • 询问"帮我看看这段代码为什么报错"
  • 请求"帮我优化一下 SQL 查询"
  • 技术问题"接口调不通怎么办"
  • 配置问题"帮我配置一下环境"

不相关消息(对 DevBot):

  • 产品相关"这个需求文档需要补充用户画像"
  • 测试相关"测试用例已经写完了"
  • 项目管理"下周里程碑需要调整"
  • 日常闲聊

3.3 实现架构

复制代码
gate.js (消息入口)
    │
    ▼
checkGroupGate() ──▶ checkSmartFilter() ──▶ callRelevanceModel()
    │                      │                      │
    │                      │                      └── 调用 Ollama 本地模型
    │                      │
    │                      └── 读取 IDENTITY.md 获取 Agent 身份信息
    │
    ▼
checkDmGate()  (私信直接通过)

四、实现步骤

Step 1:配置 Ollama 和模型

bash 复制代码
# 安装 Ollama
# 下载 gemma2 模型
ollama pull gemma2:2b

Step 2:修改插件代码

在 gate.js 中添加 checkSmartFilter 函数:

javascript 复制代码
// Smart Filter 配置
const smartFilterConfig = accountFeishuCfg?.smartFilter;

// 被 @ 时直接通过
if (mentionedBot) {
    return { allowed: true };
}

// 调用本地小模型判断
const isRelevant = await callRelevanceModel({
    message: ctx.content,
    senderName: ctx.senderName,
    chatName: ctx.chatName,
    config: smartFilterConfig,
    agentIdentity: identityContent,
});

// 根据判断结果决定是否允许通过
return { 
    allowed: isRelevant,
    recordOnly: !isRelevant
};

Step 3:模型调用实现

javascript 复制代码
async function callRelevanceModel(params) {
    const { message, config, agentIdentity } = params;
    
    const response = await fetch(`${config.baseUrl}/chat/completions`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${config.apiKey}`,
        },
        body: JSON.stringify({
            model: config.model,  // gemma2-cpu:latest
            messages: [
                { 
                    role: 'system', 
                    content: `你是消息相关性判断助手。判断消息是否与AI助手相关。\n\n【AI助手身份】\n${agentIdentity}\n\n相关: 消息针对AI助手, 询问AI能力, 请求AI帮助\n不相关: 群成员间闲聊, 与AI无关的讨论\n\n请输出JSON格式:{"relevant": true/false}`
                },
                { 
                    role: 'user', 
                    content: `判断:${message}` 
                }
            ],
            max_tokens: 100,
            temperature: 0.1,
            response_format: { type: 'json_object' }
        }),
    });
    
    const data = await response.json();
    const content = data.choices[0].message.content;
    const parsed = JSON.parse(content);
    
    return parsed.relevant === true;
}

Step 4:配置文件

在 openclaw.json 中添加 smartFilter 配置:

json 复制代码
{
  "channels": {
    "feishu": {
      "accounts": {
        "custom-1": {
          "smartFilter": {
            "enabled": true,
            "model": "gemma2-cpu:latest",
            "apiKey": "ollama",
            "baseUrl": "http://localhost:11434/v1"
          }
        }
      }
    }
  }
}

Step 5:Agent 身份注入

读取 Agent 的 IDENTITY.md 文件,为模型提供上下文:

javascript 复制代码
async function getAgentIdentity(cfg, accountId) {
    const workspace = agent.workspace;
    const identityPath = `${workspace}/IDENTITY.md`;
    
    const response = await fetch(`file://${identityPath}`);
    if (response.ok) {
        return await response.text();
    }
    
    // 回退到基础信息
    return `AI助手名称: ${agent.identity.name}`;
}

五、效果评估

5.1 调用量减少

假设群聊日均消息 200 条,其中:

  • 与 DevBot 相关(开发问题):约 25%(50 条)
  • 与 QABot 相关(测试问题):约 20%(40 条)
  • 与 PMBot/PjMBot 相关(产品/项目管理):约 15%(30 条)
  • 与任何 Bot 都无关(其他项目讨论、日常):约 40%(80 条)

使用 Smart Filter 前:

  • 每个 Bot 都尝试处理所有消息 → 大量无效调用

使用 Smart Filter 后(以 DevBot 为例):

  • 只处理与自己相关的消息 → 50 次/天
  • 节省:约 75%(150 次/天)

5.2 响应质量

  • 90% 的消息判断准确率
  • 失败的 10% 中,大部分是边界情况(如"这个配置怎么写"这类模糊消息)
  • 平均判断延迟:~1000ms(用户无感知)

5.3 成本估算

以 OpenAI API 为例(假设 $0.002/1K tokens):

  • 节省 60% 的 API 调用
  • 假设平均每条消息 500 tokens
  • 每天节省:120 × 500 / 1000 × 0.002 = **0.12**

虽然单次成本不高,但在大规模部署时累积效应显著。


六、进阶优化建议

6.1 缓存优化

javascript 复制代码
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5分钟

function checkCache(key) {
    const cached = cache.get(key);
    if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
        return cached.result;
    }
    return null;
}

6.2 动态阈值

根据消息类型动态调整判断阈值:

  • 代码相关:更严格
  • 闲聊相关:更宽松

6.3 反馈学习

记录被错误过滤的消息,定期微调判断逻辑。


七、总结

通过引入本地小模型进行消息预判,我们成功实现了:

  • ✅ 75% 的大模型调用减少(按身份过滤)
  • ✅ ~1000ms 的无感延迟
  • ✅ 90% 的判断准确率
  • ✅ 零成本的本地部署

该方案的核心价值在于:让每个 Bot 只关注与自己身份相关的内容,避免"一个项目讨论触发所有 Bot 回复"的混乱场面,提升用户体验的同时显著降低 API 成本。


参考资料


本文档基于实际项目实践整理,方案已在本地环境验证有效。

相关推荐
死磕音视频1 天前
Open WebUI 入门:用 Docker 装上本地对话界面并连接 Ollama
docker·ollama·本地大模型·open webui
xzlAwin2 天前
Win10 安装OpenClaw 龙虾
ai·openclaw·龙虾
mudtools2 天前
在飞书 SDK 上用 Microsoft Agent Framework 搭一个能干活的工作搭子
人工智能·ai·.net·飞书·agent
极致了3 天前
飞书插件、RPA、API三条路的真实分界线
飞书·rpa
xzlAwin3 天前
Win10 安装 Ollama 本地AI
ai·ollama
玩泥巴的4 天前
在飞书 SDK 上用 Microsoft Agent Framework 搭一个能干活的工作搭子
ai·.net·飞书·agent
玩泥巴的5 天前
一份声明,多份产物:飞书 SDK 的 AI 工具面是怎么生成的
ai·.net·飞书·agent
还卿一钵无情泪5 天前
PEFT-Transformers、Unsloth、LLaMA-Factory 微调框架 横向对比
深度学习·大模型·llama·ollama
读完一本书5 天前
Ollama 跑得慢?我试了 6 个参数,只有 3 个真有用
人工智能·ollama
Flynn Liang5 天前
保姆级|Spring AI 2.0 第一个 Demo:Spring Boot 4 接入大模型(含国内可用方案 + 完整 pom)
人工智能·spring·ollama·springai·deepseek·springai入门·java接入大模型