news 2026/8/21 20:29:02

用Python打造AI监督桌宠:开源项目my_ai_town实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python打造AI监督桌宠:开源项目my_ai_town实战指南

你是不是也经常这样:打开电脑准备写代码,结果刷了半小时手机;计划今天完成一个功能模块,结果在调试环境上耗了一下午;明明想学习新技术,却总被各种琐事打断。自律这件事,对开发者来说,有时候比解决一个技术难题还难。

今天要聊的,就是一个用“魔法”打败“魔法”的解决方案——一个开源的桌面宠物(桌宠)。但它不是普通的卖萌小猫,而是一条会“监督”你工作的“蓝色大肥鱼”。这个项目在 GitHub 上叫my_ai_town,它把 AI 智能体(Agent)的概念,从云端搬到了你的桌面上,变成了一个具象化的、有互动的“工作伙伴”。

这篇文章要解决的,远不止“如何运行一个桌宠程序”。我们真正要探讨的是:如何利用开源技术和 AI 能力,为自己构建一个低成本、高趣味性的“外部监督系统”。对于独立开发者、远程工作者、自由职业者或者任何需要对抗拖延症的程序员来说,这或许是一个将技术用于自我提升的绝佳实践。

我们将从这条“蓝色大肥鱼”出发,拆解一个开源桌宠项目的完整实现,包括环境搭建、核心原理、代码解读,并最终让你能定制属于自己的“数字监工”。你会发现,它背后串联起了 Python 桌面应用开发、跨平台 GUI、简单的 AI 交互逻辑,以及最重要的——如何将个人需求转化为一个有趣的 Side Project。

1. 核心痛点:我们为什么需要一个“桌宠监工”?

在深入代码之前,我们先明确需求。传统的待办事项(Todo List)或番茄钟(Pomodoro)应用是“被动”的,它们安静地躺在那里,等你主动去看、去操作。而“监工桌宠”的设计理念是“主动”的,它通过视觉存在感和随机互动,创造一种轻微的“被注视”压力,从而提升你的专注度。

这解决了几个具体问题:

  1. 视觉提醒:一个始终在桌面角落活动的角色,比系统通知栏的一个图标更具提醒效力。
  2. 情感化交互:将枯燥的“工作时间到”提示,转化为“小鱼盯着你,催你干活”的趣味场景,降低心理抵触。
  3. 低侵入性监督:它不会像某些强制锁屏软件一样粗暴地打断你,而是通过存在感进行温和的督促,更适合需要创造性思考的编程工作。
  4. 技术人的浪漫:自己动手,用代码创造一个独一无二的“伙伴”,这个过程本身就有极大的成就感和驱动力。

my_ai_town项目提供的,正是一个可高度自定义的基座。你得到的不仅是一条鱼,更是一个能够理解简单指令、做出反馈的智能体框架。

2. 项目概览与技术栈选择

根据项目信息,my_ai_town是一个开源项目,其核心是创建一个具有简单 AI 行为的桌面宠物。从“桌宠开发 Python”等热词可以推断,其技术栈很可能以 Python 为主。

一个典型的桌面宠物项目会涉及以下技术层面:

  • GUI 框架:用于创建无边框、可拖动、始终置顶的窗口。常见选择有PyQt5/PySide6TkinterKivy,或者更轻量的pywebview+ HTML/JS。
  • 图形渲染:显示宠物动画。可以是Pygame(适合2D精灵动画),或是直接使用 GUI 框架的QLabel加载 GIF/APNG 序列帧。
  • 行为逻辑:控制宠物何时移动、做什么动作、如何响应事件(如点击、拖拽)。这部分是“大脑”。
  • AI 集成(可选进阶):为宠物注入更智能的交互能力。例如,集成一个轻量级本地 LLM(大语言模型)或调用云端 AI API,让宠物能进行简单的对话或根据你的活动(如键盘鼠标静止时长)做出提醒。

my_ai_town项目名中的 “AI Town” 暗示了其可能包含多智能体模拟或更复杂的 AI 行为树,但作为桌宠,我们可以先聚焦于其最核心的桌面交互部分。

3. 环境准备与项目初始化

