Files
konabot/AGENTS.md

9.2 KiB
Raw Blame History

AGENTS.md

本文件面向两类协作者:

  • 手写代码的人类朋友
  • 会在此仓库中协助开发的 AI Agents

这个项目以手写为主,欢迎协作,但请先理解这里的约束和结构,再开始改动。

项目定位

  • 这是一个娱乐性质的、私域使用的 QQ Bot 项目。
  • 虽然主要用于熟人环境,但依然要按“不信任输入”的标准写代码。
  • 不要因为使用场景偏内部,就默认消息内容、安全边界、调用参数一定可靠。

基本原则

1. 默认不信任用户输入

所有来自聊天消息、命令参数、平台事件等的输入,都应视为不可信。

开发时至少注意以下几点:

  • 不假设输入类型正确,先校验再使用。
  • 不假设输入长度合理,注意超长文本、大量参数、异常嵌套结构。
  • 不假设输入内容安全避免直接拼接到文件路径、SQL、shell 参数、HTML 或模板中。
  • 不假设用户一定按预期使用命令,错误输入要能优雅失败。
  • 对任何外部请求、文件读写、渲染、执行型逻辑,都要先考虑滥用风险。

2. 优先保持现有风格

  • 这是一个以人工维护为主的项目,改动应尽量贴近现有写法。
  • 除非有明确收益,不要为了“看起来更现代”而大规模重构。
  • 新增能力时,优先复用已有通用模块,而不是重复造轮子。

3. 小步修改,影响清晰

  • 尽量做局部、明确、可解释的改动。
  • 修改插件时,避免顺手改动无关插件。
  • 如果要调整公共模块,先确认是否会影响大量插件行为。

仓库结构

konabot/

核心代码目录。

konabot/common/

通用模块目录。

  • 放置可复用的基础能力、工具模块、公共逻辑。
  • 如果某段逻辑可能被多个插件共享,应优先考虑放到这里。
  • 修改这里的代码时,要额外关注兼容性,因为它可能被很多插件依赖。

konabot/docs/

Bot 内部文档系统使用的文档目录。

  • 这是给用户看的文档来源。
  • 文档会通过 man 指令被触发和展示。
  • 虽然文档文件通常使用 .txt 后缀,但内容可以按 markdown 风格书写。
  • .md 后缀文件会被忽略,因此 .md 更适合只留给仓库维护者阅读的附加说明。
  • 文档文件名就是用户查询时使用的指令名,应保持简洁、稳定、易理解。

补充说明:

  • konabot/docs/user/ 是直接面向用户检索的文档。
  • konabot/docs/lib/ 更偏向维护者参考。
  • konabot/docs/concepts/ 用于记录概念。
  • konabot/docs/sys/ 用于特定范围可见的系统文档。

konabot/plugins/

插件目录。

  • 插件数量很多,是本项目最主要的功能承载位置。
  • 插件可以是单文件,也可以是文件夹形式。
  • 新增插件或修改插件时,请先观察相邻插件的组织方式,再决定采用单文件还是目录结构。
  • 如果逻辑已经明显超出单文件可维护范围,应拆成目录插件,不要把一个文件堆得过大。

根目录文档

docs/

仓库根目录下的 docs/ 主要用于记录一些可以通用的模块说明和开发文档。

  • 这里的内容主要面向开发和维护。
  • 适合放公共模块说明、集成说明、配置说明、开发笔记。
  • 不要把面向 man 指令直接展示给用户的文档放到这里;那类内容应放在 konabot/docs/ 下。

对 AI Agents 的具体要求

如果你是 AI Agent请遵守以下约定

修改前

  • 先阅读将要修改的文件以及相关上下文,不要只凭文件名猜用途。
  • 先判断目标逻辑属于公共模块、用户文档,还是某个具体插件。
  • 如果需求可以在局部完成,就不要扩大改动范围。

修改时

  • 优先延续现有命名、目录结构和编码风格。
  • 不要因为“顺手”而批量格式化整个项目。
  • 不要擅自重命名大量文件、移动目录、替换现有架构。
  • 涉及用户输入、路径、网络、数据库、渲染时,主动补上必要的校验与防御。
  • 如果要新增 konabot/common/ 或其他会被多处依赖的模块,优先考虑 NoneBot2 框架下的依赖注入方式,而不是把全局状态或硬编码依赖散落到调用方。
  • 写文档时,区分清楚是给 man 系统看的,还是给仓库维护者看的。

修改后

  • 检查改动是否误伤其他插件或公共模块。
  • 如果新增了用户可见功能,考虑是否需要补充 konabot/docs/ 下对应文档。
  • 如果新增或调整了通用能力,考虑是否需要补充根目录 docs/ 下的说明。

