
做了快十年运维我的终端窗口从来没有像最近这一年这么乱过。左边是常规的 SSH 会话中间开着某个 AI 编程助手的对话界面右边还挂着一个专门用来跑代码修改的命令行工具。每接一款新的 AI 编程助手就要多开一个终端、多记一套快捷键、多维护一份上下文而且这些上下文之间基本是断的。后来我干脆花了一段时间把这些工具统一收进了一个终端程序里起名 aiopsterm。这是一个完全开源的运维终端设计目标很明确让运维的人和 AI 坐在同一个终端前用同一种方式协作。项目发布之后很多朋友第一反应都问这不就是把 API 凑一块吗真做起来才会发现聚合 API 只是最表层的东西。人机共用一个会话、共享上下文、共同遵守同一套权限规则这些才是真正麻烦的地方。下面我把自己的设计思路、实现细节、踩过的坑原原本本讲一遍。1. 回到出发点被一堆 AI 终端逼出来的项目1.1 一次凌晨故障带来的教训今年春天有个凌晨线上服务告警说接口成功率掉到 30% 以下。我打开终端习惯性先查进程、日志、系统负载一眼看不出问题。于是我想让 AI 帮我分析日志打开助手 A把最近 500 行日志贴过去它给了几个方向我又打开助手 B问同一份日志能不能用脚本画个请求量分布助手 B 说可以但需要我再提供一次数据。整个过程里我反复做一件事从 A 的上下文里把结论复制到 B再把 B 的中途结果贴回终端去试。等终于定位到是一个定时任务把连接池打满已经过去一个多小时。那次之后我复盘真正花在改代码上的时间不到 10 分钟剩下 50 多分钟全耗在捣鼓上下文。说实话不是这些 AI 不强而是人和 AI、AI 和 AI 之间的上下文是断的。每个助手都像一个自成一体的收件箱但用户真正需要的是一个收件箱能装下所有 AI 的来信也能装下我自己的命令。这个感触直接催生了 aiopsterm 的第一个原型。1.2 “人和 AI 共同设计”到底是什么意思很多人以为运维终端加 AI 就是嵌一个聊天窗让 AI 回答命令怎么写。aiopsterm 不是这个定位。它从一开始就把“人”和“AI”当成两种平等的对话参与方人可以发消息、跑命令、改配置AI 也可以发消息、请求执行命令、修改工具状态两边在同一个会话里交流AI 的每一次工具调用都走同一套权限和审计规则。换句直白的话说AI 在 aiopsterm 里不是一个“咨询顾问”而是一个“能碰键盘的操作员”只不过它的每一次操作都需要经过人的批准。这种设计带来的实际价值在故障处理场景里特别明显AI 可以自己执行 ls、df、grep 这类只读命令去摸情况但遇到 rm、重启服务这类有副作用的操作就必须停下来等人确认。人不会变成纯旁观者AI 也不会变成只顾聊天的“嘴强王者”。1.3 为什么是 17 款而不是一个统一接口就完事你可能会问搞一个统一 API 网关不就好了问题是市面上的 AI 编程助手并不都存在一个标准接口后面。我试着把主流工具分了几类终端原生 AgentClaude Code、Codex CLI、Gemini CLI、OpenCode 这类它们自己有完整的对话循环和工具调用机制独立 CLI 工具Aider、Qwen Code、DeepSeek Coder 这类偏代码仓库改造以命令行参数驱动为主IDE 插件内核Cline、Continue、Copilot 这类本身运行在编辑器里但核心逻辑可以复用API 形态各种 OpenAI 兼容接口、自建模型服务、本地模型服务直接走 HTTP 协议。这四类工具的接入方式、会话格式、工具调用机制差异很大。比如终端原生 Agent 一般有交互式 TUIAider 是命令行参数驱动API 服务则是纯请求响应。aiopsterm 能做到“一个收件箱管 17 款”靠的不是让它们都改接口而是我在中间加了一层驱动适配层把各种工具的输入输出规约成同一种内部协议。新增一个驱动通常只需要加一个文件这也是 17 这个数字没有成为维护噩梦的原因。2. 整体设计思路一个适合人与 AI 共同使用的终端2.1 三层架构会话层、驱动层、执行层aiopsterm 的整体架构我分成了三层职责边界很清晰会话层管“说什么”。所有消息人的提问、AI 的回复、工具调用的请求和结果都以统一消息格式进入会话按会话维度落盘存储。目前存储用 SQLite 加 JSONL 日志双写SQLite 方便检索JSONL 方便导出复盘。驱动层管“怎么接”。每个 AI 后端实现一个 Driver 接口核心方法就几个SendMessage、ListModels、CallTool、StreamResponse。无论背后是 Claude Code、Aider 还是 OpenAI 兼容 API驱动层会把它转换成内部统一消息格式。执行层管“能不能做”。AI 请求执行命令时不直接碰系统 shell而是先经过权限引擎分 allow、ask、deny 三档再决定放行、人工确认、还是直接拒绝。所有执行记录进审计日志。这套分层最大的好处是上层业务逻辑完全不用关心背后接的是哪款 AI。加一个新驱动只需要新增一个文件实现那几个接口然后在配置文件里注册一行。17 款听起来很多实际维护复杂度并不高因为大多数逻辑都在公共层。用个生活里的类比会话层是会议室驱动层是各种语言的翻译官执行层是门口的安保三者各干各的活互不干扰。2.2 为什么选择 TUI 而不是 Web 页面第一个版本我也纠结过做 Web 界面。但反复试下来运维场景里 TUI 才是更合适的主界面运维工作本身就在终端里。服务器出问题时通常就是 SSH 进去不会先开浏览器再连个管理台资源占用低。单个二进制文件就能跑没有 Node、没有浏览器进程在资源紧张的机器上也扛得住和现有工具链契合。可以放在 tmux 或 screen 里挂后台配合 alias 随时唤起输出可以被管道、重定向人和 AI 都能继续处理交互更克制。Web 界面容易把功能堆得越来越满终端界面反而逼着你把核心动作做得足够清晰。技术实现上这个项目用 Go 编写终端 UI 基于 bubbletea 那一套组件模型逻辑层和渲染层分开。这样未来如果想加一个 Web 只读仪表盘可以在不动核心逻辑的前提下补一层 API。2.3 一套内部消息协议人和 AI 之间的公共语言要让“人和 AI 共同使用”不变成一句空话底层必须有一套双方都认识的消息协议。aiopsterm 内部的消息大概分这么几类user_text人输入的文本也可以是 Markdownai_textAI 流式输出的回复tool_callAI 请求执行某个工具或命令携带完整参数tool_result工具执行的结果可能是文本也可能是 JSONsystem_notice系统事件比如权限审批通过、会话超时、驱动重连成功。每条消息都有一个 id、rolehuman 或 ai 或 system、timestamp、session_id。这条链路之所以关键是因为不同 AI 的 API 格式千差万别但到了 aiopsterm 内部统一都是这套结构。AI 要执行命令本质是产生一个 tool_call人的确认本质是回复另一个消息。两边都通过消息完成交互这才是“共同设计”在协议层的体现。再往上所有的消息都可以导出成 JSONL方便交给工单系统、审计系统或者直接扔给另一个 AI 做事故复盘。3. 核心功能拆解从一个收件箱到一次可审批的操作3.1 收件箱式会话管理aiopsterm 的界面形态很像一个邮件客户端左侧是会话列表右侧是当前会话内容AI 有新回复时会话标题会亮起未读标记全局搜索可以跨会话捞关键词。值班时我一般挂三个会话一个处理告警一个写部署脚本一个用来事后补故障文档。以前这三个需求可能对应三个不同 AI 工具现在都在一个界面里切换。常用操作就是几个j/k 在会话列表上下移动回车进入会话/ 全局搜索c 新建会话d 归档会话。每个会话独立绑定自己的驱动和 system prompt避免 A 会话的上下文被 B 会话干扰。这一点看着不起眼实际用起来特别重要。AI 编程助手各有各的记忆和上下文窗口如果没有清晰的会话隔离几个任务混在一起模型很容易答非所问。3.2 命令执行与权限确认命令权限大概是运维场景里最关键的部分。AI 学习能力很强但幻觉也真实存在不能让它直接在 shell 里跑 rm -rf。aiopsterm 的权限模型分三档allow只读、安全的命令直接执行。比如 ls、grep、cat、ps、df、free、kubectl get。这些命令适合让 AI 自主执行能显著提升排查效率ask有副作用的命令需要人确认。比如 kubectl apply、rm、mv、curl 发请求、systemctl restart。AI 可以先给出命令人按 y 确认后执行deny后果不可控的命令直接拒绝。比如 rm -rf /、DROP TABLE、shutdown 这类配置里可以写正则或命令前缀。规则文件放在项目目录下也能按会话覆盖。实际使用时AI 发出 tool_call 后终端会在底部弹出一个确认区显示完整命令、执行目录、预期影响范围比如删除哪几个文件人用 y/n 决定。目前对常见命令已经做了静态分析提示比如 rm 会列出目标路径kubectl apply 会列出文件更精细的命令影响预测还在完善中。3.3 多 AI 路由让合适的 AI 干合适的活不同模型擅长的事情真的不一样。我在本地配置里维护了一份路由规则可以按关键词把任务分给不同的驱动日志分析、简单的 shell 命令转换走速度快的轻量模型复杂代码重构、多文件修改走擅长代码的 Agent比如 Claude Code、Codex CLI 这一类涉及敏感数据的分析走本地模型比如 Ollama 里的 Qwen 系列数据不出内网。路由规则不一定要很复杂。最简单的做法是每个会话手动绑定一个驱动进阶一点可以在配置里写 keyword-rules消息里出现“日志”“排查”“定位”就走分析型驱动出现“重构”“写测试”“改代码”就走编码型驱动。我特别常用的一个功能是开一个多驱动会话一个驱动当分析员负责读日志出结论另一个驱动当程序员根据结论改代码。两边的消息都在同一个会话里我只需要最后拍板。这在过去单工具时代很难实现因为上下文根本串不起来。3.4 插件系统人和 AI 共享同一批工具运维团队通常有一堆自研脚本deploy.sh、healthcheck.py、build_and_push.sh。过去这些东西只有人会调用AI 想用也不知道怎么用。aiopsterm 的插件系统让用户注册一个命令之后AI 在对话中也可以直接调用。比如注册 deploy 命令并声明它需要 deploy 权限AI 在合适场景下会主动执行 deploy但会先走 ask 审批。插件目前分两类简单命令包装写一个脚本声明参数和环境变量即可Go 插件适合更复杂的逻辑能访问会话上下文。命令输出可以是纯文本也可以是 JSON如果是 JSONAI 更容易解析。这相当于把团队积累的操作经验变成一组 AI 也能理解和使用的基础工具。人调用这些脚本时用的是肌肉记忆AI 调用这些脚本时用的是工具定义但两边最终都落在同一套审批和审计体系里。4. 安装部署与接入 AI 服务实战4.1 安装与环境准备安装方式我尽量做简单目前支持三种直接下载二进制从 GitHub Releases 拉对应平台的压缩包解压后放到 /usr/local/binHomebrew 安装如果你在同一台机器上安装过开发工具可以直接执行 brew install aiopsterm/aiopsterm源码编译需要 Go 1.22 以上进入项目根目录执行 go build ./cmd/aiopsterm 即可。装好之后先确认版本能正常输出aiopsterm version然后执行aiopsterm init生成一份配置文件模板默认放在~/.config/aiopsterm/config.yaml。如果你的系统路径不太一样以仓库 README 里的说明为准。第一次跑起来之后我建议先建一个本地会话试试手确认终端渲染正常再接入真实 AI 服务避免环境问题和服务问题混在一起排查。4.2 配置文件里到底要写什么配置文件是整个终端的核心我贴一份最小可用的示例storage: dir: ~/.local/share/aiopsterm drivers: - name: local-openai type: openai_compatible model: qwen2.5-coder-14b api_base: http://127.0.0.1:8000/v1 api_key_env: AIOPSTERM_OPENAI_KEY timeout: 60s - name: claude-code type: exec command: claude cwd: /srv/app env: TERM: xterm-256color router: default_driver: local-openai keyword_rules: - keywords: [重构, 写测试, 改代码] driver: claude-code - keywords: [日志, 磁盘, 排查, 定位] driver: local-openai permission: allow: - ls - grep - cat - ps - df - kubectl get ask: - rm - mv - curl - systemctl restart - kubectl apply deny: - rm -rf / - shutdown - reboot这里有几个值得注意的点。第一api_key_env 非常关键不要在配置文件里写死 key而是指向一个环境变量名否则一旦配置文件被提交到仓库后果很难办。第二exec 类型驱动会用子进程启动外部 CLI需要设置好 TERM 和 cwd否则外部工具可能因为终端宽度或者工作目录不对而出问题。第三keyword_rules 是可选的如果你更习惯手动指定完全可以不写这段。4.3 接入 17 款 AI 后端的三种方式接入方式不一定要每个工具都单独折腾目前支持三种方式覆盖绝大多数场景方式 AOpenAI 兼容 API。现在很多服务商或本地推理框架比如 vLLM、Ollama 的 OpenAI 兼容端点都提供 /v1/chat/completions填一个 api_base 就能连。适合公司内部统一网关或模型聚合层也是我日常用得最多的一种方式稳定、简单、好排查。方式 B本地 CLI 执行。exec 驱动会启动一个子进程比如直接启动 Claude Code然后捕获它的 stdout 和 stderr 作为消息流。好处是能用上原生工具的完整能力比如它自己的代码检索、终端工具代价是进程管理更复杂遇到 TTY 交互类场景需要维持 PTY建议配合 tmux 使用。方式 CMCP server 接入。aiopsterm 支持作为 MCP 客户端去连接以 MCP server 方式暴露的工具。一个工具只要实现了 MCP 接口就能被 aiopsterm 里的 AI 以 tool 的方式调用老工具不需要改任何业务代码。17 款不是写死了由某一种方式接入。你完全可以按团队现状选要省钱省事统一走 openai_compatible要保留某个 Agent 的完整能力就挂 exec要让老工具变成 AI 可调用的服务就包成 MCP server。4.4 实战让 AI 排查一次磁盘告警用一段模拟的终端输出来展示完整交互过程$ aiopsterm new --driver local-openai --cwd /srv/app [session: 16f3, driver: local-openai] 你帮我看下为什么磁盘快满了重点查 /srv/app/logs 下的大文件。 AI: 我先依次看磁盘使用和目录占用分布。 [tool_call] df -h [result] /dev/vda1 80G 74G 3.2G 96% / [tool_call] du -sh /srv/app/logs/* | sort -rh | head -20 [result] /srv/app/logs/access.log 12G /srv/app/logs/error.log 8.2G AI: access.log 体积增长异常。建议先确认当前写入进程再决定是否归档旧日志。 [tool_call] lsof | grep access.log | head -10 [result] nginx: worker processes... AI: 是 nginx 正在写。建议先压缩归档 3 天前的日志段并清理超过 7 天的归档 rm /srv/app/logs/access.log.2025-*.gz # 7天前归档约 15G 空间 ---- 需要确认 ---- 你y [sys] 已执行返回码 0 AI: 清理完成。当前磁盘使用率 82%建议在 crontab 增加日志轮转任务。注意看这个交互有几个关键点。AI 的第一个只读命令直接放行没有打扰人进入 du 大目录扫描需要一点时间最后删归档文件属于明确有副作用的操作走了一次人工确认。整个过程所有命令和结果都保留在会话里后续复盘直接导出 JSONL 就行这比传统“复制粘贴终端文本”的复盘方式省力得多。5. 常见问题与排查技巧实录5.1 问题速查表用了几周之后我整理了一份遇到频率最高的问题速查表现象可能原因排查方法调接口一直 401api_key_env 指向的环境变量没设置用echo $变量名确认改完要重新 source 或重启终端请求被限流同一个 key 并发太多减少同时打开的会话或在配置里给 driver 增加 rate_limitAI 说“没有权限执行”命令命中了 deny或权限默认 deny调整 permission 规则把命令加入 allow/askexec 驱动一直卡住PTY 环境不对工具等待交互输入在 tmux 内运行将 TERM 设为 xterm-256color给 exec 设置 pty 为 true会话内容串味多会话共享了同样的 system prompt检查会话基础设置确认每个 session 独立绑定驱动和 prompt中文字符乱码终端编码不一致设置 LANGzh_CN.UTF-8并确认终端编码为 UTF-8AI 反复读大文件费 token没有做结果截断给命令启用 max_output 限制比如 tail 只回最后 100 行这张表也是我在仓库 issue 里回复最多的内容。很多时候问题不是出在 aiopsterm 本身而是使用环境的基础配置没对齐。先把终端环境、环境变量、PTY 这几个基础项排干净再去看驱动的问题能少走很多弯路。5.2 踩过的几个坑第一个坑是 API key 泄露。早期做演示时我把 api_key 写进示例配置文件并推到仓库几分钟内就收到自动扫描机器人的提醒。后来全部改成 api_key_env 引用环境变量并在 README 里加红字警告任何情况下不要提交真实密钥。这件事之后我也养成了习惯所有项目配置模板里都只写xxx_env之类的占位符。第二个坑是权限太严导致 AI 完全没用。一开始为了安全权限默认 deny 一切AI 每一步都要问人体验非常笨重。后来改成“高频只读命令默认放行 有副作用命令精确确认 危险命令直接拦截”三档模型体验才正常。这里有个原则运维终端里的 AI 是要干活的不是要变成一个只会说话不会动手的顾问权限设计要在安全和效率之间找到平衡点。第三个坑是流式输出与终端渲染的兼容问题。早期 TUI 在 Windows Terminal 上渲染某些宽度字符会错位后来统一做了中英文宽度计算。建议开发阶段就在 WSL2 或 macOS 上跑Windows 原生体验还在持续完善中。5.3 省 token 和提速的小技巧用 AI 编程助手干活最大的成本往往不是工具本身而是 token。几个实测下来的技巧尽量用只读命令先探路不要一次性把所有内容都塞给 AI大文件用 tail 和 head 加管道截断再用 grep 过滤关键字而不是直接读全量文件命令输出设置 max_output 限制防止一次返回几万行结果把上下文打爆明确告诉 AI 使用 JSON 输出减少来回修正的次数切换会话时手动 compact 一下把不重要的内容折叠保留关键结论给 AI 一个明确的 system prompt减少无效探索。我发现很多时候问题不在模型能力而在“投喂姿势”。你把日志先 cut 到最近 200 行再让 AI 看效果比让它自己读一个 2M 的文件好得多。这既是省 token也是保质量。6. 开源之后的一些感受和计划6.1 开源带来的变化代码公开之后我最大的感受是开源让这个项目的安全底线被更多人盯着。有人帮我发现了 exec 驱动在回收子进程时可能遗留僵尸进程的问题有人提交了 Windows 下按键映射的修复还有人提供了把 OpenAI 兼容 API 的 tool call 格式自动转换到 Claude 格式的补丁。这些是我一个人测试时根本测不出来的场景。社区反馈的 issue 和 PR实际上是这个项目最宝贵的“免费测试工”。许可证我选了 Apache-2.0而不是 MIT。原因很简单项目里会有用户自定义的插件和驱动Apache-2.0 带了明确的专利授权条款对来贡献代码的公司开发者更友好同时它也允许商业使用不会影响有人想拿它做二开。开源不是把代码往 GitHub 一扔就完事README、截图、示例配置、许可证说明这些东西决定了别人是否愿意花时间看你的项目甚至是否愿意帮你提 issue。6.2 后续计划与一点个人体会后续的路线图大概有这几块支持更多本地模型尤其是小显存可跑的 7B 到 14B 代码模型让敏感数据尽量不离开内网把会话同步做成团队共享模式几个同事可以加入同一个运维会话协同复盘增强 MCP server 能力让外部工具链可以反过来订阅 aiopsterm 的会话事件再细粒度一些的权限策略比如按目录、按时间段、按命令参数组合来控制。做这个项目的过程中我对“工具型 AI 产品”的理解比过去清楚了很多。一开始我也以为难点是适配 17 个工具的 API做到后面才发现真正的难点是给 AI 和人建立一套都能理解和遵守的协作规则权限怎么分、上下文怎么存、操作怎么审计。这些规则定好了多接几个驱动只是工作量问题。aiopsterm 现在还远谈不上完美但至少证明了一件事运维终端不该逼着人在十几个 AI 窗口之间来回切换也不该让 AI 在没人监管的情况下乱动生产环境。如果你也在被一堆 AI 终端折磨欢迎来仓库看看提 issue 或者直接 clone 下去改成你自己的版本。