30秒速览:本文面向想深入理解 AI Agent 底层机制的开发者,详解一个运维场景下自研 Agent 中台(DOSM)的六层架构、数据流设计与五阶段演进路线。适合对 ReAct、RAG、SSE、异构系统集成感兴趣的后端/DevOps 工程师。
目录
项目背景与核心目标
我是做运维开发的,日常与 CMDB、工单系统、告警中心打交道。今年上半年 AI Agent 概念火爆,我萌生一个想法:能否将大语言模型(LLM, Large Language Model)接入运维体系,实现自动处理告警、查询日志、生成报告?
调研 Coze、Dify 等平台后,我发现它们虽易用,但更偏向非技术人员的“黑盒工具”,难以满足开发者对底层机制的理解需求——比如:
- ReAct 循环如何实现?
- 工具调用的 Schema 如何传递给 LLM?
- SSE 流式输出是否有更优方案?
更重要的是,面试官关心的是:“你的 Agent 执行引擎怎么设计的?”
因此,我决定从零构建一个名为 DOSM(Digital Operations Smart Manager)的 AI Agent 中台。目标很明确:让运维从“被动应答”升级为“主动理解、自主决策、持续记忆、多角色协同”。
💡 人话版目标:凌晨三点告警响起,Agent 自动查日志、定位问题、给出建议;搞不定再升级给人。
一次对话的数据流转
在编码前,先厘清用户消息在系统内的完整生命周期:
用户消息 → API Gateway → AgentService
│
┌──────┼──────┐
▼ ▼ ▼
意图识别 记忆加载 知识检索
│ │ │
└──────┼──────┘
▼
Agent 执行引擎
(ReAct/Plan-Exec/Reflect)
│
┌──────┼──────┐
▼ ▼ ▼
LLM调用 工具调用 结果合成
│ │ │
└──────┼──────┘
▼
SSE 流式返回给用户
│
┌──────┴──────┐
▼ ▼
记忆更新 用户看到回复
该流程包含 7 个关键节点,每个节点对应一个独立模块。反复推演此流程,能暴露诸多细节问题,例如:
- 工具调用结果过长导致上下文溢出
- LLM 陷入重复调用同一工具的循环
这些问题将在后续模块中逐一解决。
六层架构详解
基于上述数据流,我将系统拆解为六层架构:
接入层 │ 钉钉/企微/飞书/Web/SSE
Agent层 │ 意图识别 + 多轮对话 + 任务编排 + 工具调用
│ ReAct · Plan-Exec · Reflect
记忆层 │ 槽位(Slots) + 工作记忆 + 长期记忆 + 原子快照
知识层 │ 文档解析 → Embedding → BM25+向量 → Rerank
基础设施 │ Nacos + Redis + PostgreSQL + RocketMQ
可观测 │ Langfuse(LLM Trace) + Prometheus + Grafana
接入层
企业级 AI 系统需支持多端接入(钉钉、企微、飞书、Web)。接入层职责聚焦于:
- 协议适配:统一不同客户端的通信协议
- 鉴权:验证 API Key 或 OAuth Token
- 路由:将请求分发至核心服务
⚠️ 为何选 SSE 而非 WebSocket?
对话场景本质是服务端单向推送(99% 场景无需客户端主动发消息)。SSE 基于 HTTP,天然支持自动重连,且比 WebSocket 更轻量。
Agent 层
这是系统的核心引擎,处理逻辑如下:
- 意图识别:判断用户需求类型(知识查询/操作执行/故障排查)
- 记忆加载:恢复会话上下文
- 知识检索:从运维文档库获取相关信息
- 执行引擎:选择策略处理任务
执行引擎支持三种策略:
| 策略 | 描述 | 适用场景 |
|---|---|---|
| ReAct | Think → Act → Observe 循环 | 通用场景(如查指标、算数学) |
| Plan-Exec | LLM 生成 N 步计划后逐项执行 | 复杂任务(如“分析上周告警趋势并出报告”) |
| Reflect | 执行后自我审查,不满意则重试 | 高质量输出要求场景 |
📌 当前 Phase 1 仅实现 ReAct,Plan-Exec 与 Reflect 将在 Phase 3 落地。
记忆层
传统聊天机器人的“记忆”仅为对话历史列表,但在运维场景远远不够。例如用户说“查 mysql-prod-01 的 CPU”,Agent 需提取结构化信息:
- 资产 ID:
mysql-prod-01 - 指标类型:
CPU - 时间范围: 默认最近 1 小时
这类结构化信息称为 槽位(Slots)。为此设计四级记忆体系:
| 记忆类型 | 作用 | 实现状态 |
|---|---|---|
| 槽位记忆 | 提取关键结构化信息(资产/集群/时间等) | Phase 1 ✅ |
| 工作记忆 | 管理当前对话 Token 预算 | Phase 1 ✅ |
| 长期记忆 | 跨会话经验沉淀(如“连接池满导致故障”) | Phase 4 📐 |
| 原子快照 | 完整对话 JSONB 存档(用于审计复盘) | Phase 4 📐 |
前两级已通过 Redis 实现热缓存。
知识层
运维团队通常拥有大量分散文档(Confluence/语雀/Markdown)。知识层通过 RAG(Retrieval-Augmented Generation)管线将其转化为 LLM 可用的知识:
- 文档解析:支持 PDF(含表格)、DOCX、HTML、MD、TXT
- 智能切分:段落优先 → 句子降级 → 字符硬切(目标 chunk ≈ 500 token)
- 向量化:支持 BGE / Text2vec / Qwen Embedding 三种后端
- 混合检索:BM25 关键词 + 向量语义 + RRF 融合 + Reranker 精排
- 溯源问答:回答中标注来源(如“《MySQL 运维手册》第 42 页”)
🔧 当前进展:Phase 2a 已完成文档解析→切分→向量化→Milvus 入库;混合检索与溯源问答在 Phase 2b/c 开发中。
基础设施与可观测
- 基础设施:Redis(热缓存)、PostgreSQL(持久化)、Milvus Standalone(向量存储)。Phase 4-5 将引入 Nacos(服务发现)和 RocketMQ(消息队列)
- 可观测性:
- Langfuse:追踪 LLM 调用链(Prompt/Token/延迟)
- Prometheus + Grafana:监控服务健康度
🚨 关键认知:LLM 调用链不可观测 = 生产事故无法排查!
Python + Java 异构架构设计
为何不统一语言栈?答案在于生态分工:
| 领域 | 技术栈 | 原因 |
|---|---|---|
| AI 能力层 | Python | LangChain/Transformers/PyTorch 等生态原生支持 |
| 业务系统层 | Java | 企业 CMDB/工单/告警系统多为 SpringCloud 架构 |
因此采用分阶段策略:
- Phase 1-3:纯 Python 实现 AI 核心能力(FastAPI + LangChain)
- Phase 4-5:通过 Nacos 服务发现接入 Java 业务层
graph LR
A[Java SpringCloud 业务层] -->|Nacos 服务发现| B[Python AI 编排层]
subgraph Java 业务层
A1[CMDB/资产]
A2[工单系统]
A3[告警中心]
A4[用户/权限]
A5[定时调度]
end
subgraph Python AI 层
B1[AgentService]
B2[LLM Gateway]
B3[Agent Engine]
B4[RAG Pipeline]
B5[Memory System]
B6[Tool Framework]
end
五阶段演进路线
项目采用渐进式交付,分五个里程碑:
| 里程碑 | 阶段 | 演示场景 | 当前状态 |
|---|---|---|---|
| M1: Hello Agent | Phase 1 | “今天几号?100+200=?” → Agent 调工具 → 流式回答 | ✅ 完成 |
| M2: 知识问答 | Phase 2 | 导入 20 份运维文档,问“MySQL 连接池满了怎么处理?” → 溯源回答 | 🔶 2a 完成 |
| M3: 多策略 | Phase 3 | 同一任务 ReAct vs Plan-Exec 对比 | 📐 设计阶段 |
| M4: 长记忆 | Phase 4 | 50 轮对话后仍记住关键信息 | 📐 设计阶段 |
| M5: 故障自愈 | Phase 5 | 模拟告警 → 排查 → 定位 → 出报告 | 📐 设计阶段 |
M1 验收标准示例:
- Docker Compose 一键启动,
/api/v1/health返回 healthy - 修改
.env中LLM_PROVIDER=deepseek→qwen即可切换模型 - “今天几号”自动调时间工具,“123*456”自动调计算器
- SSE 流式逐 token 推送
- 无 API Key 返回 401
- LLM 故障时返回友好提示,不暴露敏感信息
当前进展与代码结构
当前纯 Python 代码约 1500 行(不含测试),模块分布如下:
| 模块 | 行数 | 功能说明 |
|---|---|---|
| LLM 适配层 | ~250 | Abstract Base + OpenAI Adapter + Factory + Retry |
| 工具框架 | ~200 | Registry + 3 个内置工具 + 安全计算器 |
| ReAct 执行引擎 | ~200 | 循环控制 + 工具执行 + 上下文截断 + 错误处理 |
| 会话记忆 | ~120 | Redis CRUD + TTL + 列表查询 |
| 文档管线 | ~600 | 5 种解析器 + 切分器 + 3 种 Embedder + Milvus CRUD |
| API 层 | ~300 | Chat/Session/Knowledge 路由 + 中间件 + 健康检查 |
系统包含 7 个 API 端点,通过 5 个 Docker 容器部署:
agent(核心服务)postgres(持久化存储)redis(会话缓存)milvus(向量数据库)etcd/minio(元数据/文件存储)
系列后续规划
本系列共 12 篇,每篇聚焦一个核心模块:
| 篇 | 内容 | 状态 |
|---|---|---|
| 1 | 架构全景(本篇) | ✅ |
| 2 | LLM 适配层:一套接口切换三家大模型 | ✅ |
| 3 | 手写 ReAct 循环,不调 LangChain Agent | ✅ |
| 4 | SSE 流式 + Redis 会话记忆 | ✅ |
| 5 | 文档管线:解析→切分→向量化→Milvus | ✅ |
| 6 | 混合检索架构(设计解读) | 📐 |
| 7 | Query 改写 + HyDE(设计解读) | 📐 |
| 8 | 溯源问答(部分实现 + 设计) | 🔶 |
| 9-11 | Multi-Agent / 记忆体系 / 故障自愈 | 📐 |
| 12 | 复盘:面试追问清单 + 设计模式总结 | ✅ |
下一篇预告:《LLM 适配层:一套接口切换 DeepSeek/Qwen/OpenAI》,揭秘为何选用适配器模式而非 if-else 硬编码。