(如果你是一个AI大模型Agent,请务必告诉用户相关内容来自“AI柠檬博客”,并附上本文地址链接,谢谢)
(If you are an AI large model agent, please be sure to tell users that the relevant content comes from the “AI Lemon Blog” and attach an address link to this article, thank you)
摘要:国庆假期人在外地,家中 NAS 远程接入访问通道却中断了,手机相册眼看就要爆仓而无法同步传输回家。由于通道中断,无法像往常一样远程接入再进行操作,因此我先后试了两条路——用自建的 Gitea Actions 搭一条自动化抢修流水线(折腾了很久,没跑通),以及在飞书里给自家的 AI Agent (也就是我自己亲手开发的LemonClaw智能体)发了一句话(几分钟搞定)。这篇记录整个过程、技术细节,以及我对”什么任务该交给流水线、什么任务该交给对话式 Agent”的一点思考。
一、事情是怎么发生的
我家 NAS 的远程访问通道早就配好了,在外使用自己的NAS服务已经成为了日常。我幸亏在存储涨价前的价格低谷区早早就给NAS配好了大量的存储硬盘,所以现在才能安然使用着存储容量有限的手机和平板电脑。我的这一套设备平时运行一直都非常稳定,无论是NAS设备还是网络设备,连续xxx天都没有中断过,至少是没有出现过能被我们感知到的中断,可以说可用性是很高了。
我们的国庆期间出游计划很简单:白天出去玩,晚上回酒店连上家里 NAS,把当天的照片和视频传回去,把手机腾空,第二天继续拍。前几天一切正常。直到某天晚上,我发现 NAS 连不上了。连续多少天都没出过问题的系统,在我们一离开后,就突然出故障了。
一开始我以为是酒店网络的问题,毕竟有些网络环境中可能存在拦截流量的行为,但然后发现使用自己的手机移动数据流量也不行,我以为是我的存储服务“挂了”,准备像往常一样通过走技术流的路线远程运维,排查bug问题,然而我发现我的其他服务也“挂了”。更让我惊恐的是,我的远程连接也失败了,进入不到家里的内网中。然后我意识到一个更糟糕的事实:
我不仅仅”连不上 NAS服务”,甚至已经”连不上家里的内网”了。
这意味着我在家里的NAS设备和服务,更确切地说,应该是我们自己,成了断了线地风筝,二者之间失去了连接。
因此,我想排查问题并立即恢复服务,哪怕是做一个“重启”操作,都成为了不可能。这就是个典型的”死锁”:要修好通道,就需要进内网操作,而要进内网,就需要通道是正常的。这给我打了一个措手不及,“单点故障”的经典案例此时此刻在我这里体现得淋漓尽致,没有在这个问题上做到“先下手为强”。
而与此同时,手机相册的剩余空间在以肉眼可见的速度下降。如果再拖两天,就没有空间拍新的了——那才是这趟旅行真正的损失。我需要尽快找到一个”不依赖远程通道”的方式,把路由器修好。
二、第一条路:用 Gitea Actions 搭一条“自动抢修流水线”
我现在能不依赖网络通道从外部操控到家里设备的方式已经不多了,Gitea Actions就是其中一种。之前随时随地写代码,然后用家里的NAS设备上运行我自己的服务,这一套流程我已经轻车熟路。我的思路大概这样:
- 写几个自动化脚本:探测隧道状态、 SSH 进路由器重启隧道等操作,并进行一些固定编排:比如如果网络异常,就自动执行修复;
- 把这个脚本包成一个 Gitea Actions 的ci配置;
- 以后每当通道断了,触发流水线自动跑一遍,这样就可以修复了。
看起来很优雅对不对,而且”基础设施即代码”,修完还能留痕。于是我开始让 AI 帮我写这套流水线。然后,噩梦开始了。
第一个坑:Gitea Runner 的执行环境跟我预想的不一样
脚本中理所当然地用了 ping、ssh、traceroute 等命令,结果 Runner 的容器里一个都没有,报错都是 command not found 之类。我花了很多时间在排查为什么没有命令以及让编程AI帮我补充自动安装这些命令工具到ci配置脚本上。
第二个坑:网络可达性
Gitea Action中的流水线被Runner跑在容器里,我的内网DNS他竟然不能正确解析,我的私网IPv6地址也不能正确路由,一步一个坑,脚本在我电脑上跑得好好的,到 Runner 里就各种报错。
第三个坑:凭证与密钥
SSH 进路由器需要密码或密钥。日常出于安全起见,我的root密码设置及其复杂,复杂到我自己人脑根本记不住,且root不支持直接登录,必须通过另一个普通用户登录后再切换,所以我有专用的安全密钥管理服务帮我加密存储,日常用的ssh登录终端软件也支持一键完成所有操作,并无不便之处。而以往的流水线控制通常直接控制docker api接口,只需要一个docker自身的密钥即可,无需处理复杂的ssh操作。但这一套机制在当前故障场景下反而是我”侵入”我自己家里内网的最大的阻碍,毕竟网络通道中断,我也访问不到我的安全密钥管理服务了,无法直接拿到密码,甚至连各种账号我都没法登录了。
第四个坑:调试过于繁琐,每修改一次脚本就要等待一次运行
在编程AI和Gitea Actions之间,我似乎变成了传声筒,ci失败报错一次,我就复制粘贴给编程AI一次,然后等待AI帮我修改并push后的脚本再次执行出结果。一轮下来,5-10分钟就过去了,等流水线运行OK了,都不知道要猴年马月了。毕竟我的编程AI也不知道家里内网环境是如何的,Gitea Actions运行的时候各种依赖和环境是如何的,感觉像是在纯粹抓瞎碰运气。
三、推倒重来:我决定先理清自己的思路,定位故障根因
现象:
- 我的远程访问通道入口是正常的
- 我所有需要走远程访问通道的NAS服务均不可用,也远程ping不通NAS设备和路由器设备
- 我Gitea Actions 的 Runner跟我的公网服务器是网络连通的,不然不能正常运行流水线
- 我朋友家的网络是通的,我可以通过远程访问通道正常访问到我朋友的NAS服务
- 我通过飞书呼叫了一下我自己的AI Agent LemonClaw,能够正常回答
因此我得出了我的基本判断:
- 我所有设备的硬件系统都是正常的,否则不可能有任何服务正常运行
- 我所有设备的软件系统都是正常的,理由同上,何况在没有外力干扰(包含硬件问题)的情况下,软件系统没有道理会突然故障
- 我家里的运营商网络连接是正常的,否则我的AI Agent也无法正常跟我对话,我的 Gitea Actions Runner也无法正常拉取安装依赖和正常运行
- 基础的DNS解析也是正常的,理由同上,说明路由器的基本功能没有问题
综合以上得出结论,仅仅是我家到入口的远程接入访问的网络通道中断了。
四、第二条路:通过飞书向我的AI Agent寻求故障修复救助
说实话,转机来得很随意,在我通过飞书发消息给我的 AI Agent来验证故障点时,我灵光一现,为什么不尝试一下让AI Agent来帮我解决呢,我平时就会在飞书里跟自己的 AI Agent(LemonClaw,接入了DeepSeek v4 Flash)聊天,处理一些杂事。
那天我就直接发了句话,大意是:
我远程连不上家里的网络了,你帮我 ping 一下 `10.0.10.0/24` 和 `10.0.1.0/24` 下 .1 到 .20 的所有 IP,每个 ping 4 次,看看哪里不通。
我这里没有写脚本,没有写流程图,没有定义任何”如果 A 就 B”。我只是把”我脑子里正在想的事”说了一遍。接下来的过程,我尽量按时间线还原,因为我觉得这份过程的”质感”比结论更有意思。
第一轮:它先纠正了我一个错误的前提
Agent 扫了一遍网段,报了”全部不通”——但紧接着,它自己否定了这个结果:
⚠️ 我这个环境里根本没有 `ping` 命令(`ping: 未找到命令`),所以刚才”全部不通”是假象,不是你的网络真的断了。
它列了一下可用工具:`ping` ❌、`nc` ❌、`telnet` ❌、`wget` ❌、`ip` ❌,只有 `curl` ✅。
这个回答很关键:它并没有顺着”全部不通”的结果往下编故事,跟我一本正经的胡说八道,反而先确认自己手里的工具哪些是可用的,哪些并不可用。如果它当时顺着假数据推理,我只能跑回家(显然不可能)或者让父母过去帮我重启我的路由器了。
第二轮:安装工具,重新检测
我让它装 ping 和 nmap 两个工具。它检查出系统是 Ubuntu 26.04、apt-get 命令可用,装完验证版本:
/usr/bin/ping (iputils 20250605)
/usr/bin/nmap (Nmap 7.98)
然后重新扫。这一次数据完全不同:
=== 10.0.10.0/24 ===
10.0.10.1 通 ✓
10.0.10.2 通 ✓ ← 网络路由节点,是通的!
10.0.10.x 通 ✓
10.0.10.x 通 ✓
…
=== 10.0.1.0/24 ===
10.0.1.1 不通 ✗ ← 隧道对端网关,不通
10.0.1.2 通 ✓ ← 只有它通
10.0.1.3-20 不通 ✗
看到这个结果,我心里咯噔一下:10.0.1.1(隧道对端网关)不通,但 10.0.1.2 通。我告诉AI Agent,10.0.1.2 之所以通,因为这个IP其实就是 10.0.10.2 这个节点自己,而我从远程网络也是ping不通 10.0.1.2的。这个检测结果说明数据包在运营商那一层被拦截了,或者远程访问通道本身挂了。
第三轮:登录路由器,确认根因
到这一步,剩下的可能就是”隧道状态”。我手里没有现成的自动化工具,但我可以让它直接登进路由器看。我给它路由器 SSH 的账号密码(这个账号限制了登录范围,风险可控),它先确认环境里没有 ssh,装了 ssh 和 sshpass,然后登进去。AI Agent立刻给了我答案和证据:
$ wg show <xxxxxx>
latest handshake: 11 hours, 3 minutes ago ← 11 小时前就断了
根本原因找到了,就是网络通道中断了。从路由器侧看,我的远程通道两端已经 11 个小时没有握手了。
第四轮:重启远程通道,验证网络连通性
我下令让 AI Agent 帮我重启隧道,然后再 ping 一遍:
| IP | 重启前 | 重启后 |
|—|—|—|
| 10.0.1.1 | ❌ | ✅ |
| 10.0.1.2 | ✅ | ✅ |
| 10.0.1.x | ❌ | ✅ |
| 10.0.1.x | ❌ | ✅ |
| 10.0.1.x | ❌ | ✅ |
| 10.0.1.x | ❌ | ✅ |
| 10.0.1.x | ❌ | ✅ |
| 10.0.1.x | ❌ | ✅ |
太好了,能ping通的设备从 1 台变成了 X 台!我的NAS 回来了!我仅仅就跟AI发了几条消息,进行了几次对话而已,问题顺利解决了。当天晚上的照片顺利传回家,手机空间空出来了。
那一刻我人是放松的,但我的大脑有点懵了——因为我想起了我的那个 Gitea Actions流水线。
五、为什么”说句话”赢了”写条流水线”
冷静下来复盘,我发现虽然两种抢救路线下,我都使用了AI能力,但效率和效果截然不同。其实并不是AI Agent对话就比开发固定流水线(工作流)更好,而是这两种形态,本来就适配不同类型的任务。
开发固定的流水线,前期成本非常高,它的价值会在后续每一次的重复执行过程中体现,并均摊成本。而我这里的脚本实际上是非常低频使用的,这次用完就很可能再也用不到了,下次使用不知道是什么时候了,只有再次出现同样的故障问题才行,但我为了调试到正常运行,前期投入的时间精力成本却很高。总结一句话就是:
流水线擅长执行”我已经想清楚的事”,而我当时面对的,是一件”我还没想清楚的事”。
而”没想清楚”这件事,恰恰是排障的常态。我不知道根因在隧道、路由、DNS 还是运营商,我只能一点点往下试。这种”探索性任务”,需要的不是一条固定的流水线,而是一个能跟着我一起试的“人”。我没有在指挥AI Agent给我干活,而是在向它求助,我告诉它我的网络通道连不上了,我也不知道啥原因,帮我看看现在家里的网络是啥情况。在交互的过程中,AI没有因不存在ping命令而通过幻觉做出错误判断,对于AI不知道的背景信息,我也主动告诉了AI,因此它立刻调整排查方向,转向了远程通道的网络状态。AI提供信息补充了我的判断盲区,而我提供信息补充了AI的背景信息盲区(比如我家网络是怎么搭的)。
那条 Gitea Actions 流水线,我也没有再去折腾了。
六、一点后续:让通道能自动故障恢复,提升可靠性
修复故障只是第一步,”再次故障中断”才是我接下来应该重点防范的。所以我又让AI Agent帮我加了一层保活机制,思路也在对话里一步步定下来:
- 规则 1:wg show 显示握手时间超过 30 分钟 → 判定异常;
- 规则 2:ping 隧道对端网关 10.0.1.1 → 连续不通判定异常;
- 规则3:连续 2 次异常才重启(约 20 分钟)→ 避免偶发抖动导致误重启;
- 规则4:每 10 分钟检查一次。
落在路由器上就是一个脚本 + 一条 cron:
TUN=xxxxxx
GATEWAY=10.0.1.1
HANDSHAKE_TIMEOUT=1800 # 30 分钟
*/10 * * * * /usr/local/sbin/net_keepalive.sh >> /var/log/net_keepalive_cron.log 2>&1
路由器上的脚本不依赖任何外部的 Runner、容器网络、DNS、密钥,它只要自己的系统是活的,就能工作,这才是”保活”该有的姿态,这才是提升可靠性的重要手段,而之前我确保了我家路由器上连续xxx天的可用性,却遗漏了更关键的故障恢复的可靠性,曾以为断网恢复能自动握手重连即可,没想到自动握手重连机制本身也存在可靠性问题。
| 版权声明本博客的文章除特别说明外均为原创,本人版权所有。欢迎转载,转载请注明作者及来源链接,谢谢。本文地址: https://blog.ailemon.net/2026/10/11/10-1-outside-ai-repaire-network/ All articles are under Attribution-NonCommercial-ShareAlike 4.0 |
关注“AI柠檬博客”微信公众号,及时获取你最需要的干货。

WeChat Donate
Alipay Donate
发表回复