DeepSeek接入QQ机器人:OneBot协议与拟人化回复实战
2026/9/9 13:55:23 网站建设 项目流程

把 DeepSeek 接入 QQ 机器人,让它像真人一样在群里聊天,是最近被问得非常多的一块内容。这个需求听起来只是把大模型 API 和 QQ 消息通道连起来,真正动手时会发现要处理的细节不少:OneBot 协议怎么上报消息、API Key 怎么配置、人设提示词怎么写才不像客服、以及为什么所有消息都回复反而显得特别假。这篇保姆级教程按照一条完整主线展开:QQ 群消息通过 OneBot 框架上报到本地 Python 服务,服务按概率决定要不要回复,命中后调用 DeepSeek 的 chat API,再把模型输出发回群聊。整套流程跑通后,你可以继续扩展多群人设、上下文记忆、延迟回复和敏感词过滤。

1. 先理解整条链路:消息从 QQ 群到 DeepSeek 再回来

1.1 没有官方接口时,社区方案怎么工作

普通开发者申请 QQ 官方机器人接口的门槛不低,而且官方接口面向的更多是群管理、客服这类的功能型机器人,并不适合“个人小号在群里像真人一样聊天”。所以社区普遍采用另一条路径:找一个 OneBot 协议实现的框架,让它登录一个用来当机器人的 QQ 小号,监听这个号收到的消息,再把消息按标准格式上报给你自己的程序。

把这条链路写成文字就是:

QQ 群消息 -> OneBot 框架 -> HTTP POST 上报到本地服务 -> Python 程序判断要不要回复 -> 调用 DeepSeek API -> 本地服务返回回复内容 -> OneBot 框架把消息发回群聊。

这里最容易误解的是:OneBot 不是 QQ 官方提供的东西,而是社区定义的一套消息协议标准。它的价值在于,只要框架实现了 OneBot 11 协议,你的程序就可以用同一套代码对接不同的框架,不用为每个封装重写一遍。常见实现有 NapCat、Lagrange.OneBot、LLOneBot 等,具体选哪个主要看自己的运行环境。

1.2 OneBot 11 协议在链路中的位置

OneBot 11 协议有多种连接方式,本文只用其中最简单的一种:HTTP 上报。框架把消息事件以 JSON 格式 POST 到你在配置里填写的地址,例如 http://127.0.0.1:8765/onebot。你的程序收到 JSON 后,如果希望立即回复,可以在 HTTP 响应体里直接返回:

{"reply": "你好呀"}

框架会自动把这段文本发回触发消息的群聊或私聊。对保姆级入门来说,这种“快速回复”方式足够跑通整条链路,不需要额外写发消息的调用。

一条典型的群消息事件长这样:

{ "post_type": "message", "message_type": "group", "group_id": 123456789, "user_id": 987654321, "self_id": 111222333, "raw_message": "[CQ:at,qq=111222333]小梦在吗", "sender": {"user_id": 987654321, "nickname": "测试用户"} }

私聊时没有 group_id,message_type 是 private。后面写程序时主要看的字段就是 post_type、message_type、raw_message、user_id、self_id。post_type 表示事件类型,只有 message 才是消息事件;raw_message 是带 CQ 码的原始文本;self_id 是机器人的 QQ 号,后面判断“是不是在 @ 我”要用它。

1.3 概率回复是拟人化的第一层手段

真人不会回复群里每一条消息。如果一个机器人对每条消息都秒回,哪怕语气再自然,群友看一会儿也会觉得假。概率回复的思路是:让程序按一定概率决定是否回应,其他时候保持沉默。这样既保留了参与感,又不会让人持续注意到这是一个自动回复程序。

回复策略特点适用场景
全部回复链路简单,但容易刷屏,也容易被识别为机器人测试链路、私聊调试
固定关键词回复只回复命中关键词的消息,稳定但不够自然功能型机器人
关键词优先 + 概率回复被 @ 或叫到名字必回,普通消息按概率回拟人化聊天机器人

