系统架构概览
PAI 采用 FastAPI + LangGraph 构建后端,支持多平台即时通讯接入。项目提供两种架构模式:main分支 — 多节点 Router 架构:Router 节点使用 LLM 意图分类,将请求路由到 6 个专业节点feat/single-agent分支 — 单 Agent 架构:Agent + Harness 分层,单一 Agent 拥有全部工具并自主决策
当前生产环境运行的是
feat/single-agent 分支。两种架构共享相同的底层服务组成和数据流,核心差别在于 LangGraph 工作流的组织方式。高层架构
整个系统的请求处理流程如下:服务组成
PAI 通过 Docker Compose 编排以下服务:backend (FastAPI)
核心后端服务,运行在 8000 端口。负责 Webhook 接收、消息处理、LangGraph 工作流执行、工具调用等全部业务逻辑
memory_worker
独立的记忆处理进程,与 backend 共享同一镜像。负责异步提取和持久化用户长期记忆,避免阻塞主请求流程
frontend (React + Vite)
Web 前端,运行在 3001 端口。提供基于 WebSocket 的流式对话界面
db (PostgreSQL 15)
主数据库,使用
postgres:15-alpine 镜像。存储用户、会话、消息、账单、日程等业务数据,配合 pgvector 扩展支持向量检索redis (Redis 7)
使用
redis-stack-server:7.4.0-v6 镜像。用于 LangGraph 检查点持久化、会话缓存与消息去重gewechat
微信个人号接入服务(GeWeChat),运行在 2531 端口。实现微信消息的收发桥接
napcat
QQ 接入服务(NapCat),运行在 3000 端口。通过 OneBot v11 协议将 QQ 消息转发到后端 Webhook
数据流
以下是一条消息从接收到响应的完整数据流:memory_worker 以独立进程运行,通过数据库轮询待处理消息(memory_status = PENDING),异步完成记忆提取和存储,不影响主流程响应速度。关键设计决策
为什么选择 LangGraph
有状态的对话管理
有状态的对话管理
LangGraph 提供内置的检查点(Checkpointing)机制,支持跨轮次的状态持久化。配合
AsyncRedisSaver,可以在生产环境中可靠地保存和恢复对话状态,无需手动管理状态序列化。图结构的工作流编排
图结构的工作流编排
相比线性的 Chain,LangGraph 的
StateGraph 支持条件边(conditional edges),可以根据运行时状态动态决定执行路径。例如 ledger_manager 处理完账单后可以有条件地路由到 chat_manager 继续对话。节点级别的工具隔离
节点级别的工具隔离
每个节点拥有独立的工具集(通过
toolsets.py 中的 NODE_TOOL_NAMES 定义),避免了工具权限混乱,同时便于独立测试和扩展。两种架构的选择
- 多节点 Router(main 分支)
- 单 Agent(feat/single-agent 分支)
关注点分离
关注点分离
每个节点专注于一个领域(记账、日程、对话等),拥有独立的系统提示词和工具集。这使得每个节点可以针对特定场景进行深度优化,而不是用一个通用节点处理所有请求。
LLM 意图分类的灵活性
LLM 意图分类的灵活性
Router 使用 LLM 进行意图分类(
with_structured_output),支持 7 种意图。相比基于规则的路由,LLM 路由可以理解自然语言的模糊表达,并结合会话上下文做出更准确的判断。可扩展性
可扩展性
添加新的业务能力只需要:定义新节点、在
toolsets.py 注册工具集、在 workflow.py 中添加节点和路由边。无需修改现有节点的逻辑。