1. 为什么“先建工作空间”是AI原生运维的第一性原理
1.1 从一个真实的翻车现场说起
去年我接手了一个中等规模的微服务集群,大概四十多个服务,跑在三个环境里。当时团队想搞“智能化运维”,第一反应就是接个大模型进来,让它帮忙看日志、分析告警。我们花了大概两周时间,把日志接口、监控接口、告警接口全部对接给模型,做了一个看起来挺像样的对话入口。结果上线第三天就出事了——一个核心支付服务开始间歇性超时,模型给出的分析是“建议重启该服务”,值班同学照做了,重启完确实好了十分钟,然后继续超时。后来人工排查发现,根因是下游一个不起眼的配置中心连接池被打满了,重启支付服务只是暂时释放了连接,根本没解决问题。
这件事让我彻底想明白一个道理:AI原生运维不是把大模型接到运维系统上就完事了,而是要让AI像人一样,对每个系统有“上下文感知能力”。人为什么能排查出根因?因为老运维脑子里有一张图——他知道支付服务依赖配置中心,知道配置中心的连接池参数是多少,知道最近有没有人改过配置。而当时的AI,看到的只是孤立的日志和指标,它没有“工作空间”这个概念,自然给不出靠谱的判断。
所以标题里说的“先给每个系统建一个工作空间”,本质上是在解决AI运维的上下文缺失问题。工作空间就是AI的“工位”,在这个工位里,它能看到这个系统所有相关的信息:代码仓库、部署配置、监控面板、历史告警、变更记录、依赖关系。没有这个工位,AI就是个到处乱逛的临时工,今天看看这个日志,明天查查那个指标,永远建立不起对系统的整体认知。
1.2 工作空间到底装了什么
很多人第一次听到“工作空间”这个词,会以为就是建个文件夹把文档丢进去。不是的。一个合格的AI运维工作空间,至少包含五类信息,我把它叫做“五件套”:
- 静态资产:这个系统的代码仓库地址、镜像仓库地址、部署清单(Kubernetes YAML或者Helm Chart)、配置文件模板。这些东西让AI知道“这个系统长什么样”。
- 动态指标:Prometheus或者同类监控系统里这个系统相关的所有指标,包括CPU、内存、QPS、延迟、错误率,以及自定义的业务指标。这是AI的“体检数据”。
- 日志与事件:这个系统产生的日志流、Kubernetes事件、变更审计日志。这是AI的“病历本”。
- 依赖拓扑:这个系统依赖了谁、被谁依赖、中间件是谁、数据库是谁。这是AI的“关系网”。
- 操作历史:最近谁做了什么变更、什么时候发的版、回滚过几次。这是AI的“记忆”。
这五类信息缺一不可。我见过有些团队只给AI接监控指标,结果AI看到CPU高了就喊扩容,完全不知道是因为上游突然来了流量高峰,扩完容流量一过又浪费资源。也见过只给AI接日志的,AI能从日志里看出报错,但不知道这个报错对应的服务版本是哪个,给出的修复建议驴唇不对马嘴。
提示:工作空间的信息不是越多越好,而是要“全而准”。我建议初期先覆盖核心系统,每个系统的五件套必须完整,宁可少接几个系统,也不要接一堆信息残缺的系统。信息残缺的工作空间比没有工作空间更危险,因为AI会基于不完整的信息给出看似合理实则错误的判断。
1.3 AI原生运维和传统AIOps的根本区别
这里需要厘清一个概念。传统AIOps(智能运维)的核心是“算法找规律”,比如用时间序列异常检测算法发现指标异常,用聚类算法把相似告警归并,用根因分析算法定位故障点。这些算法的共同特点是:它们不需要理解系统,只需要理解数据。
AI原生运维不一样。它的核心是“Agent理解系统”。Agent(智能体)不是被动地等数据喂进来,而是主动地去工作空间里探索。比如你问它“支付服务为什么变慢了”,它会自己去查支付服务的监控指标、去看最近的变更记录、去对比上下游服务的延迟变化、去翻日志里的异常堆栈。这个过程和人排查问题的思路是一样的。
打个比方:传统AIOps像是一个只会看仪表盘的司机,仪表盘亮红灯他就报警;AI原生运维像是一个有经验的修车师傅,他不仅看仪表盘,还会打开引擎盖听声音、闻气味、摸温度,综合判断问题出在哪。
这就是为什么“工作空间”是AI原生运维的基石。没有工作空间,Agent就没有探索的空间,只能退化成传统AIOps的算法调用器。有了工作空间,Agent才能真正发挥它的推理能力。
1.4 适合谁来参考这套思路
这套思路适合三类人:
第一类是运维工程师,尤其是正在被“告警风暴”折磨的SRE。如果你每天要处理几百条告警,其中大部分是噪音,那工作空间+Agent的方案能帮你把噪音过滤掉,让AI先做一轮初筛。
第二类是平台工程师,正在建设内部运维平台或者DevOps平台。工作空间可以作为平台的核心抽象,把散落在各个工具里的信息聚合起来,不仅给AI用,也给人用。
第三类是AI应用开发者,想切入运维场景但不知道从哪下手。工作空间是一个很好的切入点,它比做通用Agent简单,因为运维领域的边界相对清晰,信息源也相对标准化。
不管你属于哪一类,我的建议都是:不要一上来就追求全自动。先建工作空间,让AI能回答问题,再逐步让它能执行操作。步子迈大了容易扯着蛋,这是我踩过坑之后的真心话。
2. 工作空间的核心架构与关键设计决策
2.1 工作空间的数据模型怎么设计
建工作空间的第一步是设计数据模型。我试过三种方案,最后选了一种最“笨”但最稳的。
第一种方案是“大宽表”,把所有信息塞进一个Elasticsearch索引里,字段随便加。这种方案上手快,但很快就会出现字段爆炸、查询性能下降、数据一致性差的问题。我试过在一个索引里塞了三百多个字段,后来连自己都记不清哪个字段是干什么的。
第二种方案是“图数据库”,用Neo4j把系统、服务、依赖、告警都建成节点和边。这种方案查询关系很爽,但写入和维护成本高,而且大部分运维场景其实不需要那么复杂的图查询。
第三种方案是我最终采用的:分层存储+统一标识。具体来说:
- 资产层用关系型数据库(PostgreSQL就行),存系统元数据、依赖关系、负责人信息。这部分数据量小,但要求强一致。
- 指标层用时序数据库(Prometheus或者VictoriaMetrics),存监控指标。这部分数据量大,但写入模式简单。
- 日志层用日志系统(Loki或者Elasticsearch),存日志和事件。这部分要求全文检索能力。
- 向量层用向量数据库(比如Milvus或者Qdrant),存文档、历史工单、变更记录的向量化表示。这部分给Agent做语义检索用。
四层之间用一个统一的“系统标识”串起来。这个标识我建议用“环境-系统名-实例ID”的三段式,比如prod-payment-service-001。所有层的数据都带上这个标识,Agent查询的时候先拿到标识,再去各层拉数据。
注意:统一标识看起来简单,但实际落地时最容易出问题。我见过很多团队,监控系统里叫
payment,日志系统里叫payment-service,CMDB里叫支付服务,Agent一查就懵了。建议在建工作空间之前,先花一周时间把命名规范统一了,磨刀不误砍柴工。
2.2 Agent在工作空间里怎么“干活”
工作空间建好了,接下来要让Agent在里面干活。这里的关键是设计好Agent的“工具集”。Agent不是直接访问数据库的,而是通过工具来操作。我一般给Agent配这几类工具:
查询类工具:查指标、查日志、查依赖、查变更记录。这类工具是只读的,Agent可以随便调,不用担心搞出问题。
分析类工具:异常检测、趋势预测、相关性分析。这类工具封装了一些算法,Agent不需要自己算,直接调就行。
操作类工具:重启服务、扩容、回滚、修改配置。这类工具是写操作,必须加审批或者二次确认。我的做法是初期全部禁用,等Agent的准确率上来了再逐步开放。
协作类工具:创建工单、通知负责人、拉群。这类工具让Agent能和人协作,而不是自己闷头干。
工具集的设计原则是:查询类要丰富,分析类要精准,操作类要克制。我见过有团队一上来就给Agent开放了重启权限,结果Agent因为一个误判把生产环境的核心服务重启了,虽然没造成大事故,但把大家吓出一身冷汗。
Agent调用工具的流程一般是这样的:先理解用户的问题,然后规划需要调哪些工具,接着按顺序调用,最后综合结果给出回答。这个过程和人在工作空间里排查问题是一模一样的。
2.3 为什么不用“一个大Agent管所有系统”
这是我在架构设计上纠结最久的一个问题。最初的方案是做一个“全能Agent”,它能看到所有系统的工作空间,用户问什么它查什么。听起来很美好,但实际跑起来问题很多。
第一个问题是上下文爆炸。四十多个系统的信息全塞给Agent,光是系统列表就占了几千个token,真正有用的信息反而被淹没了。Agent经常答非所问,因为它被无关信息干扰了。
第二个问题是权限混乱。不同系统有不同的负责人和权限要求,一个大Agent很难做到精细化的权限控制。你不想让一个实习生通过Agent查到核心支付系统的敏感配置吧?
第三个问题是准确率下降。我做过对比测试,同样的问题,用“全能Agent”的准确率是62%,用“每个系统一个专属Agent”的准确率是89%。差距非常明显。
所以我的建议是:每个系统建一个工作空间,每个工作空间配一个专属Agent。用户提问时,先路由到对应系统的Agent,再由这个Agent在工作空间里干活。如果问题涉及多个系统,就由多个Agent协作,或者由一个“协调Agent”来调度。
这个架构的好处是:每个Agent的上下文是干净的,权限是清晰的,准确率也高。坏处是Agent数量多了之后管理成本上升,但这个问题可以通过模板化来解决——大部分Agent的配置是相似的,只有工具集和知识库不同。
2.4 工作空间的“冷启动”怎么做
新建一个工作空间,最怕的是“空荡荡”。Agent进去一看,什么信息都没有,问它问题它也说不知道。所以工作空间的冷启动很重要。
我的做法是分三步走:
第一步,自动发现。写一个采集器,从现有的监控系统、日志系统、CMDB、代码仓库里自动拉取信息,填充工作空间的基础数据。这一步能解决80%的信息填充问题。
第二步,人工补全。自动发现拿不到的信息,比如系统的业务含义、关键联系人、特殊注意事项,需要人工补。我一般会做一个简单的表单,让系统负责人花十分钟填一下。别小看这十分钟,它能让Agent的回答质量提升一个档次。
第三步,历史沉淀。把过去半年的告警记录、工单记录、变更记录导入工作空间,让Agent有“历史经验”可以参考。这一步是长期工程,可以边用边补。
冷启动做完之后,工作空间就算“活”了。但要注意,工作空间不是建完就不管了,它需要持续更新。我的做法是每天自动同步一次基础数据,每周人工review一次知识库,每月做一次全面盘点。
3. 从零搭建一个AI运维工作空间的完整实操
3.1 环境准备与基础组件选型
假设你现在要从零开始搭一套,我把我用过的组件清单列一下,都是经过生产验证的,不是随便找的。
| 组件类型 | 推荐选型 | 备选方案 | 选择理由 |
|---|---|---|---|
| 关系型数据库 | PostgreSQL 15 | MySQL 8 | JSON字段支持好,适合存半结构化的资产数据 |
| 时序数据库 | VictoriaMetrics | Prometheus | 单机性能强,运维简单,兼容PromQL |
| 日志系统 | Loki | Elasticsearch | 资源占用低,和Grafana集成好 |
| 向量数据库 | Qdrant | Milvus | 部署简单,API友好,适合中小规模 |
| Agent框架 | LangChain | LlamaIndex | 工具调用生态成熟,社区活跃 |
| 大模型 | 本地部署开源模型 | 商用API | 数据不出内网,成本可控 |
| 编排层 | 自研轻量调度器 | Airflow | 运维场景不需要那么重的编排 |
选型的原则是:能用单机就不用集群,能用开源就不用商业,能本地部署就不上云。运维数据敏感,而且量级通常没有互联网业务那么大,单机方案足够撑住。
环境准备的具体步骤:
# 以Ubuntu 22.04为例,安装Docker和Docker Compose sudo apt update sudo apt install -y docker.io docker-compose-plugin # 创建数据目录 sudo mkdir -p /data/aiops/{postgres,victoria,loki,qdrant} sudo chown -R $USER:$USER /data/aiops # 启动基础组件(docker-compose.yml片段)version: '3.8' services: postgres: image: postgres:15 volumes: - /data/aiops/postgres:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: your_password ports: - "5432:5432" victoria: image: victoriametrics/victoria-metrics:latest volumes: - /data/aiops/victoria:/victoria-metrics-data ports: - "8428:8428" qdrant: image: qdrant/qdrant:latest volumes: - /data/aiops/qdrant:/qdrant/storage ports: - "6333:6333"这套环境在一台16核64G的机器上跑,支撑五十个系统的工作空间没问题。如果系统数量更多,可以把时序数据库和向量数据库拆出去单独部署。
提示:大模型的选择很关键。我试过用7B参数的模型做Agent,工具调用的准确率只有70%左右,经常调错工具或者参数传错。后来换成14B以上的模型,准确率提升到90%以上。如果条件允许,建议至少用14B的模型,量化后的版本在24G显存的卡上能跑。
3.2 工作空间元数据的建模与录入
环境准备好之后,开始建数据模型。我在PostgreSQL里建了这几张核心表:
-- 系统表 CREATE TABLE systems ( id SERIAL PRIMARY KEY, sys_key VARCHAR(128) UNIQUE NOT NULL, -- 统一标识,如 prod-payment-service name VARCHAR(256) NOT NULL, env VARCHAR(32) NOT NULL, -- prod/staging/dev owner VARCHAR(128), description TEXT, created_at TIMESTAMP DEFAULT NOW() ); -- 依赖关系表 CREATE TABLE dependencies ( id SERIAL PRIMARY KEY, from_sys VARCHAR(128) NOT NULL, to_sys VARCHAR(128) NOT NULL, dep_type VARCHAR(64), -- rpc/db/cache/mq critical BOOLEAN DEFAULT FALSE, UNIQUE(from_sys, to_sys, dep_type) ); -- 资产表 CREATE TABLE assets ( id SERIAL PRIMARY KEY, sys_key VARCHAR(128) NOT NULL, asset_type VARCHAR(64), -- repo/image/config/dashboard asset_uri TEXT NOT NULL, extra JSONB, UNIQUE(sys_key, asset_type, asset_uri) ); -- 知识条目表 CREATE TABLE knowledge ( id SERIAL PRIMARY KEY, sys_key VARCHAR(128) NOT NULL, category VARCHAR(64), -- faq/runbook/incident title VARCHAR(512), content TEXT, embedding_id VARCHAR(128), -- 对应向量库里的ID created_at TIMESTAMP DEFAULT NOW() );建完表之后,写一个采集脚本,从现有系统里拉数据。我一般用Python写,因为运维同学对Python最熟悉。
import psycopg2 import requests def sync_systems_from_cmdb(): """从CMDB同步系统列表""" resp = requests.get("http://cmdb.internal/api/systems") systems = resp.json() conn = psycopg2.connect("dbname=aiops user=postgres password=your_password host=localhost") cur = conn.cursor() for sys in systems: cur.execute(""" INSERT INTO systems (sys_key, name, env, owner, description) VALUES (%s, %s, %s, %s, %s) ON CONFLICT (sys_key) DO UPDATE SET name = EXCLUDED.name, owner = EXCLUDED.owner, description = EXCLUDED.description """, (sys['key'], sys['name'], sys['env'], sys['owner'], sys['desc'])) conn.commit() cur.close() conn.close()这个脚本每天跑一次,保证工作空间的元数据是最新的。依赖关系可以从服务网格或者调用链系统里拉,资产信息可以从代码仓库和镜像仓库的API拉。
录入的时候有个坑要注意:不要一次性把所有系统都录进来。我建议先选三到五个核心系统做试点,跑通了再逐步扩展。一次性全录进来,数据质量问题会把你淹没,而且Agent的表现不好你也找不到原因。
3.3 Agent工具集的具体实现
工具集是Agent和工作空间之间的桥梁。我用LangChain的Tool抽象来实现,每个工具就是一个Python函数。
from langchain.tools import tool import requests @tool def query_metrics(sys_key: str, metric: str, duration: str = "1h") -> str: """查询指定系统的监控指标。 Args: sys_key: 系统标识,如 prod-payment-service metric: 指标名称,如 cpu_usage, qps, latency_p99 duration: 查询时间范围,如 1h, 6h, 24h """ # 调用VictoriaMetrics的PromQL接口 query = f'{metric}{{sys="{sys_key}"}}' resp = requests.get( "http://localhost:8428/api/v1/query_range", params={"query": query, "start": f"-{duration}", "step": "60s"} ) data = resp.json() # 简化返回,只给Agent关键信息 values = data['data']['result'][0]['values'] if data['data']['result'] else [] if not values: return f"未查询到 {sys_key} 的 {metric} 指标数据" latest = values[-1][1] max_val = max(float(v[1]) for v in values) avg_val = sum(float(v[1]) for v in values) / len(values) return f"{sys_key} 的 {metric}:当前值 {latest},最大值 {max_val:.2f},平均值 {avg_val:.2f}" @tool def query_logs(sys_key: str, keyword: str, duration: str = "1h") -> str: """查询指定系统的日志。 Args: sys_key: 系统标识 keyword: 搜索关键词,如 error, timeout, exception duration: 查询时间范围 """ # 调用Loki的查询接口 end = int(time.time() * 1e9) start = end - parse_duration(duration) query = f'{{sys="{sys_key}"}} |= "{keyword}"' resp = requests.get( "http://localhost:3100/loki/api/v1/query_range", params={"query": query, "start": start, "end": end, "limit": 50} ) # 返回日志摘要 ... @tool def query_dependencies(sys_key: str) -> str: """查询指定系统的依赖关系。""" conn = psycopg2.connect(...) cur = conn.cursor() cur.execute("SELECT to_sys, dep_type, critical FROM dependencies WHERE from_sys = %s", (sys_key,)) deps = cur.fetchall() cur.execute("SELECT from_sys, dep_type FROM dependencies WHERE to_sys = %s", (sys_key,)) upstream = cur.fetchall() ... return f"下游依赖:{deps};上游调用方:{upstream}" @tool def query_changes(sys_key: str, duration: str = "24h") -> str: """查询指定系统最近的变更记录。""" ...工具实现有几个要点:
第一,返回值要精简。Agent的上下文窗口有限,工具返回一大堆原始数据反而会干扰它。我一般只返回关键统计值和少量样本,比如“最大值、平均值、当前值”和“最近三条错误日志”。
第二,参数要少而明确。工具的参数越多,Agent调错的概率越大。我尽量把参数控制在三个以内,而且参数名要直白,比如sys_key、metric、duration。
第三,错误处理要友好。工具调用失败时,不要抛异常,而是返回一个描述性的错误信息,让Agent知道发生了什么。比如“未查询到数据”比“KeyError”对Agent友好得多。
第四,工具描述要详细。LangChain的工具描述会作为prompt的一部分传给模型,描述写得越清楚,模型调用得越准确。我一般会在描述里写清楚参数的含义、格式、示例。
3.4 把工作空间和Agent串起来
工具写好了,接下来要把它们和Agent串起来。我用的是LangChain的AgentExecutor,配置如下:
from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain.prompts import ChatPromptTemplate # 系统提示词,这是Agent的“人设” SYSTEM_PROMPT = """你是一个专业的运维助手,负责帮助工程师排查 {sys_key} 系统的问题。 你可以使用以下工具来获取信息: - query_metrics: 查询监控指标 - query_logs: 查询日志 - query_dependencies: 查询依赖关系 - query_changes: 查询变更记录 工作原则: 1. 先理解问题,再规划需要查什么信息 2. 查询信息时,优先查最近1小时的数据 3. 给出结论时,必须基于查询到的实际数据,不要臆测 4. 如果信息不足,明确告诉用户还需要什么信息 5. 涉及操作类建议时,必须提醒用户人工确认 当前系统:{sys_key} 系统描述:{sys_desc} """ prompt = ChatPromptTemplate.from_messages([ ("system", SYSTEM_PROMPT), ("human", "{input}"), ("placeholder", "{agent_scratchpad}"), ]) # 为每个系统创建一个Agent实例 def create_system_agent(sys_key, sys_desc, tools): agent = create_openai_tools_agent(llm, tools, prompt) return AgentExecutor( agent=agent, tools=tools, verbose=True, max_iterations=10, # 防止Agent陷入死循环 handle_parsing_errors=True, ) # 路由层:根据用户问题找到对应的系统 def route_question(question): # 简单实现:用关键词匹配 for sys_key in all_systems: if sys_key in question or all_systems[sys_key]['name'] in question: return sys_key # 复杂实现:用一个小模型做意图分类 return classify_intent(question)这里有几个实操心得:
max_iterations一定要设。我试过不设限制,Agent有时候会陷入“查了指标觉得不够,又去查日志,查完日志觉得不够,又去查指标”的死循环,烧了一堆token还没给出答案。设成10次一般够用。
verbose模式在调试时开,生产时关。verbose会把Agent的每一步思考都打出来,调试的时候很有用,但生产环境日志量太大。
路由层是必须的。不要让用户手动指定系统,那样体验太差。用关键词匹配做第一版就行,准确率不够再上模型分类。
每个系统的Agent要独立配置。不同系统的工具集可能不一样,比如有的系统没有配置中心,那就不需要查配置的工具。独立配置能让Agent更专注。
3.5 一个完整的排查案例演示
说了这么多理论,来看一个实际案例。用户问:“支付服务今天下午开始变慢了,帮我看看什么原因。”
路由层识别出sys_key = prod-payment-service,把问题转给支付服务的Agent。
Agent的思考过程(简化版):
第一步,调用query_metrics查延迟指标:
query_metrics(sys_key="prod-payment-service", metric="latency_p99", duration="6h")返回:当前值 1250ms,最大值 1800ms,平均值 320ms。说明下午确实有延迟飙升。
第二步,调用query_metrics查QPS:
query_metrics(sys_key="prod-payment-service", metric="qps", duration="6h")返回:当前值 1200,最大值 1250,平均值 1180。QPS没有明显变化,排除流量突增。
第三步,调用query_dependencies查依赖:
query_dependencies(sys_key="prod-payment-service")返回:下游依赖 config-center(配置中心)、mysql-main、redis-cache。
第四步,调用query_metrics查下游依赖的延迟:
query_metrics(sys_key="config-center", metric="latency_p99", duration="6h")返回:config-center 的延迟从下午2点开始从 5ms 飙升到 800ms。
第五步,调用query_changes查配置中心的变更:
query_changes(sys_key="config-center", duration="24h")返回:下午1点50分,有人修改了配置中心的连接池大小,从 200 改成了 20。
Agent综合以上信息,给出结论:“支付服务变慢的根因是配置中心在下午1点50分进行了变更,连接池从200缩小到20,导致配置读取延迟飙升,进而拖慢了支付服务。建议回滚该变更或调大连接池。”
整个过程Agent调用了五次工具,耗时约15秒。如果人工排查,至少需要20分钟。这就是工作空间+Agent的价值。
注意:这个案例里Agent能定位到根因,关键在于工作空间里有完整的依赖关系和变更记录。如果只接了监控指标,Agent最多只能告诉你“支付服务变慢了,配置中心也变慢了”,但没法建立因果关系。所以再强调一遍,五件套要完整。
4. 落地过程中最容易踩的坑与排查手册
4.1 Agent答非所问的五个常见原因
这是最常见的问题。你问A,Agent答B,或者答得云里雾里。我总结了五个原因和对应的解法:
| 现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| Agent调用工具时参数传错 | 工具描述不清晰 | 看verbose日志里Agent传的参数 | 完善工具描述,加参数示例 |
| Agent查了无关的系统 | 路由层匹配错误 | 检查路由层的匹配逻辑 | 改用模型做意图分类 |
| Agent给出臆测的结论 | 系统提示词约束不够 | 看Agent是否基于实际数据回答 | 在提示词里强调“必须基于数据” |
| Agent反复查同一个工具 | max_iterations没设或太大 | 看日志里工具调用次数 | 设max_iterations=10,加去重逻辑 |
| Agent回答太啰嗦 | 提示词没有输出格式要求 | 看回答长度 | 在提示词里规定输出格式和字数 |
我重点说一下“Agent给出臆测结论”这个问题。大模型有个毛病,就是它倾向于给出一个“看起来合理”的答案,哪怕它没有足够的信息。在运维场景里这很危险,因为一个错误的结论可能导致错误的操作。
我的解法是在系统提示词里加一条硬约束:“如果你没有查询到相关数据,必须明确说‘未查询到数据,无法判断’,禁止基于常识或经验给出推测性结论。”这条约束加上之后,Agent的“幻觉率”明显下降。
另外,我还会在Agent给出结论后,做一个“事实校验”:把Agent的结论和它查询到的数据做比对,如果结论里提到的数字在查询结果里找不到,就标记为可疑。这个校验可以用简单的字符串匹配实现,不需要模型。
4.2 工作空间数据不同步的排查思路
工作空间的数据来自多个系统,不同步是常态。我遇到过这几种情况:
监控指标延迟。Prometheus默认15秒抓一次,VictoriaMetrics可能有额外的写入延迟。如果Agent查的是最近1分钟的数据,可能查不到。解法是在工具里把查询时间范围往前推5分钟,或者明确告诉Agent“最近5分钟的数据可能不完整”。
日志采集延迟。Loki的采集链路是Promtail -> Loki,中间可能有几十秒的延迟。如果Agent查“刚刚发生的错误”,可能查不到。解法是让Agent查“最近5分钟”而不是“最近1分钟”。
CMDB更新延迟。CMDB的数据往往是人工维护的,更新不及时。如果新上线的服务没录入CMDB,Agent就查不到。解法是做一个自动发现机制,从Kubernetes的API里自动同步服务列表,和CMDB做比对,发现差异就告警。
依赖关系过期。服务之间的依赖关系是动态变化的,今天A依赖B,明天可能就不依赖了。如果依赖关系没更新,Agent的分析就会出错。解法是定期从服务网格或者调用链系统里重新拉取依赖关系,每周更新一次。
排查数据不同步的问题,我的经验是:先看数据源,再看采集链路,最后看工作空间。大部分问题出在数据源本身,而不是工作空间。
4.3 权限与安全的红线怎么划
AI运维涉及生产系统,权限和安全是红线。我的做法是“三层隔离”:
第一层,网络隔离。工作空间的各个组件部署在内网,不暴露公网。Agent访问工具走内网API,不走公网。
第二层,数据隔离。不同系统的工作空间数据在逻辑上隔离,Agent只能访问自己系统的数据。敏感数据(如数据库密码、密钥)不进入工作空间,Agent查询时返回脱敏后的结果。
第三层,操作隔离。查询类工具直接开放,分析类工具记录审计日志,操作类工具必须人工审批。我一般会做一个审批流,Agent提出操作建议,推送给系统负责人,负责人确认后才执行。
提示:不要给Agent开放“删除”类操作,哪怕是测试环境。我见过一个案例,Agent在测试环境误删了一个数据库,虽然可以恢复,但浪费了半天时间。删除操作永远应该由人来做。
另外,Agent的对话记录要保存,至少保存半年。这不仅是审计要求,也是改进Agent的依据。我每周会抽看一些对话记录,看看Agent哪些问题答得好,哪些答得不好,然后针对性地优化提示词和工具。
4.4 成本控制的实操经验
大模型调用是有成本的,尤其是用商用API的时候。我算过一笔账:一个中等规模的集群,每天大概有200次Agent调用,每次调用平均消耗3000个token(包括系统提示词、工具调用、工具返回、最终回答),一天就是60万token。如果用商用API,一天的成本大概在几十到几百元不等。
控制成本有几个办法:
第一,缓存常用查询。有些查询是重复的,比如“支付服务的QPS是多少”,可能一天被问十几次。我加了一层缓存,同样的查询5分钟内直接返回缓存结果,不调模型。
第二,精简系统提示词。系统提示词每次调用都要传,如果写得太长,成本会很高。我一般控制在500字以内,只保留最关键的约束。
第三,工具返回精简。前面说过,工具返回的数据要精简,这不仅是为了Agent的准确率,也是为了省token。返回一堆原始数据,token消耗会翻好几倍。
第四,用本地模型做初筛。简单的查询(比如“查一下CPU使用率”)用本地的小模型处理,复杂的分析才用大模型。这样能省不少钱。
第五,设置每日限额。给每个系统设一个每日token限额,超了就停止服务,第二天恢复。这能防止异常调用把预算烧光。
我实测下来,用本地部署的14B模型,一台24G显存的机器,每天处理500次调用没问题,成本就是电费。如果预算有限,建议优先考虑本地部署。
4.5 常见问题速查表
最后整理一份速查表,都是我实际遇到过的问题:
| 问题 | 排查步骤 | 解决方案 |
|---|---|---|
| Agent不调用工具,直接回答 | 检查工具是否注册成功 | 确认tools列表非空,检查工具描述 |
| Agent调用工具报错 | 看verbose日志里的错误信息 | 检查工具函数的参数类型和返回值 |
| Agent回答超时 | 看max_iterations和工具耗时 | 减少max_iterations,优化工具查询性能 |
| 工作空间查不到数据 | 检查数据源和采集链路 | 确认数据已写入,检查查询语句 |
| Agent回答不准确 | 检查工作空间数据完整性 | 补全五件套,完善系统提示词 |
| 模型响应慢 | 检查模型部署的硬件资源 | 升级GPU,或换用更小的量化模型 |
| 多个系统问题混淆 | 检查路由层匹配逻辑 | 改用模型做意图分类,加系统隔离 |
这份表我贴在工位上,遇到问题先查表,能解决80%的常见问题。剩下的20%需要具体分析,但有了这份表,至少不会像无头苍蝇一样乱撞。
5. 工作空间的扩展方向与长期演进
5.1 从单系统到多系统协作
单个系统的工作空间跑通之后,下一步自然是多系统协作。比如用户问“支付服务变慢是不是因为订单服务的问题”,这就需要两个系统的Agent协作。
我的做法是引入一个“协调Agent”,它不直接查数据,而是负责调度。协调Agent收到问题后,先拆解成子问题,分发给对应的系统Agent,收集结果后再综合。
协调Agent的实现比系统Agent简单,它不需要工具集,只需要一个“分发”工具和一个“汇总”工具。但难点在于子问题的拆解和结果的融合,这需要比较强的推理能力,建议用大一点的模型。
多系统协作的典型场景包括:跨系统的故障排查、容量规划、变更影响分析。这些场景单系统Agent搞不定,必须多Agent协作。
5.2 从被动问答到主动巡检
现在的工作空间是“被动”的,用户问什么它答什么。下一步是让它“主动”起来,定期巡检,发现问题主动告警。
主动巡检的实现方式是:给每个系统的工作空间配一个定时任务,每隔一段时间(比如5分钟)自动跑一遍检查项,包括核心指标是否异常、是否有新的错误日志、是否有未预期的变更。发现异常就推送给负责人。
主动巡检的关键是“降噪”。如果巡检太频繁,告警太多,大家就会麻木。我的做法是:只对“确认异常”的情况告警,疑似异常先记录不告警。确认异常的判断可以用规则+模型结合的方式,规则做初筛,模型做确认。
5.3 从运维场景到研发场景的延伸
工作空间的思路不仅适用于运维,也适用于研发。比如给每个代码仓库建一个工作空间,把代码、CI/CD流水线、测试报告、代码评审记录都放进去,配一个Agent帮开发者查问题。
我试过在代码评审场景用这个思路:Agent自动检查代码变更是否影响了依赖的系统,是否有对应的测试覆盖,是否有性能风险。效果不错,能帮评审人省不少时间。
研发场景的工作空间和运维场景的工作空间,底层架构是一样的,只是数据源和工具集不同。所以前期投入建工作空间的成本,可以在多个场景复用,这是很划算的。
5.4 我个人的一些体会
做AI原生运维这一年多,我最大的体会是:技术不是瓶颈,数据才是。大模型的能力已经足够强了,Agent框架也很成熟,真正难的是把数据整理好、把工作空间建好。我见过太多团队,模型选型纠结了两个月,工作空间的数据却乱七八糟,最后做出来的东西没法用。
另一个体会是:不要追求全自动。AI运维的目标不是取代人,而是帮人省时间。Agent能帮你把排查时间从20分钟缩短到2分钟,这就很好了。剩下的2分钟,让人来做决策,这样既高效又安全。
最后一个体会是:从小处着手。不要一上来就搞大平台,先选一个系统,建一个工作空间,配一个Agent,跑通一个场景。跑通之后再复制到其他系统。我见过太多“大平台”项目,做了一年还在开发,而小步快跑的项目已经上线半年了。
这个方向后续还可以扩展很多,比如把工作空间和混沌工程结合,让Agent在故障演练中学习;比如把工作空间和容量管理结合,让Agent做资源预测。但这些都是后话,先把基础的工作空间建好,把五件套填满,把Agent调准,比什么都重要。