概率回复不是随机乱回。更合理的设计是分层判断:提到机器人名字必回,被 @ 必回,私聊尽量都回,群聊普通消息按概率回。后面第 4 节的代码就按这个顺序实现。

2. 环境准备:Python、OneBot 框架、API Key

2.1 准备的材料清单

材料说明注意事项
一台电脑或服务器用来跑 Python 服务和 OneBot 框架学习阶段可以是一台能运行 QQ 的电脑
QQ 小号用来登录 OneBot 框架不要用主号,避免日常使用受影响
Python 3.10+运行主程序建议 3.10 或更高版本
DeepSeek API Key调用大模型接口在开放平台创建,按量付费
OneBot 框架负责登录 QQ 和收发消息以 NapCat 为例说明,其他框架思路相同

2.2 安装 Python 依赖

项目只需要四个依赖,分别是 Web 服务框架 FastAPI、开发服务器 uvicorn、OpenAI 兼容 SDK 和读取环境变量的 python-dotenv:

pip install "fastapi>=0.110" "uvicorn[standard]>=0.29" "openai>=1.35" "python-dotenv>=1.0"

安装完成后可以用下面的命令确认环境已经就绪:

python -c "import fastapi, openai, dotenv; print('ok')"

如果输出 ok,说明依赖安装成功。版本号这里只是示例,实际以 pip 能拉取到的稳定版本为准。

2.3 在 DeepSeek 开放平台创建 API Key

登录 DeepSeek 开放平台,在 API Keys 页面创建一个新的 Key。创建后立刻复制保存,因为 Key 通常只显示一次。然后把账户余额准备好,接口是按 tokens 计费的,具体价格以开放平台页面为准。

这里要确认三件套:API Key、base_url、模型名。DeepSeek 提供 OpenAI 兼容接口,常见配置是 base_url 为 https://api.deepseek.com,模型名常见有 deepseek-chat 和 deepseek-reasoner。模型名和价格会调整,落地前先到官方文档确认一次。学习环境先用普通对话模型 deepseek-chat 就够了,后面会解释为什么。

2.4 启动 OneBot 框架并配置上报地址

以社区常用的 NapCat 为例:下载对应平台的版本,按文档启动,然后用你的 QQ 小号登录。登录成功后,在连接管理里找到 HTTP 上报相关配置,新增一条上报规则,地址填:

http://127.0.0.1:8765/onebot

然后勾选启用的消息事件类型。不同版本的配置界面和字段名不完全一样,但核心概念一致:把消息事件 POST 到本地服务的地址。如果你用的是其他 OneBot 实现,只需要找到同等的“HTTP 上报地址”或“HTTP Post URL”配置项。

注意:上报地址里的端口必须是 Python 服务实际监听的端口。很多新手改了一个端口,却忘了改另一个,最后怎么测都没有消息进来。

配置完成后先不要急着写程序,可以查看框架日志,确认事件确实有在往外发。这样才能在排错时区分是框架的问题还是自己程序的问题。

2.5 学习环境与生产环境的差异

整套链路在本机跑通很容易,但生产环境至少要再做四件事:第一,API Key 不要写死在代码里,放到环境变量或配置管理平台;第二,把服务的监听地址从 127.0.0.1 改成 0.0.0.0 并配置防火墙安全组,让框架能访问到它;第三,用 systemd、supervisor 或 Docker 守护进程,挂掉后能自动拉起;第四,日志要落盘,方便半夜出问题时排查。这些在第 7 节还会展开。

3. 先单独验证 DeepSeek API:人设和参数都在这层决定

3.1 最小调用脚本

在接 QQ 之前,先单独验证 DeepSeek API 能正常回复。新建一个 test_deepseek.py:

from openai import OpenAI client = OpenAI( api_key="sk-你申请的Key", base_url="https://api.deepseek.com", ) resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "user", "content": "你好"} ], temperature=1.0, max_tokens=100, ) print(resp.choices[0].message.content)

运行:

python test_deepseek.py

如果 Key 正常、账户有余额,会输出一段模型生成的文本。这一步通过后,再进 QQ 链路,至少能确定问题不在 API 层。

3.2 影响“说话感觉”的关键参数

调用接口时要理解几个参数,它们直接决定回复像客服还是像真人:

参数作用对拟人化的影响建议
temperature采样温度,越高越随机太低会变成标准客服腔,太高容易胡说0.8 到 1.2 之间试验
max_tokens最大生成 token 数太长像小作文,太短接不上话300 到 600
top_p核采样阈值一般保持默认即可1.0
presence_penalty提高话题多样性太高容易跑题默认或 0
frequency_penalty降低重复用词太高句子会碎默认或 0

不是所有参数在每种模型上都支持同样的效果,这里说的是通用规律,具体以官方文档为准。拟人化调优的核心思路是:不要一次只调一个变量,先固定人设,再慢慢调 temperature。

3.3 system prompt 就是人设

很多人只把 system prompt 当“给模型的规则”,其实在拟人化场景里,它就是你给机器人写的人设底稿。下面是示例:

SYSTEM_PROMPT = ( "你叫小梦,是群里一个普通群友,不是客服。" "你说话口语化,喜欢短句,偶尔开玩笑,会用语气词。" "不要一开口就报解决方案,不要每句话都用感叹号。" "不要暴露自己是 AI,也不要说明自己是语言模型。" "别人问你是不是机器人时,你可以笑着岔开话题。" )

把这段人设放进 system prompt 后,模型回复的语气会明显不同。要注意的是,人设不要只写“你是真人”,还要写清楚具体行为边界,否则模型还是会按默认的助手风格回答。后面第 7 节会补充敏感内容过滤和话题拒绝。

4. 编写 QQ 机器人主程序:上报接收、概率判定、API 调用

4.1 项目结构与配置分离

建议按下面结构组织项目:

qq-bot/ ├── .env ├── config.py ├── main.py └── requirements.txt

requirements.txt 内容:

fastapi>=0.110 uvicorn[standard]>=0.29 openai>=1.35 python-dotenv>=1.0

.env 存放所有需要经常调整的参数:

DEEPSEEK_API_KEY=sk-这里换成你的Key DEEPSEEK_BASE_URL=https://api.deepseek.com DEEPSEEK_MODEL=deepseek-chat REPLY_PROBABILITY=0.3 PRIVATE_REPLY_PROBABILITY=0.8 COOLDOWN_SECONDS=30 TEMPERATURE=1.0 MAX_TOKENS=400 BOT_NAME=小梦 SYSTEM_PROMPT=你叫小梦,是群里一个普通群友,不是客服。你说话口语化,喜欢短句,偶尔开玩笑,会用语气词。不要一开口就报解决方案,不要每句话都用感叹号。不要暴露自己是 AI。

把配置放到 .env 而不是写死在代码里,是为了不用改代码就能调概率、换人设、换模型。config.py 负责读取:

import os from dotenv import load_dotenv load_dotenv() DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY", "") DEEPSEEK_BASE_URL = os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com") DEEPSEEK_MODEL = os.getenv("DEEPSEEK_MODEL", "deepseek-chat") REPLY_PROBABILITY = float(os.getenv("REPLY_PROBABILITY", "0.3")) PRIVATE_REPLY_PROBABILITY = float(os.getenv("PRIVATE_REPLY_PROBABILITY", "0.8")) COOLDOWN_SECONDS = float(os.getenv("COOLDOWN_SECONDS", "30")) TEMPERATURE = float(os.getenv("TEMPERATURE", "1.0")) MAX_TOKENS = int(os.getenv("MAX_TOKENS", "400")) BOT_NAME = os.getenv("BOT_NAME", "小梦") SYSTEM_PROMPT = os.getenv("SYSTEM_PROMPT", "")

