ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

自建Agent驱动可观测性自动化:从聊天助手到运维监控的工程实践

自建Agent驱动可观测性自动化:从聊天助手到运维监控的工程实践 Atlas 这类“通过自建 Agent 为创业公司运营提供可观测性observability”的项目把 AI Agent 从聊天助手推向了运维自动化。可观测性在创业团队里长期是个尴尬话题业务增长快、人员少、基础设施变化频繁传统监控体系要么太重要么配置成本高于实际收益。Atlas 的思路是让 Agent 自己判断要观测什么、自己去接数据源、自己生成监控项和仪表盘并在运行过程中不断修正。本文不从产品官网复述功能而是从工程实现角度拆解这类系统的设计难点核心循环怎么设计、最小实现怎么写、验证机制为什么比生成能力更重要、上线后有哪些排错路径。读者如果正在做 AI Agent 应用或者想用 LLM 减轻可观测性建设负担这篇内容都可以直接对照落地。1. 先理清创业公司运营观测缺的不是工具而是“搭观测的人”1.1 创业公司运维观测的真实痛点创业公司的后端团队通常只有一个名号实际上每个人都要兼顾业务开发、发布、线上问题处理和值班。可观测性建设的真实痛点不是“没有 Prometheus”或者“没有 Grafana”而是没有人能把监控体系搭起来并持续维护。业务上线前需要回答几个问题核心链路是哪几条哪些指标真正反映业务健康告警阈值定多少仪表盘放哪几个面板。这些问题在成熟公司由 SRE 团队负责在创业公司往往被无限搁置。结果是线上出了故障靠用户反馈或者靠某位开发顺手打开数据库看一眼。Atlas 这类系统想解决的正是“搭观测的人”缺失的问题。它把监控项定义、SQL 查询生成、仪表盘编排、告警规则配置这些原本需要人工完成的资产建设任务交给 Agent 自动生成。1.2 传统可观测性链路为什么覆盖不了运营场景传统可观测性链路可以拆成五层采集器、存储、查询、展示、告警。每一层都有成熟开源方案但把它们串起来需要大量人工配置。以最常见的组合 Prometheus Grafana 为例环节需要人工做的事创业团队常见结果采集部署 exporter编写抓取配置只采集了 CPU、内存等基础指标存储配置留存周期、容量规划指标存几天就过期查询编写 PromQL 计算业务指标业务指标没有人写展示设计仪表盘、维护图表默认模板凑合用告警编写规则、配置通知渠道告警规则严重缺失或噪音大这套链路适合基础设施监控但创业公司更关心的是“今天订单失败率为什么升高”“新用户注册转化是不是在下降”。这些运营类指标往往存在业务数据库里需要写 SQL 去统计而不是靠基础设施指标反映。传统工具链没有自动把业务表和运营目标变成监控资产的能力所以即使部署了整套监控平台运营观测仍然空白。1.3 “自建 Agent”到底自建了什么“Self-building agents”直译是自我构建的 Agent容易误解成 Agent 会无限地修改自己的代码或系统权限。实际在 Atlas 这类场景里它自建的对象是观测资产而不是 Agent 自身。所谓观测资产包括以下几类监控检查项一段可执行查询和判定规则例如“一小时内订单失败率超过 5%”。仪表盘面板把多个查询结果组织成可视化视图。告警规则阈值、时间窗口、通知渠道的组合。数据源连接从某个数据库或 API 拉取数据的能力。自建的含义是给定一个运营目标Agent 根据当前数据结构、已有资产和运行状态自动生成上述资产而不是从预置模板里挑选。模板只能覆盖已知场景自建 Agent 理论上能覆盖业务快速变化时不断出现的新场景。这里要特别区分两个概念。Atlas 做的不是自动修复auto-remediation也就是不直接去改代码、重启服务或者回滚发布。它做的是自动建立观测能力把“可观测”这一步自动化。实际要不要修复、怎么修复仍然由人决策。2. Atlas 这类系统把 Agent 循环拆成了四个阶段2.1 核心循环感知、规划、构建、验证要让 Agent 自动生成可用的监控资产不能只靠一次 LLM 调用。真实环境里Agent 必须理解当前系统状态才能生成正确的查询和规则。整个循环可以拆成四步感知Perceive读取数据库结构、已有资产列表、历史运行结果形成当前上下文。规划Plan根据用户目标和上下文决定要构建哪些资产拆成步骤。构建Build执行规划中的每个步骤生成 SQL、仪表盘 JSON、告警规则。验证Verify对生成结果做语法校验、试运行、结果合理性判断通过后才激活。四步构成闭环。验证失败时失败信息会反馈给 Agent让它重新规划或修改查询。这个“生成后必须验证”的循环是自建 Agent 和普通代码生成工具的核心区别。普通代码生成模型只负责输出一段看起来合理的代码而观测系统里的生成结果会立即影响线上监控质量。一条错误的 SQL 可能让仪表盘永远空白一条错误告警规则可能让团队在凌晨反复被误报叫醒。所以验证阶段不是可选项而是整个系统可靠性的支柱。2.2 系统分层与模块职责从工程结构看一个 Atlas 风格系统可以拆成四层层职责关键组件连接层管理数据源、执行查询、读取 schema数据库连接池、只读账号、超时控制Agent 核心层上下文组装、规划、调用 LLM、解析输出Prompt 模板、工具定义、步骤执行器验证层校验语法、试运行、结果合理性检查SQL 校验器、查询执行器、规则引擎资产层存储资产管理、状态流转、审计配置库、审批接口、版本记录这四层各司其职。连接层负责安全和性能Agent 核心层负责决策验证层负责质量把关资产层负责让生成结果变成持久化配置。实践中很容易犯的错误是把 Agent 逻辑和资产存储混在一起。Agent 生成结果后直接写进生产配置没有中间态后续想回滚或者审计就很难。正确的做法是 Agent 只输出资产定义由资产层统一处理状态流转和持久化。2.3 为什么“生成监控项”比“生成文本”难得多很多人会问LLM 连代码都能生成生成一条监控 SQL 有什么难难在三个地方。第一是上下文完整性。生成一条正确 SQL 必须知道表名、字段名、字段类型、数据量级、时间字段格式。Agent 如果拿不到完整 schema或者 schema 与实际库不一致生成结果大概率不可用。第二是正确性验证。代码生成可以靠编译或单元测试验证监控 SQL 的验证要复杂得多。基础语法正确不代表逻辑正确字段存在不代表口径正确一条能跑出结果的查询也可能统计错了业务含义。第三是环境约束。生产环境的数据库查询有超时、有并发限制、有敏感数据访问控制。Agent 生成的查询不能影响线上业务这要求验证层在受限环境下执行试运行而不是直接连生产库跑。理解这三点就能明白为什么这类系统要把大量工程投入放在“上下文收集”和“验证层”上而不是单纯优化 Prompt 让它生成得更漂亮。3. 用一个最小 Python 实现跑通“自建监控检查项”3.1 环境准备与目录结构下面用一个最小 Python 实现演示核心循环。示例只做学习用不接入真实 LLM 时可以先用规则函数模拟 Agent 输出跑通流程后再接 OpenAI 兼容接口。环境要求项目推荐值说明Python3.10 以上使用 dataclass、类型注解数据库SQLite本地无依赖适合演示LLM SDKopenai 或兼容 SDK也可以用 mock 函数替代依赖管理pip venv保持环境干净目录结构按模块拆分方便后面扩展atlas-demo/ ├── core.py # 资产模型与状态流转 ├── agent.py # Agent 主循环 ├── validate.py # 验证层 ├── store.py # 资产存储 ├── data/ │ └── demo.db # 本地测试数据库 └── config.yaml # Agent 配置先创建虚拟环境并安装依赖python3 -m venv .venv source .venv/bin/activate pip install openai pyyaml如果只是跑流程验证不调用真实模型可以跳过 openai 安装用 mock 函数代替。3.2 数据模型用 ObservedAsset 表达 Agent 产出的资产任何 Agent 生成结果在进入生产前都应该有一个明确的中间状态。这里定义 ObservedAsset 作为统一资产模型# core.py from dataclasses import dataclass, field from typing import Any import time dataclass class ObservedAsset: asset_type: str # check | dashboard | alert_rule name: str definition: dict status: str draft # draft - validated - active created_at: float field(default_factorytime.time) updated_at: float field(default_factorytime.time) def to_dict(self) - dict: return { asset_type: self.asset_type, name: self.name, definition: self.definition, status: self.status, created_at: self.created_at, updated_at: self.updated_at, }状态流转固定为 draft - validated - active。任何新生成资产必须先进入 draft验证通过才变成 validated最后通过审批或自动策略才 active。这个模型避免 Agent 生成结果直接生效的风险。3.3 实现 Agent 主循环Agent 主循环按感知、规划、构建、验证四步组织。这里用一个可替换的 llm_client 参数便于接 mock 或真实模型。# agent.py import json import sqlite3 import time from core import ObservedAsset from validate import validate_check class AtlasAgent: def __init__(self, db_path: str, llm_client, store: dict): self.db_path db_path self.llm llm_client self.store store # name - ObservedAsset self.max_steps 5 self.max_build_attempts 2 def collect_context(self) - dict: 感知阶段读取 schema 和已有资产 conn sqlite3.connect(self.db_path) cur conn.cursor() cur.execute(SELECT name FROM sqlite_master WHERE typetable) tables cur.fetchall() schema_ctx {} for (table,) in tables: cur.execute(fPRAGMA table_info({table})) schema_ctx[table] [row[1] for row in cur.fetchall()] conn.close() return { schema: schema_ctx, existing_assets: list(self.store.keys()), } def plan(self, goal: str, context: dict) - list: prompt self._build_plan_prompt(goal, context) response self.llm.plan(prompt) return json.loads(response)[steps] def run(self, goal: str): context self.collect_context() steps self.plan(goal, context) created [] for step in steps[: self.max_steps]: if step[kind] build_check: asset self._build_check(step, context) if asset is not None: created.append(asset) return created def _build_check(self, step: dict, context: dict): 构建阶段生成 SQL 并保存 draft 资产 definition { metric: step[metric], query: step[query], threshold: step.get(threshold, 0.0), window: step.get(window, 1 hour), } asset ObservedAsset( asset_typecheck, namestep[name], definitiondefinition, ) self.store[asset.name] asset return assetAgent 循环里最要紧的是把每一步结果落进 store而不是临时变量。这样后续验证、审批、追溯都有依据。3.4 让 Agent 生成一个订单健康检查先用规则函数模拟 LLM验证整个流程# mock_llm.py def mock_plan(prompt: str) - str: return json.dumps({ steps: [ { kind: build_check, name: one_hour_order_failure, metric: order_failure_rate, query: ( SELECT SUM(CASE WHEN statusfailed THEN 1 ELSE 0 END) * 1.0 / COUNT(*) FROM orders WHERE created_at datetime(now, -1 hour) ), threshold: 0.05, window: 1 hour, } ] })真实接入时plan prompt 需要把 schema 和已有资产列表完整注入。mock 能帮助先跑通状态流转再逐步替换成真实模型。用 demo 数据执行# run_demo.py import sqlite3 from agent import AtlasAgent from mock_llm import mock_plan conn sqlite3.connect(data/demo.db) conn.execute( CREATE TABLE IF NOT EXISTS orders ( id INTEGER PRIMARY KEY, status TEXT, created_at TEXT) ) conn.execute(INSERT INTO orders VALUES (1, success, datetime(now, -30 minutes))) conn.execute(INSERT INTO orders VALUES (2, failed, datetime(now, -30 minutes))) conn.commit() conn.close() agent AtlasAgent(data/demo.db, llm_clientmock_llm, store{}) created agent.run(监控订单健康度重点看一小时内失败率) for asset in created: print(asset.to_dict())运行后会看到 Agent 生成一个名为 one_hour_order_failure 的检查项状态是 draft。这个流程体现了一个重要设计Agent 只负责生成不负责上线。4. 几个关键设计决策权限、验证、成本、审批4.1 权限边界Agent 只能写配置不能直接动数据Agent 需要连接数据库读取 schema 和试运行查询但它不应该拥有写入权限。设计上要遵守两条边界第一Agent 使用的数据库账号必须是只读账号。即使 Agent 生成了错误的 DELETE 或 UPDATE也会被执行层直接拒绝。SQLite 场景可以在连接层检查语句前缀生产数据库应该在账号权限层就限制。第二Agent 能修改的只有可观测性配置即检查项、仪表盘、告警规则不能直接修改业务表、不能执行 DDL、不能改权限配置。配置变更走资产层统一接口不做直接写入。# validate.py 中的只读检查示例 def ensure_read_only(sql: str): normalized .join(sql.strip().lower().split()) allowed_prefixes (select, with, explain) if not any(normalized.startswith(p) for p in allowed_prefixes): raise ValueError(fquery must be read-only, got: {sql[:80]})只读检查是最后一道兜底真正的安全边界还是要靠数据库账号权限。应用层检查能拦截失误不能替代底层的权限控制。4.2 验证机制比生成能力更值得投入Agent 生成能力再强如果验证机制薄弱用户就无法信任输出结果。一个完整的验证层至少包含四道检查检查项作用失败处理语法校验确认 SQL 可以被解析丢弃并重新生成只读校验防止写入和 DDL直接拒绝试运行确认查询能执行返回错误信息给 Agent结果合理性确认字段类型、行数、数值范围合理标为待人工确认# validate.py import sqlite3 def validate_check(asset, db_path: str, timeout: int 5) - dict: query asset.definition[query] try: ensure_read_only(query) except ValueError as e: return {ok: False, error: str(e)} conn sqlite3.connect(db_path) conn.execute(fPRAGMA query_only ON) try: cur conn.cursor() cur.execute(query) columns [d[0] for d in cur.description] if cur.description else [] rows cur.fetchmany(5) return {ok: True, columns: columns, sample_rows: rows} except Exception as e: return {ok: False, error: repr(e)} finally: conn.close()试运行结果非常关键。字段是否存在、查询是否超时、返回的数据是否为空这些信息都应该回传给 Agent作为下一轮生成或修改的依据。如果 Agent 第一次生成的查询字段名错误验证层能把具体错误字符串注入上下文让它修正。4.3 成本控制把步数和重试次数变成显式参数调用 LLM 有成本Agent 循环如果失控一次任务可能产生几十次模型调用。把成本相关参数显式放到配置里# config.yaml agent: llm: model: gpt-4o-mini temperature: 0.2 max_tokens: 2000 limits: max_steps_per_run: 5 max_build_attempts: 2 validate_timeout_seconds: 10 guards: read_only: true require_approval: true allowed_asset_types: [check, dashboard, alert_rule]参数含义和影响参数默认建议调大的影响调小的风险max_steps_per_run5单次任务可覆盖更多资产成本上升复杂目标可能完不成max_build_attempts2修复失败的几率更高低质量结果直接进入人工处理temperature0.2输出更随机更适合代码生成取低值validate_timeout_seconds10复杂查询可跑完超时导致误判失败成本控制的原则是宁可让 Agent 少干活也不要让它无限重试。一次失败的生成返回给用户比后台悄悄重试十次花掉大量 token 更可控。4.4 审批流draft - validated - active生成结果要经过状态流转才能生效。推荐最简审批流所有 Agent 生成资产先进入 draft。验证层通过后提升为 validated。需要人工确认时validated 状态等待审批。审批通过后变为 active才写入监控系统。# store.py def approve(store: dict, name: str) - dict: asset store.get(name) if asset is None: raise KeyError(fasset not found: {name}) if asset.status ! validated: raise ValueError(only validated asset can be approved) asset.status active asset.updated_at time.time() return asset.to_dict()对于信任度高的团队也可以配置自动审批策略但必须保留全量审计。人工审批的价值不在于拦截所有问题而是让团队对 Agent 生成的内容保持知情。注意生成能力决定系统上限验证和审批决定系统下限。实际落地时应该先做厚验证层再放开 Agent 的生成范围。5. 运行验证如何确认 Agent 生成的观测资产真的可用5.1 启动本地环境在 demo 目录执行python run_demo.py正常情况下会输出类似下面的结果{ asset_type: check, name: one_hour_order_failure, definition: { metric: order_failure_rate, query: SELECT SUM(...) FROM orders WHERE ..., threshold: 0.05, window: 1 hour }, status: draft, created_at: 1741234567.89, updated_at: 1741234567.89 }这个输出说明 Agent 完成了感知、规划、构建三阶段产物是合理结构。接下来需要手动执行验证函数from agent import AtlasAgent from validate import validate_check agent AtlasAgent(data/demo.db, llm_clientmock_llm, store{}) created agent.run(监控订单健康度) asset created[0] print(validate_check(asset, data/demo.db))5.2 三种验证方式验证 Agent 生成的观测资产至少做三层检查第一层是静态检查。确认 SQL 是否只读、字段是否存在、查询是否超时。这层自动化完成不需要人工。第二层是语义核对。把试运行返回的 sample_rows 和真实业务数据对比确认统计口径正确。例如失败率的样本数据是 0.5要人工确认“数据库中确实有一条 failed 订单和一条 success 订单”。第三层是持续观察。Agent 生成的检查项在激活后要持续跑一段时间对比真实告警是否与业务故障吻合。这是最容易被忽略的部分。一个监控项生成出来如果连续一周没有触发也没有业务事件并不一定说明它正确问题可能是阈值过高或查询条件写错导致永远返回 0。5.3 预期输出与日志为了让排查有据可依每个阶段都要输出结构化日志。日志里至少包含任务 ID、当前步骤、LLM 调用 token 数、验证结果、状态变化。task_idabc123 phaseperceive tablesorders size2 schema_oktrue task_idabc123 phaseplan steps1 cost_tokens320 task_idabc123 phasebuild assetone_hour_order_failure statusdraft task_idabc123 phasevalidate assetone_hour_order_failure oktrue columns[failure_rate] rows1 task_idabc123 phaseapprove assetone_hour_order_failure statusactive日志的关键是让每个状态变化都能追溯。某条告警误报时翻开日志就能看到这个告警规则是哪次任务生成、由谁审批、当时的 schema 是什么。5.4 学习环境与生产环境差异demo 跑通不等于可以上线。两类环境差异很大维度学习/本地环境生产环境数据源SQLite 本地测试库真实业务库只读账号执行权限应用层校验数据库账号只读 网络隔离审批可跳过必须所有变更可回滚存储JSON 文件数据库 配置中心审计无全量审计包括 prompt 和输出成本可忽略需要预算上限和告警自身观测无Agent 自身也要被监控生产环境最需要额外补的是“对 Agent 的监控”。Agent 本身也是一个线上服务它调用的数据源、生成频率、失败率、token 消耗都要有观测。如果监测系统本身由 Agent 生成一旦 Agent 挂了观测也会失效所以要保留一套独立于 Agent 的基础监控。6. 常见问题排查从现象倒推根因6.1 Agent 反复循环不收敛现象是 Agent 不断生成新的检查项或者反复重试同一个失败步骤任务迟迟不结束。常见原因有三个上下文没有注入已有资产列表导致重复创建同名检查项验证失败信息没有完整回传给 LLM导致 Agent 不知道错在哪max_build_attempts 设置过大给了 Agent 无限重试的空间。检查方式先看日志中的 phase 分布。如果大量出现 plan 和 build说明计划阶段没有收敛如果大量出现 validate 失败说明上下文信息不完整。处理方式是每次 plan 前把 store 中已有资产全量注入 prompt同时把验证错误原样回传。例如字段不存在的错误字符串要完整放进下一轮生成上下文。6.2 生成查询引用了不存在的字段现象是 SQL 能通过语法检查但试运行报 no such column。根因往往是 Agent 拿到的 schema 与真实库不一致。可能原因有schema 提取时机太早表结构后来变了使用了缓存 schema多个数据源时把 A 库的表结构当作 B 库的上下文使用。排查路径先确认查询属于哪个数据源再对比该数据源当前 schema。关键手段是让感知阶段每次运行都重新提取 schema不缓存超过设定时长的 schema 信息。生产环境可以用 information_schema 或 PRAGMA 实时获取。6.3 告警不触发或者频繁误报告警不触发的原因包括阈值设置过高、时间窗口使用了固定时间而不是相对时间、查询结果一直为空。频繁误报则相反阈值过低或者统计口径把正常波动也算成了异常。排查顺序应该是先看查询结果是否正常再确认阈值口径最后看时间窗口定义。很多问题出在时间表达式上例如用了 2025-01-01 00:00:00 这样的硬编码时间而不是 datetime(now, -1 hour)。对仪表盘和告警系统来说时间窗口必须使用相对时间。6.4 排错速查表问题现象常见原因检查方式处理建议Agent 重复生成同类型监控项上下文没有注入已有资产查看日志中 existing_assets 字段plan prompt 中注入现有资产清单SQL 报字段不存在schema 与库不一致对比日志中的 schema 和 DB 实际结构每次 run 重新读取 schema仪表盘面板一直无数据查询用了固定时间范围检查 dashboard JSON 时间参数改用相对时间变量告警不触发阈值过高或查询为空试运行查询并人工核对结果调低阈值并用历史数据回测误报频繁统计口径包含正常波动核对 SQL 条件和业务语义增加排除条件或调整窗口LLM 调用超时prompt 太长或并发过高查看调用耗时和 token 数拆分上下文增加超时重试token 消耗超预算步数或重试次数过大监控 cost_tokens 和调用次数限制 max_steps 和 max_build_attempts排错原则先看输入和上下文再看验证日志最后才怀疑模型能力。多数问题出在上下文不完整而不是 LLM 不会写 SQL。7. 落地建议把整套流程放进创业团队的真实节奏7.1 先固定一个可观测域不要一开始就让 Agent 覆盖全公司所有监控。建议先选一个业务域例如订单系统、支付回调或者注册转化数据源数量控制在一到两个表结构相对稳定。固定域的好处是上下文可控、验证标准清晰、问题定位容易。订单域的 check 生成正确后再逐步扩展到用户域、营销域。Agent 每次扩展都叠加在已有资产基础上避免一次性面对过于复杂的 schema 和多个数据源。7.2 每次变更都必须可追溯Agent 生成的资产要像代码变更一样管理。每条 check、每个 dashboard 都要记录生成时间、任务 ID、调用的模型。输入的目标和上下文快照。验证结果和测试数据。审批人、生效时间。审计存储要独立于 Agent 的资产存储防止 Agent 异常时连审计记录也被修改。回滚能力同样重要任何 active 状态的资产都应该能回滚到上一个 validated 版本。7.3 不要让 Agent 无限重试LLM 调用有成本Agent 在循环中消耗的 token 会在账单上直接体现。落地时建议设置双重上限单任务是硬限制比如 max_steps5、max_build_attempts2。全局是软限制比如每小时最多执行 20 个任务超出后排队并告警。成本监控本身应该独立不能依赖 Agent 自己上报因为 Agent 异常时可能连上报逻辑都失效。7.4 上线前检查清单数据源连接是否使用只读账号权限是否按库最小化。查询是否都有超时控制试运行是否在独立环境执行。生成的资产是否默认 draft 状态是否有审批流程。是否有全量审计日志日志是否包含 prompt 快照和验证结果。是否设置 token 预算上限和任务数上限。Agent 自身是否有独立监控Agent 故障是否有兜底告警。是否需要回滚机制历史版本是否可恢复。是否先限制在单一业务域schema 变更后是否能自动感知。这套清单本质上是在回答一个问题当 AI 开始替团队做观测决策时团队怎么保证它做得既安全又正确。回答清楚这个问题Atlas 的“self-building”才会真正产生价值。下一步最值得做的实验是在本地库里放一份和线上结构一致的脱敏 schema让 Agent 自动生成三类资产检查项、仪表盘、告警规则。先跑通“生成 - 验证 - 审批 - 激活”的完整链路再逐步接入真实数据和真实模型。这条路比一开始就追求复杂架构更稳也更接近创业团队实际需要的自动化节奏。
返回列表