尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
基于Electron与Vue 3的AI运维工作台:整合SSH、知识库与AI助手
1. 运维日常的割裂感为什么我决定自己造一个工作台干运维这行的朋友应该都有同感一天下来屏幕上最少开着三个窗口。左边一个终端连着服务器中间一个记事本记着各种命令和配置片段右边还挂着一个聊天窗口要么是跟同事确认变更窗口要么是在群里同步故障进展。三个窗口来回切切到最后自己都忘了刚才那条命令是从哪个机器上抄下来的。这个项目标题里的“三开”两个字精准地戳中了我的痛点。所谓三开就是SSH 客户端、记事本、聊天工具同时运行。SSH 客户端负责连服务器执行命令记事本负责存命令模板、IP 清单、变更记录聊天工具负责沟通协调。这三者之间没有任何数据流通全靠人脑和剪贴板做“中间件”。一次简单的重启服务操作可能要经历“聊天框确认→记事本找命令→SSH 粘贴执行→回聊天框汇报”四个步骤中间任何一个环节出错轻则重来重则引发生产事故。我做的这款Mini Assistant定位就是一个AI 运维工作台。它不是要替代专业的 SSH 客户端也不是要做一个全能聊天软件而是把“连服务器、查资料、记东西、问 AI、同步信息”这几件事收拢到一个界面里。目标用户很明确每天需要登录多台服务器做重复性操作、又不想在多个工具之间反复横跳的中小团队运维人员。哪怕你刚入行不久只要管着三五台机器这个思路都能直接拿去用。下面我会从整体设计思路、核心功能拆解、实操落地过程、踩坑排查四个维度把这个工作台从想法到跑通的完整过程讲清楚。代码和配置都会给到可直接参考的版本你照着改改就能跑起来。2. 整体设计思路不做大而全只做“刚好够用”2.1 为什么是“工作台”而不是“客户端”一开始我也想过是不是直接给现有 SSH 客户端写个插件就行了。调研了一圈发现主流 SSH 客户端的插件体系要么太重要么扩展能力有限想在里面塞一个 AI 对话面板和命令知识库改造成本比从头写一个还高。而且插件形态受宿主限制哪天宿主升级了接口变了维护成本全压在自己身上。所以最终选定的路线是做一个独立的桌面工作台把 SSH 连接能力作为其中一个模块而不是把工作台塞进 SSH 客户端里。这个决策背后的逻辑是运维的核心诉求不是“连上服务器”这个动作本身而是“完成一次变更并留下记录”这个完整闭环。SSH 只是闭环里的一环记事本和沟通也是。工作台形态可以自由编排这三者的关系插件形态则处处受制。技术选型上桌面端用Electron做壳前端用Vue 3 TypeScriptSSH 连接层用Node.js 的 ssh2 库AI 对话走通用的大模型 API本地数据存储用SQLite。这套组合的好处是前端生态成熟写界面快ssh2 库稳定支持交互式 shell 和 SFTPSQLite 单文件存储备份迁移都方便不需要额外部署数据库服务。2.2 三个核心模块的职责划分工作台内部拆成三个核心模块每个模块职责单一通过一个统一的事件总线通信。连接管理模块负责维护 SSH 会话池。每台服务器对应一个会话对象包含连接状态、当前工作目录、最近执行的命令历史。会话池的好处是切换服务器时不需要重新输入密码或密钥直接复用已有连接。这里有个细节会话空闲超过一定时间我设的是 15 分钟自动断开避免占用服务器连接数但连接配置和命令历史保留在本地。知识库模块负责管理命令模板、服务器清单、变更记录。命令模板支持变量占位符比如systemctl restart {{service_name}}执行时弹出输入框让你填具体服务名。服务器清单除了 IP、端口、用户名还可以打标签比如“生产”“测试”“数据库”方便按标签批量操作。变更记录是自动生成的每次执行命令后把命令内容、目标服务器、执行时间、返回结果摘要写进 SQLite后续排查问题时可以直接搜。AI 助手模块负责两件事一是把自然语言转成可执行的命令或操作步骤二是对命令执行结果做解读。比如你输入“看看磁盘还剩多少空间”它会生成df -h并提示你选择目标服务器执行完返回结果后它会把关键信息提取出来告诉你哪个分区快满了。这个模块不直接执行命令所有 AI 生成的命令都需要人工确认后才下发这是安全底线。2.3 数据流转与安全边界三个模块之间的数据流转遵循一个原则AI 可以读上下文但不能直接写执行指令。具体来说AI 助手能读取当前选中的服务器信息、最近的命令历史、知识库里的模板但生成的命令必须经过一个“确认层”才能进入连接管理模块执行。确认层会做几件事检查命令是否在危险命令黑名单里比如rm -rf /、mkfs、dd写盘操作检查目标服务器是否匹配命令的适用范围标签记录操作人和时间戳。这个设计参考了运维领域“四眼原则”的思路虽然做不到双人复核但至少保证 AI 不会在你不知情的情况下把危险命令发出去。实测下来这个确认层拦截过好几次我手滑打错的命令比如本来想重启 nginx 结果打成了重启整个网络服务。3. 核心细节解析从连接池到 AI 提示词3.1 SSH 连接池的实现要点连接池的核心是一个 Map 结构key 是userhost:portvalue 是 ssh2 的 Client 实例和对应的 shell 流。建立连接时优先尝试密钥认证密钥文件路径从本地配置读取密钥认证失败再走密码认证密码用系统密钥链加密存储不落明文。这里有个容易踩的坑ssh2 库的 shell 流是单工的同一时间只能有一个命令在执行。如果你在命令还没返回结果时又发了一条两条命令的输出会混在一起根本分不清哪条是哪条。我的处理方式是给每个会话加一个执行队列新命令进来先排队等上一条命令的exit事件触发后再执行下一条。队列长度设了上限20 条超过就提示用户清理。另一个细节是命令超时处理。有些命令会卡住不返回比如tail -f或者等待输入的交互式命令。我给每条命令设了默认 30 秒超时超时后发送CtrlC中断并把已捕获的输出返回给用户标记为“超时中断”。这个超时时间可以在设置里按服务器调整比如数据库服务器可以设长一点。3.2 命令模板的变量系统设计命令模板用双花括号做变量占位符支持三种变量类型文本变量、枚举变量、服务器标签变量。文本变量就是执行时弹框让你输入比如{{service_name}}枚举变量预先定义可选值比如{{env}}可选“生产/测试/开发”服务器标签变量会自动替换成匹配标签的服务器列表用于批量执行。变量解析用了一个简单的正则替换引擎按顺序处理先替换服务器标签变量因为可能影响目标服务器选择再替换枚举变量下拉选择最后替换文本变量输入框。替换完成后命令进入确认层确认层会高亮显示所有被替换的部分让你一眼看出哪些地方是动态填充的。注意变量值里如果包含 shell 特殊字符比如$、、;需要做转义处理否则可能被 shell 解释成其他含义。我的做法是对变量值做单引号包裹同时把值里的单引号替换成\这是 shell 里处理单引号的标准做法。3.3 AI 提示词工程让模型输出可执行的命令AI 助手的效果好坏八成取决于提示词。我试过很多版本最终稳定下来的提示词结构是这样的你是一个运维命令生成助手。根据用户的自然语言描述生成一条可以在 Linux 服务器上执行的 shell 命令。 约束条件 1. 只输出命令本身不要输出解释、不要用 markdown 代码块包裹。 2. 如果用户描述模糊选择最保守、影响最小的命令。 3. 禁止生成任何删除文件、格式化磁盘、修改系统关键配置的命令。 4. 如果无法确定用户意图输出 UNCERTAIN 并附上你需要澄清的问题。 当前服务器信息 - 主机名{{hostname}} - 操作系统{{os_info}} - 最近执行的命令{{recent_commands}} 用户描述{{user_input}}这个提示词的关键在于约束条件第 3 条和第 4 条。第 3 条是硬性安全限制第 4 条是让模型在不确定时主动停下来问而不是瞎猜。实测下来加了第 4 条之后模型生成危险命令的概率明显下降因为它有了“说不确定”这个出口不用硬着头皮编一个命令出来。3.4 本地存储的表结构设计SQLite 里建了四张表servers服务器清单、templates命令模板、execution_log执行记录、ai_conversationsAI 对话历史。其中execution_log是核心表字段包括id、server_id、command、exit_code、output_summary、executed_at、operator。output_summary只存前 500 个字符完整输出如果需要保留单独存到文件里数据库里只存文件路径。这样设计的原因是SQLite 单表数据量超过十万行之后查询性能会明显下降。执行记录是增长最快的表每天几百条很正常所以做了冷热分离最近 30 天的记录留在数据库里更早的归档到文件需要时再导入查询。4. 实操过程从零把工作台跑起来4.1 环境准备与项目初始化先确保本地有 Node.js 18 以上版本然后初始化项目mkdir mini-assistant cd mini-assistant npm init -y npm install electron vue3 typescript ssh2 better-sqlite3 axios npm install -D electron-builder vite vitejs/plugin-vue目录结构按功能划分mini-assistant/ ├── main/ # Electron 主进程 │ ├── index.ts # 入口 │ ├── ssh-pool.ts # SSH 连接池 │ └── storage.ts # SQLite 操作 ├── renderer/ # 前端界面 │ ├── App.vue │ ├── components/ │ │ ├── ServerList.vue │ │ ├── Terminal.vue │ │ ├── TemplatePanel.vue │ │ └── AiChat.vue │ └── main.ts ├── shared/ # 共享类型定义 │ └── types.ts └── package.json主进程和渲染进程通过ipcMain/ipcRenderer通信。所有 SSH 操作和数据库操作都在主进程做渲染进程只负责界面展示和用户输入。这样做的原因是ssh2 和 better-sqlite3 都是原生模块在渲染进程里用会有兼容性问题放主进程最稳妥。4.2 SSH 连接池的核心代码连接池的实现大概 200 行核心逻辑如下import { Client } from ssh2; interface Session { client: Client; stream: any; queue: string[]; busy: boolean; lastActive: number; } class SSHPool { private sessions new Mapstring, Session(); async getSession(config: ServerConfig): PromiseSession { const key ${config.user}${config.host}:${config.port}; const existing this.sessions.get(key); if (existing existing.client) { existing.lastActive Date.now(); return existing; } const client new Client(); await new Promisevoid((resolve, reject) { client.on(ready, resolve).on(error, reject).connect({ host: config.host, port: config.port, username: config.user, privateKey: config.privateKeyPath ? fs.readFileSync(config.privateKeyPath) : undefined, password: config.password, readyTimeout: 10000, }); }); const stream await new Promiseany((resolve) { client.shell({ term: xterm-256color }, (err, s) resolve(s)); }); const session: Session { client, stream, queue: [], busy: false, lastActive: Date.now() }; this.sessions.set(key, session); return session; } async exec(session: Session, command: string, timeout 30000): Promisestring { if (session.busy) { session.queue.push(command); return ; } session.busy true; return new Promise((resolve) { let output ; const timer setTimeout(() { session.stream.write(\x03); resolve(output \n[超时中断]); }, timeout); const onData (data: Buffer) { output data.toString(); }; session.stream.on(data, onData); session.stream.write(command \n); const checkExit setInterval(() { if (output.includes(__CMD_DONE__)) { clearInterval(checkExit); clearTimeout(timer); session.stream.removeListener(data, onData); session.busy false; resolve(output.replace(__CMD_DONE__, )); if (session.queue.length 0) { const next session.queue.shift()!; this.exec(session, next); } } }, 200); }); } }这里用了一个小技巧在命令末尾追加; echo __CMD_DONE__通过检测这个标记来判断命令是否执行完毕。比单纯等exit事件更可靠因为有些命令不会触发exit。4.3 命令模板与变量替换的实现模板存储格式是 JSON存在 SQLite 的templates表里{ name: 重启服务, command: systemctl restart {{service_name}} systemctl status {{service_name}}, variables: [ { key: service_name, type: text, label: 服务名称, default: nginx } ], tags: [生产, 测试] }变量替换函数function renderTemplate(template: string, values: Recordstring, string): string { return template.replace(/\{\{(\w)\}\}/g, (_, key) { const val values[key] ?? ; return ${val.replace(//g, \\)}; }); }注意这里对变量值做了单引号包裹和转义防止注入。虽然是自己用的工具但安全习惯要养好万一哪天分享给同事用不至于出问题。4.4 AI 对话模块的接入AI 模块通过 HTTP 请求调用大模型 API请求体里带上系统提示词和用户输入。为了控制成本我做了两层缓存相同问题的回答缓存 24 小时相同命令的解读结果缓存 7 天。缓存存在 SQLite 里key 是输入内容的哈希值。对话界面用了一个简单的消息列表用户消息和 AI 回复交替显示。AI 回复如果是命令会渲染成一个带“执行”按钮的卡片点击后把命令填入命令输入框并自动选中当前服务器。这个交互设计比让 AI 直接执行要安全得多也符合运维人员“先看再执行”的习惯。4.5 打包与分发开发完成后用 electron-builder 打包npx electron-builder --config electron-builder.yml配置文件里指定目标平台为当前系统输出格式选dir方便调试正式发布再改成nsisWindows或dmgmacOS。打包时注意把better-sqlite3和ssh2标记为external这两个原生模块需要单独处理不能直接打进 asar 包。5. 常见问题与排查技巧实录5.1 连接相关的问题问题一密钥认证失败但命令行 ssh 能连上。这种情况多半是密钥格式问题。ssh2 库对密钥格式有要求OpenSSH 新格式的密钥以-----BEGIN OPENSSH PRIVATE KEY-----开头在旧版本 ssh2 里不支持。解决办法是升级 ssh2 到最新版或者用ssh-keygen -p -m PEM -f keyfile把密钥转成 PEM 格式。问题二连接成功但执行命令没输出。检查 shell 流是否正常建立。有些服务器默认 shell 是/sbin/nologin或者受限 shell这种情况下client.shell()会失败。可以改用client.exec()执行单条命令虽然不支持交互但至少能拿到输出。问题三中文乱码。服务器 locale 设置问题。在建立连接后先执行export LANGen_US.UTF-8或者export LANGzh_CN.UTF-8根据服务器实际支持的 locale 来设。如果服务器没装中文 locale那就只能显示英文这个没办法。5.2 命令执行相关的问题问题四命令执行到一半卡住。大概率是命令在等待输入。比如apt install会问 yes/nopasswd会等密码输入。解决办法是在命令前加DEBIAN_FRONTENDnoninteractive或者用yes |管道。更通用的做法是在命令末尾加 /dev/null把标准输入重定向到空设备。问题五输出内容太多界面卡死。终端组件渲染大量文本时性能会急剧下降。我的处理方式是输出超过 1000 行时只渲染最后 500 行前面的折叠起来提供一个“查看完整输出”的按钮点击后把完整输出写到临时文件用系统默认编辑器打开。问题六批量执行时部分服务器失败。批量执行需要做错误隔离一台失败不能影响其他台。我的做法是每台服务器独立执行结果分别记录最后汇总成一个报告标出成功和失败的服务器。失败的原因也记录下来方便排查。5.3 常见问题速查表问题现象可能原因排查方法解决方案连接超时网络不通或防火墙拦截telnet host port测试端口检查网络和防火墙规则认证失败密钥格式不对或密码错误用命令行 ssh 验证转换密钥格式或重置密码命令无输出shell 流未建立检查 shell 类型改用 exec 模式中文乱码locale 设置问题locale命令查看设置 LANG 环境变量执行卡住命令等待输入查看命令是否需要交互重定向标准输入输出过多卡顿终端渲染性能瓶颈观察输出行数限制渲染行数批量执行部分失败单台服务器异常查看失败服务器日志错误隔离单独重试5.4 几个踩过的坑坑一SQLite 并发写入报错。better-sqlite3 是同步 API多个地方同时写会报SQLITE_BUSY。解决办法是开 WAL 模式并且把所有写操作串行化用一个队列管理。坑二Electron 打包后原生模块找不到。需要把better-sqlite3和ssh2的.node文件手动复制到打包目录并在主进程里用process.resourcesPath拼接路径加载。坑三AI 生成的命令包含 markdown 代码块标记。模型有时候不听话还是会输出bash这样的标记。解决办法是在解析前先做一次清洗把代码块标记去掉。坑四命令历史记录泄露敏感信息。有些命令包含密码比如mysql -u root -ppassword。我的处理是在记录前做一次脱敏把-p后面的内容替换成***。这个规则可以配置默认开启。6. 一些个人体会和后续想法这个工作台我从有这个想法到跑通第一个版本大概花了三个周末。中间推翻重来过一次最初想把所有功能都塞进一个界面结果界面乱得没法用。后来改成左侧服务器列表、中间终端、右侧 AI 对话和模板面板的三栏布局才顺手起来。实际用下来最大的收益不是 AI 帮我生成了多少命令而是所有操作都有了记录。以前在聊天框里说“我重启一下 nginx”说完就完了过两天想查是什么时候重启的、重启前后有什么变化根本找不到。现在每次执行命令都自动记录搜索一下就能看到完整的时间线。这个价值比 AI 本身还大。后续想加的功能有两个一是操作回放把一次变更涉及的所有命令按时间顺序串起来生成一个可回放的操作序列方便复盘和交接二是多机协同把多台服务器的执行结果做对比比如批量检查磁盘空间自动标出异常的那台。这两个功能都不难核心数据模型已经支持了只是界面还需要打磨。如果你也想自己搭一个我的建议是先从连接池和命令记录做起这两个是基础做好了就能明显感觉到效率提升。AI 模块可以后面再加它是个锦上添花的东西不是必需品。另外安全确认层一定要有哪怕只是简单的危险命令黑名单也能帮你避免很多手滑事故。
RELATED

