graph TB
%% ==================== 外部实体 ====================
subgraph External["外部实体层"]
User([用户 User])
Admin([管理员 Admin])
OneBotServer["OneBot 协议端<br/>(NapCat / Lagrange.Core)"]
LLM_API["大模型 API 服务商<br/>(OpenAI / Claude / DeepSeek / etc.)"]
end
%% ==================== 核心入口层 ====================
subgraph EntryPoint["核心入口层 (src/Undefined/)"]
Main["main.py<br/>启动入口"]
ConfigLoader["ConfigManager<br/>配置管理器<br/>[config/manager.py + loader.py]"]
ConfigHotReload["ConfigHotReload<br/>热更新应用器<br/>[config/hot_reload.py]"]
ConfigModels["配置模型<br/>[config/models.py]<br/>ChatModelConfig<br/>VisionModelConfig<br/>SecurityModelConfig<br/>AgentModelConfig"]
OneBotClient["OneBotClient<br/>WebSocket 客户端<br/>[onebot/ + onebot.py shim]"]
Context["RequestContext<br/>请求上下文<br/>[context.py]"]
WebUI["webui.py<br/>配置控制台<br/>[src/Undefined/webui.py]"]
end
%% ==================== 消息处理层 ====================
subgraph MessageLayer["消息处理层 (src/Undefined/)"]
MessageHandler["MessageHandler<br/>消息处理器<br/>[handlers/]"]
AutomationService["AutomationService<br/>自动化运行时<br/>[automations/service.py]<br/>• 事件匹配 • DAG 执行<br/>• APScheduler 时间触发"]
subgraph BilibiliModule["Bilibili 模块 (bilibili/)"]
BilibiliParser["parser.py<br/>标识符解析<br/>• BV/AV号 • URL<br/>• b23.tv短链 • 小程序JSON"]
BilibiliDownloader["downloader.py<br/>视频下载<br/>• DASH流 • ffmpeg合并"]
BilibiliSender["sender.py<br/>视频发送<br/>• 视频消息 • 降级信息卡片"]
end
subgraph GitHubModule["GitHub 模块 (github/)"]
GitHubParser["parser.py<br/>仓库标识解析<br/>• URL • SSH • owner/repo • JSON"]
GitHubClient["client.py<br/>public API 获取<br/>• 仓库信息 • contributors"]
GitHubSender["sender.py<br/>图片卡片发送<br/>• 头像 • 简介 • 统计"]
end
subgraph SecurityLayer["安全防线 (services/)"]
SecurityService["SecurityService<br/>安全服务<br/>• 注入攻击检测<br/>• 速率限制<br/>[security.py]"]
InjectionAgent["InjectionResponseAgent<br/>注入响应生成<br/>[injection_response_agent.py]"]
end
CommandDispatcher["CommandDispatcher<br/>命令分发器<br/>• /help /stats /admin<br/>• /bugfix /faq<br/>[services/command.py]"]
MessageBatcher["MessageBatcher<br/>同 sender 短时合并<br/>• 按 (scope, sender_id) 分桶<br/>• T1=window_seconds 结束 batch<br/>• T2=pre_send_seconds 投机预发送<br/>• 拍一拍/buffer 内 @bot 旁路<br/>• 首条 @bot 整批走 mention 队列<br/>[services/message_batcher/ + shim]"]
subgraph QueueSystem["车站-列车 队列系统 (services/)"]
AICoordinator["AICoordinator<br/>AI 协调器<br/>• Prompt 构建<br/>• 队列管理<br/>• 回复执行<br/>[services/coordinator/ + ai_coordinator.py shim]"]
QueueManager["QueueManager<br/>队列管理器<br/>[queue_manager.py]"]
subgraph ModelQueues["ModelQueue 队列组 (按模型隔离)"]
Q_SuperAdmin["超级管理员队列<br/>优先级: 最高"]
Q_Private["私聊队列<br/>优先级: 高"]
Q_Mention["群聊 @队列<br/>优先级: 中"]
Q_Normal["群聊普通队列<br/>优先级: 普通<br/>自动修剪: 保留最新2条"]
end
DispatcherLoop[("按模型节奏<br/>发车循环<br/>默认 1Hz")]
end
end
%% ==================== AI 核心能力层 ====================
subgraph AILayer["AI 核心能力层 (src/Undefined/ai/)"]
AIClient["AIClient<br/>AI 客户端主入口<br/>[ai/client/ + client.py shim]<br/>• 技能热重载 • MCP 初始化<br/>• Agent intro 生成"]
subgraph AIComponents["AI 组件"]
PromptBuilder["PromptBuilder<br/>提示词构建器<br/>[ai/prompts/ + prompts.py shim]"]
ToolSearchSession["ToolSearchSession<br/>请求级工具按需投影<br/>[ai/tool_search.py]<br/>• 名称检索 • schema 逐轮扩展"]
ModelRequester["ModelRequester<br/>模型请求器<br/>[ai/llm/ + llm.py shim]<br/>• OpenAI SDK • 工具清理<br/>• Thinking 提取"]
ToolManager["ToolManager<br/>工具管理器<br/>[tooling.py]<br/>• 工具执行 • Agent 工具合并<br/>• MCP 工具注入"]
MultimodalAnalyzer["MultimodalAnalyzer<br/>多模态分析器<br/>[ai/multimodal/ + multimodal.py shim]<br/>• 图片/音频/视频"]
SummaryService["SummaryService<br/>总结服务<br/>[summaries.py]<br/>• 聊天记录总结<br/>• 标题生成"]
TokenCounter["TokenCounter<br/>Token 统计<br/>[tokens.py]"]
Parsing["Parsing<br/>响应解析<br/>[parsing.py]"]
end
end
%% ==================== 技能系统层 ====================
subgraph SkillsLayer["Skills 技能系统 (src/Undefined/skills/)"]
subgraph RegistryLayer["注册表核心"]
ToolRegistry["ToolRegistry<br/>工具注册表<br/>[registry.py]<br/>• 延迟加载 • 热重载支持<br/>• 执行统计"]
AgentRegistry["AgentRegistry<br/>Agent 注册表<br/>[registry.py]<br/>• Agent 发现 • 工具聚合"]
AgentToolRegistry["AgentToolRegistry<br/>Agent 专用工具注册表<br/>[agents/agent_tool_registry.py]<br/>• MCP 支持"]
IntroGenerator["IntroGenerator<br/>Agent 介绍生成器<br/>[agents/intro_generator.py]<br/>• 自动 hash 检测<br/>• intro.generated.md"]
AnthropicSkillRegistry["AnthropicSkillRegistry<br/>Anthropic Skills 注册表<br/>[anthropic_skills/]<br/>• SKILL.md 解析<br/>• 渐进式披露"]
end
subgraph AtomicTools["基础工具 (skills/tools/)"]
T_End["end<br/>结束对话"]
T_Python["python_interpreter<br/>Python 解释器"]
T_Time["get_current_time<br/>获取当前时间"]
T_GetPicture["get_picture<br/>获取图片"]
T_GetUserInfo["get_user_info<br/>获取用户信息"]
T_ArxivPaper["arxiv_paper<br/>arXiv 论文发送 / UID 获取"]
T_BilibiliVideo["bilibili_video<br/>B站视频下载发送 / UID 获取"]
end
subgraph Toolsets["工具集 (skills/toolsets/, 13大类)"]
TS_Group["group.*<br/>• get_member_list<br/>• get_member_info<br/>• get_honor_info<br/>• get_files"]
TS_Messages["messages.*<br/>• send_message<br/>• get_recent_messages<br/>• get_forward_msg"]
TS_Memory["memory.*<br/>• add / delete<br/>• list / update"]
TS_Contacts["contacts.*<br/>• query_friends<br/>• query_groups"]
TS_GroupAnalysis["group_analysis.*<br/>• member_structure<br/>• message_mix<br/>• member_activity<br/>• activity_trend<br/>• inactive_risk<br/>• member_messages<br/>• join_statistics<br/>• new_member_activity"]
TS_Notices["notices.*<br/>• list / get / stats"]
TS_Render["render.*<br/>• render_html<br/>• render_latex<br/>• render_markdown"]
TS_Automation["automation.*<br/>• list / get / create<br/>• update / delete / set_enabled"]
TS_Cognitive["cognitive.*<br/>• search_events<br/>• get_profile<br/>• search_profiles"]
TS_MCP["mcp.*<br/>MCP 工具集"]
TS_Memes["memes.*<br/>• search_memes<br/>• send_meme_by_uid"]
end
subgraph IntelligentAgents["智能体 Agents (skills/agents/, 7个)"]
A_Info["info_agent<br/>信息查询助手<br/>(18个工具)<br/>• weather_query<br/>• *hot 热搜<br/>• bilibili_*<br/>• arxiv_search<br/>• whois"]
A_Web["web_agent<br/>网络搜索助手<br/>(4个工具 + MCP)<br/>• grok_search<br/>• firecrawl_search<br/>• web_search<br/>• crawl_webpage<br/>• Playwright MCP"]
A_File["file_analysis_agent<br/>文件分析助手<br/>• extract_* (PDF/Word/Excel/PPT)<br/>• describe_pdf_page<br/>• analyze_code<br/>• analyze_multimodal"]
A_Naga["naga_code_analysis_agent<br/>NagaAgent 代码分析<br/>(7个工具)<br/>• read_file / glob<br/>• search_file_content"]
A_Self["undefined_self_code_agent<br/>Undefined 自身代码查阅<br/>(4个工具)<br/>• read_file / list_directory<br/>• glob / search_file_content"]
A_Entertainment["entertainment_agent<br/>娱乐助手<br/>(9个工具)<br/>• ai_draw_one<br/>• horoscope<br/>• video_random_recommend"]
A_Code["code_delivery_agent<br/>代码交付助手<br/>(13个工具)<br/>• Docker 容器隔离<br/>• Git 仓库克隆<br/>• 代码编写验证<br/>• 打包上传"]
end
subgraph CommandsLayer["平台指令 (skills/commands/)"]
Cmd_Core["核心指令<br/>• help • stats"]
Cmd_Admin["管理指令<br/>• admin (ls/add/del)"]
Cmd_FAQ["FAQ 指令<br/>• faq (ls/view/search/del)"]
Cmd_Fun["娱乐指令<br/>• bugfix"]
end
subgraph MCPIntegration["MCP 集成 (src/Undefined/mcp/)"]
MCPRegistry["MCPToolRegistry<br/>MCP 工具注册表<br/>[registry.py]<br/>• 连接 MCP Server<br/>• 工具转换"]
MCP_Config["MCP 配置<br/>config/mcp.json<br/>(全局配置)"]
MCP_Agent_Private["Agent 私有 MCP<br/>mcp.json<br/>(按 Agent)"]
end
subgraph AnthropicSkills["Anthropic Skills (skills/anthropic_skills/)"]
AS_Registry["AnthropicSkillRegistry<br/>Skills 注册表<br/>[anthropic_skills/__init__.py]<br/>• 自动发现 • 热重载"]
AS_Loader["SKILL.md 解析器<br/>[anthropic_skills/loader.py]<br/>• YAML frontmatter<br/>• Markdown body"]
AS_Global["全局 Skills<br/>skills/anthropic_skills/<br/>• pdf-processing<br/>• code-review"]
AS_Agent["Agent 私有 Skills<br/>agents/<name>/anthropic_skills/"]
end
end
%% ==================== 存储与上下文层 ====================
subgraph StorageLayer["存储与上下文层 (src/Undefined/)"]
subgraph ContextLayer["上下文管理"]
RequestContext["RequestContext<br/>[context.py]<br/>• UUID 追踪<br/>• 资源容器<br/>• 自动传播"]
ContextFilter["RequestContextFilter<br/>日志过滤器<br/>• request_id<br/>• group_id / user_id"]
ResourceRegistry["ContextResourceRegistry<br/>资源注册表<br/>[context_resource_registry.py]<br/>• 动态扫描"]
end
subgraph StorageComponents["存储组件"]
HistoryManager["MessageHistoryManager<br/>消息历史管理<br/>[utils/history.py]<br/>• 懒加载<br/>• 10000条限制"]
MemoryStorage["MemoryStorage<br/>置顶备忘录<br/>[memory.py]<br/>• 500条上限<br/>• 自动去重"]
EndSummaryStorage["EndSummaryStorage<br/>短期总结存储<br/>[end_summary_storage.py]"]
CognitiveService["CognitiveService<br/>认知记忆服务<br/>[cognitive/service/]<br/>• 事件检索 • 侧写读取<br/>• 入队 memory job"]
CognitiveJobQueue["JobQueue<br/>认知任务队列<br/>[cognitive/job_queue.py]<br/>• pending/processing/failed"]
CognitiveHistorian["HistorianWorker<br/>后台史官<br/>[cognitive/historian/]<br/>• 独立事实改写 • 闸门重试<br/>• 侧写合并(最新优先/去冗)"]
CognitiveVectorStore["CognitiveVectorStore<br/>向量存储<br/>[cognitive/vector_store.py]<br/>• events/profiles<br/>• 时间衰减加权排序<br/>• MMR 去重"]
CognitiveProfileStorage["ProfileStorage<br/>侧写存储<br/>[cognitive/profile_storage.py]<br/>• users/groups Markdown<br/>• 历史快照"]
MemeSystem["MemeSystem<br/>表情包存储<br/>[memes/]<br/>• worker.py (两阶段识别)<br/>• sqlite+chromadb<br/>• blob 持久化"]
FAQStorage["FAQStorage<br/>FAQ 存储<br/>[faq.py]<br/>• data/faq/{group_id}/"]
AutomationStorage["AutomationStorage<br/>自动化存储<br/>[automations/storage.py]"]
TokenUsageStorage["TokenUsageStorage<br/>Token 使用统计<br/>[token_usage_storage.py]<br/>• 自动归档<br/>• gzip 压缩<br/>• 流式可选 TTFT/TPS"]
end
subgraph IOLayer["异步 IO 层 (src/Undefined/utils/)"]
IOUtils["IO 工具<br/>[io.py]<br/>• write_json<br/>• read_json<br/>• append_line<br/>• 文件锁 (flock/msvcrt) + 原子写入"]
CacheUtils["缓存工具<br/>[cache.py]<br/>• 定期清理"]
SenderUtils["Sender 工具<br/>[sender.py]"]
end
end
%% ==================== 数据持久化层 ====================
subgraph Persistence["数据持久化层 (data/)"]
Dir_History["history/<br/>• group_{id}.json<br/>• private_{id}.json"]
Dir_FAQ["faq/<br/>• {group_id}/<br/> - {date}-{seq}.json"]
Dir_TokenUsage["token_usage_archives/<br/>• token_usage.jsonl<br/>• *.jsonl.gz"]
Dir_Cognitive["cognitive/<br/>• chromadb/<br/>• profiles/<br/>• queues/"]
File_Memory["memory.json<br/>(置顶备忘录)"]
File_EndSummary["end_summaries.json<br/>(短期总结)"]
File_ScheduledTasks["automations.json<br/>(自动化)"]
Dir_Logs["logs/<br/>• bot.log<br/>• 轮转日志"]
File_Config["config.toml<br/>config.local.json"]
end
%% ==================== 资源文件层 ====================
subgraph Resources["资源文件层 (res/)"]
Prompts["prompts/<br/>• undefined.xml<br/>• agent_self_intro.txt<br/>• analyze_multimodal.txt"]
Intros["agents/intro/<br/>• intro.md<br/>• intro.generated.md"]
end
%% ==================== 连接线 ====================
%% 外部实体到核心入口
User -->|"消息"| OneBotServer
Admin -->|"指令"| OneBotServer
OneBotServer <-->|"WebSocket<br/>Event / API"| OneBotClient
%% 核心入口层内部
Main -->|"初始化"| ConfigLoader
Main -->|"订阅变更"| ConfigHotReload
Main -->|"创建"| OneBotClient
Main -->|"创建"| AIClient
ConfigLoader --> ConfigModels
ConfigLoader -->|"读取"| File_Config
ConfigLoader -->|"变更回调"| ConfigHotReload
ConfigHotReload -->|"热更新"| AIClient
ConfigHotReload -->|"热更新"| QueueManager
WebUI -->|"读写"| File_Config
OneBotClient -->|"消息事件"| MessageHandler
%% 消息处理层
MessageHandler -->|"1. 安全检测"| SecurityService
SecurityService -.->|"API 调用"| LLM_API
SecurityService -->|"注入攻击"| InjectionAgent
MessageHandler -->|"2. 指令?"| CommandDispatcher
CommandDispatcher -->|"执行结果经统一发送层写历史"| OneBotClient
MessageHandler -->|"2.5 非命令自动管线"| BilibiliParser
BilibiliParser -->|"BV号"| BilibiliDownloader
BilibiliDownloader -->|"视频文件"| BilibiliSender
BilibiliSender -->|"发送"| OneBotClient
MessageHandler -->|"2.6 非命令自动管线"| GitHubParser
GitHubParser -->|"仓库ID"| GitHubClient
GitHubClient -->|"public仓库信息"| GitHubSender
GitHubSender -->|"发送图片卡片"| OneBotClient
MessageHandler -->|"2.7 自动化"| AutomationService
AutomationService -->|"读写"| AutomationStorage
AutomationStorage -->|"异步读写"| IOUtils
MessageHandler -->|"3. 自动回复"| AICoordinator
AICoordinator -->|"3.1 入桶等待合并"| MessageBatcher
MessageBatcher -->|"3.2 flush 合并批次"| AICoordinator
AICoordinator -->|"创建上下文"| RequestContext
AICoordinator -->|"入队"| QueueManager
QueueManager -->|"分发"| ModelQueues
ModelQueues -->|"轮询取值"| DispatcherLoop
DispatcherLoop -->|"异步执行"| AIClient
%% AI 核心能力层
AIClient --> PromptBuilder
AIClient --> ToolSearchSession
AIClient --> ModelRequester
AIClient --> ToolManager
AIClient --> MultimodalAnalyzer
AIClient --> SummaryService
AIClient --> TokenCounter
ModelRequester <-->|"API 请求"| LLM_API
PromptBuilder -->|"注入记忆"| MemoryStorage
PromptBuilder -->|"注入总结"| EndSummaryStorage
PromptBuilder -->|"注入认知"| CognitiveService
PromptBuilder -->|"注入历史"| HistoryManager
ToolSearchSession -->|"注入延迟工具名"| PromptBuilder
ToolSearchSession -->|"投影本轮 schema"| ModelRequester
T_End -->|"写短期摘要"| EndSummaryStorage
T_End -->|"enqueue_job(memo/observations)"| CognitiveService
CognitiveService -->|"入队"| CognitiveJobQueue
CognitiveJobQueue -->|"dequeue / requeue"| CognitiveHistorian
CognitiveHistorian -.->|"background rewrite / merge"| LLM_API
CognitiveHistorian -->|"upsert events/profiles"| CognitiveVectorStore
CognitiveHistorian -->|"写侧写"| CognitiveProfileStorage
CognitiveService -->|"query events/profiles"| CognitiveVectorStore
CognitiveService -->|"读取侧写"| CognitiveProfileStorage
ToolManager -->|"获取工具"| ToolRegistry
ToolManager -->|"获取 Agent"| AgentRegistry
ToolManager -->|"获取 MCP"| MCPRegistry
%% 技能系统层
ToolRegistry --> AtomicTools
ToolRegistry --> Toolsets
AgentRegistry --> IntelligentAgents
AgentRegistry -->|"触发"| IntroGenerator
CommandDispatcher -->|"动态加载"| CommandsLayer
A_Web -->|"私有 MCP"| MCP_Agent_Private
MCP_Agent_Private -->|"连接"| MCPRegistry
MCP_Config -->|"全局 MCP"| MCPRegistry
%% 存储层
RequestContext -->|"日志增强"| ContextFilter
RequestContext -->|"资源扫描"| ResourceRegistry
MessageHandler -->|"保存消息"| HistoryManager
AICoordinator -->|"记录统计"| TokenUsageStorage
CommandDispatcher -->|"FAQ 操作"| FAQStorage
%% IO 层到持久化
HistoryManager -->|"异步读写"| IOUtils
MemoryStorage -->|"异步读写"| IOUtils
TokenUsageStorage -->|"异步读写<br/>自动归档"| IOUtils
FAQStorage -->|"异步读写"| IOUtils
CognitiveJobQueue -->|"异步读写"| IOUtils
CognitiveProfileStorage -->|"异步读写"| IOUtils
IOUtils --> Dir_History
IOUtils --> File_Memory
IOUtils --> File_EndSummary
IOUtils --> Dir_TokenUsage
IOUtils --> Dir_FAQ
IOUtils --> Dir_Cognitive
IOUtils --> File_ScheduledTasks
%% 资源文件
PromptBuilder -->|"加载"| Prompts
IntroGenerator -->|"生成"| Intros
IntelligentAgents -->|"读取"| Intros
%% Agent 递归调用
IntelligentAgents -->|"递归调用"| AIClient
%% 样式定义
classDef external fill:#ffebee,stroke:#c62828,stroke-width:2px
classDef core fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef message fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
classDef ai fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px
classDef skills fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
classDef storage fill:#e0f7fa,stroke:#00838f,stroke-width:2px
classDef io fill:#fce4ec,stroke:#c2185b,stroke-width:1px
classDef persistence fill:#f5f5f5,stroke:#616161,stroke-width:1px
classDef resource fill:#fff8e1,stroke:#ff8f00,stroke-width:1px
classDef queue fill:#e8eaf6,stroke:#3949ab,stroke-width:2px
classDef agent fill:#e1f5fe,stroke:#0277bd,stroke-width:2px
class User,Admin,OneBotServer,LLM_API external
class Main,ConfigLoader,ConfigHotReload,ConfigModels,OneBotClient,Context,WebUI core
class MessageHandler,AutomationService,SecurityService,InjectionAgent,CommandDispatcher,MessageBatcher,AICoordinator message
class AIClient,PromptBuilder,ModelRequester,ToolManager,MultimodalAnalyzer,SummaryService,TokenCounter,Parsing ai
class ToolRegistry,AgentRegistry,AgentToolRegistry,IntroGenerator skills
class RequestContext,ContextFilter,ResourceRegistry,HistoryManager,MemoryStorage,EndSummaryStorage,CognitiveService,CognitiveJobQueue,CognitiveHistorian,CognitiveVectorStore,CognitiveProfileStorage,FAQStorage,AutomationStorage,TokenUsageStorage storage
class IOUtils,CacheUtils,SenderUtils io
class Dir_History,Dir_FAQ,Dir_TokenUsage,Dir_Cognitive,File_Memory,File_EndSummary,File_ScheduledTasks,Dir_Logs,File_Config persistence
class Prompts,Intros resource
class QueueManager,ModelQueues,DispatcherLoop queue
class A_Info,A_Web,A_File,A_Naga,A_Self,A_Entertainment,A_Code agent
sequenceDiagram
autonumber
participant U as 用户
participant OB as OneBot<br/>协议端
participant MC as main.py<br/>入口
participant OH as OneBotClient
participant MH as MessageHandler
participant SS as SecurityService
participant CD as CommandDispatcher
participant MB as MessageBatcher
participant AC as AICoordinator
participant QM as QueueManager
participant AI as AIClient
participant LLM as 大模型API
participant TM as ToolManager
participant ST as Storage
%% 消息接收流程
U->>OB: 发送消息
OB->>OH: WebSocket 转发
OH->>MC: 触发消息事件
MC->>MH: handle_message()
%% 安全检测
MH->>SS: detect_injection()
SS->>LLM: 安全模型检测
LLM-->>SS: 检测结果
alt 检测到注入
SS->>MH: 拦截并响应
else 安全
%% 指令处理
MH->>CD: 解析斜杠命令
alt 是命令
CD->>ST: FAQ/管理员操作
CD->>ST: 写入命令输出历史
CD-->>OB: 返回结果
OB->>U: 发送响应
else 非命令消息
MH->>MH: 并行检测 skills/pipelines 管线
opt 命中自动提取管线
MH->>MH: 并行处理全部命中的自动提取
MH->>OH: 发送视频/卡片/PDF
OH->>OB: WebSocket API
OB->>U: 显示自动提取结果
MH->>ST: 写入自动提取结果历史和附件 UID
end
%% AI处理流程
MH->>AC: handle_auto_reply()
alt 拍一拍 / buffer 内 @bot
AC->>QM: 立即按优先级入队
else 普通消息进合并桶
AC->>MB: submit(BufferedMessage)
MB-->>MB: TYPING: 重置 T1/T2 静默计时
opt T2=pre_send_seconds 到期
MB->>AC: handle_batched_dispatch(投机批次 + BatchDispatchToken)
AC->>QM: 提前入队抢时间
end
MB-->>MB: T1=window_seconds 到期结束 batch
opt 未启用投机或尚未预发送
MB->>AC: handle_batched_dispatch(最终批次)
AC->>QM: 按首条触发的优先级入队
end
end
%% 上下文创建
AC->>AC: 创建 RequestContext
AC->>ST: 保存历史记录
AC->>QM: add_group_mention/normal_request()
%% 队列处理
QM->>QM: 按模型节奏发车循环
QM->>AC: execute_reply()
%% AI 调用
AC->>AI: ask()
%% Prompt 构建
AI->>ST: 加载记忆
AI->>ST: 加载历史
AI->>ST: 加载总结
AI->>ST: 语义检索认知事件 + 读取侧写
AI->>AI: build_messages()
%% 模型请求
AI->>LLM: chat.completions.create()
%% 工具调用循环
loop 最多 1000 次迭代
LLM-->>AI: 返回 tool_calls
AI->>TM: execute_tool()
alt 是普通工具
TM->>ST: 执行工具
TM-->>AI: 工具结果
else 是 Agent
TM->>AI: 递归调用
AI->>LLM: 子请求
LLM-->>AI: 返回
AI-->>TM: Agent 结果
TM-->>AI: 合并结果
end
AI->>LLM: 继续请求
end
LLM-->>AI: 最终回复
AI->>ST: 记录 Token 使用
AI-->>AC: 返回回复内容
AC->>ST: 保存总结
AC->>ST: end 工具入队认知任务(异步)
AC->>OH: 发送消息
OH->>OB: WebSocket API
OB->>U: 显示回复
end
end
graph TB
subgraph SkillsArchitecture["Skills 系统架构"]
AIClient["AIClient<br/>主入口"]
subgraph RegistrySystem["注册表系统"]
BaseRegistry["BaseRegistry<br/>基础注册表<br/>• 延迟加载<br/>• 热重载<br/>• 执行统计<br/>[registry.py]"]
ToolRegistry["ToolRegistry<br/>工具注册表"]
AgentRegistry["AgentRegistry<br/>Agent 注册表"]
AgentToolReg["AgentToolRegistry<br/>Agent 专用注册表<br/>• MCP 支持"]
end
subgraph ToolsLayer["Tools 层"]
AtomicTools["原子工具<br/>(skills/tools/)"]
Toolsets["工具集<br/>(skills/toolsets/)"]
subgraph ToolsetsDetail["工具集详情"]
TGroup["group.*<br/>群管理"]
TMsg["messages.*<br/>消息"]
TMem["memory.*<br/>记忆"]
TContacts["contacts.*<br/>联系人"]
TGroupAnalysis["group_analysis.*<br/>群分析"]
TNotice["notices.*<br/>公告"]
TRender["render.*<br/>渲染"]
TSched["automation.*<br/>自动化"]
TCognitive["cognitive.*<br/>认知记忆"]
TMCP["mcp.*<br/>MCP 工具集"]
TMemes["memes.*<br/>表情包"]
end
end
subgraph AgentsLayer["Agents 层"]
InfoAgent["info_agent<br/>信息查询"]
WebAgent["web_agent<br/>网络搜索<br/>• MCP Playwright"]
FileAgent["file_analysis_agent<br/>文件分析"]
NagaAgent["naga_code_analysis_agent<br/>代码分析"]
SelfCodeAgent["undefined_self_code_agent<br/>自身代码查阅"]
EntAgent["entertainment_agent<br/>娱乐"]
CodeAgent["code_delivery_agent<br/>代码交付"]
end
subgraph CommandsLayer2["Commands 层"]
CmdPlugins["指令插件库<br/>(skills/commands/)"]
end
subgraph IntroSystem["Intro 系统"]
IntroGen["IntroGenerator<br/>介绍生成器"]
IntroUtils["IntroUtils<br/>合并工具"]
IntroFiles["intro.md +<br/>intro.generated.md"]
end
subgraph MCPLayer["MCP 层"]
MCPReg["MCPToolRegistry<br/>MCP 注册表"]
MCPGlobal["全局 MCP<br/>config/mcp.json"]
MCPAgent["Agent 私有 MCP<br/>{agent}/mcp.json"]
end
end
%% 连接
AIClient --> ToolRegistry
AIClient --> AgentRegistry
AIClient --> IntroGen
BaseRegistry --> ToolRegistry
BaseRegistry --> AgentRegistry
ToolRegistry --> AtomicTools
ToolRegistry --> Toolsets
Toolsets --> ToolsetsDetail
AgentRegistry --> AgentsLayer
BaseRegistry -.->|"模式参考"| CommandsLayer2
AgentRegistry --> AgentToolReg
AgentToolReg --> InfoAgent
AgentToolReg --> WebAgent
AgentToolReg --> FileAgent
AgentToolReg --> NagaAgent
AgentToolReg --> SelfCodeAgent
AgentToolReg --> EntAgent
WebAgent --> MCPAgent
MCPAgent --> MCPReg
MCPGlobal --> MCPReg
IntroGen --> IntroFiles
IntroUtils --> IntroFiles
AgentsLayer --> IntroUtils
graph LR
subgraph StorageArchitecture["存储架构"]
subgraph Context["上下文"]
RC["RequestContext<br/>• UUID<br/>• 资源容器"]
end
subgraph IOLayer["IO 层<br/>[utils/io.py]"]
IO["异步 IO<br/>• write_json<br/>• read_json<br/>• append_line<br/>• 文件锁"]
end
subgraph StorageTypes["存储类型"]
History["MessageHistoryManager<br/>data/history/<br/>• 懒加载<br/>• 10000条限制"]
Memory["MemoryStorage<br/>data/memory.json<br/>• 500条上限"]
EndSummary["EndSummaryStorage<br/>data/end_summaries.json"]
CognitiveSvc["CognitiveService<br/>认知记忆入口"]
CognitiveQueue["JobQueue<br/>data/cognitive/queues/"]
CognitiveVector["CognitiveVectorStore<br/>data/cognitive/chromadb/"]
CognitiveProfile["ProfileStorage<br/>data/cognitive/profiles/"]
FAQ["FAQStorage<br/>data/faq/{group_id}/<br/>• ID: YYYYMMDD-NNN"]
Tasks["AutomationStorage<br/>data/automations.json<br/>• DAG + Cron"]
TokenUsage["TokenUsageStorage<br/>data/token_usage.jsonl<br/>• 自动归档<br/>• gzip 压缩<br/>• 流式可选 TTFT/TPS"]
end
subgraph Persistence["持久化"]
FS["文件系统"]
end
end
%% 连接
RC -->|"记录统计"| TokenUsage
RC -->|"保存消息"| History
RC -->|"读写"| Memory
RC -->|"读写"| EndSummary
RC -->|"检索/入队"| CognitiveSvc
RC -->|"FAQ 操作"| FAQ
RC -->|"任务管理"| Tasks
CognitiveSvc --> CognitiveQueue
CognitiveSvc --> CognitiveVector
CognitiveSvc --> CognitiveProfile
TokenUsage --> IO
History --> IO
Memory --> IO
EndSummary --> IO
CognitiveQueue --> IO
CognitiveProfile --> IO
FAQ --> IO
Tasks --> IO
CognitiveVector --> FS
IO -->|"异步安全"| FS
graph TB
subgraph QueueModel["车站-列车 队列模型"]
subgraph QueueManager["QueueManager<br/>队列管理器"]
direction TB
Start["启动"]
Loop["按模型节奏循环<br/>默认 1Hz"]
Check["检查各队列"]
Dispatch["分发请求"]
Exec["执行回调"]
Start --> Loop
Loop --> Check
Check -->|"有请求"| Dispatch
Dispatch --> Exec
Exec --> Loop
end
subgraph ModelQueues["ModelQueue<br/>按模型隔离的队列组"]
direction TB
subgraph AdminQueue["超级管理员队列"]
QA1["请求 1"]
QA2["请求 2"]
QA3["请求 3"]
PriorityA["优先级: 最高"]
end
subgraph PrivateQueue["私聊队列"]
QP1["请求 1"]
QP2["请求 2"]
PriorityP["优先级: 高"]
end
subgraph MentionQueue["群聊 @队列"]
QM1["请求 1"]
QM2["请求 2"]
PriorityM["优先级: 中"]
end
subgraph NormalQueue["群聊普通队列"]
QN1["请求 1"]
QN2["请求 2"]
QN3["请求 3"]
QN_N["...最多保留最新2条"]
PriorityN["优先级: 普通<br/>自动修剪"]
end
end
subgraph Features["特性"]
F1["非阻塞: 即使前一个请求未完成,<br/>新请求也会按时分发"]
F2["优先级: 四级优先级,<br/>确保重要消息优先响应"]
F3["隔离性: 每个模型独立队列,<br/>互不干扰"]
F4["自动修剪: 普通队列超过10条时,<br/>只保留最新2条"]
F5["可配置节奏: 每个模型可独立设置<br/>队列发车间隔"]
end
end
%% 样式
style AdminQueue fill:#ffebee,stroke:#c62828
style PrivateQueue fill:#fff3e0,stroke:#ef6c00
style MentionQueue fill:#e8f5e9,stroke:#2e7d32
style NormalQueue fill:#e3f2fd,stroke:#1565c0
graph TB
subgraph AgentStructure["Agent 标准结构"]
subgraph FileStructure["文件结构"]
Config["config.json<br/>工具定义<br/>(OpenAI Function)"]
Handler["handler.py<br/>执行逻辑<br/>• 多轮迭代<br/>• 工具并发"]
Prompt["prompt.md<br/>系统提示词"]
Intro["intro.md<br/>手动介绍"]
IntroGen["intro.generated.md<br/>自动生成介绍"]
MCP["mcp.json<br/>私有 MCP (可选)"]
end
subgraph ExecutionFlow["执行流程"]
Input["用户请求"]
BuildTools["构建工具列表<br/>• 本地工具<br/>• MCP 工具"]
Iteration["多轮迭代<br/>最多 20-30 次"]
Parallel["并发执行<br/>asyncio.gather"]
Output["返回结果"]
Input --> BuildTools
BuildTools --> Iteration
Iteration -->|"调用工具"| Parallel
Parallel -->|"结果"| Iteration
Iteration -->|"完成"| Output
end
subgraph IntroGeneration["Intro 生成流程"]
Detect["检测文件变更<br/>• config.json<br/>• handler.py<br/>• tools/"]
Hash["计算 Hash"]
Queue["加入生成队列"]
Generate["AI 生成介绍<br/>(IntroGenerator)"]
Merge["合并 intro.md<br/>+ intro.generated.md"]
Cache["保存 Hash 缓存"]
Detect --> Hash
Hash -->|"变更"| Queue
Queue --> Generate
Generate --> Merge
Merge --> Cache
end
end
graph LR
subgraph MCPArchitecture["MCP 集成架构"]
subgraph GlobalMCP["全局 MCP"]
Config["config/mcp.json<br/>全局配置"]
MCPReg["MCPToolRegistry<br/>mcp/registry.py"]
end
subgraph AgentMCP["Agent 私有 MCP"]
WebAgent["web_agent"]
WebMCP["web_agent/mcp.json<br/>Playwright MCP"]
end
subgraph MCPServer["MCP Server"]
Playwright["@playwright/mcp@latest<br/>• 网页截图<br/>• 浏览器自动化"]
Filesystem["@modelcontextprotocol/server-filesystem<br/>• 文件访问"]
Other["其他 MCP Server..."]
end
subgraph ToolExecution["工具执行"]
TM["ToolManager<br/>ai/tooling.py"]
StdTools["标准工具"]
MCPTools["MCP 工具"]
end
end
%% 连接
Config --> MCPReg
WebAgent -->|"临时加载"| WebMCP
WebMCP -->|"连接"| Playwright
MCPReg -->|"连接"| Filesystem
MCPReg -->|"连接"| Other
MCPReg -->|"注册"| MCPTools
TM --> StdTools
TM --> MCPTools
graph TB
subgraph AnthropicSkillsArch["Anthropic Skills 架构"]
subgraph Registry["注册表系统"]
ASReg["AnthropicSkillRegistry<br/>[anthropic_skills/__init__.py]<br/>• 自动发现<br/>• 热重载<br/>• XML 元数据生成"]
ASLoader["SKILL.md 解析器<br/>[anthropic_skills/loader.py]<br/>• YAML frontmatter<br/>• Markdown body<br/>• name/description 校验"]
end
subgraph SkillsStorage["Skills 存储"]
GlobalSkills["全局 Skills<br/>skills/anthropic_skills/<br/>• pdf-processing/<br/>• code-review/<br/>• data-analysis/"]
AgentSkills["Agent 私有 Skills<br/>agents/<name>/anthropic_skills/<br/>• search-tips/<br/>• specialized-domain/"]
end
subgraph SkillStructure["Skill 目录结构"]
SkillMD["SKILL.md<br/>• YAML frontmatter<br/> - name (必填)<br/> - description (必填)<br/>• Markdown 正文"]
References["references/<br/>参考文档 (可选)"]
Scripts["scripts/<br/>脚本文件 (可选)"]
Assets["assets/<br/>资源文件 (可选)"]
end
subgraph ToolIntegration["工具集成"]
TM2["ToolManager"]
PB["PromptBuilder<br/>元数据注入"]
end
end
%% 连接
ASReg --> ASLoader
ASLoader --> GlobalSkills
ASLoader --> AgentSkills
GlobalSkills --> SkillStructure
AgentSkills --> SkillStructure
SkillStructure --> References
SkillStructure --> Scripts
SkillStructure --> Assets
ASReg -->|"注册 skill-_-<name>"| TM2
ASReg -->|"XML 元数据"| PB
遵循 agentskills.io 开放标准,参照 Claude Code 实现。
SKILL.md 格式:
---
name: pdf-processing
description: 从 PDF 文件中提取文本和表格,填写表单。当用户提到 PDF 时使用。
---
# PDF 处理指南
## 文本提取
使用 pdfplumber...
## 表格提取
...核心特性:
- 渐进式披露:元数据(name + description)始终注入 system prompt(Level 1),完整内容按需调用获取(Level 2)
- 自动发现:扫描目录下所有包含
SKILL.md的子目录 - 工具注册:每个 skill 注册为
skills-_-<name>function tool - 热重载:监视
SKILL.md变更,自动重新加载 - Agent 私有:支持在
agents/<name>/anthropic_skills/下存放 agent 专属 skills
| 配置类别 | 关键配置项 | 说明 |
|---|---|---|
| 基础配置 | core.bot_qq, core.superadmin_qq, onebot.ws_url |
机器人身份和连接 |
| 模型配置 | models.chat / models.vision / models.agent / models.security |
四类模型独立配置(含 queue_interval_seconds) |
| 功能开关 | skills.hot_reload, skills.intro_autogen_enabled, skills.tool_search_enabled |
热重载、自动生成和主 AI 按需工具投影 |
| 日志配置 | logging.level, logging.file_path, logging.max_size_mb |
日志系统 |
| MCP 配置 | mcp.config_path |
MCP 配置文件路径 |
| 存储配置 | token_usage.* |
Token 归档和清理策略 |
| 认知记忆 | cognitive.enabled, cognitive.query.*, models.embedding.* |
事件检索、时间衰减加权、侧写与后台史官 |
| Bilibili | bilibili.auto_extract_enabled, bilibili.cookie, bilibili.prefer_quality |
B站视频自动提取与下载 |
| arXiv | arxiv.auto_extract_enabled, arxiv.max_file_size, arxiv.auto_extract_max_items |
arXiv 论文自动提取、搜索与 PDF 发送 |
| GitHub | github.auto_extract_enabled, github.request_timeout_seconds, github.request_retries, github.auto_extract_max_items |
GitHub public 仓库自动提取与图片卡片发送 |
| 思考链 | *.thinking_enabled |
思维链支持 |
| 思维链兼容 | *.thinking_tool_call_compat |
思维链 + 工具调用兼容 |
| WebUI | webui.url, webui.port, webui.password |
配置控制台 |
| 微信 iLink | weixin.enabled, weixin.state_dir, weixin.*_seconds |
微信私聊帐号生命周期、重试与本地状态 |
- 外部实体层:用户、管理员、OneBot 协议端 (NapCat/Lagrange.Core)、大模型 API 服务商
- 核心入口层:main.py 启动入口、配置管理器 (config/loader.py + parsers/ + load_sections/)、热更新应用器 (config/hot_reload.py)、OneBotClient (onebot/ + onebot.py shim)、WeixinService (
weixin/+weixin-ilink-client)、RequestContext (context.py)、Runtime API Server (api/app.py → api/routes/ 路由子模块,含 naga/ 子包) - 消息处理层:MessageHandler (
handlers/)、统一 DeliveryAddress 路由 (utils/message_targets.py)、SecurityService (security.py)、CommandDispatcher (services/command.py + commands/ mixins)、自动处理管线 (skills/pipelines/)、AutomationService (automations/service.py,pipeline 之后、对应 AI loop 之前 await,命中可拦截)、MessageBatcher (services/message_batcher/)、AICoordinator (services/coordinator/ + ai_coordinator.py 门面)、QueueManager (queue_manager.py)、Bilibili/arXiv/GitHub 解析与发送模块 自动提取由PipelineRegistry并行检测、并行处理全部命中的管线;随后await自动化工作流,未拦截时再进入 AI 自动回复。 - AI 核心能力层:AIClient (ai/client/ + client.py shim)、PromptBuilder (ai/prompts/ + prompts.py shim)、ModelRequester (ai/llm/ + llm.py shim)、ToolManager (tooling.py)、MultimodalAnalyzer (ai/multimodal/ + multimodal.py shim)、SummaryService (summaries.py)、TokenCounter (tokens.py)。OpenAI Chat Completions / Responses、Anthropic Messages SDK 归一化、CoT 续传与文本 Tool Call 容错见模型 API 与兼容层。
- 存储与上下文层:MessageHistoryManager (utils/history.py, 10000条限制)、MemoryStorage (memory.py, 置顶备忘录, 500条上限)、EndSummaryStorage、CognitiveService + JobQueue + HistorianWorker + VectorStore + ProfileStorage、MemeService + MemeWorker + MemeStore + MemeVectorStore (表情包库)、FAQStorage、AutomationStorage (
data/automations.json;旧scheduled_tasks.json启动时一次性转为新格式,不删旧文件、不双写)、TokenUsageStorage (自动归档) - 技能系统层:ToolRegistry (registry.py)、AgentRegistry、7个 Agents、13类 Toolsets
- 异步 IO 层:统一 IO 工具 (utils/io.py),包含 write_json、read_json、append_line、跨平台文件锁 (flock/msvcrt)
- 数据持久化层:历史数据目录、FAQ 目录、Token 归档目录、记忆文件、总结文件、自动化文件、微信绑定/游标/隔离/审计状态
微信接入由主进程独立管理,不依赖 OneBot 是否在线。WeixinService 先校验帐号与 peer,再把已绑定来源映射为逻辑 QQ 私聊交给 MessageHandler;未知来源在写历史或调用 AI 之前进入隔离存储。DeliveryAddress 将逻辑身份与物理通道分离:qq:<id> 和 wechat:<id> 可共享同一个用户历史、认知记忆与权限,但发送器、消息合并 scope 和 transport 元数据保持通道隔离。自动化同样持久化规范 address,旧 target_type + target_id 在加载时转换为 group: 或 qq: 地址。
针对高并发消息处理,Undefined 实现了全新的 ModelQueue 调度机制:
- 多模型隔离:每个 AI 模型拥有独立的请求队列组("站台"),互不干扰。
- 非阻塞发车:实现了可配置节奏的非阻塞调度循环(默认 1Hz)。列车按节奏出发,带走一个请求到后台异步处理。
- 高可用性:即使前一个请求仍在处理(如耗时的网络搜索),新的请求也会按时被分发,不会造成队列堵塞。
- 优先级管理:支持四级优先级(超级管理员 > 私聊 > 群聊@ > 群聊普通),确保重要消息优先响应。
- 关停收敛:
MessageHandler.close()会先 flushMessageBatcher,再调用QueueManager.drain()等待已入队请求和在途请求自然完成,最后才停止队列处理器,避免缓冲消息只入队未执行。
| Agent | 功能定位 | 工具数量 | 核心能力 |
|---|---|---|---|
| info_agent | 信息查询助手 | 18个 | 天气查询、热搜榜单、网络检测、B站信息查询、arXiv 搜索等 |
| web_agent | 网络搜索助手 | 3个 + MCP | 网页搜索、爬虫、Playwright MCP |
| file_analysis_agent | 文件分析助手 | 多个 | PDF/Word/Excel/PPT解析、指定 PDF 页视觉分析、代码分析、多模态分析、arXiv/Bilibili UID 获取分析 |
| naga_code_analysis_agent | NagaAgent 代码分析 | 7个 | 代码库浏览、文件搜索、目录遍历 |
| undefined_self_code_agent | Undefined 自身代码查阅 | 4个 | 受限读取源码、测试、文档、资源、脚本与 App |
| entertainment_agent | 娱乐助手 | 9个 | AI 绘图、星座运势、小说搜索、随机视频推荐等 |
| code_delivery_agent | 代码交付助手 | 13个 | Docker 隔离、仓库克隆、代码验证、打包上传 |
- Tools (基础工具):原子化的功能单元,如
send_message,get_history,bilibili_video,arxiv_paper。 - Toolsets (复合工具集):13大类工具集 (attachments, group, messages, memory, contacts, group_analysis, music, notices, render, automation, cognitive, mcp, memes)。
- 注册表延迟导入 + 热重载:启动时读取
config.json建立本地 schema,handler.py仅在首次执行工具时导入;当skills/下的config.json/handler.py发生变更时会自动重新加载。 - 模型 schema 按需投影:启用
skills.tool_search_enabled后,主 AI 的请求级ToolSearchSession只投影配置为始终加载的工具、虚拟tool_search和本轮已检索工具的 schema,其余工具仅注入规范名称;搜索命中的 schema 从下一模型轮开始可用,新ask()会重置。该机制不改变本地完整注册表、handler 导入时机或子 Agent 工具集。 - Agent 自我介绍自动生成:启动时按 Agent 代码/配置 hash 生成
intro.generated.md并与intro.md合并。
- 统一 IO 工具 (
src/Undefined/utils/io.py):任何涉及磁盘读写的操作(JSON 读写、行追加)都必须通过该层,内部使用asyncio.to_thread将阻塞调用移出主线程。 - 内核级文件锁:引入跨平台文件锁 (Linux/macOS 使用
flock,Windows 使用msvcrt);通过锁文件实现跨平台一致的互斥语义。 - 原子写入:关键 JSON 写入使用“写临时文件 +
os.replace原子替换”,避免进程异常退出导致文件半写损坏。 - 存储组件异步化:所有核心存储类(Memory, FAQ, Tasks)现已全面提供异步接口,确保机器人响应不受磁盘延迟影响。
- 资源加载:提示词与预置文案通过
src/Undefined/utils/resources.py读取,优先从运行目录加载同名res/...(便于覆盖),若不存在再回退到安装包自带资源,并提供仓库结构兜底,避免依赖启动时的工作目录。 - 本地 Prompt 插槽:两份主 Prompt 提供 P0/P1/P2/P3/summary 稳定插槽;
[prompt.file_includes]指向的 UTF-8 文件在每次请求构建时检查修改时间,未变化时复用缓存、变化时重新读取,支持内容与配置路径热更新。推荐的config/prompts/*.local.*同时从 Git 与构建产物排除。 - 提示词结构安全:结构化 Prompt/历史消息注入使用
src/Undefined/utils/xml.py做必要的 XML 转义,降低用户输入破坏结构或干扰解析的风险。
架构图版本: v3.8.1 更新日期: 2026-07-14 基于代码版本: 最新 main 分支