注意:.env 文件里不要出现中文引号或全角字符,否则解析会失败。API Key 也不要提交到 Git 仓库,建议把 .env 写入 .gitignore。

4.2 OneBot 事件上报接收端

主程序用 FastAPI 提供一个 POST 接口,路径和 OneBot 框架里配置的上报地址保持一致。核心逻辑是过滤事件类型:

from fastapi import FastAPI, Request app = FastAPI() @app.post("/onebot") async def onebot_event(request: Request): data = await request.json() # 只处理消息事件,忽略通知、请求等其他事件 if data.get("post_type") != "message": return {} message_type = data.get("message_type") # group 或 private raw_message = data.get("raw_message") or "" user_id = data.get("user_id") self_id = data.get("self_id") # 防止机器人自己触发自己 if not user_id or user_id == self_id: return {} return {}

post_type 是 OneBot 事件类型里最重要的一层过滤。不做这层判断的话,退群通知、好友请求等事件也会进到你的逻辑里,容易干扰判断。

4.3 概率回复与冷却时间

概率回复的实现用 random 模块就够了,但判定顺序要设计好:

import random import re import time last_reply_time = {} def clean_message(raw_message: str) -> str: return re.sub(r"\[CQ:[^\]]*\]", "", raw_message).strip() def is_at_me(raw_message: str, self_id: int) -> bool: return f"[CQ:at,qq={self_id}]" in raw_message def should_reply(raw_message: str, message_type: str, self_id: int) -> bool: if not clean_message(raw_message): return False # 被 @ 必回 if is_at_me(raw_message, self_id): return True # 被叫到名字必回 if config.BOT_NAME and config.BOT_NAME in raw_message: return True # 私聊默认高概率,群聊按配置概率 if message_type == "private": return random.random() < config.PRIVATE_REPLY_PROBABILITY return random.random() < config.REPLY_PROBABILITY

冷却时间用字典记录每个群或每个用户上次回复的时间:

def in_cooldown(chat_key: str, cooldown_seconds: float) -> bool: now = time.time() if now - last_reply_time.get(chat_key, 0) < cooldown_seconds: return True last_reply_time[chat_key] = now return False

冷却时间的意义是防止机器人连续接管聊天节奏。真人不可能每条都接话,所以即使概率命中了,如果 30 秒内刚回过这个群,这次也可以跳过。

4.4 清洗消息并判断是否被 @

raw_message 里带 CQ 码,例如 [CQ:at,qq=123]、[CQ:image,file=...]。如果直接把整段文本送给大模型,会出现两个问题:第一,CQ 码是机器语言,模型很难理解;第二,如果群里只发了一张图,清洗后文本为空,就不该触发回复。

clean_message 的作用就是去掉所有 [CQ:...] 代码,只留纯文本。is_at_me 判断字符串里是否包含指向机器人自身的 CQ 码。这里的 self_id 来自事件上报,是机器人自己的 QQ 号。

4.5 调用 DeepSeek 并返回回复

调用部分用 AsyncOpenAI 异步接口,避免多个群同时发消息时阻塞:

from openai import AsyncOpenAI client = AsyncOpenAI( api_key=config.DEEPSEEK_API_KEY, base_url=config.DEEPSEEK_BASE_URL, ) async def ask_deepseek(user_message: str) -> str: messages = [ {"role": "system", "content": config.SYSTEM_PROMPT}, {"role": "user", "content": user_message}, ] resp = await client.chat.completions.create( model=config.DEEPSEEK_MODEL, messages=messages, temperature=config.TEMPERATURE, max_tokens=config.MAX_TOKENS, stream=False, ) return resp.choices[0].message.content.strip()

拿到模型输出后,直接在 HTTP 响应里返回:

return {"reply": reply}

OneBot 框架收到这个响应后,会把 reply 内容发回触发消息的聊天窗口。如果希望群聊回复时自动 @ 发消息的人,可以在响应里再加 at_sender: true。拟人化场景建议默认不开,除非对方本来就是 @ 机器人的。

4.6 完整 main.py

把上面几块拼起来,完整代码如下:

import logging import random import re import time from fastapi import FastAPI, Request from openai import AsyncOpenAI import config logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s") logger = logging.getLogger("qq-bot") app = FastAPI() client = AsyncOpenAI( api_key=config.DEEPSEEK_API_KEY, base_url=config.DEEPSEEK_BASE_URL, ) last_reply_time = {} def clean_message(raw_message: str) -> str: return re.sub(r"\[CQ:[^\]]*\]", "", raw_message).strip() def is_at_me(raw_message: str, self_id: int) -> bool: return f"[CQ:at,qq={self_id}]" in raw_message def should_reply(raw_message: str, message_type: str, self_id: int) -> bool: if not clean_message(raw_message): return False if is_at_me(raw_message, self_id): return True if config.BOT_NAME and config.BOT_NAME in raw_message: return True if message_type == "private": return random.random() < config.PRIVATE_REPLY_PROBABILITY return random.random() < config.REPLY_PROBABILITY def in_cooldown(chat_key: str, cooldown_seconds: float) -> bool: now = time.time() if now - last_reply_time.get(chat_key, 0) < cooldown_seconds: return True last_reply_time[chat_key] = now return False async def ask_deepseek(user_message: str) -> str: messages = [ {"role": "system", "content": config.SYSTEM_PROMPT}, {"role": "user", "content": user_message}, ] resp = await client.chat.completions.create( model=config.DEEPSEEK_MODEL, messages=messages, temperature=config.TEMPERATURE, max_tokens=config.MAX_TOKENS, stream=False, ) return resp.choices[0].message.content.strip() @app.post("/onebot") async def onebot_event(request: Request): try: data = await request.json() except Exception: return {} if data.get("post_type") != "message": return {} message_type = data.get("message_type") raw_message = data.get("raw_message") or "" user_id = data.get("user_id") self_id = data.get("self_id") if not user_id or user_id == self_id: return {} if not should_reply(raw_message, message_type, self_id): return {} chat_key = str(data.get("group_id") or data.get("user_id") or user_id) if in_cooldown(chat_key, config.COOLDOWN_SECONDS): return {} user_message = clean_message(raw_message) if not user_message: return {} logger.info("触发回复 chat=%s user=%s msg=%s", chat_key, user_id, user_message) try: reply = await ask_deepseek(user_message) except Exception as exc: logger.exception("DeepSeek 调用失败: %s", exc) return {} logger.info("模型回复: %s", reply) return {"reply": reply}

这个版本是学习环境的最小闭环。生产环境还要把日志落盘、加入重试、补充敏感词过滤和更完善的上下文管理。

5. 启动运行与效果验证

5.1 启动顺序与命令

先启动 OneBot 框架并登录 QQ 小号,确认框架已经在线,再启动 Python 服务:

python -m uvicorn main:app --host 0.0.0.0 --port 8765

监听地址用 0.0.0.0,这样即使 OneBot 框架和 Python 服务不在同一台机器,也能通过内网 IP 访问。如果都在本机,用 127.0.0.1 也可以。启动后看到类似下面的日志,说明服务已经就绪:

INFO: Uvicorn running on http://0.0.0.0:8765 INFO: Application startup complete.

5.2 用 curl 模拟一条群消息

在真实登录 QQ 之前,先用 curl 模拟一条 OneBot 上报,验证接收和回复逻辑:

curl -X POST http://127.0.0.1:8765/onebot \ -H "Content-Type: application/json" \ -d '{ "post_type": "message", "message_type": "group", "group_id": 123456789, "user_id": 987654321, "self_id": 111222333, "raw_message": "小梦在吗", "sender": {"user_id": 987654321, "nickname": "测试用户"} }'