相关推荐

AI运维工作台Mini Assistant:整合SSH终端、智能笔记与AI查询

AI运维工作台Mini Assistant:整合SSH终端、智能笔记与AI查询

1. 运维人的日常困局:为什么我们总在三个窗口之间反复横跳干运维这行的朋友应该都有体会,一天下来真正花在“解决问题”上的时间,可能还不到三分之一。剩下的时间去哪了?全耗在窗口切换上了。左边一个终端连着生产环境&#xff0c…

📅 2026/10/22 5:52:08
GitHub 趋势周报:AI 应用与本地优先工具成为新主流

GitHub 趋势周报:AI 应用与本地优先工具成为新主流

GitHub 趋势周报我每周都刷,基本当早报看。2026年第40周这份榜单,整体感觉跟前几个季度很不一样:上榜项目不再一窝蜂地做“大而全”的平台型项目,而是回到小而美的效率工具;AI 相关项目依旧过半,但主角已经…

📅 2026/10/22 5:52:08
数据库迁移成本怎么算?三类场景成本结构与隐性成本全拆解

数据库迁移成本怎么算?三类场景成本结构与隐性成本全拆解

1. 先说结论:迁移成本不是一个数,而是一条会变化的曲线做数据库替换这件事,最怕的是把成本当成一个静态数字来对比。很多人给我的第一版估算表里只有软件授权费、迁移工具费、人力成本三行,算完觉得“好像也不贵嘛”,等…

