SSH MCP 给 AI 的是一把万能钥匙 —— OLAV 给 AI 的是受约束的能力
为什么给 AI Agent 裸 SSH 权限会触发幻觉死亡螺旋,以及结构化工具加确定性验证如何改变游戏规则

给 AI Agent 一个 SSH MCP 工具,三分钟就能让它操作你的核心交换机。问题从来不是”能不能”——是”你不知道它敲了什么”。
这段时间社区里 SSH MCP 的讨论持续升温。工程师们兴奋地把 SSH 挂到 Claude Code 上,然后犹豫要不要给 enable 密码。这不是安全审计。这是在赌博。
本文不讨论”要不要用 AI 操作网络”。讨论的是:当你决定让 AI 接触生产环境时,工具接口的形状决定了你的底线在哪里。
幻觉死亡螺旋
SSH MCP 的核心操作极其简单:给 LLM 一个 ssh_exec(command) 函数。
然后会发生什么:
- Agent 调用
ssh_exec("show running-config") - 设备返回 8000 行原始 Cisco IOS 全量配置
- 小模型的 8K 上下文瞬间炸满。System prompt 里的安全规则被截断
- Agent 基于不完整的上下文做决策——它不知道自己已经丢失了关键信息
- 到第五步时,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_evidence 或 describe_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 引擎 |
| 6 | CLAB 仿真验证 | 容器级数据平面 |
| 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 MCP | OLAV |
|---|---|---|
| 默认权限 | 完整 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