因为消息里包含了机器人名字“小梦”,should_reply 会直接返回 True,不需要碰概率。正常响应类似:

{"reply":"在呀,刚看完剧,怎么啦?"}

如果消息不包含名字,例如只发“今天天气怎么样”,那就要看概率是否命中了。没命中时响应是:

{}

这一步能帮你快速确认 FastAPI 服务、DeepSeek 调用、概率判定三个环节是否正常。如果你在 Windows 命令行里粘贴中文遇到编码问题,可以改用 Python 的 requests 脚本发送同样的 JSON。

5.3 真机测试:私聊、群聊、概率观察

curl 验证通过后,再用 QQ 小号真机测试。建议顺序是:

  1. 先用私聊测试,因为私聊不会打扰别人,而且默认概率是 0.8,更容易触发。
  2. 私聊正常后,再拉一个小群,先发一条包含机器人名字的消息,确认群回复正常。
  3. 最后把概率调到 1.0 观察一两次群聊链路,确认无误后再调回 0.3。

可以在 .env 里临时把 REPLY_PROBABILITY 改成 1.0,重启服务验证,验证完改回来。这样能避免在群里发十几条消息都因为概率问题以为程序坏了。

注意:验证链路时临时把概率调到 1.0,验证完记得改回来,否则机器人会回复群里每条消息,很容易被当成骚扰。

5.4 日志怎么看

main.py 里的 logging 会输出三类关键信息:触发记录、模型回复、异常堆栈。例如:

2025-01-12 21:03:15 [INFO] 触发回复 chat=123456789 user=987654321 msg=小梦在吗 2025-01-12 21:03:18 [INFO] 模型回复: 在呀,刚看完剧,怎么啦?

日志里建议至少包含三个信息:哪个会话触发的、用户原始消息是什么、模型最终回复是什么。排查“群里有人问为什么没回”时,先看日志里有没有触发记录,有触发记录再看模型是否报错,没有触发记录就说明是概率或冷却跳过了。

6. 常见问题排查:从“不回复”到“回复太假”

6.1 先按链路顺序排查

遇到问题不要乱改配置,按下面顺序来:

  1. 输入是否正确:消息是否真的上报到了本地服务,可以用 curl 模拟验证。
  2. 文件路径和命名:config.py、.env、main.py 是否在同一目录,有没有拼错文件名。
  3. 依赖版本:openai、fastapi 版本是否过低或不兼容。
  4. 配置是否生效:启动时打印一份 config 里的关键参数,确认 .env 被正确读取。
  5. 端口和网络:OneBot 框架能否访问到 Python 服务的地址,防火墙有没有拦截。
  6. 日志异常:FastAPI 日志、DeepSeek 返回内容、框架日志是否有明确报错。

6.2 典型问题汇总

问题现象常见原因检查方式处理建议
机器人完全不回复OneBot 上报地址没配或配错看框架日志、curl 测本地接口把上报地址指到 http://127.0.0.1:8765/onebot
curl 有回复,QQ 里没回复框架登录态异常、发送频率过高看框架日志,换小号测试重新登录,降低频率,避免短时间连续发消息
API 报 401Key 写错或无效检查 .env 是否有多余空格重新复制 Key
API 报 402账户欠费查看开放平台余额充值后重试
API 报 429触发限流看返回内容增加重试和退避,降低调用频率
概率回复不生效.env 没加载成功启动时打印 REPLY_PROBABILITY确认 load_dotenv 生效
回复像客服人设不够具体、temperature 太低打印实际使用的 SYSTEM_PROMPT重写人设,调高 temperature
纯图片或表情消息也触发没清洗 CQ 码打印 raw_message用 clean_message 清洗后判断空文本
部署到服务器后收不到消息上报地址写了 127.0.0.1检查 OneBot 配置改成服务器内网或公网可达地址