插件开发建议

  • 单个插件内部优先保持自洽,不要把特定业务逻辑过早抽成公共模块。
  • 当多个插件开始重复同类逻辑时,再考虑上移到 konabot/common/
  • 插件应尽量对异常输入有稳定反馈,而不是直接抛出难理解的错误。
  • 如果插件会访问外部服务,要考虑超时、失败降级和返回内容校验。

最基本的用户交互书写建议

  • 先用清晰、可收敛的规则匹配消息,再进入处理逻辑,不要一上来就在 handler 里兜底解析所有输入。
  • 在 handler 里尽早提取纯文本、拆分命令和参数,并对缺失参数、非法参数、异常格式给出稳定反馈。
  • 如果用户输入只允许有限枚举值,先定义允许集合,再进行归一化和校验。
  • 输出优先保持简单直接;能一句话说明问题时,不要返回难懂的异常堆栈或过度技术化提示。
  • 涉及渲染、网络请求、图片生成等较重操作时,先确认输入合理,再执行昂贵逻辑。
  • 如果插件只是做单一交互,优先保持 handler 简短,把渲染、请求、转换等逻辑拆成独立函数。
  • 倾向于使用 UniMessage / UniMsg 这一套消息抽象来组织收发消息,而不是把平台细节和文本拼接散落在各处。
  • 倾向于显式构造返回消息并发送,而不是大量依赖 NoneBot2 原生的 .finish() 作为主要输出路径,除非该场景确实更简单清晰。

关于公共能力的依赖方式

  • 新建通用能力时,优先设计成可注入、可替换、可测试的接口。
  • 如果一个模块未来可能被多个插件依赖,优先考虑 NoneBot2 的依赖注入,而不是让调用方手动维护重复的初始化流程。
  • 除非确有必要,不要让插件直接依赖隐藏的全局副作用。
  • 如果使用单例、缓存或全局管理器,要明确其生命周期、并发行为以及关闭时机。

运行环境与部署限制

这个项目默认会跑在 Docker 环境里,修改功能时请先意识到运行环境不是一台“什么都有”的开发机。

容器环境

  • 运行时基础镜像是 python:3.13-slim,不是完整桌面 Linux很多系统库默认不存在。
  • 项目运行依赖 Playwright Chromium、字体库、图形相关库以及部分额外二进制工具。
  • 构建阶段和运行阶段是分离的;不要假设在 builder 里装过的系统包runtime 里也一定可用。
  • 额外制品目前通过多阶段构建放进镜像,例如 typst

Docker 相关要求

  • 如果你新增的 Python 依赖背后还需要 Linux 动态库、字体、图形库、编译工具或其他系统包,必须同步检查并在 Dockerfile 中补齐。
  • 不要只让本地虚拟环境能跑;要默认以容器可运行作为完成标准之一。
  • 如果新功能依赖系统命令、共享库、浏览器能力或字体,请在提交说明里明确写出原因。
  • .dockerignore 当前会排除 /.env/.git/data 等内容;不要依赖这些文件被复制进镜像。
  • 关于额外制品的管理,优先先阅读根目录文档 docs/artifact.md;适合统一管理的二进制或外部资源,倾向于复用 konabot/common/artifact.py,而不是在各插件里各自处理下载和校验。

本地运行

  • 本地开发可参考 justfile,当前主要入口是 just watch
  • 如果你的改动影响启动方式、依赖准备方式或运行命令,记得同步更新对应文档或脚本。

分支与协作流程

  • 本项目托管在个人 Gitea 实例:https://gitea.service.jazzwhom.top/mttu-developers/konabot
  • 如果需要创建 Pull Request优先倾向使用 tea CLIhttps://gitea.com/gitea/tea
  • Pull Request 创建后,当前主要会有自动机器人做初步评审,项目维护者会手动查看;不要催促立即合并,也不要默认会马上进主分支。
  • 如果当前是在仓库本体上直接开发、而不是在 fork 上工作,尽量提醒用户不要直接在主分支持续改动,优先使用功能分支。
  • 除非用户明确要求,否则不要擅自把改动直接合并到主分支。

文档编写建议

面向 man 的文档

  • 放在 konabot/docs/ 对应子目录。
  • 文件名直接对应用户查询名称。
  • 建议内容简洁,优先说明“做什么、怎么用、示例、注意事项”。
  • 使用 .txt 后缀;内容可以写成接近 markdown 的可读格式。

面向开发者的文档

  • 放在仓库根目录 docs/
  • 主要描述公共模块、配置方法、设计说明、维护经验。
  • 可以使用 .md