在开始之前,请确保你的开发环境已经就绪。我们将以最通用的 Python 环境为例进行说明。

3.1 基础环境

  • 操作系统:Windows 10/11, macOS, 或 Linux(本文以 Windows 为例,其他系统类似)。
  • Python 版本:建议使用 Python 3.8 及以上版本。你可以通过命令行检查:
    python --version # 或 python3 --version
  • 包管理工具pip应已随 Python 安装。

3.2 获取项目代码

访问项目 GitHub 仓库(假设地址为https://github.com/mewamew/my_ai_town,根据输入材料),使用git克隆到本地:

git clone https://github.com/mewamew/my_ai_town.git cd my_ai_town

如果未安装git,也可以直接下载项目的 ZIP 包并解压。

3.3 创建虚拟环境(强烈推荐)

为避免依赖冲突,为项目创建独立的 Python 虚拟环境。

# 在项目根目录下 python -m venv venv

激活虚拟环境:

  • Windows (CMD/PowerShell):
    .\venv\Scripts\activate
  • macOS/Linux:
    source venv/bin/activate

激活后,命令行提示符前通常会显示(venv)

3.4 安装依赖

查看项目根目录下是否存在requirements.txtpyproject.toml文件。这是安装依赖的关键。

# 如果存在 requirements.txt pip install -r requirements.txt # 或者,如果使用 poetry 等工具,请参照项目 README

注意:如果项目没有提供明确的依赖文件,你需要根据其代码中import的库来手动安装。一个典型的桌宠项目可能依赖:

pip install PyQt5 pygame pillow numpy

具体依赖需以项目实际代码为准。

4. 项目结构与核心原理拆解

在运行项目前,我们先剖析一下它的目录结构,这能帮助我们理解其设计思路。一个组织良好的桌宠项目可能包含以下部分:

my_ai_town/ ├── assets/ # 资源文件夹 │ ├── sprites/ # 宠物精灵图(PNG序列或GIF) │ │ └── blue_fat_fish/ # “蓝色大肥鱼”的所有动画帧 │ ├── sounds/ # 音效文件 │ └── config/ # 配置文件 ├── src/ # 源代码 │ ├── pet_engine.py # 宠物行为引擎核心类 │ ├── ui_window.py # 主窗口和GUI逻辑 │ ├── ai_agent.py # AI交互逻辑(如果存在) │ └── utils.py # 工具函数 ├── main.py # 程序入口点 ├── requirements.txt # Python依赖列表 └── README.md # 项目说明文档

4.1 核心原理:一个桌宠是如何工作的?

一个基本的桌宠程序,其运行循环可以概括为以下几步:

  1. 创建透明置顶窗口:使用 GUI 库创建一个没有标题栏、边框的窗口,并设置为“始终在最前面”。
  2. 加载与显示动画:将宠物的图片资源(通常是带透明通道的 PNG 序列)加载到内存,并在窗口中按一定帧率循环播放,形成动画效果。
  3. 实现交互逻辑
    • 拖动:监听鼠标事件,当鼠标在宠物图像上按下并移动时,更新窗口位置。
    • 点击反馈:监听点击事件,触发特定的动画(如跳跃、生气)或播放音效。
    • 随机行为:通过一个定时器,让宠物在一定时间间隔后自动执行一些动作,如走动、睡觉、切换表情。
  4. 集成“监督”逻辑(本项目重点):这是区别于普通桌宠的关键。程序需要监控用户的活动状态(例如,通过监听全局键盘鼠标事件,或检测特定应用窗口是否活跃),并根据规则触发宠物的“监督”行为。例如,当检测到用户超过30分钟未活动(可能在看视频),宠物就播放一个“催促工作”的动画和音效。

5. 核心代码实现与解读

让我们基于通用模式,构建一个简化版的“监督桌宠”核心代码。即使my_ai_town的具体实现不同,以下代码也能帮助你理解其骨架。

5.1 主窗口与宠物显示(使用 PyQt5)

我们选择PyQt5作为 GUI 框架,因为它功能强大、跨平台,且能轻松实现透明窗口和图形渲染。

文件:main.py

import sys import random from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel from PyQt5.QtCore import Qt, QTimer, QPoint, pyqtSignal from PyQt5.QtGui import QMovie, QPixmap import ctypes import time class DesktopPet(QMainWindow): # 定义一个信号,用于触发监督行为 urge_to_work = pyqtSignal() def __init__(self): super().__init__() self.initUI() self.initPetBehavior() self.initMonitorTimer() def initUI(self): # 设置窗口属性:无边框、透明、置顶 self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool) self.setAttribute(Qt.WA_TranslucentBackground) # 创建一个标签用于显示宠物动画(GIF) self.pet_label = QLabel(self) self.movie = QMovie(‘assets/sprites/blue_fat_fish/idle.gif‘) # 假设有 idle 动画 self.pet_label.setMovie(self.movie) self.movie.start() # 设置窗口大小匹配动画大小 self.resize(self.movie.frameRect().size()) self.setFixedSize(self.size()) # 固定大小 # 初始位置放在屏幕右下角 screen_geometry = QApplication.desktop().screenGeometry() self.move(screen_geometry.width() - self.width() - 50, screen_geometry.height() - self.height() - 50) self.show() def initPetBehavior(self): """初始化宠物的随机行为定时器""" self.behavior_timer = QTimer(self) self.behavior_timer.timeout.connect(self.randomAction) self.behavior_timer.start(10000) # 每10秒触发一次随机行为 # 连接监督信号到具体的反馈动作 self.urge_to_work.connect(self.onUrgeToWork) def initMonitorTimer(self): """初始化用户活动监控定时器""" self.monitor_timer = QTimer(self) self.monitor_timer.timeout.connect(self.checkUserActivity) self.monitor_timer.start(60000) # 每60秒检查一次 self.last_activity_time = time.time() self.idle_threshold = 30 * 60 # 30分钟无活动视为闲置 def mousePressEvent(self, event): """鼠标按下事件,用于拖动窗口""" if event.button() == Qt.LeftButton: self.drag_position = event.globalPos() - self.frameGeometry().topLeft() event.accept() def mouseMoveEvent(self, event): """鼠标移动事件,实现拖动""" if event.buttons() == Qt.LeftButton and hasattr(self, ‘drag_position‘): self.move(event.globalPos() - self.drag_position) event.accept() def randomAction(self): """宠物随机执行的动作,如眨眼、走动、跳跃""" actions = [‘blink‘, ‘move_slightly‘, ‘change_expression‘] action = random.choice(actions) # 这里可以切换不同的动画GIF if action == ‘blink‘: self.movie.stop() self.movie = QMovie(‘assets/sprites/blue_fat_fish/blink.gif‘) self.pet_label.setMovie(self.movie) self.movie.start() QTimer.singleShot(500, self.restoreIdle) # 0.5秒后恢复待机 def restoreIdle(self): """恢复待机动画""" self.movie.stop() self.movie = QMovie(‘assets/sprites/blue_fat_fish/idle.gif‘) self.pet_label.setMovie(self.movie) self.movie.start() def checkUserActivity(self): """检查用户是否在闲置(简化版:仅检查时间间隔)""" # 注意:实际项目中,获取系统空闲时间需要调用系统API,以下为Windows示例 try: class LASTINPUTINFO(ctypes.Structure): _fields_ = [(“cbSize“, ctypes.c_uint), (“dwTime“, ctypes.c_uint)] lastInputInfo = LASTINPUTINFO() lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo) ctypes.windll.user32.GetLastInputInfo(ctypes.byref(lastInputInfo)) idle_time = (ctypes.windll.kernel32.GetTickCount() - lastInputInfo.dwTime) // 1000 # 转换为秒 except Exception: # 跨平台或备用方案:使用简单的时长判断(不精确) current_time = time.time() idle_time = current_time - self.last_activity_time # 这里可以添加更精确的全局事件监听,但复杂度较高 if idle_time > self.idle_threshold: print(f“[监督触发] 用户已闲置 {idle_time//60} 分钟,小鱼要发话了!“) self.urge_to_work.emit() # 发出监督信号 # 重置活动时间,避免连续触发 self.last_activity_time = time.time() def onUrgeToWork(self): """当需要督促工作时触发的动作""" # 切换为“生气”或“催促”的动画 self.movie.stop() self.movie = QMovie(‘assets/sprites/blue_fat_fish/angry.gif‘) self.pet_label.setMovie(self.movie) self.movie.start() # 可以在这里播放一段音效 # QSound.play(‘assets/sounds/urge.wav‘) # 显示一个气泡对话框(需要额外UI组件) print(“蓝色大肥鱼:我允许你偷懒了吗?快回去工作!“) QTimer.singleShot(3000, self.restoreIdle) # 3秒后恢复 if __name__ == ‘__main__‘: app = QApplication(sys.argv) pet = DesktopPet() sys.exit(app.exec_())

代码解读

  1. DesktopPet类继承自QMainWindow,创建了一个无边框透明窗口。
  2. initUI方法初始化界面,加载宠物的待机动画(GIF格式),并将窗口置于屏幕右下角。
  3. initPetBehaviorinitMonitorTimer分别设置了两个QTimer
    • behavior_timer: 控制宠物自主的随机动作,增加生动性。
    • monitor_timer: 核心的“监督”逻辑,定期检查用户空闲时间。
  4. checkUserActivity方法尝试获取系统空闲时间(Windows API示例)。当空闲时间超过阈值(30分钟),就发射urge_to_work信号。
  5. onUrgeToWork是信号对应的槽函数,会切换为生气动画,并在控制台输出督促语句。这是“监督”功能的核心体现。
  6. 鼠标事件处理实现了窗口的拖动功能。

5.2 资源文件组织

项目需要一个清晰的资源目录。你需要准备宠物的动画帧。

  • 方案A(推荐):使用 GIF 动画。准备多个 GIF 文件,如idle.gif(待机)、blink.gif(眨眼)、angry.gif(生气)、walk.gif(走动)。GIF 支持透明,且QMovie能直接播放。
  • 方案B:使用 PNG 序列帧。需要自己编写代码控制帧切换,灵活性更高,但更复杂。

一个简单的assets目录结构如下:

assets/ ├── sprites/ │ └── blue_fat_fish/ │ ├── idle.gif │ ├── blink.gif │ ├── angry.gif │ └── walk.gif └── sounds/ └── urge.wav

5.3 进阶:集成简单 AI 对话(可选)

如果想让你的桌宠更“智能”,可以集成一个轻量级的本地 LLM 或调用云端 API。这里以调用 OpenAI 格式的本地模型(如通过ollama运行的模型)为例,进行概念性展示。

文件:ai_chat.py(简化示例)

import requests import json class PetAI: def __init__(self, base_url=“http://localhost:11434/api/generate“): self.base_url = base_url self.personality = “你是一只蓝色的大肥鱼,是用户的桌面宠物兼工作监督员。你的语气要严厉又带点可爱,当用户偷懒时,你要用幽默但坚定的方式督促他回去工作。回答要简短,不超过两句话。“ def generate_response(self, user_input): """生成AI回复""" prompt = f“{self.personality}\n用户说:{user_input}\n小鱼回复:” payload = { “model“: “qwen:7b“, # 替换为你本地运行的模型名 “prompt“: prompt, “stream“: False } try: response = requests.post(self.base_url, json=payload, timeout=10) if response.status_code == 200: result = response.json() return result.get(‘response‘, ‘小鱼今天不想说话~‘).strip() else: return “网络好像不太对劲...“ except Exception as e: print(f“AI调用失败: {e}“) return “(小鱼思考中,但没想出来)“ # 在主窗口中集成 # 可以添加一个右键菜单,点击后弹出输入框,将用户输入传给 PetAI,并在桌面显示气泡回复。

注意:这需要你在本地部署兼容 OpenAI API 的模型服务(如ollama)。对于纯桌宠项目,这不是必须的,但能极大增强趣味性。

6. 运行与效果验证

  1. 确保环境与依赖:在虚拟环境中,确认已安装PyQt5(pip install PyQt5)。
  2. 准备资源:按照上述结构,至少准备一个idle.gifangry.gif放在对应的assets目录下。可以从开源游戏素材网站寻找或自己绘制。
  3. 运行主程序
    python main.py
  4. 预期效果
    • 屏幕右下角会出现一个无边框的动画窗口(你的蓝色大肥鱼)。
    • 你可以用鼠标拖动它到任何位置。
    • 每隔10秒左右,宠物会随机做一个动作(如眨眼)。
    • 当你长时间(示例为30分钟)不操作电脑(或根据代码逻辑),宠物会切换成生气动画,并在控制台打印督促语句。
  5. 验证监督功能:为了快速测试,你可以将checkUserActivity方法中的idle_threshold暂时改为10(10秒),然后停止操作电脑,观察10秒后宠物是否会触发督促行为。

7. 常见问题与排查思路

问题现象可能原因排查方式解决方案
运行后无窗口显示1. 资源路径错误。
2. PyQt5 未正确安装。
3. 代码存在语法错误。
1. 检查控制台是否有FileNotFoundError
2. 运行python -c “import PyQt5.QtWidgets; print(‘ok‘)“
3. 仔细查看运行时的错误信息。
1. 使用绝对路径或确保相对路径正确。
2. 重新安装pip install PyQt5
3. 根据错误信息修正代码。
窗口有黑色背景,不透明setAttribute(Qt.WA_TranslucentBackground)未生效,或图片背景不透明。1. 检查窗口标志设置顺序。
2. 确认使用的 GIF/PNG 图片背景是否为透明通道。
1. 确保在setWindowFlags之后调用setAttribute
2. 使用图像处理软件确保素材背景透明。
宠物动画不播放1. GIF 文件损坏或格式不支持。
2.QMovie未启动。
1. 尝试用其他软件打开 GIF。
2. 检查是否调用了movie.start()
1. 转换或重新制作 GIF。
2. 确保start()setMovie()之后调用。
无法拖动窗口鼠标事件未被正确捕获或处理。检查mousePressEventmouseMoveEvent方法是否被重写,以及事件是否被accept()确保事件处理函数中调用了event.accept()
监督功能永不触发1. 活动检测逻辑错误。
2. 定时器未工作。
3. 阈值设置过大。
1. 在checkUserActivity中打印idle_time值。
2. 检查monitor_timer是否正常启动。
3. 临时将阈值调小测试。
1. 修正获取系统空闲时间的代码,或换用更可靠的库如pyautogui检测鼠标位置变化。
2. 确保定时器信号正确连接。
CPU 占用率过高动画刷新率过快或循环逻辑有误。1. 检查 GIF 帧率。
2. 检查定时器间隔是否太短。
1. 优化 GIF,减少帧数和尺寸。
2. 将行为定时器间隔调整到合理值(如5-10秒)。

8. 最佳实践与进阶开发建议

一个玩具项目和生产级 Side Project 之间,差的就是这些细节。

8.1 工程化建议

  • 配置文件:将宠物的行为参数(如各种定时器间隔、动画路径、空闲阈值)抽离到config.iniconfig.yaml文件中,方便非开发者调整。
  • 日志系统:使用 Python 的logging模块替代print,记录宠物的行为、错误和用户交互,便于调试。
  • 状态管理:为宠物设计一个清晰的状态机(如IDLE,MOVING,SLEEPING,URGING),使行为逻辑更清晰。
  • 跨平台兼容:获取系统空闲时间的 API 在 Windows、macOS、Linux 上各不相同。可以使用pyautogui来近似检测(检查最近一段时间内鼠标像素位置是否变化),或者使用平台特定的库(如win32apifor Windows,Quartzfor macOS)。

8.2 功能增强方向

  • 更精准的“工作”检测:不仅仅是全局空闲,可以结合psutil库检测特定进程(如chrome.exe,steam.exe)是否在前台运行过久,实现更精准的“摸鱼检测”。
  • 丰富的交互方式:除了点击,可以支持双击喂食、右键菜单设置、语音输入(集成speech_recognition)等。
  • 数据统计与可视化:记录每日“被督促”次数、专注时长,并生成简单的统计图表,形成正向反馈。
  • 插件化系统:设计插件接口,允许通过编写 Python 脚本为宠物添加新技能、新动画或新的监督规则。

8.3 性能与体验优化

  • 资源懒加载:动画图片较多时,不要一次性全部加载进内存,使用时再加载。
  • 动画平滑:移动宠物时使用缓动函数,而不是直接设置坐标,让移动更自然。
  • 多显示器支持:计算窗口位置时,考虑多显示器的情况。
  • 系统托盘图标:添加托盘图标,实现最小化到托盘、退出、暂停监督等功能。

9. 总结:从“玩具”到“工具”的思考

通过这个“蓝色大肥鱼”桌宠项目,我们完成了一次从创意到代码的完整实践。它起点是一个有趣的 Side Project,但其内核涉及了 GUI 编程、事件驱动、多线程(定时器)、系统交互,甚至可选的 AI 集成,是一个非常好的全栈练手项目。

更重要的是,它代表了一种思路:用技术解决自身的非技术痛点。作为开发者,我们擅长构建工具去解决别人的问题,却常常忽视用同样的能力来优化自己的工作流和生活习惯。这个桌宠,就是一个将外部监督内化为趣味化数字存在的尝试。

你可以完全按照本文的代码骨架,从零开始打造你的专属桌宠。也可以深入研究my_ai_town这类开源项目,学习它们更复杂的 AI 行为树和多智能体模拟是如何实现的。无论是为了对抗拖延症,还是单纯享受创造的乐趣,动手实现它,你会收获的远不止一个桌面宠物。

下一步,你可以

  1. 克隆并运行my_ai_town项目,看看原作者实现了哪些更酷的功能。
  2. 替换资源:将蓝色大肥鱼换成你喜欢的任何角色形象。
  3. 修改规则:将“30分钟闲置”的监督规则,改为“检测到代码编辑器失去焦点超过10分钟”等更贴合程序员工作的规则。
  4. 分享你的版本:将你的修改发布到 GitHub,或写成一篇属于自己的 CSDN 博客。

技术最有魅力的地方,在于它能将想象变为现实。现在,就让这条(或你创造的)数字伙伴,开始它的监督工作吧。

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

GitHub推送农场泛滥:64%垃圾信息背后的识别与防御实战

最近在 GitHub 上做项目,你有没有感觉首页的“探索”推荐,或者某些冷门仓库的 Issues 区,突然变得有点“热闹”了?点进去一看,很多是内容雷同、链接可疑的评论或 PR,甚至一些沉寂多年的仓库,也突…

作者头像 李华
网站建设 2026/8/21 20:24:17

SparkSQL 之 Hive On Spark 原理分析

摘要:Hive on Spark 让传统 Hive 数仓跑在 Spark 引擎上。本文从 RSC 远程作业提交机制、HQL 编译 6 步、MR/Tez/Spark 三引擎对比、完整配置清单四个维度,配合 2 张架构图,彻底解析 Hive on Spark 原理。 关键词:Hive on Spark, …

作者头像 李华
网站建设 2026/8/21 20:22:07

Project Graph 节点图快速上手指南:把散乱思路变成能拖拽的图

Project Graph 节点图快速上手指南:把散乱思路变成能拖拽的图 【免费下载链接】project-graph A node-based visual tool for organizing thoughts and notes in a non-linear way. 项目地址: https://gitcode.com/gh_mirrors/pr/project-graph 脑子里的想法…

作者头像 李华
网站建设 2026/8/21 20:20:54

NoFences:免费开源的 Windows 桌面图标分区工具

NoFences:免费开源的 Windows 桌面图标分区工具 【免费下载链接】NoFences 🚧 Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences NoFences 是一款完全免费、开源的 Windows 桌面图标分区工具。它把…

作者头像 李华
网站建设 2026/8/21 20:20:24

制造业物料控制(MC)与MRP实战解析:从职责到SAP系统实现

大家好,我是深耕制造业信息化与供应链管理多年的技术博主。在日常工作中,无论是实施SAP、Oracle等ERP系统,还是进行内部流程优化,物料控制(MC)与物料需求计划(MRP)都是绕不开的核心模…

作者头像 李华