📅 2026/10/22 5:52:08
MORE NEWS

更多资讯

📰

零碳校园能耗管理平台建设:从电表到碳报告的全链路实践

简介:这是一份面向智慧校园建设者与碳中和规划人员的零碳绿色校园能耗管理平台建设方案PPT。内容基于当前智慧校园基础层建设背景,从两部委绿色学校创建政策与3060双碳目标切入,梳理零碳校园“三步走”建设路径,并围绕碳资产及能效…

📰

XSS深度审计实战:从上下文分析到CSP绕过策略

很多做安全的朋友习惯在漏洞点放一个<script>alert(1)</script>&#xff0c;弹窗成功就“收获”&#xff0c;没弹窗就觉得这里没有 XSS。这个习惯做功能验证还行&#xff0c;做深度审计容易漏掉真正的风险。Alert(1)只是探测器&#xff0c;不是武器库——真正要回答…

📰

创新创业大赛路演PPT改造指南:叙事框架、内容替换与答辩避坑

简介&#xff1a;这份创新创业大赛创意PPT以“企业效率管理平台”为核心&#xff0c;适合创业团队、中小企业管理者及高校教学参考&#xff0c;清晰阐述了如何借助一体化平台提升内部管理与外部销售效率。压缩包内仅有1个PPT格式文件&#xff0c;体积约438KB&#xff0c;短小精…

