为部署系统添加 AI 智能诊断能力,通过分析 Node Exporter 指标数据,自动生成诊断报告。
接收告警 → 构建提示词 → Docker 容器 → Python MCP → AI 多轮对话 → 生成报告
↓ ↓
启动 Python 环境 调用 Prometheus/GitHub MCP
↓ ↓
执行诊断脚本 实时查询指标/代码
- 后端框架: go-zero
- 数据库: MongoDB
- AI 服务: Claude API / OpenAI API / 通义千问(可配置,通过 MCP)
- MCP 工具: Prometheus MCP(指标查询)+ GitHub MCP(代码分析,可选)
- 运行环境: Docker 容器(Python 3.12 + MCP Server)
- 指标来源: Prometheus(实时查询,无需存储)
重要变更:当前实现基于 MCP 架构,不再存储指标数据,指标由 Prometheus MCP 实时查询。
type Deployment struct {
Id string `bson:"_id,omitempty" json:"id,omitempty"`
// TODO: 添加业务字段
CreatedTime time.Time `bson:"createdTime" json:"createdTime"`
UpdatedTime time.Time `bson:"updatedTime" json:"updatedTime"`
}MCP 架构下不需要此模型,原因:
- 指标数据由 Prometheus MCP 实时查询,无需存储
- AI 通过 MCP 工具直接调用 Prometheus API
- 避免数据冗余和同步问题
type Report struct {
Id string `bson:"_id,omitempty" json:"id,omitempty"`
DeploymentId string `bson:"deploymentId" json:"deploymentId"` // 关联的部署ID
Content string `bson:"content" json:"content"` // AI 生成的报告(纯文本)
Status ReportStatus `bson:"status" json:"status"` // 报告生成状态
CreatedTime time.Time `bson:"createdTime" json:"createdTime"`
UpdatedTime time.Time `bson:"updatedTime" json:"updatedTime"`
}
// 报告状态枚举
type ReportStatus string
const (
ReportStatusGenerating ReportStatus = "generating" // 生成中
ReportStatusCompleted ReportStatus = "completed" // 已完成
ReportStatusFailed ReportStatus = "failed" // 生成失败
)
type ReportModel interface {
Insert(ctx context.Context, report *Report) error
FindByDeploymentId(ctx context.Context, deploymentId string) (*Report, error)
Update(ctx context.Context, report *Report) error
DeleteByDeploymentId(ctx context.Context, deploymentId string) error
}状态说明:
generating: 报告生成中(MCP 多轮对话进行中)completed: 报告生成成功failed: 报告生成失败(AI 调用失败或其他错误)
报告格式(AI 输出格式): 当前实现中,报告以 JSON 格式存储,包含以下字段:
{
"promQL": ["查询语句1", "查询语句2"],
"content": "【问题概述】\n...\n【根因分析】\n...\n【影响范围】\n...\n【解决方案】\n..."
}其中:
promQL: 字符串数组,包含诊断过程中识别出的异常指标的 Prometheus 查询语句content: 字符串,包含详细的诊断报告,格式如下:【问题概述】 简要描述告警反映的问题 【根因分析】 详细说明问题的根本原因,引用具体的指标数据和分析过程 【影响范围】 说明问题影响的系统范围和严重程度 【解决方案】 提供具体的解决步骤和建议
集合1: Deployment
// 主键索引
{ "_id": 1 }
// 查询优化索引(根据业务需求添加)
{ "createdTime": -1 }集合2: Reports
// 主键索引
{ "_id": 1 }
// 部署ID唯一索引(一个部署只有一份报告)
{ "deploymentId": 1 } unique
// 时间索引
{ "createdTime": -1 }
// 状态索引(用于查询生成中/失败的报告)
{ "status": 1, "updatedTime": -1 }注意:Metrics 集合已废弃,不再需要创建。
// backend/internal/config/config.go
package config
import "github.com/zeromicro/go-zero/rest"
type Config struct {
rest.RestConf
MongoDB struct {
URI string
Database string
}
// 新增:AI 服务配置
AI AIConfig
// 新增:Prometheus 配置(可选,如果需要主动抓取指标)
Prometheus PrometheusConfig `json:",optional"`
}
type AIConfig struct {
BaseURL string `json:",optional"` // API 基础 URL,从环境变量读取
APIKey string // API 密钥,从环境变量读取
Model string `json:",default=gpt-4"` // 模型名称
Timeout int `json:",default=30"` // 超时时间(秒)
PrometheusURL string `json:",optional"` // Prometheus URL(MCP 模式需要)
GitHubToken string `json:",optional"` // GitHub Personal Access Token(可选)
GitHubToolsets string `json:",default=repos,issues,pull_requests,releases"` // GitHub MCP 工具集
}重要变更:
- 新增
PrometheusURL: MCP 模式下必需,用于 Prometheus MCP 连接 - 新增
GitHubToken: 可选,提供后自动启用 GitHub MCP 进行代码分析 - 新增
GitHubToolsets: GitHub MCP 工具集配置(默认包含 repos, issues, pull_requests, releases) - 移除
MaxRetries: MCP 模式下由 Python 脚本内部处理 - 移除
PrometheusConfig: 统一到AIConfig中
AI 服务商支持:
BaseURL: 支持不同 AI 服务商的端点- OpenAI:
https://api.openai.com/v1 - Claude:
https://api.anthropic.com/v1 - 通义千问:
https://dashscope.aliyuncs.com/compatible-mode/v1 - ModelScope:
https://api-inference.modelscope.cn
- OpenAI:
Model: 根据不同服务商使用不同模型名称- OpenAI:
gpt-4,gpt-3.5-turbo - Claude:
claude-3-5-sonnet-20241022 - 通义千问:
qwen-max,qwen-turbo - ModelScope:
Qwen/Qwen3-Coder-480B-A35B-Instruct
- OpenAI:
# backend/etc/hackathon-api.yaml
Name: hackathon-api
Host: 0.0.0.0
Port: 8888
Mongo:
URL: mongodb://localhost:27017
Database: hackathon
AI:
BaseURL: ${AI_BASE_URL} # 从环境变量读取
APIKey: ${AI_API_KEY} # 从环境变量读取
Model: claude-3-5-sonnet-20241022
Timeout: 60 # MCP 模式需要更长时间
PrometheusURL: http://localhost:9090 # Prometheus URL(必需)
GitHubToken: ${GITHUB_TOKEN} # GitHub Token(可选,提供后自动启用 GitHub MCP)
GitHubToolsets: repos,issues,pull_requests,releases
Qiniu:
AccessKey: ${QINIU_ACCESS_KEY}
SecretKey: ${QINIU_SECRET_KEY}
Bucket: your-bucket
DownloadHost: https://your-cdn.com
VM:
VMUIURL: http://localhost:8428环境变量示例:
# OpenAI
export AI_BASE_URL="https://api.openai.com/v1"
export AI_API_KEY="sk-xxx"
# Claude
export AI_BASE_URL="https://api.anthropic.com/v1"
export AI_API_KEY="sk-ant-xxx"
# 通义千问
export AI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
export AI_API_KEY="sk-xxx"
# ModelScope(免费)
export AI_BASE_URL="https://api-inference.modelscope.cn"
export AI_API_KEY="your-modelscope-api-key"
# GitHub MCP(可选)
export GITHUB_TOKEN="ghp_xxx" # 提供后自动启用 GitHub 代码分析功能
# 七牛云
export QINIU_ACCESS_KEY="xxx"
export QINIU_SECRET_KEY="xxx"Docker 容器准备: MCP 模式需要 Docker 容器运行 Python 环境和 MCP Server:
cd backend/internal/clients/diagnosis/py
./build-docker.sh # 构建镜像// backend/internal/clients/diagnosis/interface.go
package diagnosis
import (
"context"
"github.com/Z3Labs/Hackathon/backend/internal/types"
)
type DiagnosisClient interface {
// GenerateReport 为指定部署生成诊断报告
// 接收告警回调请求,返回报告内容、错误信息
GenerateReport(req *types.PostAlertCallbackReq) (string, error)
}
type AIClient interface {
GenerateCompletion(ctx context.Context, prompt string) (response string, tokensUsed int, err error)
}重要变更:
- 输入参数从
deploymentId改为*types.PostAlertCallbackReq(告警回调请求) - 新增
AIClient接口,用于 AI 调用的抽象层
// backend/internal/clients/diagnosis/client.go
package diagnosis
import (
"context"
"fmt"
"time"
"github.com/zeromicro/go-zero/core/logx"
"github.com/Z3Labs/Hackathon/backend/internal/config"
"github.com/Z3Labs/Hackathon/backend/internal/model"
"github.com/Z3Labs/Hackathon/backend/internal/svc"
"github.com/Z3Labs/Hackathon/backend/internal/types"
)
type diagnosisClient struct {
ctx context.Context
reportModel model.ReportModel
aiClient AIClient
logx.Logger
}
// New 创建诊断客户端
func New(ctx context.Context, svcCtx *svc.ServiceContext, aiConfig config.AIConfig) DiagnosisClient {
return &diagnosisClient{
ctx: ctx,
reportModel: svcCtx.ReportModel,
aiClient: NewMCPClient(aiConfig), // 使用 MCP 客户端
Logger: logx.WithContext(ctx),
}
}
// GenerateReport 生成诊断报告
func (c *diagnosisClient) GenerateReport(req *types.PostAlertCallbackReq) (string, error) {
deploymentId := req.Labels["deploymentId"]
// 1. 检查是否已存在报告(避免重复生成)
existingReport, _ := c.reportModel.FindByDeploymentId(c.ctx, deploymentId)
if existingReport != nil {
return "", fmt.Errorf("部署 %s 的诊断报告已存在,避免重复生成", deploymentId)
}
// 2. 先插入一条状态为"生成中"的记录
report := &model.Report{
DeploymentId: deploymentId,
Content: "",
Status: model.ReportStatusGenerating,
CreatedTime: time.Now(),
UpdatedTime: time.Now(),
}
if err := c.reportModel.Insert(c.ctx, report); err != nil {
return "", fmt.Errorf("创建报告记录失败: %w", err)
}
// 3. 构建提示词(基于告警信息)
prompt := buildPromptTemplate(req)
// 4. 调用 AI 接口(通过 MCP 查询指标并生成诊断报告)
reportContent, tokensUsed, err := c.aiClient.GenerateCompletion(c.ctx, prompt)
if err != nil {
// AI 调用失败,更新状态为失败
report.Status = model.ReportStatusFailed
report.Content = err.Error()
report.UpdatedTime = time.Now()
if updateErr := c.reportModel.Update(c.ctx, report); updateErr != nil {
c.Errorf("更新报告状态失败: %v", updateErr)
}
return "", fmt.Errorf("AI 调用失败: %w", err)
}
// 5. 更新报告内容和状态为完成
report.Content = reportContent
report.Status = model.ReportStatusCompleted
report.UpdatedTime = time.Now()
if err := c.reportModel.Update(c.ctx, report); err != nil {
return "", fmt.Errorf("更新报告失败: %w", err)
}
c.Infof("部署 %s 诊断报告生成成功,Token 消耗: %d", deploymentId, tokensUsed)
return reportContent, nil
}关键变更:
- 移除指标查询逻辑:不再从数据库查询指标,改为基于告警回调信息
- 移除异常检测逻辑:MCP 模式下,AI 通过 Prometheus MCP 实时查询指标进行分析
- 新增报告状态管理:支持
generating、completed、failed三种状态 - 错误处理增强:AI 调用失败时,更新报告状态为
failed并保存错误信息
核心架构:通过 Docker 容器运行 Python MCP 环境
// backend/internal/clients/diagnosis/mcpclient.go
package diagnosis
import (
"bytes"
"context"
"fmt"
"os/exec"
"regexp"
"strings"
"time"
"github.com/zeromicro/go-zero/core/logx"
"github.com/Z3Labs/Hackathon/backend/internal/config"
)
const (
diagnosisContainerName = "diagnosis-service"
diagnosisImageName = "diagnosis-service:latest"
pyReturnSplit = "#####" // Python 脚本输出分隔符
)
var jsonRegex = regexp.MustCompile(`\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}`)
type mcpClient struct {
containerName string // Docker 容器名称
scriptPath string // 容器内 Python 脚本路径
apiKey string // AI API Key
baseURL string // AI Base URL
model string // AI 模型名称
prometheusURL string // Prometheus URL
githubToken string // GitHub Token(可选)
githubToolsets string // GitHub MCP 工具集
timeout time.Duration // 超时时间
logger logx.Logger // 日志记录器
}
// NewMCPClient 创建 MCP AI 客户端
func NewMCPClient(cfg config.AIConfig) AIClient {
client := &mcpClient{
containerName: diagnosisContainerName,
scriptPath: "/app/diagnosis_runner.py",
apiKey: cfg.APIKey,
baseURL: cfg.BaseURL,
model: cfg.Model,
prometheusURL: cfg.PrometheusURL,
githubToken: cfg.GitHubToken,
githubToolsets: cfg.GitHubToolsets,
timeout: time.Duration(cfg.Timeout) * time.Second,
logger: logx.WithContext(context.Background()),
}
// 启动容器(如果未运行)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := client.ensureContainer(ctx); err != nil {
client.logger.Errorf("启动诊断服务容器失败: %v", err)
}
return client
}
func (c *mcpClient) GenerateCompletion(ctx context.Context, prompt string) (string, int, error) {
// 设置超时(MCP 调用需要更长时间)
ctx, cancel := context.WithTimeout(ctx, c.timeout*2)
defer cancel()
// 确保容器运行
if err := c.ensureContainer(ctx); err != nil {
return "", 0, fmt.Errorf("确保容器运行失败: %w", err)
}
// 构建 docker exec 命令参数
args := []string{
"exec", "-i",
c.containerName,
"python", c.scriptPath,
"--prompt", prompt,
"--api-key", c.apiKey,
"--base-url", c.baseURL,
"--model", c.model,
"--prometheus-url", c.prometheusURL,
}
// 添加 GitHub MCP 参数(如果配置)
if c.githubToken != "" {
args = append(args, "--github-token", c.githubToken)
if c.githubToolsets != "" {
args = append(args, "--github-toolsets", c.githubToolsets)
}
}
cmd := exec.CommandContext(ctx, "docker", args...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// 执行命令
err := cmd.Run()
if err != nil {
return "", 0, fmt.Errorf("生成分析报告失败: %w\nstdout: %s\nstderr: %s",
err, stdout.String(), stderr.String())
}
// 解析输出
result := strings.TrimSpace(stdout.String())
if result == "" {
return "", 0, fmt.Errorf("Python 脚本返回空结果")
}
split := strings.Split(result, pyReturnSplit)
if len(split) > 1 {
c.logger.Infof("Python 脚本执行成功,日志:\n%s", split[0])
returnValue := strings.TrimSpace(strings.Join(split[1:], pyReturnSplit))
// 提取 JSON
findString := jsonRegex.FindString(returnValue)
if findString != "" {
return findString, 0, nil // MCP 模式下无法获取准确的 token 数
}
return "", 0, fmt.Errorf(returnValue)
}
return "", 0, fmt.Errorf(result)
}
// ensureContainer 确保容器运行
func (c *mcpClient) ensureContainer(ctx context.Context) error {
if c.isContainerRunning(ctx) {
return nil
}
return c.startContainer(ctx)
}
// 其他容器管理方法(isContainerRunning, startContainer 等)...关键特性:
- Docker 容器化:隔离 Python 环境,避免依赖冲突
- 自动容器管理:自动启动和管理 Docker 容器
- MCP 多工具支持:同时支持 Prometheus MCP 和 GitHub MCP
- 错误处理:完善的日志记录和错误传递
核心变更:MCP 模式下,提示词基于告警回调信息构建,AI 通过 MCP 工具主动查询指标数据。
// backend/internal/clients/diagnosis/prompt.go
package diagnosis
import (
"fmt"
"strings"
"github.com/Z3Labs/Hackathon/backend/internal/types"
)
func buildPromptTemplate(req *types.PostAlertCallbackReq) string {
// 构建标签信息
labelsStr := formatMap(req.Labels)
// 构建注解信息
annotationsStr := formatMap(req.Annotations)
// 提取描述信息
description := req.Desc
if desc, ok := req.Annotations["description"]; ok && desc != "" {
description = desc
}
prompt := fmt.Sprintf(`你是一个专业的 DevOps 运维诊断专家,擅长分析系统告警并定位问题根因。
**收到以下告警信息**:
告警类型:%s
告警名称: %s
告警状态: %s
严重程度: %s
描述信息: %s
触发值: %.2f
开始时间: %s
接收时间: %s
结束时间: %s
告警源: %s
需要处理: %t
紧急程度: %t
**标签信息**:
%s
**注解信息**:
%s
**你的任务**:
1. **使用 Prometheus MCP 工具查询相关指标**
- 使用 get_targets() 检查 Prometheus 抓取目标状态
- 使用 execute_query() 查询关键指标(CPU、内存、网络、应用指标等)
- 使用 execute_range_query() 获取时间范围内的趋势数据
- 使用 get_metric_metadata(metric: "metric_name") 获取指标元数据
- 使用 list_metrics() 列出所有可用指标名称
- 根据告警信息中的标签 hostname 精准查询相关实例的指标
2. **分析发布失败的根本原因**
- 结合告警信息和查询到的指标数据
- 分析指标之间的关联关系
- 识别异常模式和趋势
- 定位问题的根本原因
3. %s
4. **输出格式**
重要:请严格按照以下JSON格式输出!!!,你的输出只有一个json,不要用 markdown代码块 标记或任何额外的文本说明
{
"promQL": ["查询语句1", "查询语句2"],
"content": "报告内容"
}
其中:
- promQL: 字符串数组,包含你在诊断分析过程中识别出的异常指标的Prometheus查询语句
- content: 字符串,包含详细的诊断报告,格式如下:
【问题概述】
简要描述告警反映的问题
【根因分析】
详细说明问题的根本原因,引用具体的指标数据和分析过程
【影响范围】
说明问题影响的系统范围和严重程度
【解决方案】
提供具体的解决步骤和建议
现在请开始诊断分析:`,
req.Key,
req.Alertname,
req.Status,
req.Severity,
description,
req.Values,
req.StartsAt,
req.ReceiveAt,
req.EndsAt,
req.GeneratorURL,
req.NeedHandle,
req.IsEmergent,
labelsStr,
annotationsStr,
fmt.Sprintf(github_search_prompt, req.RepoAddress, req.Tag),
)
return prompt
}
// GitHub 代码分析提示词(可选)
var github_search_prompt = `根据以上排查信息,
若确定问题的存在,则进一步分析 GitHub 仓库 "%s" 发布 release 中的潜在 bug:
1. 用 "get_release_by_tag" 获取指定 tag %s 的release,若没有查到相关信息,则使用 "get_latest_release"获取最新一个release,
然后从 body 中提取该次发布的 PR 编号,若该次发布存在pr,则继续,否则结束分析。
2. 逐个分析 PR,对每个 PR 编号,依次调用以下工具:
### 2.1 获取 PR 基本信息
工具:pull_request_read
- method: "get"
- pullNumber: [PR编号]
### 2.2 获取代码变更文件
工具:pull_request_read
- method: "get_files"
- pullNumber: [PR编号]
### 2.3 获取代码 Diff
工具:pull_request_read
- method: "get_diff"
- pullNumber: [PR编号]
3. 分析每个 PR 的 diff,查找常见的致命 bug(忽略不会导致发布失败的小问题):
- 空指针问题
- 资源泄漏(未关闭连接、文件句柄)
- 并发安全
- 逻辑错误
4. 若查找到可能的错误,则输出:PR编号 + 文件路径 + 问题描述 + 建议修复`
// formatMap 格式化 map 为易读的字符串
func formatMap(m map[string]string) string {
if len(m) == 0 {
return "(无)"
}
var lines []string
for key, value := range m {
lines = append(lines, fmt.Sprintf(" - %s: %s", key, value))
}
return strings.Join(lines, "\n")
}关键特性:
- MCP 工具指导:明确指示 AI 使用哪些 MCP 工具查询数据
- GitHub 代码分析:可选的 GitHub MCP 集成,分析发布相关的代码变更
- 结构化输出:要求 AI 返回包含 promQL 和 content 的 JSON 格式
- 灵活性:AI 可以根据告警信息自主决定查询哪些指标
backend/internal/clients/diagnosis/py/
├── Dockerfile # Docker 镜像定义
├── build-docker.sh # 构建脚本
├── requirements.txt # Python 依赖
├── diagnosis_runner.py # 主入口脚本
├── simple_anthropic_mcp.py # MCP 集成逻辑
├── .env.template # 环境变量模板
└── .env # 本地环境变量(不提交到 Git)
FROM python:3.12-slim
WORKDIR /app
# 安装 Node.js(GitHub MCP 需要)
RUN apt-get update && apt-get install -y nodejs npm curl && rm -rf /var/lib/apt/lists/*
# 安装 Python 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 安装 GitHub MCP Server
RUN npm install -g @modelcontextprotocol/server-github
# 复制脚本
COPY . .
# 保持容器运行
CMD ["tail", "-f", "/dev/null"]# requirements.txt
anthropic>=0.40.0
mcp>=1.3.2
prometheus-mcp-server>=0.3.0
python-dotenv>=1.0.0- ✅ 创建 Python MCP 环境目录结构
- ✅ 编写 Dockerfile 和 requirements.txt
- ✅ 实现 diagnosis_runner.py 入口脚本
- ✅ 实现 simple_anthropic_mcp.py MCP 集成
- ✅ 构建 Docker 镜像
- ✅ 扩展 Config 添加 AI 配置(PrometheusURL、GitHubToken)
- ✅ 实现 Report Model(新增 Status 字段)
- ✅ 实现 MCP 客户端(mcpclient.go)
- ✅ 实现 DiagnosisClient 核心逻辑
- ✅ 实现提示词构建(基于告警回调)
- ✅ 端到端测试(告警 → MCP → 报告生成)
- 🔲 性能优化(容器启动时间、MCP 调用超时)
- 🔲 错误处理完善(网络失败、AI 超时)
- 🔲 提示词优化(提高报告质量)
- 🔲 支持更多 AI 服务商(OpenAI、通义千问)
- 🔲 添加 MCP 工具缓存机制
- 🔲 实现报告历史版本管理
- 🔲 添加诊断报告评分功能
MCP 调用链路:
Go Backend → Docker Exec → Python Container → MCP Client → AI + Tools
↓ ↓ ↓
构建提示词 启动 MCP Sessions 多轮对话查询指标
↓ ↓ ↓
传递参数 Prometheus MCP 生成诊断报告
GitHub MCP (可选)
关键特性:
- 多轮对话:AI 可以多次调用 MCP 工具,逐步收集数据
- 工具路由:同时支持 Prometheus 和 GitHub 两个 MCP Server
- 实时查询:无需预存指标数据,按需实时查询
容器生命周期管理:
// 1. 检查容器是否运行
if c.isContainerRunning(ctx) {
return nil
}
// 2. 尝试启动已存在的容器
if c.tryStartExistingContainer(ctx) {
return nil
}
// 3. 创建新容器
docker run -d --name diagnosis-service --restart unless-stopped diagnosis-service:latest重启策略:
unless-stopped:自动重启,除非手动停止- 系统重启后自动恢复运行
- 确保服务高可用性
报告状态流转:
generating (生成中) → completed (成功) / failed (失败)
↓ ↓ ↓
先插入记录 更新内容 保存错误信息
错误处理策略:
- AI 调用失败:更新报告状态为
failed,保存错误信息 - 容器启动失败:记录日志,返回错误给调用方
- 超时处理:MCP 调用设置 2 倍超时时间(默认 120 秒)
# OpenAI SDK(兼容多个 AI 服务商)
go get github.com/sashabaranov/go-openai说明:
- 只需要一个 SDK,通过配置不同的 BaseURL 支持多个服务商
- 无需额外的 HTTP 客户端,SDK 内置
# 设置环境变量
export AI_BASE_URL="https://api.openai.com/v1"
export AI_API_KEY="sk-xxx"
# 启动服务
cd backend
go run hackathon.go -f etc/hackathon-api.yaml# 设置环境变量
export AI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
export AI_API_KEY="sk-xxx" # 通义千问的 API KEY
# 修改配置文件中的 Model
# Model: qwen-max
# 启动服务
cd backend
go run hackathon.go -f etc/hackathon-api.yaml# 需要第三方 OpenAI-compatible 代理服务
export AI_BASE_URL="https://your-proxy-service.com/v1"
export AI_API_KEY="sk-ant-xxx"
# 修改配置文件中的 Model
# Model: claude-3-5-sonnet-20241022
# 启动服务
cd backend
go run hackathon.go -f etc/hackathon-api.yaml本实现方案提供了一个简洁高效的 AI 智能诊断系统架构,核心特点:
- ✅ 数据模型解耦:Metrics、Reports 独立存储,易于扩展和查询
- ✅ 简化数据处理:Report 直接存储 JSON 字符串,前端解析,无需后端结构体映射
- ✅ 统一 AI 接口:使用 OpenAI SDK,一套代码支持多个 AI 服务商
- ✅ 配置灵活:BaseURL 和 APIKey 从环境变量读取,方便切换服务商
- ✅ 接口简洁:DiagnosisClient 只有一个核心方法
GenerateReport
1. 查询指标数据 (MetricModel.FindByDeploymentId)
↓
2. 异常检测 (静态阈值)
↓
3. 构建提示词 (buildPromptTemplate)
↓
4. 调用 AI (OpenAI SDK)
↓
5. 提取 JSON (extractJSON)
↓
6. 保存报告 (ReportModel.Insert) - 直接存储 JSON 字符串
| 设计点 | 方案 | 优势 |
|---|---|---|
| 数据模型 | 独立的 Metrics 和 Reports 表 | 解耦、易扩展、查询灵活 |
| Report 存储 | JSON 字符串 | 简化后端逻辑、AI 格式变更无需改代码 |
| AI 集成 | 统一使用 OpenAI SDK | 一套代码支持多服务商 |
| 配置管理 | 环境变量 + YAML | 安全、灵活、易部署 |
| Client 初始化 | 传入 ServiceContext | 充分利用 go-zero 依赖注入 |
按照文档的实施步骤,可以快速完成核心功能开发:
- 阶段 1:创建 Model (Metric、Report)
- 阶段 2:实现 DiagnosisClient
- 阶段 3:集成到 ServiceContext
- 阶段 4:测试与优化