📑 目录(点击展开)
来自萌新到处学习(抄袭,不对是集百家之长✨)做出来私用的神秘项目 主要是按照自己的需求编写一个专到狭窄的学习性质的项目(专注于提供一个深度定制化的群聊机器人体验),发出来是用来交流学习的 你可以在里面了解到以下这些技术实践:
- 完整的 LLM 聊天全链路:从提示词构建、Function Calling、MCP 工具调用,到结构化 JSON 决策解析
- 两级记忆系统:短期滑动上下文 + LLM 压缩摘要,以及基于 pgvector 的长期向量记忆
- 混合检索(Hybrid RAG):向量检索 + 全文检索(pgroonga)双路召回,RRF 融合 + 时间衰减评分
- 依赖注入架构:基于单例
DIContainer的服务解耦与管理,全异步设计
项目结构清晰,核心链路注释详细,适合想了解「如何从零搭建一个 LLM Bot」的同学参考
一个基于 NapCat 对接、专注于群聊场景的 QQ Bot,所有能力均围绕群聊深度定制
完全自主实现的 LLM 聊天全链路,从输入处理到输出决策全部可控:
- 全异步高并发:回复流程完全异步,支持多供应商 Key 池轮询,多群并发场景下也能稳定运行。
- 结构化决策输出:模型以 JSON 格式返回结构化决策(
speak回复 /update更新画像 /silence静默),工具调用通过 Function Calling 循环执行,行为完全可控且易于扩展。 - 工具扩展能力:支持 Function Calling、MCP (Model Context Protocol) 协议工具集,以及 Skills 自定义提示词;内置 17 个工具(网页搜索、记忆读写、沙盒执行 Python/Shell、子代理、定时自触发等)。
- 两级记忆系统:
- 短期:每个群 / 用户维护独立的滑动上下文窗口,超限时由 LLM 自动压缩摘要、无损续接。
- 长期:对话结束后提取关键事件,经 Embedding 向量化后存入 PostgreSQL(pgvector),检索时采用向量 + 全文双路召回 + RRF 融合 + 时间衰减评分,让 Bot 有个比较可靠的长期记忆。
注:长期记忆聚焦于对话中的事件与偏好,不适用于存储长文档,对于聊天场景下已足够实用。
- 用户画像:为每位用户维护称呼、关系、性格、偏好等画像文档,嵌入每次对话上下文,保证跨会话态度一致。
- 高可用降级:主模型 API 出现异常时,自动按配置顺序切换到备用供应商和模型,保证有问必达。
- 拟人化交互:
- 自然发送表情包,支持分段回复模拟真实打字节奏。
- 达到条件时主动融入群聊话题,而不只是被动等待 @。
- 支持人设切换等基础功能。
在群里 @bot 后以 / 开头即可触发(例如 @atri-bot /help --list,需使用QQ的@而非直接输入名字):
- 参数解析:支持
-/--参数风格,内置参数类型校验。 - 权限管理:内置多级权限系统,支持拉黑或授予管理员权限,可在任意处理环节拒绝非法调用。
- 自动帮助文档:通过装饰器声明参数描述后,
--help文档自动生成,无需手写。
- 插件系统:
atribot/plugins/下的插件启动时自动加载,支持消息/通知/请求事件订阅与管道中间件,可热重载。 - 子 Agent 协作:
sub_agent工具可将复杂多步任务委派给独立子代理(自带工具集 + LLM 循环)执行。 - 定时自触发:
schedule_self_trigger工具可让 Bot 在指定时间主动发起一次群聊思考。 - 高性能关键词匹配:关键词响应底层采用 AC 自动机,即使配置上万条规则也能保持毫秒级响应。
- 群成员变动提醒:成员加入或退出时自动通知。
- 戳一戳互动:被戳时不只会响应,还会「戳回去」。
- 稳健架构基础:数据库连接池 + 消息队列,从容应对并发压力。
首先需要一个能够与 QQ 通信的前端,推荐使用 NapCat:
注:你也可以自己实现前端,只要能对接上即可。
项目当前仅支持 PostgreSQL 数据库。
- 安装数据库:建议安装较新的 PostgreSQL 版本。官方安装文档
- 安装数据库插件:
- 必须安装
pgvector(向量检索)pgvector 项目地址 - 必须安装
pgroonga(全文检索)PGroonga 文档
- 必须安装
- 数据库初始化:
项目提供了初始化 SQL 文件,推荐使用
docker/db/info.sql(含完整表结构与扩展配置)。 也可参考atribot/docs/PostgreSQL基础.sql(开发版)。 进入数据库(Linux 示例):然后按顺序执行 SQL 文件创建表结构。sudo -u postgres psql
推荐优先使用本地的 dengcao/Qwen3-Embedding-0.6B:F16。当然你也可以接入其他 Embedding API(OpenAI 格式兼容),只是仓库里目前主要按 Ollama 的使用方式测试过。
推荐使用 Ollama 进行本地部署:
ollama run dengcao/Qwen3-Embedding-0.6B:F16注意:如果更换 Embedding 模型,之前构建的向量数据需要重新构建。
支持接入 GPT-SoVITS。
实现 Bot 主动发送语音或通过命令调用语音功能,可以设置语速、情感等常用参数;当然前提是你已经准备好了自己的语音模型。
使用前需要修改 atribot/commands/audio/TTS.py 中的参考音频路径,以及 GPT-SoVITS 接口端口地址。
{
"这里是对应的情感": {
"refer_wav_path": "这里是参考音频的完整路径",
"prompt_text": "参考音频的对应文本",
"prompt_language": "参考文本对应的语言"
},
"平静": {
"refer_wav_path": "/home/atri/tts_reference/夏生さんが望むのでしたら.mp3",
"prompt_text": "夏生さんが望むのでしたら",
"prompt_language": "ja"
}
}为 AI 模型配备了默认的代码沙盒环境,使其能够安全地执行用户请求或自主生成的代码片段。当前实现基于 Docker 🐳沙盒,支持运行 Python 等语言的代码,可用于代码解释、数据计算等场景。
- 扩展性:如需支持其他类型的沙盒(如 Web 沙盒、系统命令沙盒),可继承
atribot/LLMchat/sandbox/sandbox_base.py中的基类并实现相应接口。 - 文件操作:AI 上下文中能够看到的文件可以放到 Python 环境中进行简单处理。
如果要使用默认的 Docker 沙盒,需要本机安装 Docker,并先在项目根目录构建沙盒镜像:
docker build -t atri-sandbox:latest -f atribot/LLMchat/sandbox/Dockerfile .然后在 assets/config.json 的 sand_box 中指定该镜像名(默认 atri-sandbox:latest)即可。沙盒为可选能力,初始化失败不会阻断 Bot 启动。
关于沙盒镜像的构建、逐段解读、自定义扩展与常见问题,详见 沙盒 Dockerfile 教程。
在启动前,请务必检查 assets 目录中的配置:
- 将
config copy.json重命名为config.json并配置(记得查看如何配置配置文件.py)。其中model.connect指定主模型供应商与模型名,model.chat_parameter控制采样参数(temperature/top_p/max_tokens/stream/tool_choice),model.standby_model维护备用模型列表。 - 平台连接:
config.platforms.<name>配置与 NapCat 的对接方式(adapter固定为onebot,connection_type支持WebSocket_client/WebSocket_server/http,access_token需与 NapCat 一致,url为地址)。 - 将
supplier_config copy.json重命名为supplier_config.json并配置(模型供应商配置,支持任意 OpenAI 兼容的)。cp "assets/config copy.json" assets/config.json cp "assets/supplier_config copy.json" assets/supplier_config.json
- MCP 配置:默认路径在
atribot/LLMchat/MCP/mcp_server.json,可通过"active": false控制特定 MCP 工具是否启用。 - Skills 文件夹:默认路径在
atribot/LLMchat/skills/agent_skills。 - 根目录
document/下可按项目结构放置音频、表情包等资源文件。 - 表情包:在
document/img/emojis文件夹下新建文件名代表内部表情的文件夹,放入对应名称的图片(支持 .jpg, .jpeg, .png, .gif),LLM 即可在聊天中自然发送。
项目依赖 Python 3.14 环境,推荐使用 uv 管理依赖。
使用 uv (推荐):
# 进入项目根目录
uv sync
uv run main.py使用 pip:
Linux / macOS 请分别使用 requirements-linux.txt、requirements-macos.txt。
pip install -r requirements-windows.txt
python main.py
⚠️ 重要:请务必在项目根目录执行启动命令,否则可能出现路径解析错误。
仓库已经补齐了可直接运行的 Docker Compose 配置,默认会启动:
atri-db:带pgvector + pgroonga的 PostgreSQLatri-bot:ATRI 主程序容器
首次使用前,至少确认两件事:
assets/supplier_config.json中的模型接口可用。- NapCat 能连接到
ws://宿主机IP:8888/websocket?access_token=你的token。
推荐先复制一份环境变量文件:
cp .env.docker.example .env注意:请检查
.env文件中的端口与 Token 设置,确保与 NapCat 配置一致。
环境变量说明(.env.docker.example):
| 变量 | 说明 | 默认值 |
|---|---|---|
ATRI_DB_SUPERUSER_PASSWORD |
PostgreSQL 超级用户密码 | 180710 |
ATRI_DB_NAME |
应用数据库名称 | atri |
ATRI_DB_APP_USER |
应用数据库用户 | atri |
ATRI_DB_APP_PASSWORD |
应用数据库密码 | 180710 |
ATRI_DB_PORT_FORWARD |
宿主机映射端口 | 5432 |
ATRI_BOT_PORT |
Bot WebSocket 服务端口 | 8888 |
ATRI_ACCESS_TOKEN |
NapCat 连接验证 Token | ATRI114514 |
ATRI_CONNECTION_TYPE |
连接类型(WebSocket_server/client) | WebSocket_server |
ATRI_NAPCAT_URL |
NapCat WebSocket 地址(客户端模式) | host.docker.internal:3001 |
ATRI_SANDBOX_IMAGE |
AI 沙盒使用的 Docker 镜像 | python:3.14-slim |
TZ |
容器时区 | Asia/Shanghai |
然后直接启动:
docker compose up -d --build如果你已经跑过旧版本数据库结构,升级后建议先清理旧数据卷再重建:
docker compose down -v
docker compose up -d --build查看日志:
docker compose logs -f app
docker compose logs -f db停止并删除容器:
docker compose down如果需要连数据库看表:
docker compose exec db psql -U postgres -d postgres说明:
- 容器启动时会基于
assets/config.json生成一份运行时配置,不会覆盖你原本的本地配置。 - 默认把宿主机的
assets/、document/、log/、temp/挂进容器,便于直接改配置和保留运行数据。 - 内置 AI 沙盒默认只做镜像名覆盖;如果你还想让容器内再调用 Docker 沙盒,需要额外挂载 Docker Socket。
ATRI-main/
├─main.py # 项目入口
├─pyproject.toml # Python 项目依赖与构建配置
├─docker-compose.yml # Docker Compose 启动配置
├─.env.docker.example # Docker 环境变量示例
├─README.md / README.en.md # 中英文说明文档
├─requirements-*.txt # 各平台依赖导出文件
├─tests/ # 🧪 单元测试与集成测试
├─assets/ # ⚙️ 配置文件与示例
├─atribot/ # 核心代码
│ ├─bot_framework.py # Bot 初始化与服务装配入口
│ ├─commands/ # 💻 群聊命令实现
│ │ ├─audio/ # 音频与 TTS 相关命令
│ │ ├─bromidic/ # 图片 / B 站等杂项功能命令
│ │ ├─interior/ # 内部管理与状态查询命令
│ │ └─test/ # 实验性 / 测试命令
│ ├─common_utils/ # 通用工具函数
│ │ ├─cluster_utils.py # 图聚类与连通分量分析
│ │ ├─data_manage.py # 数据管理工具
│ │ ├─db_format.py # 数据库格式化
│ │ ├─http_client.py # 异步 HTTP 客户端
│ │ ├─json_utils.py # JSON 处理与序列化
│ │ ├─message_utils.py # 消息处理工具
│ │ ├─music.py # 音乐分享工具
│ │ ├─request_header.py # HTTP 请求头配置
│ │ ├─similarity.py # 文本相似度计算
│ │ ├─timer.py # 计时与限频工具
│ │ ├─validation.py # 参数验证工具
│ │ └─file/ # 文件、图片、文本处理
│ │ ├─file_utils.py # 文件操作工具
│ │ ├─image_utils.py # 图片处理与压缩
│ │ ├─media_utils.py # 媒体文件处理
│ │ └─text_utils.py # 文本清洗与格式化
│ ├─core/ # 核心架构
│ │ ├─atri_config.py # 配置加载与管理
│ │ ├─logger.py # 日志系统
│ │ ├─service_container.py # 依赖注入容器 (DIContainer)
│ │ ├─time_trigger.py # 定时任务调度器
│ │ ├─cache/ # 上下文缓存与生命周期管理
│ │ ├─command/ # 命令系统与权限管理
│ │ ├─db/ # 数据库连接与数据访问
│ │ ├─event_bus/ # 事件总线(按 PostType 分发监听器)
│ │ ├─pipeline/ # 中间件管道(含群白名单 WhitelistMiddleware)
│ │ ├─platform/ # 多平台适配层(适配器 / 消息队列 / 发送客户端)
│ │ ├─network_connections/ # 发送客户端(QQAPIClient 等)
│ │ └─type/ # 核心类型定义(事件信封 / 消息段)
│ ├─docs/ # 开发文档与笔记
│ ├─LLMchat/ # 🧠 LLM 聊天与 Agent 能力
│ │ ├─chat.py # 群聊/私聊对话处理入口
│ │ ├─emoji_system.py # 表情包管理与自然发送
│ │ ├─initiative_chat.py # 主动发起群聊话题
│ │ ├─LLM_supervisor.py # LLM 调度与降级策略
│ │ ├─media_processor.py # 多模态消息转文本
│ │ ├─prepare_model_prompt.py # 提示词构建与组装
│ │ ├─token_manage.py # Token 用量统计与管理
│ │ ├─agent/ # 子 Agent 系统
│ │ ├─character_setting/ # 人设预设(15+ 角色)
│ │ ├─discard_tools/ # 已废弃 / 旧版工具
│ │ ├─MCP/ # MCP 协议工具集成
│ │ │ ├─mcp_tool_manager.py # MCP 工具管理器
│ │ │ ├─tool_calls.py # 工具调用编排
│ │ │ ├─tool_executor.py # 工具执行引擎
│ │ │ ├─tool_model.py # 工具数据模型
│ │ │ └─local_mcp_tools/ # 本地 MCP 工具集
│ │ ├─memory/ # 记忆系统
│ │ │ ├─memory_system.py # 记忆系统门面
│ │ │ ├─memory_extractor.py # LLM 记忆提取
│ │ │ ├─memory_retriever.py # 向量 + 全文混合检索
│ │ │ ├─memory_consolidator.py # 记忆合并去重
│ │ │ ├─user_info_system.py # 用户画像系统
│ │ │ └─prompts.py # 记忆提示词模板
│ │ ├─model_api/ # 模型供应商接口
│ │ ├─RAG/ # 检索增强生成(含 vector_store.py 向量存储 / MemoryCategory)
│ │ ├─sandbox/ # 代码沙盒环境
│ │ ├─skills/ # Agent Skills 管理
│ │ │ ├─skills_manager.py # Skills 加载与管理
│ │ │ ├─validator.py # YAML 属性验证
│ │ │ ├─parser.py # Markdown 解析
│ │ │ ├─models.py # 数据模型
│ │ │ └─agent_skills/ # Skills 提示词文件
│ │ └─tools/ # 函数调用工具集(共 17 个)
│ │ ├─web_search/ # 网页搜索
│ │ ├─web_extract/ # 网页内容提取
│ │ ├─run_python_code/ # 沙盒 Python 执行
│ │ ├─run_command/ # 沙盒 Shell 命令
│ │ ├─memory_search/ # 记忆检索
│ │ ├─memory_storage/ # 记忆写入
│ │ ├─send_image_message/ # 图片消息发送
│ │ ├─send_speech_message/ # 语音消息发送
│ │ ├─send_file / add_file # 沙盒文件进出
│ │ ├─schedule_self_trigger # 定时自触发
│ │ ├─sub_agent/ # 子代理
│ │ ├─load_skill_prompt/ # Skills 提示词加载
│ │ └─... # 其余工具
│ ├─plugins/ # 🔌 插件系统
│ │ ├─plugin.py # Plugin 基类(事件 / 中间件装饰器)
│ │ ├─manager.py / loader.py # 插件管理器与加载器(热重载)
│ │ ├─emoji_like/ # 消息贴表情镜像
│ │ ├─group_manager/ # 群管理 + 关键词回复 + 加群审批
│ │ └─poke_reaction/ # 戳一戳反馈
│ ├─log/ # 运行时日志(每日轮转,保留 7 天)
│ └─web_panel/ # Web 管理面板(当前未启用)
├─docker/ # 🐳 Docker 相关资源
│ ├─db/ # 数据库初始化脚本与镜像文件
│ └─python/ # Python 容器环境相关资源
├─document/ # 🎨 运行时资源目录
│ ├─audio/ # 音频素材
│ ├─file/ # 通用文本 / 文件资源
│ ├─img/ # 图片资源
│ │ ├─ATRI_qrcode/ # 二维码资源
│ │ ├─emojis/ # 表情包目录
│ │ └─tmp/ # 临时图片目录
│ ├─video/ # 视频资源
│ └─temp/ # 临时运行文件
NapCat (QQ客户端)
│ WebSocket / HTTP
▼
平台适配器 (OneBotAdapter,支持多平台)
│
▼
MessageQueue (消息队列)
│
▼
Pipeline (WhitelistMiddleware 群白名单过滤)
│
▼
EventBus (按 PostType 分发)
│
├──► AtCommandRule 路由 (@bot /cmd 命令 → CommandSystem)
├──► 插件事件处理器 (Plugin.on_message / on_notice 等)
└──► initiativeChat 路由 (普通聊天 / 主动对话 → LLM 决策)
群聊由 GroupChat 处理,私聊由 PrivateChat 处理;命令与聊天两条路由在 bot_framework._register_at_routes() 注册,插件处理器由 PluginManager 在启动时自动扫描并挂载。
支撑系统:除了消息主干,项目还包含以下后台支撑模块——
| 模块 | 说明 |
|---|---|
PlatformManager |
多平台适配器管理器,持有 MessageQueue + Pipeline + EventBus |
PluginManager |
插件系统:自动扫描加载 atribot/plugins/,支持热重载 |
TimeTriggerSupervisor |
定时任务调度器,支持延迟任务、固定间隔和 Cron 表达式 |
MediaProcessor |
多模态消息处理器,将图片 / 音频 / 视频统一转为文本供 LLM 理解 |
agent/ 子 Agent 系统 |
用于委派复杂多步任务,支持上下文隔离与工具链编排 |
PermissionsManagement |
四级权限校验(黑名单 → 普通用户 → 管理员 → Root) |
LLM 聊天的核心链路在 atribot/LLMchat/ 目录下,整体采用全异步流水线设计:
用户消息 (MessageEventEnvelope)
│
▼
chat.py → GroupChat.step() ← 聊天主入口
│
├─① prompt_structure() 构建提示词
│ ├─ 群聊历史 (近期消息窗口)
│ ├─ 用户画像 (UserSystem)
│ ├─ 最近记忆片段 (MemorySystem.query_user_recently_memory)
│ ├─ 表情包提示词 (EmojiCore)
│ └─ Skills 提示词 (SkillsManager)
│
├─② LLMCoordinator.run() 调度模型请求
│ ├─ 主模型请求 (model_api)
│ ├─ Function Calling 循环 (MCP/tools)
│ └─ 主模型失败时降级备用模型 (_request_model_with_fallback_)
│
├─③ 解析 JSON 响应 模型输出结构化决策
│ ├─ "speak" → 回复消息 (分段发送 / 表情包)
│ ├─ "update" → 更新用户画像
│ ├─ "silence" → 不回复
│ └─ 工具调用 → 通过 Function Calling 循环执行 (MCP / 本地工具)
│
└─④ 事后处理
├─ 上下文写回 (ChatManager)
└─ 上下文超长时触发 summarize_context() 压缩
高可用降级机制:当主模型 API 响应异常时,_request_model_with_fallback_ 会按照 config.model.standby_model 列表依次尝试备用供应商和模型,保证即使主力 Key 失效也能正常回复。
结构化输出:模型被要求返回 JSON 格式的决策列表(return 数组),每一项包含 decision 字段,使回复行为完全可控和可扩展。
记忆系统分为短期上下文缓存和长期向量记忆两层:
- 每个群/用户维护一个滑动的消息窗口
Context,直接嵌入每次请求的messages列表。 - 当上下文 token 数超限时,触发
MemorySystem.summarize_context()对旧消息进行 LLM 压缩摘要,压缩后的文本以assistant角色消息插入上下文头部,简单的进行记忆压缩。
聊天结束后
│
▼
MemorySystem.extract_stored_group_message()
│
├─ LLM 信息提取 (PURE_GROUP_FACT_RETRIEVAL_PROMPT)
│ └─ 输出结构化 JSON:per-user 事件 + 群话题
│
├─ RAGManager.calculate_embedding() 文本 → 1024维向量
│
└─ MemoryVectorStore.batch_add_memories() 写入 PostgreSQL atri_memory 表
记忆分类 (MemoryCategory):
| 分类 | 含义 | 时间半衰期 |
|---|---|---|
preference |
用户偏好 | 90 天 |
fact |
事实性记忆(默认) | 90 天 |
experience |
经历记忆 | 60 天 |
emotion |
情感记忆 | 30 天 |
group_topic |
群聊话题 | 7 天 |
knowledge |
通用知识 | ~10 年 |
domain |
领域专业知识 | ~10 年 |
guideline |
行为准则 | ~10 年 |
混合召回 (hybrid_recall):使用一条带 CTE 的 SQL 同时进行向量检索(pgvector 余弦距离)和全文检索(pgroonga),再通过 RRF(Reciprocal Rank Fusion)融合两路结果,最终叠加重要度、访问频次和时间衰减进行综合排序。
查询文本
│
├─ pgvector 向量路 (余弦距离,取前 40 候选)
├─ pgroonga 全文路 (全文评分,取前 40 候选)
│
└─ RRF 融合
+ importance / 10.0 × 权重
+ ln(1 + access_count) × 权重
+ EXP(-λ × age_days) × 时间衰减 (λ 按 category 差异化)
│
└─► 返回 Top-N 记忆
记忆自动更新与演进 (Memory Consolidator): 系统不仅支持写入和提取,还拥有针对零散片段和冲突信息的持续维护能力:
定期维护 / 新记忆提取
│
▼
冲突检测与聚类 (Cluster Utils)
│
├─ 相似度图构建 (基于 pgvector 检索获取高相似度边)
├─ 连通分量聚类 (同类同用户的相近记忆归结为 Cluster)
│
└─ 顺序安全处理机制
├─ LLM 内容合并 (解决冲突/信息动态拓展)
├─ update_memory (继承最高权重并更新向量)
└─ batch_delete (删除其余冗余碎片节点)
- 记忆动态更新:不仅是单纯的追加记录,当新提取的记忆和旧记忆发生冲突或具备连续性时,系统会调用 LLM 对既有记忆进行内容更新和属性拓展,打破原有的只增不改限制。
- 后台碎片整理:内置定时记忆维护任务,利用连通图和簇(Cluster)聚类分析近期高频且相似的记忆,通过顺序安全的非并发机制交由 LLM 执行合并和去重操作,防止重复信息冗余堆叠。
- 动态清理:严格基于记忆类型和其特有的半衰期配置,定期自动触发过期清扫,自动遗忘失去时效性的高能群话题和日常零碎记忆。
用户画像 (UserSystem):为每个用户维护一份 JSON 画像文档(称呼、关系、性格、近期话题、偏好风格等),在每次对话的 prompt 中嵌入,确保 Bot 对同一用户的态度前后一致,画像由 LLM 在对话后自动更新。
欢迎提交 Issue、PR,或者直接提出改进建议。 无论是修 Bug、补文档、优化架构,还是扩展新能力,都非常欢迎。
本项目遵循 MIT License 协议。 详情请参阅 LICENSE 文件。

