Files
HeXi/hexi/plugins/nonebot_plugin_galgame_card/CLAUDE.md
T
sansenhoshi 131b92b319 结构调整
视频解析多图/多媒体结构 消息体适配
2026-09-08 14:25:32 +08:00

5.4 KiB
Raw Blame History

CLAUDE.md — 群聊人设卡插件开发文档

本文件是本插件内开发的唯一入口文档;需要项目全局信息(Poetry 命令、启动方式、测试约定)时再查项目根目录的 CLAUDE.md。详细设计定稿见同目录 DESIGN.md。

插件概述

基于群聊语料蒸馏群成员的形象风格,生成 galgame 风格人物卡(九段画像)。

  • 目标:生成"人的画像",不是关系网分析;样貌参考为虚构,永远带标注
  • 隐私硬约束:只采集 opt-in 成员;敏感数据本地正则替换为占位符,绝不经过 LLM
  • 维度隔离:每个 (group_id, user_id) 是独立人设,跨群不混

目录结构

nonebot_plugin_galgame_card/
├── __init__.py   入口层:on_message 采集器(鉴权/采样/调治理落库)
├── models.py     数据层:五张表(persona_group/user/chat_log/impression/summary)
├── repository.py 数据层:仓储(来源无关,所有读写唯一入口)
├── processor.py  治理层:纯函数(五维提取/噪声/脱敏),可单测
├── config.py     插件配置(仅图片识别开关等;Web 鉴权统一走 /hub)
├── web_hub.py    Web API 子应用(挂载到 /api/galgame_card,auth=hexi.web_hub.web_auth)
├── DESIGN.md     设计定稿(数据模型/流水线/九段协议/证据纪律)
└── CLAUDE.md     本文件

Web 管理后台:已嵌入统一管理台 /hub/,前端由 hexi/web 渲染,API 挂载到 /api/galgame_card,鉴权与 /hub 共用 hexi.web_hub.web_auth(OAuth2 + SQLite)。功能:群开关、参与者增删、语料/印象/画像浏览与删除、清空群数据。改后端需重启 bot。

核心设计(速览,细节见 DESIGN.md)

  1. 两级闸门:群开关 persona_group.enabled(默认关)+ 个人 opt-in persona_user,都过才采集
  2. 两级流水线:语料 →(攒够 N 条)→ 印象(LLM 自然语言,增量中间层)→(攒够 M 条)→ 画像(九段 markdown,版本化)
  3. 消息五维:内容 / 谁发的 / 发给谁(回复/@)/ 几点发的 / 被回复内容快照——只存治理后纯文本
  4. 脱敏四层(desensitize()):明确模式(最长优先排序防截胡)→ 定位式(同条关键词+值)→ 跨条语境(关键词在附近消息)→ 兜底(保守替换)
  5. 九段画像协议:身份印象/性格特征/说话风格/口头禅语录/兴趣话题/相处模式/时间画像/样貌参考(虚构)/不确定信息
  6. 总结路径不进消息 handler:LLM 调用只在调度器触发,防延迟/限流

开发命令

# 跑本插件测试(治理层纯函数,9+ 个用例)
poetry run pytest tests/test_persona_processor.py

# 全量测试
poetry run pytest

# 启动/重启验证:PyCharm 的 "start bot" 运行配置(勿用 bat 脚本)

数据库

  • orm 默认库:data/nonebot_plugin_orm/db.sqlite3(不是 hexi/data/data.db)
  • 建表:bot 启动时 orm 自动 create_all(新表加在 models.py 里即可,重启生效)
  • 配置键是 SQLALCHEMY_DATABASE_URL(本插件未设置,走默认库)

开发注意事项(踩过的坑)

  1. ⚠️ orm 启动自动同步会清空表数据:.env 里 ALEMBIC_STARTUP_CHECK=false 时,nonebot_plugin_orm 每次启动都 autogenerate 同步数据库模式,模型一有变更(改 models.py)就会重建表、清空全部数据(2026-08-11 实测踩坑,全表被清)。已在本插件 __init__.py 导入期把 migrate.sync 替换为安全空操作。今后 schema 演进只准通过 repository.ensure_schema() 显式 ALTER,改完 models.py 后要在重启前手动执行对应 ALTER(或加进 ensure_schema)。
  2. on_message 必须 block=False:否则事件流被拦截,群里其他插件全废
  3. 只收群消息:handler 参数注解 GroupMessageEvent(类型注解即过滤器)
  4. 脱敏正则排序:身份证/银行卡必须在手机号之前,否则手机号截胡身份证数字段
  5. 定位式替换只替换值、保留关键词:密码是 xyz789 → 密码是 [密码],关键词不能丢
  6. 测试不能裸 import 包:__init__.py 触发 NoneBot 初始化,用 importlib 按路径加载 processor(见 tests/test_persona_processor.py,与 test_rate_limit 同款)
  7. 总结/印象生成:绝不在消息 handler 里调 LLM,走调度层(apscheduler)
  8. 仓储并发:add_summary 版本自增有并发撞 UNIQUE 风险,调度层加锁保护

当前进度

  • ✅ 数据层:五表 + 仓储(含群开关、滚动淘汰、版本自增)
  • ✅ 采集层:消息路径(监控→鉴权→治理→脱敏→采样→落库)
  • ✅ Web 管理后台:嵌入 /hub(/api/galgame_card + hexi/web 页面;群开关、参与者、数据浏览/清理)
  • ⏳ QQ 命令集:开启人设采集 / 加入人设 / 退出人设 / 查看人设(Web 已覆盖同等功能,QQ 命令可选做)
  • ⏳ 总结路径:LLM 客户端、印象生成、九段画像生成、调度触发
  • ⏳ 呈现层:人物卡展示/图片渲染

待决策点

  • 触发阈值(印象 ≥50 条新语料 / 画像 ≥5 条新印象,⏳ 待调)
  • 脱敏兜底位数(裸数字 ≥6 位默认替换 [账号],保守优先;误杀多可提到 8 位,动 BARE_DIGITS_RE)
  • 密保答案场景(中文值正则误杀率高,方案待定)
  • 命令名与权限(超管/群主)