← 博客
· OLAV Team

SSH MCP 给 AI 的是一把万能钥匙 —— OLAV 给 AI 的是受约束的能力

为什么给 AI Agent 裸 SSH 权限会触发幻觉死亡螺旋,以及结构化工具加确定性验证如何改变游戏规则

安全 AI agent 网络自动化 SSH MCP

SSH MCP vs OLAV 对比

给 AI Agent 一个 SSH MCP 工具,三分钟就能让它操作你的核心交换机。问题从来不是”能不能”——是”你不知道它敲了什么”。

这段时间社区里 SSH MCP 的讨论持续升温。工程师们兴奋地把 SSH 挂到 Claude Code 上,然后犹豫要不要给 enable 密码。这不是安全审计。这是在赌博。

本文不讨论”要不要用 AI 操作网络”。讨论的是:当你决定让 AI 接触生产环境时,工具接口的形状决定了你的底线在哪里。


幻觉死亡螺旋

SSH MCP 的核心操作极其简单:给 LLM 一个 ssh_exec(command) 函数。

然后会发生什么:

  1. Agent 调用 ssh_exec("show running-config")
  2. 设备返回 8000 行原始 Cisco IOS 全量配置
  3. 小模型的 8K 上下文瞬间炸满。System prompt 里的安全规则被截断
  4. Agent 基于不完整的上下文做决策——它不知道自己已经丢失了关键信息
  5. 到第五步时,Agent 在操作一个它已经完全不理解的网络

我们用实验验证过这一点。gemma4 31B 拿到 raw CLI 输出后,写操作任务 100% 失败。不是偶尔。是每一次。

OLAV 的解法不是写更好的 prompt。是改变工具输出的粒度

# SSH MCP 返回给 LLM 的:
NYC-core-1#show running-config
Building configuration...
Current configuration : 45821 bytes
! ... (8000 行 raw 配置) ...
end

# OLAV 返回给 LLM 的:
{
  "NYC-core-1": {
    "vendor": "cisco_ios",
    "version": "17.3.5",
    "interfaces": 48,
    "bgp_peers": 4,
    "ospf_areas": 3
  }
}

50 token vs 8000 token。OLAV 在 Python 侧处理原始输出,LLM 只拿到决策所需的结构化摘要。需要细节时,Agent 调用 query_evidencedescribe_table 按需拉取——永远不一次性塞满上下文。


安全不在 prompt 里

大多数 SSH MCP 方案的安全模型长这样:

system prompt:
"你是一个网络工程师。不要在交换机上执行危险命令。
禁止 write memory、reload、erase。"

把安全放在 prompt 里,就是把安全放在小模型最不擅长执行的地方。五次重复实验一致表明:当 8K 上下文被 raw CLI 输出填满后,安全规则会随被截断的 token 一起消失。

OLAV 的 7 层写保护不需要 LLM 配合:

机制执行者
1默认只读Python 侧硬锁
2--enable-api-write 全局开关启动参数
3按服务粒度的写权限配置文件
4强制 dry-run 前置Python 侧门控
5配置 diff 变更验证DuckDB diff 引擎
6CLAB 仿真验证容器级数据平面
7人工审批外部确认

LLM 在任意一层都无法绕过。它不需要”记住”不能 write memory——系统根本不给它写权限。

写保护与审计链


不要脑补网络行为——用数学证明

SSH MCP 架构下最大的隐性成本不是安全。是把 LLM 当作唯一推理引擎——强迫它对无法建模的网络行为进行脑补。

当 Agent 通过 SSH MCP 看到路由表,问”改这条 route-map 会不会影响 OSPF 邻居?“——LLM 说”应该不会”。这是一个语言模型在猜测一个它不可能建模的数学问题。

OLAV 不做这个猜测。它调 batfish_q——Batfish 用控制平面数学模型计算你的 OSPF 邻居到底会不会断开。不是置信度。是证明。

同样的逻辑延伸到整个验证链路:

LLM 生成变更计划
  → Batfish 差分:哪些 BGP 路由会变化?
  → NetworkX blast radius:影响多少台上游设备?
  → CLAB 仿真:在真实容器化网络操作系统里跑一遍
  → diff_snapshots 时间线:变更前的最后状态
  → dry-run 输出 → 审批 → 执行

每一步都是确定性计算,不是 LLM 的”我认为”。两者之间隔着 Batfish 的控制平面数学、NetworkX 的图论算法、CLAB 的真实数据平面行为。


排障是因果链不是猜谜

SSH MCP 的排障流程是 LLM 生成 grep 命令 → 翻几行日志 → 猜根因。没有审计链。没有可复现的推理路径。

OLAV 的排障是因果链:

1. query_evidence("BGP neighbor down", sources=["syslog", "command_output"])
   → 定位时间点 T:BGP 会话在 14:32:15 断开

2. diff_snapshots(device="core-1", before=T-1h, after=T)
   → BGP peer-group 的 remote-as 在 14:01:48 被修改

3. batfish_q("bgpSessionCheck", nodes=["core-1"])
   → 数学验证:修改后确实导致 BGP 会话无法建立

4. NetworkX 拓扑回溯
   → 影响范围:下游 3 台 leaf 交换机失去默认路由

每一步都有可查询、可回放的中间产物。不是”Agent 的推理”——是事实的链路diff_snapshots 精确到秒级配置变更,query_evidence 跨 syslog 和命令输出做统一全文索引。排障从”Agent 告诉我它觉得是什么”变成”我给你看是什么”。


工具设计就是安全设计

同一个模型在两种架构下产生天壤之别的结果。差异不在于模型——在于安全是放在 prompt 里还是放在工具代码里:

能力SSH MCPOLAV
默认权限完整 shell 权限只读,Python 硬锁
命令执行LLM 直接敲结构化工具包装
上下文消耗8000 token/次(raw CLI)50 token/次(结构化摘要)
变更验证LLM 猜测Batfish 数学证明
拓扑分析LLM 看图猜NetworkX 图计算
仿真LLM 脑补CLAB 容器级真实行为
历史对比diff_snapshots 秒级时间线
审计不知道敲了什么DuckDB 每步 tool call 可查询
记忆每次从零开始AutoRecall + L1/L2 经验蒸馏

核心问题从来不是”AI 能操作网络吗”。是:安全放在 prompt 里,还是放在工具里?

Prompt 会被截断、被遗忘、被优先级排序挤出窗口。工具不会。


OLAV 是一个开源的 AI 原生基础设施运维平台。默认只读,写完需审批,每一步都可审计。 github.com/james-olavai/olav