拒绝无效内卷!用QClaw打造打工人专属“情绪-生存-睡眠“Agent
本文介绍了基于QClaw平台开发的三个"不正经"AI助手:情绪垃圾桶(将吐槽转化为哲学论文或Rap)、暗黑料理生成器(用剩余食材创造"理论上能吃"的菜谱)和睡眠督察员(通过社交压力对抗熬夜)。这些项目展现了AI在解决日常痛点时的创意可能,同时探讨了技术伦理边界。作者通过本地化部署实现了数据隐私保护,并强调AI应该服务于人的真实需求而非宏大叙事。
I. 写在前面:为什么我们需要"不正经"的AI Agent?
去年年末,当我第N次在深夜改需求文档时,突然意识到一个问题:现有的AI助手都太"乖"了。它们总是彬彬有礼地告诉你"我理解您的 frustration",但打工人真正需要的,可能是一个能陪你一起骂甲方、然后顺便把吐槽内容改写成哲学论文的赛博知己。
腾讯推出了QClaw(人称"小龙虾AI")。这个基于OpenClaw生态的本地化Agent平台最吸引我的点在于:它支持微信直连+本地Skill开发,意味着我可以把各种脑洞大开的自动化场景做成可复用的技能包,而且数据完全不出本地。
于是,我花了两个周末,基于QClaw开发了三个"邪修"Agent:一个会把职场黑话转化为存在主义哲学的情绪垃圾桶、一个专门推荐"理论上能吃"的暗黑料理的厨房化学家,以及一个通过社死压力倒逼自律的睡眠督察员。
直达 qclaw
II. 环境准备:QClaw本地部署与开发环境配置
在动手写代码之前,我们需要先搞定基础环境。相比OpenClaw需要手动配置Node.js、Python环境和各种API Key的繁琐流程,QClaw的安装体验堪称"傻瓜式"——但这不意味着我们可以跳过对架构的理解。
核心组件解析
QClaw采用"本地客户端+微信远程"的双层架构。简单来说,你的电脑运行着一个轻量级的Agent Runtime(基于OpenClaw内核改造),它通过加密通道与腾讯的微信服务桥接。这意味着:
|
组件层级 |
功能定位 |
数据流向 |
安全边界 |
|---|---|---|---|
|
微信接入层 |
指令接收与结果推送 |
手机↔腾讯服务器 |
仅传输指令文本 |
|
QClaw Runtime |
任务调度与Skill执行 |
本地电脑运行 |
文件/数据不出本地 |
|
Skill生态层 |
具体业务逻辑实现 |
本地沙箱执行 |
敏感操作需授权 |
安装与初始化流程
访问 https://qclaw.qq.com/ 下载对应系统的安装包。这里有个坑:如果你是macOS用户,在Apple Silicon芯片上运行时,需要在"系统设置-隐私与安全性"中手动允许辅助功能权限,否则后续的文件操作Skill会报权限错误。
安装完成后,首次启动会要求绑定微信。建议用一个工作微信扫码,因为后面的"睡眠拖延对抗Agent"需要给好友发消息,用自己的主号可能会造成不必要的社死。
接下来是模型配置。QClaw内置了Kimi、MiniMax、GLM等国产大模型,内测期间免费。但对于我们的"情绪垃圾桶"和"暗黑料理"场景,我建议在设置中切换到自定义模型,接入DeepSeek-R1或Claude 3.5 Sonnet,因为这两个场景对模型的创意生成能力要求较高,需要更强的"胡说八道"功底(划掉)创意发散能力。
III. 项目一:情绪垃圾桶Agent —— 从"国粹"到"国粹艺术"
需求分析与场景拆解
这个Agent的诞生源于一个具体的痛点:某周一早上,我收到了产品经理发来的第8版需求变更,其中有一句"我们要在保持极简的同时增加功能的丰富度"。在传统的情绪管理理论中,我应该深呼吸、喝口水、理性沟通。但实际上,我只想对着空气来一段单口相声。
于是,EmoBin(情绪垃圾桶) 的设计目标很明确:
|
功能模块 |
输入 |
处理逻辑 |
输出 |
|---|---|---|---|
|
毒舌接收 |
用户的纯文本吐槽 |
情感分析+脏话过滤 |
确认接收情绪 |
|
哲学升华 |
标记为"philosophy" |
提取核心矛盾→映射存在主义/后现代理论 |
300字哲学短文 |
|
Rap转化 |
标记为"rap" |
识别韵脚→套用Flow结构→添加Punchline |
带标注的verse |
Skill架构设计与Prompt工程
在QClaw中,一个Skill本质上是包含SKILL.md(元数据定义)和若干工具脚本的目录。我们在~/.qclaw/skills/emobin/下创建如下结构:
emobin/ ├── SKILL.md # Skill的元数据与触发词定义 ├── main.py # 主逻辑处理 ├── philosophy.py # 哲学升华模块 ├── rap_generator.py # Rap生成模块 └── config.json # 配置文件
复制
SKILL.md 是QClaw识别Skill的核心文件,它需要定义触发条件和参数解析规则:
# EmoBin - 情绪垃圾桶与内容升华器 ## 描述 接收用户的职场/生活吐槽,将其转化为哲学思考或Rap歌词,实现情绪宣泄与素材积累的双重价值。 ## 触发词 - "吐槽" / "骂" / "烦死了" → 进入接收模式 - "升华一下" / "哲学模式" → 调用philosophy.py - "来段rap" / "diss一下" → 调用rap_generator.py - "保存到素材库" → 将内容追加到本地markdown文件 ## 参数 - content: 用户的原始吐槽内容(必需) - mode: 处理模式,可选"philosophy"或"rap"(默认philosophy) - intensity: 毒舌强度等级1-5(用于Rap生成时的攻击性调节) ## 示例 用户输入:"吐槽 这个需求又要改,产品经理是不是觉得时间不是成本? 模式:rap 强度:4"
复制
核心代码实现
现在来看main.py的实现。QClaw的Python SDK封装了本地文件操作和LLM调用接口,我们可以直接通过@qclaw.tool()装饰器将Python函数暴露为Agent可调用的工具。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ EmoBin - 情绪垃圾桶主模块 基于QClaw SDK v1.x开发 """ import json import os from datetime import datetime from typing import Literal import qclaw from qclaw import Context, Tool # 初始化上下文 ctx = Context() class EmoBinProcessor: def __init__(self): self.storage_path = os.path.expanduser("~/Documents/EmoBin/") self.ensure_storage() def ensure_storage(self): """确保存储目录存在""" if not os.path.exists(self.storage_path): os.makedirs(self.storage_path) # 创建素材库主文件 with open(f"{self.storage_path}/materials.md", "w", encoding="utf-8") as f: f.write("# 情绪素材库\n\n> 自动收集的吐槽与升华内容\n\n") @Tool(description="分析用户情绪强度并分类") def analyze_emotion(self, content: str) -> dict: """ 使用本地LLM分析情绪类型与强度 QClaw会自动路由到配置的模型(DeepSeek/Claude等) """ prompt = f""" 分析以下吐槽文本的情绪特征: 文本:"{content}" 请返回JSON格式: {{ "emotion_type": "anger/frustration/sarcasm/resignation", "intensity": 1-5, "keywords": ["关键词1", "关键词2"], "core_conflict": "核心矛盾总结(10字以内)" }} """ # 调用QClaw封装的本地LLM接口 response = ctx.llm.complete(prompt, temperature=0.3, json_mode=True) return json.loads(response.text) @Tool(description="将吐槽内容转化为哲学思考") def to_philosophy(self, content: str, emotion_data: dict) -> str: """ 哲学升华模块:将职场黑话映射到存在主义/后现代理论 """ philosophy_prompt = f""" 你是一位精通存在主义、后现代主义、法兰克福学派的哲学教授。 请将以下职场吐槽转化为严肃的哲学论述(300-400字): 原始吐槽:{content} 核心矛盾:{emotion_data['core_conflict']} 要求: 1. 引用至少一位哲学家(海德格尔/萨特/福柯/鲍德里亚等) 2. 使用学术化的黑话体系(异化、规训、景观社会、单向度的人等) 3. 保持原文的核心诉求,但包装成"现代性困境"的批判 4. 结尾要有升华:从个人抱怨上升到人类普遍处境 风格参考:让·鲍德里亚《消费社会》的批判语调 + 微博哲学bot的犀利感 """ result = ctx.llm.complete(philosophy_prompt, temperature=0.8) return result.text @Tool(description="将吐槽转化为Rap歌词") def to_rap(self, content: str, intensity: int, emotion_data: dict) -> str: """ Rap生成模块:带Flow标注的说唱词创作 """ flow_styles = { 1: "Jazz Boombap, 慵懒叙事", 2: "Trap, 稳定八拍", 3: "Drill, 急促进鼓", 4: "Hardcore, 双韵脚快嘴", 5: "Death Grips式工业噪音流, 无规则Flow" } rap_prompt = f""" 你是一位underground battle MC。请将以下职场吐槽改写为Rap Verse(16-20 bars): 原始素材:{content} 攻击强度:{intensity}/5 推荐Flow:{flow_styles.get(intensity, "Trap")} 创作要求: 1. 每句用[ ]标注Flow技巧(如[停顿]、[三连音]、[加速]) 2. 使用多音节韵脚(multi-syllable rhymes) 3. Punchline要狠但保持隐喻(避免直接脏话) 4. 加入Ad-libs(如"skr"、"ey")标注 5. 最后4 bars要有反转(从抱怨转向自我赋权) 输出格式: [Intro: 情绪氛围描述] [Verse 1] 歌词行1 [Flow技巧] ... [Outro] """ result = ctx.llm.complete(rap_prompt, temperature=0.9) return result.text @Tool(description="保存内容到本地素材库") def save_to_vault(self, original: str, processed: str, mode: str): """ 持久化存储到本地markdown QClaw确保所有文件操作在本地沙箱内完成 """ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M") entry = f""" ## {timestamp} | {mode.upper()}模式 **原始吐槽:** > {original} **升华内容:** {processed} --- """ vault_path = f"{self.storage_path}/materials.md" # 使用QClaw的安全文件操作API ctx.file.append(vault_path, entry, encoding="utf-8") return {"status": "saved", "path": vault_path, "timestamp": timestamp} # 实例化处理器 processor = EmoBinProcessor() @qclaw.on_message() def handle_message(content: str, mode: Literal["philosophy", "rap"] = "philosophy", intensity: int = 3): """ QClaw消息入口函数 当用户在微信发送"吐槽 xxx"时被触发 """ try: # 1. 情绪分析 ctx.send_typing() # 发送"对方正在输入"状态到微信 emotion_data = processor.analyze_emotion(content) # 2. 根据模式处理 if mode == "philosophy": result = processor.to_philosophy(content, emotion_data) title = "🧠 哲学升华版" else: result = processor.to_rap(content, intensity, emotion_data) title = "🎤 Rap Battle版" # 3. 自动保存(可选) save_result = processor.save_to_vault(content, result, mode) # 4. 构造返回消息 reply = f""" {title} {result} --- 💾 已自动保存至素材库 | 情绪强度:{'⭐' * emotion_data['intensity']} 📝 核心矛盾:{emotion_data['core_conflict']} """ return reply except Exception as e: return f"❌ 情绪处理失败:{str(e)}\n建议:尝试降低毒性或使用更隐喻的表达方式" if __name__ == "__main__": # 本地测试入口 test_content = "这个需求又要改第八版,产品经理是不是觉得时间不是成本?" print(handle_message(test_content, mode="rap", intensity=4))
复制
部署与实测效果
将上述文件保存到~/.qclaw/skills/emobin/后,在QClaw客户端的"技能广场"点击"刷新本地Skills",即可看到EmoBin卡片。点击启用后,我们在微信中测试:
输入:吐槽 周末又要加班改PPT,老板说要"对齐颗粒度",我怀疑他根本不知道这个词什么意思 模式:哲学 强度:5
Agent返回:
电脑端:

看着这段文字,我突然觉得加班也没那么惨了——毕竟我已经用资本主义的批判理论武装了自己,这波不亏。
IV. 项目二:暗黑料理生成器 —— 厨房里的化学实验
产品设计逻辑
如果说EmoBin解决的是精神需求,那么DarkChef(暗黑料理生成器)瞄准的就是物理生存需求。每个租房打工人都经历过这样的场景:周五晚上打开冰箱,发现只剩下半个洋葱、两颗鸡蛋和一盒过期一天的酸奶。外卖软件上,配送费比食材还贵。
传统的美食App在这种情况下基本没用,它们会告诉你"缺少关键食材,无法生成菜谱"。但DarkChef的核心哲学是:只要毒不死,就是新菜系。
食材知识图谱构建
这个Skill的难点在于"毒性评估"——我们需要建立一个食材搭配的禁忌知识库。不能真的把用户送进医院。我在config.json中定义了安全规则:
{ "dangerous_combos": [ { "ingredients": ["螃蟹", "柿子"], "level": 5, "reason": "鞣酸与蛋白质结合导致胃结石", "absolute_forbidden": true }, { "ingredients": ["蜂蜜", "洋葱"], "level": 3, "reason": "轻微氧化反应,可能导致腹泻", "absolute_forbidden": false } ], "toxicity_scale": { "1": "完全安全,只是口味猎奇", "2": "肠胃敏感者可能不适", "3": "建议准备健胃消食片", "4": "需要签订自愿参与协议", "5": "生化危机级别,严禁尝试" } }
复制
核心算法实现
dark_chef.py的核心是约束满足问题(CSP)求解。我们需要在"不购买新食材"的硬约束下,最大化"猎奇指数"同时确保"生存概率>90%"。
#!/usr/bin/env python3 """ DarkChef - 暗黑料理生成器 基于QClaw的食材剩余管理与黑暗料理推荐系统 """ import random import json from dataclasses import dataclass from typing import List, Tuple import qclaw from qclaw import Tool, Context ctx = Context() @dataclass class Recipe: name: str ingredients: List[str] steps: List[str] toxicity_level: int # 1-5星 flavor_profile: str survival_tips: str class DarkChefEngine: def __init__(self): self.config = self._load_config() self.cooking_methods = [ "爆炒", "乱炖", "微波加热", "空气炸锅", "搅拌机打成泥", "跨界fusion", "分子料理手法" ] def _load_config(self): skill_path = ctx.skill.get_path() # 获取当前Skill目录 with open(f"{skill_path}/config.json", "r", encoding="utf-8") as f: return json.load(f) def check_safety(self, ingredients: List[str]) -> Tuple[int, str]: """ 检查食材组合的安全性 返回:(毒性等级, 警告信息) """ max_level = 1 warnings = [] for danger in self.config["dangerous_combos"]: if all(ing in ingredients for ing in danger["ingredients"]): if danger["absolute_forbidden"]: return 5, f"🚫 致命组合:{'+'.join(danger['ingredients'])} - {danger['reason']}" max_level = max(max_level, danger["level"]) warnings.append(f"⚠️ {danger['reason']}") return max_level, "; ".join(warnings) if warnings else "✅ 理论上不会致死" @Tool(description="根据剩余食材生成暗黑料理方案") def generate_recipe(self, ingredients: str, mood: str = "绝望") -> Recipe: """ 主生成函数 ingredients: 逗号分隔的食材列表,如"鸡蛋,酸奶,老干妈" mood: 当前心情,影响料理疯狂程度 """ ing_list = [i.strip() for i in ingredients.split(",")] # 1. 安全检查 base_toxicity, warning = self.check_safety(ing_list) # 2. 如果检测到致命组合,直接拒绝 if base_toxicity == 5: return Recipe( name="生化危机预防协议", ingredients=ing_list, steps=["立即停止", "分开存放", "点外卖"], toxicity_level=5, flavor_profile="活着真好", survival_tips="请不要尝试任何组合" ) # 3. 调用LLM生成创意菜谱 prompt = f""" 你是一位疯癫的米其林黑暗料理主厨,擅长用奇怪的食材组合创造"理论上能吃"的食物。 剩余食材:{', '.join(ing_list)} 当前心情:{mood}(影响疯狂程度) 安全警告:{warning} 请生成一个料理方案,要求: 1. 菜名要有meme感或哲学隐喻 2. 烹饪步骤必须包含至少一个"邪门"操作(如"用咖啡机煮方便面") 3. 口味描述要用通感修辞(如"像失恋的周二下午") 4. 给出具体的毒性自评(1-5星)和生存建议 返回格式: 菜名:xxx 难度:⭐⭐⭐ 毒性:⭐⭐({base_toxicity}星基准) 风味档案:xxx 步骤: 1. xxx 2. xxx 生存贴士:xxx """ response = ctx.llm.complete(prompt, temperature=0.95) parsed = self._parse_recipe(response.text, ing_list, base_toxicity) # 4. 自动记录到"生存日志" self._log_attempt(parsed) return parsed def _parse_recipe(self, text: str, ingredients: List[str], base_toxicity: int) -> Recipe: """解析LLM返回的文本为结构化数据""" lines = text.strip().split("\n") name = lines[0].replace("菜名:", "").strip() if lines else "无名暗黑料理" steps = [] survival = "无" in_steps = False for line in lines: if line.startswith("步骤:"): in_steps = True continue if in_steps and line.strip(): if line.startswith("生存贴士:"): survival = line.replace("生存贴士:", "").strip() break steps.append(line.strip()) # 动态调整毒性:如果LLM给出的描述很可怕,加1星 toxicity_keywords = ["喷射", "住院", "洗胃", "幻觉"] bonus = 1 if any(k in text for k in toxicity_keywords) else 0 final_toxicity = min(5, base_toxicity + bonus) return Recipe( name=name, ingredients=ingredients, steps=steps, toxicity_level=final_toxicity, flavor_profile="猎奇向", survival_tips=survival ) def _log_attempt(self, recipe: Recipe): """记录到本地生存日志,用于后续优化""" log_entry = { "timestamp": ctx.time.now(), "recipe": recipe.name, "toxicity": recipe.toxicity_level, "ingredients": recipe.ingredients } log_path = f"{ctx.skill.get_path()}/survival_log.jsonl" ctx.file.append(log_path, json.dumps(log_entry, ensure_ascii=False) + "\n") # 初始化引擎 chef = DarkChefEngine() @qclaw.on_message() def cook(ingredients: str, style: str = "fusion"): """ QClaw入口:用户发送"今晚吃什么 鸡蛋,酸奶,老干妈" """ try: recipe = chef.generate_recipe(ingredients) # 构造可视化输出 toxicity_stars = "⭐" * recipe.toxicity_level + "☆" * (5 - recipe.toxicity_level) danger_level = ["绿色:可食用", "黄色:勇士专属", "橙色:肠胃挑战", "红色:生死状", "黑色:遗书预备"][recipe.toxicity_level - 1] reply = f""" 🍳 【{recipe.name}】 ━━━━━━━━━━━━━━━━━━━━ 🧪 食材:{' + '.join(recipe.ingredients)} ⚗️ 毒性评估:{toxicity_stars} ({danger_level}) 🎭 风味:{recipe.flavor_profile} 👨🍳 烹饪步骤: {chr(10).join(f" {i+1}. {step}" for i, step in enumerate(recipe.steps))} 💊 生存贴士:{recipe.survival_tips} ━━━━━━━━━━━━━━━━━━━━ ⚠️ 免责声明:本菜谱由AI生成,QClaw及开发者不对任何肠胃不适负责 """ # 如果毒性过高,追加安全警告 if recipe.toxicity_level >= 4: reply += "\n🚨 警告:检测到高危险操作,建议拍照留念后再食用" return reply except Exception as e: return f"厨房爆炸了:{str(e)}\n建议:还是点麦当劳吧" @qclaw.scheduled(cron="0 18 * * 5") # 每周五晚6点自动提醒 def friday_survival_check(): """ 定时任务:周五晚上检查冰箱并推送建议 QClaw支持Cron表达式定时触发 """ # 这里可以接入智能冰箱API或让用户提前拍照OCR # 简化版:随机推荐一个"周五特调" backup_ingredients = ["剩米饭", "鸡蛋", "辣酱", "可乐"] recipe = chef.generate_recipe(",".join(backup_ingredients), mood="周末前的绝望") return f""" 🍽️ 周五生存指南自动推送 检测到您可能面临"不知道吃什么"的 existential crisis。 推荐方案:{recipe.name} 毒性:{'⭐' * recipe.toxicity_level} 输入"查看详情"获取完整菜谱,或输入"外卖"放弃治疗。 """
复制
实战案例:冰箱剩余物资拯救计划
上周实测时,我的冰箱里正好有:半根胡萝卜、 yesterday's 披萨、一罐啤酒、两个鸡蛋。
输入:今晚吃什么 胡萝卜,剩披萨,啤酒,鸡蛋
DarkChef返回:
说实话,这道菜的味道介于"还能吃"和"我是谁我在哪"之间,但确实解决了我周五晚上的生存危机。更重要的是,这个过程中我完全没有打开外卖App,省下了30块配送费——这就是Agent带来的"降本增效"(物理意义上)。
V. 项目三:睡眠拖延对抗Agent —— 用社死战胜熬夜
行为设计学原理
这是三个项目中最"邪门"的一个。SleepGuard(睡眠督察员)基于一个简单的心理学原理:损失厌恶(Loss Aversion)。当我们面临"损失50元"的风险时,规避损失的动机强度是"获得50元"的两倍。
传统的睡眠App只能提醒你"该睡了",但你可以无视它。SleepGuard的做法是:如果你不在设定时间内回复验证消息,它会自动给你的微信好友发送"我熬夜了,请罚我50块"的社死认证。
技术架构与权限设计
这个Skill涉及定时任务+微信消息发送,是QClaw中权限要求最高的操作。需要在SKILL.md中明确声明权限需求:
## 权限声明 - schedule: 需要创建定时任务 - notification: 需要发送系统通知 - wechat: 需要发送微信消息(仅向指定好友) - file: 需要读写本地睡眠日志 ## 安全机制 - 所有消息发送需用户预先配置"监督人"白名单 - 每日最多发送1条惩罚消息,避免骚扰 - 提供"紧急取消"指令(睡前5分钟内有效)
复制
核心代码:社死驱动的自律系统
#!/usr/bin/env python3 """ SleepGuard - 睡眠拖延对抗系统 通过社交压力与经济损失预期倒逼自律 """ import json import time from datetime import datetime, timedelta from typing import List import qclaw from qclaw import Tool, Context, scheduler ctx = Context() class SleepGuardian: def __init__(self): self.config_path = f"{ctx.skill.get_path()}/sleep_config.json" self.state_path = f"{ctx.skill.get_path()}/sleep_state.json" self.load_config() def load_config(self): """加载用户配置""" try: with open(self.config_path, "r", encoding="utf-8") as f: self.config = json.load(f) except FileNotFoundError: # 默认配置 self.config = { "bedtime": "23:30", "supervisors": [], # 监督人微信ID列表 "fine_amount": 50, "challenge_msg": "我如果1小时内不回消息就给你转{amount}块", "grace_period_minutes": 5 } self.save_config() def save_config(self): with open(self.config_path, "w", encoding="utf-8") as f: json.dump(self.config, f, ensure_ascii=False, indent=2) @Tool(description="设置睡眠监督参数") def setup(self, bedtime: str, supervisors: List[str], fine: int = 50): """ 初始化配置 bedtime: "HH:MM"格式 supervisors: 监督人微信昵称或备注名列表 """ self.config.update({ "bedtime": bedtime, "supervisors": supervisors, "fine_amount": fine }) self.save_config() # 注册定时任务:在睡前15分钟发送预警 bedtime_dt = datetime.strptime(bedtime, "%H:%M") warning_time = (bedtime_dt - timedelta(minutes=15)).strftime("%H:%M") scheduler.daily(warning_time, self.send_bedtime_warning) scheduler.daily(bedtime, self.initiate_sleep_challenge) return f""" 🛡️ 睡眠监督系统已激活 ⏰ 就寝时间:{bedtime} 👥 监督人:{', '.join(supervisors)} 💰 违约罚金:{fine}元 ⚠️ 系统将在每天{warning_time}发送预警,{bedtime}启动挑战协议 """ @Tool(description="发送睡前预警") def send_bedtime_warning(self): """睡前15分钟提醒""" ctx.notification.send( title="🌙 睡眠预警", body=f"还有15分钟就{self.config['bedtime']}了,请准备进入睡眠模式。关闭手机或回复'准备睡觉'以取消挑战。", urgency="high" ) return "预警已发送" @Tool(description="启动睡眠挑战协议") def initiate_sleep_challenge(self): """ 核心逻辑:发送社死挑战消息给监督人 """ # 检查是否已经标记为已睡 state = self.get_today_state() if state.get("status") == "sleeping": return "用户已确认入睡,跳过挑战" # 构造挑战消息 challenge = self.config["challenge_msg"].format( amount=self.config["fine_amount"] ) full_msg = f""" 【SleepGuard自动消息】 我是{ctx.user.name}的AI睡眠督察员。 {challenge} 时间戳:{datetime.now().strftime("%H:%M:%S")} 如{self.config['grace_period_minutes']}分钟内未收到回复,视为违约。 (此消息由QClaw自动发送,用于睡眠习惯养成) """ # 发送给所有监督人 sent_count = 0 for supervisor in self.config["supervisors"]: try: ctx.wechat.send_message( to=supervisor, content=full_msg, confirm=True # 需要二次确认,防止滥用 ) sent_count += 1 except Exception as e: ctx.log.error(f"发送给{supervisor}失败: {e}") # 更新状态 self.update_state("challenge_sent", datetime.now().isoformat()) # 设置延迟检查任务 scheduler.once( delay_minutes=self.config["grace_period_minutes'], task=self.check_challenge_result ) return f"挑战已发送给{sent_count}位监督人,{self.config['grace_period_minutes']}分钟后检查回复状态" @Tool(description="检查挑战结果并执行惩罚") def check_challenge_result(self): """ 检查用户是否在规定时间内回复 如果没有,发送"社死确认"消息 """ state = self.get_today_state() if state.get("replied_in_time"): return "用户已及时回复,挑战通过" # 用户未回复,发送社死升级消息 shame_msg = f""" 【SleepGuard违约通知】 时间:{datetime.now().strftime("%H:%M")} 状态:{ctx.user.name}未在规定时间内证明已入睡 处罚:请监督执行{self.config['fine_amount']}元转账 备注:熬夜伤身,金钱伤心,望周知 🌚 """ for supervisor in self.config["supervisors"]: ctx.wechat.send_message(supervisor, shame_msg) # 记录违约 self.log_violation() return "违约处理完成" @Tool(description="用户回复验证") def verify_sleep(self, reply_code: str = ""): """ 用户收到挑战后回复此指令 """ state = self.get_today_state() if state.get("status") != "challenge_sent": return "当前没有待处理的睡眠挑战" # 检查时间是否在宽限期内 challenge_time = datetime.fromisoformat(state["challenge_time"]) if datetime.now() - challenge_time > timedelta(minutes=self.config["grace_period_minutes"]): return "⏰ 超时!宽限期已过,违约记录已生成" self.update_state("replied_in_time", True) self.update_state("status", "sleeping") # 通知监督人解除警报 for sup in self.config["supervisors"]: ctx.wechat.send_message(sup, f"✅ {ctx.user.name}已确认进入睡眠模式,今晚的社死危机解除") return "🎉 验证成功!祝你好梦。明早见。" def get_today_state(self): """获取今日状态""" try: with open(self.state_path, "r") as f: all_states = json.load(f) today = datetime.now().strftime("%Y-%m-%d") return all_states.get(today, {}) except: return {} def update_state(self, key, value): """更新状态""" today = datetime.now().strftime("%Y-%m-%d") try: with open(self.state_path, "r") as f: all_states = json.load(f) except: all_states = {} if today not in all_states: all_states[today] = {} all_states[today][key] = value with open(self.state_path, "w") as f: json.dump(all_states, f) def log_violation(self): """记录违约历史""" log_path = f"{ctx.skill.get_path()}/violations.jsonl" entry = { "date": datetime.now().isoformat(), "amount": self.config["fine_amount"], "supervisors_count": len(self.config["supervisors"]) } ctx.file.append(log_path, json.dumps(entry) + "\n") # 初始化 guardian = SleepGuardian() @qclaw.on_message() def handle_sleep_cmd(command: str, *args): """ 命令分发 支持: - "设置睡眠 23:30 监督人A,监督人B 50" - "准备睡觉"(验证回复) - "查看违约记录" """ if command.startswith("设置睡眠"): # 解析:设置睡眠 HH:MM 监督人列表 金额 parts = command.split() if len(parts) < 3: return "格式错误。示例:设置睡眠 23:30 张三,李四 50" time_str = parts[1] supervisors = parts[2].split(",") fine = int(parts[3]) if len(parts) > 3 else 50 return guardian.setup(time_str, supervisors, fine) elif "睡觉" in command or "睡了" in command: return guardian.verify_sleep() elif "违约" in command: # 简单统计 log_path = f"{ctx.skill.get_path()}/violations.jsonl" try: with open(log_path, "r") as f: lines = f.readlines() total = len(lines) total_fine = sum(json.loads(l)["amount"] for l in lines) return f"📊 历史违约{total}次,累计应罚{total_fine}元(赶紧给监督人转账吧)" except: return "暂无违约记录,继续保持!" else: return "可用指令:\n1. 设置睡眠 [时间] [监督人] [金额]\n2. 准备睡觉(收到挑战后回复)\n3. 查看违约记录" if __name__ == "__main__": # 测试设置 print(guardian.setup("23:30", ["TestUser"], 50))
复制
实战效果:社死是第一生产力
设置了我的室友和一位关系铁的同事作为监督人,罚金设定为50元。第一周的数据如下:
|
日期 |
挑战结果 |
就寝时间 |
备注 |
|---|---|---|---|
|
3/25 |
✅ 成功 |
23:28 |
收到挑战后立刻回复,避免社死 |
|
3/26 |
✅ 成功 |
23:15 |
提前入睡,系统未触发挑战 |
|
3/27 |
❌ 违约 |
00:15 |
打游戏忘记时间,触发社死广播 |
|
3/28 |
✅ 成功 |
23:35 |
室友收到违约消息后加强了监督 |
3月27日的违约事件尤其值得记录。当时我在打《艾尔登法环》,完全没看微信。结果23:45时,我的手机疯狂震动——室友在群里@我:"睡了吗?没睡的话50块先转给我?"同事也发来一个"?"。那一刻的羞耻感,比任何睡眠App的提醒都管用。
VI. 总结:Agent的边界与可能性

