为了随时随地控制 AI Agent,我做了一个 Web Terminal
·
为了随时随地控制 AI Agent,我做了一个 Web Terminal
为什么要做这个 Web Terminal?作为一个 AI 爱好者,我经常需要远程控制我的 AI Agent——无论是训练模型、调整参数,还是让它帮我处理数据。但传统的 SSH 终端虽然强大,却不够灵活:我需要记住一堆命令、手动配置环境,而且无法在移动设备上轻松操作。更糟糕的是,每次我想让 AI Agent 执行一个复杂任务,比如“分析这份 CSV 文件并生成趋势图”,我都得写一堆代码,然后等待结果。于是,我决定自己动手,做一个 Web Terminal。它不是一个普通的命令行界面,而是一个专为 AI Agent 设计的控制中心——你可以在任何设备上(手机、平板、笔记本)通过浏览器连接,用自然语言或代码直接指挥 AI,甚至让 AI 自动执行任务并返回结果。这篇文章会带你从零开始,理解这个 Web Terminal 的核心设计,并附上可运行的代码示例。## 核心设计:WebSocket + AI 集成我的 Web Terminal 基于三个原则:1. 实时通信:使用 WebSocket 代替传统的 HTTP 轮询,让 AI Agent 的输出像终端一样流畅。2. 自然语言接口:除了支持 Shell 命令,还能解析自然语言指令(比如“帮我检查系统资源”),并自动调用 AI 模型。3. 可扩展性:通过插件机制,你可以轻松添加新的 AI 功能(比如图像识别、数据可视化)。### 技术栈- 后端:Python + FastAPI(WebSocket 支持) + OpenAI API(模拟 AI Agent)- 前端:HTML + JavaScript(xterm.js 终端模拟器)- 通信:WebSocket(双向实时)## 第一步:搭建 WebSocket 服务后端是核心,它负责接收指令、调用 AI Agent,并返回结果。下面是一个简单的 FastAPI 服务,支持 WebSocket 通信。python# server.pyfrom fastapi import FastAPI, WebSocket, WebSocketDisconnectfrom fastapi.responses import HTMLResponseimport asyncioimport jsonapp = FastAPI()# 模拟 AI Agent:根据指令执行任务async def ai_agent(command: str) -> str: """ 模拟 AI Agent 处理命令。 如果是自然语言,调用一个虚拟的 AI 模型(实际可用 OpenAI API)。 """ # 简单规则:如果是代码指令,直接执行(这里用 sleep 模拟) if command.startswith("!"): # 以 ! 开头的指令认为是代码 task = command[1:].strip() await asyncio.sleep(1) # 模拟执行时间 return f"[AI Executor] 已执行任务: {task}\n结果: 任务完成,无错误。" else: # 自然语言指令:调用 AI 模型解析 # 实际中可调用 OpenAI API,这里用 mock await asyncio.sleep(0.5) response = f"[AI Assistant] 收到指令: '{command}'\n建议: 运行 '!分析数据' 来处理数据。" return response@app.websocket("/ws/terminal")async def websocket_endpoint(websocket: WebSocket): await websocket.accept() print("客户端已连接") try: while True: # 接收前端发送的指令 data = await websocket.receive_text() print(f"收到指令: {data}") # 调用 AI Agent 处理 result = await ai_agent(data) # 模拟流式输出(分多段发送,体验更真实) for line in result.split("\n"): await websocket.send_text(json.dumps({"type": "output", "data": line + "\n"})) await asyncio.sleep(0.3) # 模拟逐行输出 # 发送完成信号 await websocket.send_text(json.dumps({"type": "prompt", "data": ">>> "})) except WebSocketDisconnect: print("客户端断开连接")# 前端页面(嵌入 HTML)@app.get("/")async def get(): with open("terminal.html", "r") as f: html = f.read() return HTMLResponse(html)这个后端做了三件事:- 接受 WebSocket 连接。- 解析指令:自然语言用 ai_agent 函数处理,代码指令(以 ! 开头)直接模拟执行。- 流式返回结果:让终端体验更真实。## 第二步:前端终端界面前端使用 xterm.js 和 xterm-addon-fit 来模拟一个专业的终端。它通过 WebSocket 连接到后端,并支持输入输出。html<!-- terminal.html --><!DOCTYPE html><html><head> <title>AI Agent Web Terminal</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.min.css"> <script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.min.js"></script> <style> body { margin: 0; padding: 20px; background: #1e1e1e; } #terminal { height: 400px; } </style></head><body> <div id="terminal"></div> <script> // 初始化终端 const term = new Terminal({ cursorBlink: true, fontSize: 14, theme: { background: '#1e1e1e' } }); const fitAddon = new FitAddon.FitAddon(); term.loadAddon(fitAddon); term.open(document.getElementById('terminal')); fitAddon.fit(); // 连接 WebSocket const socket = new WebSocket("ws://localhost:8000/ws/terminal"); let currentInput = ""; // 当前输入行 // WebSocket 消息处理 socket.onmessage = function(event) { const msg = JSON.parse(event.data); if (msg.type === "output") { term.write(msg.data); // 写入输出 } else if (msg.type === "prompt") { term.write(msg.data); // 显示提示符 currentInput = ""; // 重置输入 } }; // 处理键盘输入 term.onKey((e) => { const key = e.key; // 回车:发送指令 if (key === '\r') { term.write('\n'); // 换行 socket.send(currentInput); // 发送到后端 currentInput = ""; } // 退格:删除最后一个字符 else if (key === '\x7f') { if (currentInput.length > 0) { currentInput = currentInput.slice(0, -1); term.write('\b \b'); // 删除光标前字符 } } // 普通字符 else if (key.length === 1) { currentInput += key; term.write(key); } }); // 初始提示符 term.write(">>> "); </script></body></html>这个前端界面:- 使用 xterm.js 模拟终端外观。- 通过 WebSocket 实时发送指令、接收输出。- 支持退格、回车等基本操作。## 第三步:运行与测试1. 安装依赖:bashpip install fastapi uvicorn2. 启动服务:bashuvicorn server:app --reload --host 0.0.0.0 --port 80003. 打开浏览器访问 http://localhost:8000。你会看到一个黑底绿字的终端界面。试试输入:- 你好,帮我检查资源(自然语言)- !训练模型(代码指令)输出会像真实终端一样逐行显示。现在,你可以在手机或平板上打开这个地址,随时随地控制 AI Agent!## 进阶:让 AI 自动执行复杂任务我还在 Web Terminal 中加入了“任务链”功能。例如,输入 !分析数据 后,AI Agent 会自动执行以下步骤:1. 读取指定 CSV 文件。2. 调用 Python 库(如 pandas)分析数据。3. 生成图表并返回结果。这里是一个简化的实现:python# 在 ai_agent 函数中添加任务链支持async def ai_agent(command: str) -> str: if command == "!分析数据": # 模拟多步骤任务 tasks = [ "读取 data.csv...", "计算平均值...", "生成趋势图...", "发送报告..." ] for task in tasks: await asyncio.sleep(0.5) yield f"[进度] {task}\n" yield "[完成] 分析结果已保存到 report.html\n" # 其他指令...这样,AI Agent 就不再是一个简单的命令处理器,而是一个能自主完成复杂任务的智能助手。## 总结这个 Web Terminal 项目让我实现了“随时随地控制 AI Agent”的梦想。它用 WebSocket 解决了实时通信问题,用自然语言接口降低了使用门槛,并通过流式输出保留了终端体验。关键点是:- WebSocket 双向通信:比 HTTP 轮询更快、更省资源。- 自然语言与代码统一:用户可以用最舒服的方式发号施令。- 模块化设计:ai_agent 函数可以轻松扩展,比如接入 OpenAI 的 API 或自定义 AI 模型。当然,这个原型还有很多改进空间,比如增加认证、支持文件上传、集成更多 AI 模型等。但核心思想已经成型:将 AI Agent 的控制权交还给用户,而 Web Terminal 就是那个桥梁。如果你也有类似需求,不妨试试这个方案——只需几行代码,你就能拥有一个专属的 AI 控制台。
更多推荐


所有评论(0)