基于 Go + CloudWeGo/Eino 框架构建的 Tool-Use 智能运维 Agent,接入 Prometheus 告警、腾讯云 CLS 日志(MCP 协议)、MySQL 等数据源,通过自研 Tool-Use 循环引擎驱动 LLM 自动完成「告警 → 日志检索 → 根因分析 → 方案生成」的闭环排障。
┌──────────────────────────────────────────────────────────────┐
│ PulseAgent │
│ │
│ ┌─────────────┐ ┌──────────────────────────────────────┐ │
│ │ Frontend │──→│ GoFrame HTTP Server │ │
│ │ (暗夜模式) │←──│ /api/chat (对话) │ │
│ │ 拖拽上传 │ │ /api/upload (文档上传) │ │
│ │ SSE 流式 │ │ /metrics (Prometheus 指标) │ │
│ └─────────────┘ └──────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────▼───────────────────────────┐ │
│ │ Tool-Use Loop Engine (自研) │ │
│ │ │ │
│ │ for i := 0; i < MaxIter; i++ { │ │
│ │ resp = model.Generate(messages) │ │
│ │ if no ToolCalls → Stream() 输出 │ │
│ │ else → 执行工具 → 追加结果 │ │
│ │ } │ │
│ └──────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Prometheus │ │ 腾讯云 CLS │ │ MySQL │ │
│ │ query_alerts │ │ MCP 协议 │ │ query_database │ │
│ └───────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌───────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ SubAgent │ │ read_document│ │ Memory System │ │
│ │ 多Agent协作 │ │ PDF/TXT/MD │ │ .md + YAML索引 │ │
│ └───────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Prometheus + Grafana 可观测性 │ │
│ │ Counter: 请求计数 Histogram: 延迟分布 Gauge: 活跃数 │ │
│ │ 告警: LowQPS / HighP99 / HighErrorRate / HighActive │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
摒弃 Eino 原生 ReAct 有向图调度,自研极简循环引擎。工具调用阶段 Generate() 非流式快速执行,最终回答阶段切换 Stream() 流式输出,通过 SSE 逐字推送前端。
// internal/ai/engine/loop_stream.go
for iteration := 0; iteration < MaxIterations; iteration++ {
resp := model.Generate(ctx, messages) // 非流式,快速拿工具调用
if len(resp.ToolCalls) == 0 {
stream := model.Stream(ctx, messages) // 切换流式,逐字输出
for chunk := range stream { onChunk(chunk) }
return
}
// 执行工具,追加结果到 messages
for _, tc := range resp.ToolCalls {
result := toolMap[tc.Name].Invoke(ctx, tc.Args)
messages = append(messages, toolResultMsg(result))
}
}为什么不用 Eino ReAct?
- Graph 模式工具调用后无法流式输出,用户等 30s 无反馈
- 长链路易死循环,Graph 会卡死
解决长链路排障中 Token 爆炸与 OOM 问题,实测 Token 消耗降低 ~60%。
| 级别 | 策略 | 阈值 |
|---|---|---|
| L1 大结果预截断 | 工具返回 >50KB 时只保留 2KB 摘要 | 50KB |
| L2 会话滑动窗口 | 保留 System Prompt + 最近 40 条消息 | 40 条 |
| L3 旧工具占位符 | 仅保留最近 5 轮工具原文,更早的替换为 [truncated] |
5 轮 |
废弃 Milvus 向量数据库,用 Markdown + YAML Frontmatter 持久化知识与索引。通过小模型对 MEMORY.md 索引做语义召回,消除向量幻觉,外部依赖缩减为零。
.memories/
├── MEMORY.md # 全局索引(文件名 + 描述清单)
├── prometheus_alerts.md # 记忆条目(YAML frontmatter + 内容)
└── kafka_troubleshoot.md
召回流程:扫描 frontmatter → 格式化清单 → 小模型语义匹配 → 加载命中文件
对标 Claude Code 的文档处理能力:
- 入口三级校验:空文件 → 大小阈值(50MB) →
%PDF-魔数验证 - 双路降级提取:
pdftotext优先 → 扫描版降级 OCR - 结构化错误分类:
ERR_EMPTY/ERR_ENCRYPTED/ERR_CORRUPT/ERR_TOO_LARGE
wrk 压测 → GoFrame PrometheusMiddleware 采集指标
→ Prometheus 每5s抓取 /metrics → 告警规则评估
→ AI Agent 调用 query_prometheus_alerts 工具
→ 自动生成根因分析 + 排查建议报告
三种指标:pulseagent_http_requests_total (Counter) / pulseagent_http_request_duration_ms (Histogram) / pulseagent_http_active_requests (Gauge)
主 Agent 通过 sub_agent 工具派遣子任务,Worker 创建独立模型实例和消息历史,但共享主 Agent 工具集(不含 sub_agent,避免递归)。
重构前 重构后
───────────────── ─────────────────
Milvus 向量数据库 → ✘ 删除 → Memory 文件系统
RAG Pipeline → ✘ 删除 → Tool-Use Loop
Plan-Execute-Replan Agent → ✘ 删除 → 极简循环引擎
eino StreamGraphBranch → ✘ 绕过 → 自建 RunToolLoopStream()
DeepSeek 模型 → Kimi K2.6
单 Agent → 主Agent + SubAgent
无监控 → Prometheus + Grafana
二进制 48MB → 35MB(-27%)
| 类别 | 技术 |
|---|---|
| 语言 | Go 1.24 |
| Web 框架 | GoFrame v2 |
| AI 框架 | CloudWeGo/Eino |
| 模型 | Kimi K2.6(OpenAI 兼容协议) |
| 监控 | Prometheus + Grafana |
| 数据源 | Prometheus Alerts / 腾讯云 CLS (MCP) / MySQL |
PulseAgent/
├── main.go # 入口
├── dev.sh # 开发启动脚本
├── internal/
│ ├── ai/
│ │ ├── engine/
│ │ │ ├── loop.go # Tool-Use Loop(非流式)
│ │ │ ├── loop_stream.go # Tool-Use Loop(流式)⭐
│ │ │ └── context.go # 三级上下文压缩
│ │ ├── memory/
│ │ │ ├── manager.go # 记忆管理器
│ │ │ ├── recall.go # 语义召回
│ │ │ └── types.go # 数据结构
│ │ ├── docproc/
│ │ │ ├── pdf.go # PDF 解析(魔数验证/pdftotext/分页)
│ │ │ ├── errors.go # 结构化错误分类
│ │ │ └── pdf_test.go # 单元测试
│ │ ├── tools/
│ │ │ ├── query_prometheus_alerts.go
│ │ │ ├── read_document.go
│ │ │ └── sub_agent.go # SubAgent 多 Agent 协作
│ │ └── agent/chat_pipeline/ # Chat Pipeline 编排
│ └── controller/chat/ # HTTP 接口层
├── deploy/
│ ├── start.sh # 全栈启停脚本
│ ├── prometheus/
│ │ ├── prometheus.yml # 抓取配置
│ │ └── alerts.yml # 4 条告警规则
│ └── wrk/ # 压测脚本
├── PulseAgentFrontend/ # 前端(暗夜模式/拖拽上传/流式)
└── manifest/config/config.yaml # 配置
# 开发模式(后端 + 前端 + 实时日志)
bash dev.sh
# 全栈启动(含 Prometheus + Grafana)
bash deploy/start.sh all
# 查看状态 / 停止
bash deploy/start.sh status
bash deploy/start.sh stop
# 编译
go build -o pulseagent main.go| 维度 | 数值 |
|---|---|
| 总 commit | 11 |
| 新增模块 | 5 个(engine, memory, docproc, sub_agent, prometheus middleware) |
| 删除模块 | 6 个(embedder, indexer, retriever, plan_execute_replan 等) |
| 净增代码 | +3,480 行 |
| 二进制瘦身 | 48MB → 35MB(-27%) |
MIT