通过这三个项目,我深刻体会到QClaw作为本地化Agent平台的独特价值。它不仅仅是一个"能聊天的AI",而是一个真正可以调用本地资源、执行本地任务、管理本地数据的操作系统扩展。
|
项目 |
核心技术点 |
QClaw能力依赖 |
实用性评级 |
|---|---|---|---|
|
EmoBin |
Prompt工程+文本生成 |
LLM路由、文件持久化 |
⭐⭐⭐⭐ |
|
DarkChef |
知识库检索+创意生成 |
结构化输出、定时任务 |
⭐⭐⭐ |
|
SleepGuard |
状态机+社交触发 |
微信消息、Cron调度、权限管理 |
⭐⭐⭐⭐⭐ |
当然,这些"邪修"用法也提醒我们:Agent的伦理边界需要开发者自己把握。SleepGuard的社死机制虽然有效,但如果滥用,可能会对人际关系造成真实伤害。因此我在代码中加入了"每日限额"和"紧急取消"机制——技术应该服务于人,而不是成为社交暴力的工具。
2026年被很多人称为"Agent元年",但真正让技术落地的,往往不是宏大的叙事,而是这些能解决具体痛点、甚至带点幽默感的"小工具"。当AI学会"发疯",当代码懂得"社死",或许这才是人机共生的正确打开方式。
毕竟,能让一个打工人既发泄了情绪、又吃上了晚饭、还早睡了半小时的AI,才是好AI。
参考资料与链接:
-
QClaw官网:https://qclaw.qq.com/
免责声明:DarkChef生成的菜谱仅供娱乐;SleepGuard造成的友谊破裂开发者概不负责;EmoBin生成的哲学内容请自行承担责任。
更多推荐












所有评论(0)