引言
CountBot 是一个基于 FastAPI 的多渠道 AI 助手框架,采用了经典的分层模块化架构。本文将从宏观视角剖析其整体设计哲学,帮助开发者理解如何构建一个可扩展的 AI Agent 系统。
架构总览
CountBot 的架构可以分为五个核心层次:
scss
┌──────────────────────────────────────────────────────────────────┐
│ 用户界面层 (Presentation) │
│ Web UI (Vue 3) │ Telegram │ 钉钉 │ 飞书 │ QQ │ 微信 │ Discord │
├──────────────────────────────────────────────────────────────────┤
│ 通信层 (Communication) │
│ WebSocket Handler │ Channel Manager │ REST API │ Auth │
├──────────────────────────────────────────────────────────────────┤
│ 业务逻辑层 (Business Logic) │
│ Agent Loop │ Context Builder │ Session Manager │ Subagent Mgr │
├──────────────────────────────────────────────────────────────────┤
│ 能力层 (Capabilities) │
│ Tool Registry │ LLM Provider │ Skills Loader │ Memory Store │
├──────────────────────────────────────────────────────────────────┤
│ 基础设施层 (Infrastructure) │
│ SQLite (aiosqlite) │ Enterprise Queue │ Cron Scheduler │ Config│
│ Rate Limiter │ Security Manager │ File System │ Audit Logger │
└──────────────────────────────────────────────────────────────────┘
完整系统架构图
scss
┌─────────────────────────────────────────────────────────────────────┐
│ 用户界面层 │
│ ┌──────────┐ ┌──────────┐ ┌──────┐ ┌──────┐ ┌────┐ ┌────┐ ┌────┐│
│ │ Web UI │ │ Telegram │ │ 钉钉 │ │ 飞书 │ │ QQ │ │微信│ │Disc││
│ │ (Vue 3) │ │ │ │ │ │ │ │ │ │ │ │ord ││
│ └────┬─────┘ └────┬─────┘ └──┬───┘ └──┬───┘ └─┬──┘ └─┬──┘ └─┬──┘│
└───────┼────────────┼──────────┼────────┼───────┼──────┼──────┼────┘
│ │ │ │ │ │ │
WebSocket HTTP Webhook / Bot API / WebSocket 长连接
│ └──────────┴────────┴───────┴──────┴──────┘
│ │
┌───────┼────────────────────────────────┼─────────────────────────────┐
│ │ FastAPI 应用层 │ │
│ │ │ │
│ ┌────▼──────┐ ┌──────────────┐ ┌───▼──────────┐ ┌───────────┐ │
│ │ WebSocket │ │ REST API │ │ Channel │ │ Auth │ │
│ │ Handler │ │ (14 路由组) │ │ Manager │ │ Middleware│ │
│ └────┬──────┘ └──────┬───────┘ └───┬──────────┘ └───────────┘ │
│ │ │ │ │
│ │ ┌──────▼──────┐ ┌───▼──────────┐ │
│ │ │ Session │ │ Enterprise │ │
│ │ │ Manager │ │ Message Queue│ │
│ │ └──────┬──────┘ └───┬──────────┘ │
│ │ │ │ │
│ └────────────────┼─────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ Agent Loop │ ◄──── 核心处理引擎 (ReAct 循环) │
│ └──────┬──────┘ │
│ │ │
│ ┌─────────────┼─────────────┬──────────────┐ │
│ │ │ │ │ │
│ ┌────▼─────┐ ┌───▼──────┐ ┌──▼────────┐ ┌──▼──────────┐ │
│ │ Context │ │ Tool │ │ LLM │ │ Subagent │ │
│ │ Builder │ │ Registry │ │ Provider │ │ Manager │ │
│ └────┬─────┘ └───┬──────┘ │ (LiteLLM) │ └─────────────┘ │
│ │ │ └───────────┘ │
│ ┌────▼─────┐ ┌───▼──────┐ │
│ │ Skills │ │ 15 个 │ │
│ │ Loader │ │ 内置工具 │ │
│ └──────────┘ └──────────┘ │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ Memory │ │ Cron │ │ Heartbeat │ │ Rate │ │
│ │ Store │ │ Scheduler │ │ Service │ │ Limiter │ │
│ └────────────┘ └────────────┘ └────────────┘ └──────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ SQLite (aiosqlite + SQLAlchemy 2.0) │ │
│ │ sessions │ messages │ settings │ cron_jobs │ tasks │ ... │ │
│ └───────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
核心设计原则
1. 关注点分离
每个模块只负责一个明确的职责。以消息处理为例,一条用户消息的生命周期经过:
- Channel/WebSocket → 接收原始消息
- ChannelMessageHandler → 消息预处理、命令解析、限流检查
- AgentLoop → LLM 推理与工具调用编排
- ContextBuilder → 上下文组装(系统提示词 + 记忆 + 技能 + 历史)
- LLMProvider → 模型调用(流式)
- ToolRegistry → 工具执行
2. 抽象基类驱动
系统大量使用 ABC(Abstract Base Class)模式:
python
# 渠道抽象基类
class BaseChannel(ABC):
@abstractmethod
async def start(self) -> None: ...
@abstractmethod
async def stop(self) -> None: ...
@abstractmethod
async def send(self, msg: OutboundMessage) -> None: ...
# 工具抽象基类
class Tool(ABC):
@property
@abstractmethod
def name(self) -> str: ...
@property
@abstractmethod
def description(self) -> str: ...
@property
@abstractmethod
def parameters(self) -> dict: ...
@abstractmethod
async def execute(self, **kwargs: Any) -> str: ...
# LLM Provider 抽象基类
class LLMProvider(ABC):
@abstractmethod
async def chat_stream(self, messages, tools, ...) -> AsyncIterator[StreamChunk]: ...
这种设计使得新增渠道、工具或 LLM 提供商只需实现对应接口,无需修改核心逻辑。
3. 依赖注入
app.py 中的 _create_shared_components() 函数充当了简易的 DI 容器,统一创建和注入所有共享组件:
python
def _create_shared_components(config):
provider = LiteLLMProvider(...)
memory = MemoryStore(memory_dir)
skills = SkillsLoader(skills_dir)
context_builder = ContextBuilder(workspace, memory, skills, persona_config)
tool_registry = register_all_tools(**tool_params)
subagent_manager = SubagentManager(...)
channel_manager = ChannelManager(config, bus)
return dict(provider=provider, context_builder=context_builder, ...)
4. 异步优先
整个后端基于 Python asyncio 构建,从数据库访问(aiosqlite)到 LLM 调用(异步流式)再到 WebSocket 通信,全链路异步,确保高并发下的性能表现。
核心组件详解
Agent Loop(核心处理引擎)
位置:backend/modules/agent/loop.py
Agent Loop 是整个系统的心脏,实现了完整的 ReAct(Reasoning + Acting)循环:
markdown
用户消息 → 构建上下文 → 调用 LLM → 解析响应
↓
有 tool_call? ──是──→ 执行工具 → 结果反馈 → 再次调用 LLM
│ ↑
否 │
↓ │
返回文本响应 ←──────────────────────────────┘
关键参数:
max_iterations: 最大循环次数(默认 25,可配置至 150)max_retries: 工具调用失败重试次数(默认 3)temperature: LLM 温度参数(默认 0.7)max_tokens: 单次响应最大 token 数(默认 4096)
支持特性:
- 流式响应(StreamChunk)
- 协作式取消(CancellationToken)
- 会话级上下文管理
- 多轮工具调用编排
Context Builder(上下文构建器)
位置:backend/modules/agent/context.py
负责组装发送给 LLM 的完整上下文,包括:
- 核心身份:AI 名称、性格特征、行为准则
- 技能注入:自动加载的技能(always=true)+ 可用技能摘要
- 记忆融合:从 MemoryStore 加载相关长期记忆
- 对话历史:从 SessionManager 获取历史消息
- 系统信息:当前时间、操作系统、工作空间路径
Tool Registry(工具注册表)
位置:backend/modules/tools/registry.py
管理所有可用工具的注册、查询和执行。当前内置 13 个工具:
| 工具 | 说明 |
|---|---|
read_file |
读取工作空间文件 |
write_file |
写入文件 |
edit_file |
编辑文件指定区域 |
list_dir |
列出目录内容 |
exec |
执行 Shell 命令(沙箱保护) |
web_fetch |
抓取网页内容 |
memory_write |
写入长期记忆 |
memory_search |
搜索记忆 |
memory_read |
读取记忆条目 |
spawn |
创建子代理任务 |
send_media |
发送媒体到渠道 |
screenshot |
截取屏幕截图 |
file_search |
全文搜索文件 |
conversation_history |
查询对话历史 |
工具定义采用 OpenAI Function Calling 格式(JSON Schema),支持审计日志。
LLM Provider(LLM 提供商)
位置:backend/modules/providers/
通过 LiteLLM 统一接口,支持 22 种提供商:
国际提供商:OpenAI、Anthropic、Google Gemini、Groq、Mistral AI、Cohere、Together AI、OpenRouter
国内提供商:智谱 AI (GLM)、DeepSeek、Moonshot/Kimi、阿里云百炼 (Qwen)、腾讯云混元、百度千帆 (ERNIE)、字节火山引擎 (豆包)、零一万物 (Yi)、百川智能、MiniMax
本地/自定义:Ollama、vLLM、LM Studio、Custom API (OpenAI/Gemini/Anthropic 兼容)
所有提供商统一为 StreamChunk 流式响应格式,支持文本内容、工具调用、推理内容(reasoning)和错误处理。
Channel Manager(渠道管理器)
位置:backend/modules/channels/manager.py
管理 7 种即时通讯渠道的初始化、启动/停止和消息路由:
- Telegram --- python-telegram-bot
- 钉钉 --- DingTalk Stream API
- 飞书 --- Feishu WebSocket
- QQ --- QQ 官方 Bot API
- 微信 --- 微信公众号 API
- Discord --- discord.py
消息流转路径:
markdown
渠道收到消息 → InboundMessage → EnterpriseMessageQueue(去重、异步)
→ ChannelMessageHandler(限流、预处理)
→ AgentLoop(LLM 推理 + 工具调用)
→ OutboundMessage → ChannelManager → 目标渠道
Memory Store(记忆系统)
位置:backend/modules/agent/memory.py
基于文件的行式记忆存储(JSON Lines 格式),存储在 workspace/memory/ 目录:
- 写入记忆 :LLM 通过
memory_write工具主动写入 - 搜索记忆:关键词匹配搜索
- 对话总结:自动总结对话历史写入记忆
- 上下文滚动压缩:对话超出历史窗口时,自动总结溢出消息写入记忆,信息不丢失
Skills Loader(技能系统)
位置:backend/modules/agent/skills.py
可热插拔的技能插件系统,技能以 Markdown 文件(SKILL.md)+ 脚本的形式组织:
perl
skills/
├── weather/ # 天气查询
├── email/ # 邮件管理
├── image-gen/ # 图片生成
├── image-analysis/ # 图片分析(视觉)
├── news/ # 新闻聚合
├── map/ # 地图查询
├── baidu-search/ # 百度搜索
├── web-design/ # 网页设计与部署
└── canvas-design/ # Canvas 画布设计
技能加载机制:
- YAML frontmatter 元数据(标题、描述、依赖、always 标记)
- 两级加载:always 技能自动注入系统提示词,其他技能按需通过
read_file加载 - 技能内容以文本形式传递给 LLM(非结构化工具)
Cron Scheduler(定时任务调度器)
位置:backend/modules/cron/scheduler.py
智能调度器,采用精确按需唤醒设计(非轮询):
- 数据库持久化任务(CronJob 模型)
- 标准 Cron 表达式
- 并发控制(信号量限制,默认 3 并发)
- 单任务超时保护(默认 300 秒)
- 渠道投递(执行结果推送到 Telegram/钉钉/飞书等)
- 内置 Heartbeat 问候任务
Enterprise Message Queue(企业级消息队列)
位置:backend/modules/messaging/enterprise_queue.py
异步消息队列,支持:
- 优先级调度(LOW / NORMAL / HIGH / URGENT)
- 消息去重(60 秒窗口)
- 出入站分离
- 重试机制(最多 3 次)
- 死信处理
其他核心组件
| 组件 | 位置 | 说明 |
|---|---|---|
| Rate Limiter | messaging/rate_limiter.py |
令牌桶算法流量控制,按用户维度保护 AI 服务 |
| Security Manager | config/security.py |
API 密钥 Fernet 加密、Shell 沙箱、审计日志 |
| Heartbeat Service | agent/heartbeat.py |
主动问候系统,用户空闲时自动发送温暖问候 |
| Message Analyzer | agent/analyzer.py |
对话分析,格式化消息、判断是否需要总结 |
| Personalities | agent/personalities.py |
12 种性格预设(专业、幽默、暴躁老哥等) |
| Subagent Manager | agent/subagent.py |
后台子代理任务管理 |
| Session Manager | session/manager.py |
多轮对话会话管理 |
数据流分析
一条消息从用户输入到最终响应的完整数据流:
scss
用户输入
│
├─ Web UI ──→ WebSocket Handler ──→ SessionManager(获取/创建会话)
│ │
└─ 渠道消息 ──→ ChannelManager ──→ EnterpriseMessageQueue
│
ChannelMessageHandler
│
▼
ContextBuilder(构建上下文)
├─ 系统提示词(身份 + 性格 + 规则)
├─ 技能注入(always 技能 + 可用摘要)
├─ 记忆融合(相关长期记忆)
└─ 对话历史(最近 N 条消息)
│
▼
AgentLoop.process_message()
├─ LLMProvider.chat_stream() → 流式响应
├─ 如果有 tool_call → ToolRegistry.execute()
│ └─ 结果反馈给 LLM → 继续循环
└─ 循环直到 finish_reason = "stop" 或达到 max_iterations
│
▼
├─ WebSocket 流式推送给前端
└─ OutboundMessage → 渠道回复
│
▼
SessionManager(保存消息到数据库)
模块间通信
模块间主要通过四种方式通信:
- 直接方法调用 :同步组件间的调用,如
AgentLoop调用ToolRegistry - 消息队列 :
EnterpriseMessageQueue用于渠道消息的异步解耦 - WebSocket 事件:前后端实时通信,支持流式响应和工具调用通知
- 数据库共享:通过 SQLite 共享配置、会话、消息等持久化数据
前端架构
前端采用 Vue 3 + TypeScript + Pinia 的现代化技术栈:
bash
frontend/src/
├── api/ # Axios HTTP 客户端 + WebSocket 客户端
│ ├── client.ts # HTTP 客户端(自动重试、错误处理)
│ ├── endpoints.ts # API 端点定义
│ └── websocket.ts # WebSocket 连接管理
├── store/ # Pinia 状态管理(11 个 Store)
│ ├── chat.ts # 聊天状态
│ ├── settings.ts # 设置状态
│ ├── memory.ts # 记忆状态
│ ├── skills.ts # 技能状态
│ ├── cron.ts # 定时任务状态
│ ├── tasks.ts # 后台任务状态
│ ├── tools.ts # 工具状态
│ ├── channels.ts # 渠道状态
│ └── ui.ts # UI 状态
├── modules/ # 功能模块(8 个)
│ ├── chat/ # 聊天界面(ChatWindow, SessionPanel)
│ ├── memory/ # 记忆管理(MemoryPanel, MemoryViewer, MemorySearch)
│ ├── settings/ # 设置面板(SettingsPanel)
│ ├── skills/ # 技能库(SkillsLibrary)
│ ├── scheduler/ # 定时任务(CronBuilder)
│ ├── tasks/ # 后台任务
│ ├── tools/ # 工具管理
│ └── system/ # 系统信息(SystemSidebar)
├── composables/ # Vue 3 组合式函数(14 个)
├── components/ # 通用组件(chat, layout, modals, ui)
├── i18n/ # 国际化(中文/英文)
├── assets/styles/ # 样式系统(设计系统 + 主题 + 暗色模式)
└── views/ # 页面视图
配置系统
数据库驱动的动态配置系统(backend/modules/config/):
python
AppConfig
├── providers: dict[str, ProviderConfig] # 22 种 LLM 提供商配置
├── model: ModelConfig # 模型选择、温度、token 限制
├── workspace: WorkspaceConfig # 工作空间路径
├── security: SecurityConfig # 安全策略
├── channels: ChannelsConfig # 6 种渠道配置
├── persona: PersonaConfig # AI 人设 + Heartbeat 配置
├── theme: str # 主题(auto/light/dark)
├── language: str # 语言(auto/zh-CN/en-US)
└── font_size: str # 字体大小
配置存储在 SQLite 的 settings 表中,通过 ConfigLoader 加载,支持热更新。
与其他框架的对比
| 特性 | CountBot | LangChain | OpenClaw |
|---|---|---|---|
| 架构风格 | 轻量模块化 | 重抽象链式 | 微服务化 |
| LLM 接入 | LiteLLM 统一层(22 种) | 原生适配器 | 插件式 |
| 工具系统 | JSON Schema + ABC | Tool/Toolkit | 声明式 |
| 渠道支持 | 7 种即时通讯 | 无内置 | 有限 |
| 记忆系统 | 文件行式 + 自动总结 | 向量数据库 | 可选 |
| 部署复杂度 | 单进程 SQLite | 单进程 | 多服务 |
| 定时任务 | 内置 Cron 调度器 | 无 | 无 |
| 桌面模式 | pywebview 原生窗口 | 无 | 无 |
总结
CountBot 的架构设计体现了"简单但不简陋"的理念。通过清晰的五层分层、统一的抽象接口、异步优先的设计和丰富的内置能力,在保持代码可读性的同时实现了强大的扩展能力。22 种 LLM 提供商、7 种即时通讯渠道、15 个内置工具、9 种技能插件,这些能力通过模块化设计有机组合,使得 CountBot 既能作为个人桌面助手快速上手,又能扩展为企业级多渠道 AI 服务。