6.3 关于 thinking mode 的 reasoning_content 报错

如果使用深度思考类模型,或者经过某个代理层、封装工具转发请求,可能会看到类似这样的报错:

upstream_status: http 400 cause: the reasoning_content in the thinking mode must be passed back to the api.

这个报错的含义是:思考模式下接口第一次返回的内容里带有 reasoning_content 字段,如果客户端或代理没有把它缓存下来,下一次请求时也没有原样传回,接口会拒绝继续对话。排查方向有三个:

  1. 日常拟人聊天一般不需要思考链,改用普通对话模型 deepseek-chat,问题自然消失。
  2. 如果确实要用思考模式,需要按官方文档处理 reasoning_content 字段,或者确认你使用的封装工具支持自动处理。
  3. 先分清报错来自官方 API 还是本地代理层,再看请求体里的 messages 是否携带了完整字段。

社区里出现的一些封装工具,本质是把 Key、模型和 API 调用包装成更顺手的入口。遇到这类报错时,不要只盯着工具界面,要回到 API 请求本身去排查。

7. 最佳实践与扩展方向

7.1 拟人化不只是概率

概率回复只是第一步,拟人化还有几件值得做的事:

  1. 随机延迟。真人看到消息不会秒回。要做得更自然,可以把回复从“快速回复”改成调用 OneBot 的动作接口,在发送前随机等待 1 到 3 秒。
  2. 不用句句带名字。真人很少每句话都喊对方名字,默认回复时不要总是 @ 对方,除非消息本身是 @ 过来的。
  3. 保留上下文。把最近几条群消息作为历史消息传给模型,它才能接上话题。但要注意控制长度,历史消息超过一定数量就截断。
  4. 拒绝能力。遇到不友好或者不想接的话题,人设里要允许模型岔开话题,而不是硬聊。
  5. 不回复机器人自己。代码里已经用 user_id == self_id 过滤了,部署时不要把这个判断删掉。

7.2 成本、频率和安全性控制

API 是按 tokens 计费的,拟人化聊天如果每条都调模型,一天下来成本并不低。控制成本的手段主要有三个:

  • 概率和关键词双重门槛,让真正值得回复的消息才调用 API。
  • max_tokens 限制在 400 左右,人设里明确要求“回复不超过三句话”。
  • 上下文只保留最近对话,避免每次请求都携带一长串历史。

安全性方面,至少要加一份关键词过滤清单。命中违法、暴力、色情等相关内容时,让机器人回复“不太想聊这个”或者直接不回复。不要指望大模型自带的安全能力覆盖所有场景,对外提供服务时,过滤必须在自己这层做。

7.3 部署到服务器时的额外工作

学习环境跑通后,如果要让机器人长期在线,还需要:

  • 用 systemd 或 supervisor 守护进程,服务崩溃后自动重启。
  • 日志写到文件,并按天切割,方便回溯问题。
  • API Key 放到服务端环境变量,避免写在代码仓库里。
  • 给 OneBot 框架配置 token,防止本地服务被外部直接 POST 伪造事件。
  • 上线前在测试群跑一段时间,观察回复质量、频率和账号稳定性。

7.4 下一步可以做的扩展

这套主程序的扩展点很多:同一个服务对接多个群,每个群配不同人设;把 DeepSeek 换成其他 OpenAI 兼容接口,例如本地部署的模型服务,主程序几乎不用改;在回复前加一层知识库检索,让机器人能回答群专属问题;把消息记录存到数据库,后续做数据分析和回复效果评估。

对新手来说,最有价值的练习不是急着加功能,而是把现有链路反复调试到稳定:概率、冷却、清洗、日志、异常处理,每一个环节都值得单独验证一遍。链路稳定之后,再往上加“更像人”的功能,才不会越加越乱。

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

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

立即咨询