📰

零碳校园能耗管理平台建设:从五层链路到碳排放核算落地

简介&#xff1a;面向智慧校园规划、能源管理和低碳改造相关人员的“零碳绿色校园碳中和能耗管理平台建设解决方案”PPT&#xff0c;旨在解决校园碳资产管理、能耗监管与碳中和路径规划等需求&#xff0c;系统梳理了从政策背景、建设目标到落地路径的完整思路。方案以当前校园能…

📰

从视觉小模型到AI自主修复:今日AI技术落地的关键观察

1. 今日AI圈最值得关注的三件事先聊点实在的。今天这个AI日报&#xff0c;我挑了几条真正有讨论价值的内容展开&#xff0c;不是那种“某模型又刷分了”“某公司又融资了”的宏观新闻流&#xff0c;而是从开发者、产品经理和普通用户的视角&#xff0c;看哪些变化今天真的会影响…

📰

Java SpringBoot学生作业管理系统毕业设计实战方案

每年毕业设计节点&#xff0c;作业管理系统相关题目在Java方向的热度一直很高。这个题目乍一看很常规&#xff0c;但真正动手做起来会发现&#xff0c;它几乎涵盖了Web开发的核心知识面&#xff1a;角色权限、文件上传、任务状态流转、数据统计&#xff0c;每一个模块单独拎出来…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