NoneBot2 接大模型:插件选型、配置与群机器人成本账

NoneBot2 接大模型只需两步:装一个 OpenAI 兼容的 LLM 插件,把接口地址指到 https://api.kkaiapi.com/v1 并填入 API Key。DeepSeek、GLM、Kimi、Claude、GPT 全系模型一个 Key 通用,群聊机器人的月成本可以压到一顿早饭钱。

先给结论:两条路线,五分钟接通

为什么推荐走中转而不是分别去各家官网开号:NoneBot 群机器人是典型的多模型场景,陪聊用便宜的,写长文切文笔好的,如果 DeepSeek、智谱、月之暗面、Anthropic 各开一个账号,你要维护四份 Key、四个余额、两种货币。kkaiapi 是面向中文开发者的 OpenAI 兼容模型中转,一个 Key 调全系模型,支付宝微信充值,按量计费没有订阅,机器人跑多少扣多少。

  • 现成插件路线:用 nb-cli 或 pip 安装 nonebot-plugin-llmchat 这类 OpenAI 兼容插件,在 .env.prod 里填接口地址和 Key,重启即用,适合想快速上线的群主
  • 自写插件路线:openai SDK 的 AsyncOpenAI 二十行代码起步,触发规则、会话记忆、限流策略全部自己控制,适合有定制需求的开发者
  • 接口地址统一填 https://api.kkaiapi.com/v1,模型 ID 按需填 deepseek-v4-flash、glm-5、kimi-k2.6、claude-sonnet-4-6 等,换模型只改一个字符串
  • QQ 侧协议端(NapCat、Lagrange)与 LLM 配置互不相干,先确认 OneBot v11 连接正常、机器人能复读,再去调模型

主流 NoneBot LLM 插件横向对比

NoneBot 商店里聊天类插件不少,真正维护活跃、支持自定义 OpenAI 兼容接口的就这几个。选型逻辑很简单:想要开箱即用的群聊陪聊选 llmchat,想捏人设选 naturel-gpt,想要功能型助手选 marshoai,想深度定制就自己写。 注意所有插件都要求接口兼容 OpenAI 协议,这正是用中转的另一个好处:不管上游是 DeepSeek 还是 Claude,到插件这一侧全是同一种协议,配置项完全一致。

OpenAI 兼容配置:.env 写法与连通性验证

以 nonebot-plugin-llmchat 为例,它支持多个 API 预设,群里可以用指令切换。在 .env.prod 里加一段 JSON,把两个常用模型都配上:

# nonebot-plugin-llmchat 多预设配置
LLMCHAT__API_PRESETS='[
  {
    "name": "flash",
    "api_base": "https://api.kkaiapi.com/v1",
    "api_key": "sk-xxxxxxxx",
    "model_name": "deepseek-v4-flash"
  },
  {
    "name": "glm",
    "api_base": "https://api.kkaiapi.com/v1",
    "api_key": "sk-xxxxxxxx",
    "model_name": "glm-5"
  }
]'

会话管理与限流:一个能直接抄的自写模板

现成插件满足不了需求时,自己写一个消息响应器也就二十来行。下面这个模板把三件关键事都做了:分群会话隔离(每个群独立上下文,互不串台)、上下文截断(deque 限长,最多带八轮历史,控制输入 token)、频率限流(每群五秒冷却,防刷屏也防天价账单)。 限流不只是省钱。QQ 侧高频发言容易触发平台风控,轻则消息发不出,重则封号。建议三层都做:触发层只响应 @ 或白名单关键词;频率层做冷却加每群每日调用上限;花费层用 max_tokens 限制单次输出。另外注意内存里的会话重启即丢,要长期记忆就接 localstore 插件或数据库。

import time
from collections import defaultdict, deque
from nonebot import on_message
from nonebot.adapters.onebot.v11 import GroupMessageEvent
from nonebot.rule import to_me
from openai import AsyncOpenAI

client = AsyncOpenAI(
    api_key="sk-xxxxxxxx",
    base_url="https://api.kkaiapi.com/v1",
)
history: dict[int, deque] = defaultdict(lambda: deque(maxlen=16))  # 每群 8 轮
last_call: dict[int, float] = {}

chat = on_message(rule=to_me(), priority=50, block=False)

@chat.handle()
async def handle(event: GroupMessageEvent):
    gid = event.group_id
    if time.time() - last_call.get(gid, 0) < 5:  # 每群 5 秒冷却
        return
    last_call[gid] = time.time()
    history[gid].append({"role": "user", "content": event.get_plaintext()})
    resp = await client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "system", "content": "你是群助手,回答简短。"},
                  *history[gid]],
        max_tokens=300,
    )
    reply = resp.choices[0].message.content or ""
    history[gid].append({"role": "assistant", "content": reply})
    await chat.finish(reply)

常见问题

NoneBot 接 DeepSeek 用哪个插件最省事?

群聊陪聊直接装 nonebot-plugin-llmchat,接口地址填 https://api.kkaiapi.com/v1,模型填 deepseek-v4-flash,五分钟能跑通。要精细控制触发和限流就用文中的自写模板,openai SDK 二十行搞定。

接口地址要不要带 /chat/completions 后缀?

用 openai SDK 的插件(绝大多数)填到 /v1 为止,SDK 会自动拼接路径。个别自己拼 URL 的插件报 404 时,把地址补成完整端点 https://api.kkaiapi.com/v1/chat/completions 即可。

群里有人故意刷屏套话怎么办?

三层防护:只响应 @ 触发,砍掉大部分无效调用;每群加冷却时间和每日调用上限;单次回复用 max_tokens 封顶。这样既控成本,也避免机器人高频发言触发 QQ 风控。

能给机器人设人设做角色扮演吗?

可以,在 system 提示词里写清角色设定、说话风格和背景即可。模型选择上,DeepSeek V4 系性价比和创作自由度都不错,GLM-5 中文人设稳,Kimi 适合长剧情记忆;Claude 文笔最好但内容政策较严,适合普通向创作。具体见角色扮演模型排行一文。

一个 API Key 能同时给几个 bot 用吗?

技术上一个 Key 多处共用没问题,但建议每个机器人单独建 Key:控制台按 Key 统计消耗,分账清楚,某个 bot 出问题也可以单独停用,不影响其它服务。

机器人回复很慢或超时怎么排查?

先用 curl 直接测接口,确认是链路慢还是插件卡。常见原因:选了推理型大模型导致首字慢,群聊场景换 deepseek-v4-flash 这类快模型;max_tokens 设太大拉长生成时间;协议端与 NoneBot 之间 WebSocket 断连,查 NapCat 日志。