news 2026/7/22 0:00:31

基于 Python + DeepSeek 的 QQ 私聊智能机器人项目实战(附核心源代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 Python + DeepSeek 的 QQ 私聊智能机器人项目实战(附核心源代码)

基于 Python + DeepSeek 的 QQ 私聊智能机器人项目实战(附核心源代码)

最近自己做了一个 QQ 私聊 AI 机器人,原本只是想简单接一个大模型接口做聊天,后来越做越多,就慢慢给它加上了 长期记忆、定时提醒、网页配置后台 这些功能。

到现在,这个项目已经不只是“发一句回一句”的聊天机器人了,而更像是一个轻量级的个人智能助手系统。

这篇文章我就把整个项目的思路、功能拆分和核心代码整理出来,方便自己留档,也给想做类似项目的朋友一个参考。

---

一、项目能做什么

目前这个 QQ 机器人主要实现了下面几类功能:

1. QQ 私聊对话

用户在 QQ 私聊窗口给机器人发消息,机器人后端收到消息后,会调用 DeepSeek API 生成回复,再把结果发送回 QQ。

整体流程是:

QQ用户发消息 -> Python后端接收 -> 调用DeepSeek -> 回发到QQ

---

2. 长期记忆

这个功能主要是为了让机器人不只是“看当前一句话”,而是能逐渐记住用户。

比如用户可以发:

记住:我喜欢吃辣

或者:

记住:我平时用 Windows

这些内容会被保存到本地 JSON 文件里。后续机器人在调用 DeepSeek 时,会把这些记忆一起带上,让回答更符合当前用户的习惯和信息。

---

3. 定时任务

这个模块让机器人具备“主动发消息”的能力。

比如:

每天晚上提醒学习

固定时间发送通知

后续扩展随机时间发消息

任务信息会持久化保存,因此程序重启后不会丢失。

---

4. 网页可视化配置

为了避免每次改提示词或任务都去手动改代码,我还做了一个简单的网页控制台。

这个网页可以用来:

修改系统提示词

配置机器人参数

添加 / 删除定时任务

导出配置

---

二、项目使用的技术栈

这个项目目前的技术栈并不复杂,主要包括:

Python

Flask

QQ 机器人接口

DeepSeek API

本地 JSON 存储

HTML + JavaScript

整体目标不是堆很多框架,而是尽量用简单、容易维护的方式,把功能真正跑通。

---

三、项目目录结构

我这里给一个比较简单的目录结构参考:

project/

├── app.py

├── config.json

├── memories.json

├── index.html

说明:

app.py:主后端程序

config.json:保存机器人配置和任务

memories.json:保存每个用户的长期记忆

index.html:网页配置后台

---

四、核心源代码

下面给出一版核心代码示例。

---

1. 配置和记忆文件读写

这一部分负责把配置和记忆持久化保存到本地。

import os

import json

from copy import deepcopy

from threading import Lock

CONFIG_FILE = "config.json"

MEMORY_FILE = "memories.json"

LOCK = Lock()

DEFAULT_CONFIG = {

"prompt": "你是一个有帮助的 QQ 私聊助手。回答简洁、自然、中文优先。",

"bot": {

"appId": "",

"secret": "",

"apiKey": "",

"baseUrl": "https://api.deepseek.com",

"model": "deepseek-chat",

"autoReply": True

},

"tasks": []

}

def load_json_file(path, default_value):

with LOCK:

if not os.path.exists(path):

with open(path, "w", encoding="utf-8") as f:

json.dump(default_value, f, ensure_ascii=False, indent=2)

return deepcopy(default_value)

with open(path, "r", encoding="utf-8") as f:

try:

return json.load(f)

except Exception:

return deepcopy(default_value)

def save_json_file(path, data):

with LOCK:

with open(path, "w", encoding="utf-8") as f:

json.dump(data, f, ensure_ascii=False, indent=2)

def load_config():

data = load_json_file(CONFIG_FILE, DEFAULT_CONFIG)

merged = deepcopy(DEFAULT_CONFIG)

merged.update(data)

if isinstance(data.get("bot"), dict):

merged["bot"].update(data["bot"])

if not isinstance(merged.get("tasks"), list):

merged["tasks"] = []

return merged

def save_config(data):

save_json_file(CONFIG_FILE, data)

def load_memories():

data = load_json_file(MEMORY_FILE, {})

return data if isinstance(data, dict) else {}

def save_memories(data):

save_json_file(MEMORY_FILE, data)

---

2. 长期记忆功能

这一部分负责记忆的增删改查。

def get_user_memories(user_openid):

memories = load_memories()

items = memories.get(user_openid, [])

return items if isinstance(items, list) else []

def add_user_memory(user_openid, content):

memories = load_memories()

items = memories.get(user_openid, [])

if not isinstance(items, list):

items = []

content = content.strip()

if not content:

return False

if content not in items:

items.append(content)

memories[user_openid] = items

save_memories(memories)

return True

def remove_user_memory(user_openid, content):

memories = load_memories()

items = memories.get(user_openid, [])

if not isinstance(items, list):

return False

if content in items:

items.remove(content)

memories[user_openid] = items

save_memories(memories)

return True

return False

def clear_user_memory(user_openid):

memories = load_memories()

memories[user_openid] = []

save_memories(memories)

return True

def format_user_memories(user_openid):

items = get_user_memories(user_openid)

if not items:

return "暂无长期记忆。"

return "长期记忆:\n" + "\n".join(f"- {x}" for x in items)

---

3. DeepSeek 调用代码

这里是调用大模型的核心逻辑。

from openai import OpenAI

def build_deepseek_client():

config = load_config()

bot_cfg = config["bot"]

return OpenAI(

api_key=bot_cfg.get("apiKey", ""),

base_url=bot_cfg.get("baseUrl", "https://api.deepseek.com")

)

def build_messages(user_openid, user_text, session_histories):

config = load_config()

prompt = config.get("prompt", DEFAULT_CONFIG["prompt"])

memories = get_user_memories(user_openid)

messages = [{"role": "system", "content": prompt}]

if memories:

memory_text = "以下是该用户的长期记忆,请在回答时适当参考:\n" + "\n".join(

f"- {m}" for m in memories

)

messages.append({"role": "system", "content": memory_text})

messages.extend(session_histories[user_openid])

messages.append({"role": "user", "content": user_text})

return messages

def ask_deepseek(user_openid, user_text, session_histories):

config = load_config()

model = config["bot"].get("model", "deepseek-chat")

client = build_deepseek_client()

messages = build_messages(user_openid, user_text, session_histories)

response = client.chat.completions.create(

model=model,

messages=messages,

stream=False,

timeout=30,

)

reply = response.choices[0].message.content or ""

return reply.strip() or "我刚刚没有生成有效回复。"

---

4. QQ 私聊消息处理

这里是机器人最核心的交互部分。

from collections import defaultdict

session_histories = defaultdict(list)

MAX_HISTORY = 10

def save_history(user_openid, user_text, assistant_text):

history = session_histories[user_openid]

history.append({"role": "user", "content": user_text})

history.append({"role": "assistant", "content": assistant_text})

max_items = MAX_HISTORY * 2

if len(history) > max_items:

session_histories[user_openid] = history[-max_items:]

如果你已经接好了 QQ 机器人 SDK,那么在收到私聊消息时,可以这样处理命令:

def handle_user_message(user_openid, user_text):

lower = user_text.lower().strip()

if lower in ("我的记忆", "查看记忆", "记忆"):

return format_user_memories(user_openid)

if lower in ("清空记忆",):

clear_user_memory(user_openid)

return "长期记忆已清空。"

if user_text.startswith("记住:") or user_text.startswith("记住:"):

content = user_text.split(":", 1)[1] if ":" in user_text else user_text.split(":", 1)[1]

content = content.strip()

if not content:

return "要记住的内容不能为空。"

add_user_memory(user_openid, content)

return f"已记住:{content}"

if user_text.startswith("忘记:") or user_text.startswith("忘记:"):

content = user_text.split(":", 1)[1] if ":" in user_text else user_text.split(":", 1)[1]

content = content.strip()

ok = remove_user_memory(user_openid, content)

return "已删除该记忆。" if ok else "没有找到这条记忆。"

reply = ask_deepseek(user_openid, user_text, session_histories)

save_history(user_openid, user_text, reply)

return reply

---

5. 定时任务系统

这是一个最基础的每日提醒逻辑。

import time

from datetime import datetime

def normalize_task(task):

task = deepcopy(task)

task.setdefault("id", str(int(time.time() * 1000)))

task.setdefault("enabled", True)

task.setdefault("type", "daily")

task.setdefault("time", "18:30")

task.setdefault("content", "")

task.setdefault("targetOpenid", "")

task.setdefault("createdAt", datetime.now().isoformat())

task.setdefault("lastRunAt", "")

return task

def should_run_task(task, now_dt):

if not task.get("enabled", True):

return False

task_time = task.get("time", "18:30")

last_run_at = task.get("lastRunAt", "")

try:

hour, minute = map(int, task_time.split(":"))

except Exception:

return False

today_run = now_dt.replace(hour=hour, minute=minute, second=0, microsecond=0)

if now_dt < today_run:

return False

if not last_run_at:

return True

try:

last_run = datetime.fromisoformat(last_run_at)

except Exception:

return True

return last_run.date() < now_dt.date()

发送消息的地方,这里先用打印模拟:

def send_qq_message(task):

target = task.get("targetOpenid") or "未指定用户"

content = task.get("content", "").strip()

print("=" * 50)

print("触发定时任务")

print("目标:", target)

print("内容:", content)

print("时间:", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

print("=" * 50)

return True

调度循环:

def scheduler_loop():

while True:

try:

config = load_config()

changed = False

now_dt = datetime.now()

for i, raw_task in enumerate(config["tasks"]):

task = normalize_task(raw_task)

config["tasks"][i] = task

if should_run_task(task, now_dt):

ok = send_qq_message(task)

if ok:

task["lastRunAt"] = now_dt.isoformat()

changed = True

if changed:

save_config(config)

except Exception as e:

print("定时循环异常:", repr(e))

time.sleep(5)

---

6. Flask 后台接口

为了给网页配置页提供接口,我这里加了 Flask。

from flask import Flask, jsonify, request, send_from_directory

app = Flask(__name__, static_folder=".", static_url_path="")

@app.route("/")

def index():

return send_from_directory(".", "index.html")

@app.route("/api/config", methods=["GET"])

def get_config_api():

return jsonify(load_config())

@app.route("/api/config", methods=["POST"])

def update_config_api():

data = request.get_json(force=True)

if not isinstance(data, dict):

return jsonify({"ok": False, "error": "配置格式错误"}), 400

config = deepcopy(DEFAULT_CONFIG)

config.update(data)

if isinstance(data.get("bot"), dict):

config["bot"].update(data["bot"])

tasks = data.get("tasks", [])

if not isinstance(tasks, list):

return jsonify({"ok": False, "error": "tasks 必须是数组"}), 400

config["tasks"] = [normalize_task(t) for t in tasks]

save_config(config)

return jsonify({"ok": True, "config": config})

启动:

import threading

def start_scheduler():

t = threading.Thread(target=scheduler_loop, daemon=True)

t.start()

if __name__ == "__main__":

start_scheduler()

app.run(host="0.0.0.0", port=5000, debug=True)

---

五、前端网页配置页示例

前端我做成了一个单文件 HTML,双击也能看,配合 Flask 也能跑。

下面只放一个最精简的思路代码:

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<title>QQ机器人控制台</title>

</head>

<body>

<h1>QQ机器人配置</h1>

<label>系统提示词</label><br>

<textarea id="prompt" rows="6" cols="60"></textarea><br><br>

<button onclick="saveConfig()">保存配置</button>

<script>

async function loadConfig() {

const res = await fetch('/api/config');

const data = await res.json();

document.getElementById('prompt').value = data.prompt || '';

}

async function saveConfig() {

const prompt = document.getElementById('prompt').value;

const res = await fetch('/api/config', {

method: 'POST',

headers: {'Content-Type': 'application/json'},

body: JSON.stringify({

prompt: prompt,

bot: {},

tasks: []

})

});

const data = await res.json();

alert(data.ok ? '保存成功' : '保存失败');

}

loadConfig();

</script>

</body>

</html>

---

六、项目运行方式

1. 安装依赖

pip install flask openai

如果你还要接 QQ 官方机器人 SDK,再安装对应 SDK。

2. 准备配置文件

config.json

{

"prompt": "你是一个有帮助的 QQ 私聊助手。回答简洁、自然、中文优先。",

"bot": {

"appId": "",

"secret": "",

"apiKey": "你的DeepSeekKey",

"baseUrl": "https://api.deepseek.com",

"model": "deepseek-chat",

"autoReply": true

},

"tasks": []

}

memories.json

{}

3. 启动后端

python app.py

4. 浏览器打开后台

http://127.0.0.1:5000

---

七、项目特点总结

我觉得这个项目最有意思的地方在于,它已经不是一个纯粹的“聊天 Demo”了,而开始具备一些真正像助手的能力。

它的特点可以概括成:

能聊天

能记住用户

能主动提醒

能在网页里改配置

结构清晰,方便继续扩展

后面如果继续往下做,还可以继续加:

随机时间自动发消息

工作流逻辑

可视化任务管理

更多记忆策略

更完整的后台系统

---

八、总结

这个 QQ 私聊机器人项目,本质上是一个基于 Python 搭建的小型 AI 助手系统。它结合了 DeepSeek 的对话能力、长期记忆、定时任务以及网页配置后台,不再只是一个“问一句答一句”的实验项目,而是具备了进一步扩展成完整智能助手的基础。

如果你也想自己练一个“从聊天机器人走向智能助手”的项目,这个方向还是很适合拿来练手的。

---

如果你要,我下一条可以继续给你两样东西里的一个:

1. 整合后的完整 app.py 成品版

2. 适合 CSDN 直接发布的完整排版版文章

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/13 15:10:07

医院电子病历系统怎样优化PDF文档导入速度?

项目需求分析与技术方案 作为项目负责人&#xff0c;针对企业网站后台管理系统富文本编辑器升级需求&#xff0c;结合信创国产化、多浏览器兼容、云存储集成等核心要求&#xff0c;现提出以下技术方案&#xff1a; 一、核心功能实现方案 Word/公众号内容粘贴功能 前端实现&…

作者头像 李华
网站建设 2026/7/14 14:13:31

如何在ESP32上构建你的AI伙伴:Xiaozhi-ESP32开源项目深度探索

如何在ESP32上构建你的AI伙伴&#xff1a;Xiaozhi-ESP32开源项目深度探索 【免费下载链接】xiaozhi-esp32 Build your own AI friend 项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32 你是否曾想过将大型语言模型的能力带到嵌入式设备上&#xff1f;当…

作者头像 李华
网站建设 2026/7/14 14:13:30

用MATLAB复刻经典电话通信:手把手教你实现PCM编码与双机文件传输

用MATLAB复刻经典电话通信&#xff1a;手把手教你实现PCM编码与双机文件传输 在数字通信技术飞速发展的今天&#xff0c;回望模拟电话系统的数字化历程依然充满教学价值。本文将带您用MATLAB完整复现一个微型电话通信系统&#xff0c;从声音采集、PCM编码到双机文件传输&#x…

作者头像 李华
网站建设 2026/7/14 14:13:30

【Keepalived】主备模式MASTER/BACKUP的vrrp实例配置详解

前情提要&#xff1a;本篇博客将介绍使用Keepalived搭建主从架构的vrrp实例的全部流程&#xff0c;通过本篇博客你可以学会搭建vrrp实例环境&#xff1a;系统&#xff1a;RHEL9.3Keepalived版本&#xff1a;Keepalived v2.2.8 (04/04,2023)1、配置MASTER主机编辑配置文件# 编辑…

作者头像 李华
网站建设 2026/7/14 14:13:28

verilog语法-使用function提高效率

1、function的使用场景function的作用返回一个数值&#xff0c;此数值由一串组合逻辑代码计算得到。那为什么要用function呢?主要有两大原因&#xff1a;a)当组合逻辑实现的功能比较复杂&#xff0c;无法用少量代码完成编写&#xff0c;使用function替代&#xff0c;不用在alw…

作者头像 李华
网站建设 2026/7/14 14:13:28

思科Nexus交换机 --- 华为CE6800 STP生成树对接故障

思科Nexus93180与华为6857&#xff08;堆叠&#xff09;2层互联。 STP MODE&#xff1a; 思科&#xff1a;RSTP-PVST 华为&#xff1a;RSTP STP Priority: 思科&#xff1a;32768 华为&#xff1a;49152 先说结论&#xff1a;思科的RSTP不是标准的RSTP&#xff0c;而是pvst的增…

作者头像 李华