我把AI助手部署上云后,全组都能用了
前言:前几篇文章我们搭了Agent、搭了RAG、还把它们合体了。但有个问题一直没解决——你的AI助手还跑在你自己电脑的命令行里,别人想用还得远程桌面连你的机器。这期把它打包上云,让全组同事打开浏览器就能用。
为什么必须上云?
先说说我为什么要折腾部署。
之前搭好的Agent+RAG合体版,我在自己电脑上跑得挺欢。然后发生这么几件事:
事件1:同事问我年假政策,我说"你等我一下,我开个终端跑一下"。他说"你不能直接给我个网页吗?"
事件2:我关机了,Agent就没了。第二天同事说"你那个AI助手怎么挂了",我说"我电脑关了"。
事件3:领导想试用,我给他装了Python环境配了半天依赖,他看了一眼命令行说"算了"。
核心问题就一个:本地命令行 ≠ 可用的产品。你得让别人打开浏览器、输入一个网址就能用,这才叫"部署"。
部署方案:从简单到生产
我调研了一圈,总结了四条路线:
| 本地uvicorn | |||
| Docker本地 | |||
| 云服务器+Docker | |||
| Serverless |
我选了云服务器+Docker这条路,原因很简单:可控、好调试、成本透明。下面一步步来。
第一步:用FastAPI把Agent包成API
之前我们的Agent是这样的:在命令行里输入问题,它打印回答。现在要改成:发一个HTTP请求,返回JSON。
安装依赖
pip install fastapi uvicorn 写API服务
# server.py from fastapi import FastAPI from pydantic import BaseModel from typing import Optional import os # 这里import你之前写好的Agent代码 # from agent import run_agent # 第12篇的Agent # from rag import search_knowledge_base # 第13篇的RAG app = FastAPI(title="AI搞事星球 Agent服务") # 请求/响应模型 class ChatRequest(BaseModel): question: str session_id: Optional[str] = "default" class ChatResponse(BaseModel): answer: str success: bool = True duration_ms: int = 0 # 健康检查接口(部署后用来验证服务是否活着) @app.get("/health") def health(): return {"status": "ok"} # 聊天接口 @app.post("/chat", response_model=ChatResponse) async def chat(req: ChatRequest): import time start = time.time() # 调用你之前写好的Agent # answer = run_agent(req.question) answer = f"你问的是:{req.question}(这里替换成你的Agent调用)" duration = int((time.time() - start) * 1000) return ChatResponse(answer=answer, duration_ms=duration) 本地测试
uvicorn server:app --host 0.0.0.0 --port 8000 打开浏览器访问 http://localhost:8000/docs,FastAPI自动生成了API文档,直接在网页上测试接口。
到这一步,你的Agent已经从命令行程序变成了HTTP服务。 但还是在本地跑,别人还是访问不了。
第二步:写个简单的前端页面
总不能让同事用Postman跟你聊天吧?写个最简单的HTML页面:
<!-- index.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>AI搞事星球助手</title> <style> body { font-family: sans-serif; max-width: 600px; margin: 40px auto; } #chat { height: 400px; border: 1px solid #ddd; padding: 16px; overflow-y: auto; border-radius: 8px; } .msg { margin: 8px 0; padding: 8px 12px; border-radius: 8px; } .user { background: #E8F4FD; text-align: right; } .bot { background: #F0F0F0; } input { width: 75%; padding: 10px; border: 1px solid #ddd; border-radius: 8px; } button { width: 20%; padding: 10px; background: #1A73E8; color: white; border: none; border-radius: 8px; cursor: pointer; } </style> </head> <body> <h1>AI搞事星球助手</h1> <div id="chat"></div> <div style="margin-top:12px;display:flex;gap:8px;"> <input id="input" placeholder="输入问题..." onkeypress="if(event.key==='Enter')send()"> <button onclick="send()">发送</button> </div> <script> async function send() { const input = document.getElementById('input'); const chat = document.getElementById('chat'); const q = input.value.trim(); if (!q) return; chat.innerHTML += `<div class="msg user">${q}</div>`; input.value = ''; const res = await fetch('/api/chat', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({question: q}) }); const data = await res.json(); chat.innerHTML += `<div class="msg bot">${data.answer}</div>`; chat.scrollTop = chat.scrollHeight; } </script> </body> </html> 一个能用的聊天界面,50行HTML搞定。 不用React,不用Vue,够用就行。
第三步:Docker打包
现在把后端API+前端页面打包成Docker容器,这样在任何机器上都能一键启动。
项目结构
ai-agent/ ├── app/ │ ├── server.py # FastAPI后端 │ ├── agent.py # Agent代码(第12篇) │ ├── rag.py # RAG代码(第13篇) │ └── requirements.txt # Python依赖 ├── web/ │ └── index.html # 前端页面 ├── nginx/ │ └── nginx.conf # Nginx配置 ├── Dockerfile # 后端镜像 └── docker-compose.yml # 编排文件 Dockerfile(后端镜像)
FROM python:3.11-slim ENV TZ=Asia/Shanghai \ PYTHONUNBUFFERED=1 WORKDIR /app # 先装依赖(利用Docker缓存层) COPY app/requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 再复制代码 COPY app/ . EXPOSE 8000 CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8000"] nginx.conf(反向代理+静态页面)
events {} http { server { listen 80; # 前端静态页面 root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } # API请求转发到后端 location /api/ { proxy_pass http://app:8000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } } docker-compose.yml(一键启动)
version: "3.9" services: app: build: . container_name: ai-agent-app restart: unless-stopped environment: - OPENAI_API_KEY=${OPENAI_API_KEY} volumes: - ./app/logs:/app/logs networks: - agent-net nginx: image: nginx:1.25 container_name: ai-agent-nginx restart: unless-stopped ports: - "8080:80" volumes: - ./web:/usr/share/nginx/html:ro - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - app networks: - agent-net networks: agent-net: driver: bridge 本地启动验证
# 一行命令启动 docker-compose up -d # 查看容器状态 docker ps # 访问 # http://localhost:8080 打开浏览器,看到聊天界面,输入问题能收到回复——恭喜,你的AI助手已经容器化了。
第四步:部署到云服务器
买服务器
随便选一家云厂商(阿里云/腾讯云/华为云都行),买个最便宜的轻量应用服务器: - 配置:2核4G就够(Agent跑起来主要吃内存) - 系统:Ubuntu 22.04 - 价格:大概60-100元/月
服务器初始化
# SSH连上去 ssh root@你的服务器IP # 装Docker curl -fsSL https://get.docker.com | sh # 装Docker Compose apt install docker-compose-plugin -y # 开放端口(在云控制台安全组里也要开8080) ufw allow 8080 部署代码
# 把项目传上去(用git或scp都行) git clone 你的仓库地址 ai-agent cd ai-agent # 配置环境变量 echo "OPENAI_API_KEY=sk-你的key" > .env # 启动! docker-compose up -d # 验证 curl http://localhost:8080/api/health # 返回 {"status":"ok"} 就成功了 现在全组同事打开浏览器访问 http://你的服务器IP:8080,就能用你的AI助手了。
跑了三天,踩了4个坑
坑1:Docker镜像太大,构建太慢
第一次构建镜像有2GB多,每次改代码重新build要等5分钟。
解法:Dockerfile里先COPY依赖文件再COPY代码,利用Docker缓存层。改代码后只要依赖没变,构建只需要10秒。另外用python:3.11-slim而不是python:3.11,镜像直接小了800MB。
坑2:OPENAI_API_KEY写死在代码里,一push到Git就泄露了
解法:用.env文件+环境变量。docker-compose.yml里用${OPENAI_API_KEY}引用,.env文件加到.gitignore。千万别把key提交到代码仓库,别问我怎么知道的。
坑3:服务突然挂了,不知道为什么
某天早上同事说AI助手打不开了。SSH上去一看,容器restart了十几次。
解法:加了健康检查+自动重启。docker-compose里已经有restart: unless-stopped,但还需要加健康检查:
app: build: . healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 然后在FastAPI里加结构化日志,出问题至少能看日志排查:
import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s' ) 坑4:同事同时用,服务扛不住
两个人同时提问,第二个请求要等第一个完成才能响应。因为uvicorn默认单进程。
解法:生产环境用Gunicorn管理多个uvicorn worker:
CMD ["gunicorn", "server:app", "-k", "uvicorn.workers.UvicornWorker", "-w", "4", "-b", "0.0.0.0:8000"] 4个worker,能同时处理4个请求,小团队够用了。
从Demo到生产:还差什么
| 可用性 | ||
| 安全 | ||
| 监控 | ||
| 日志 | ||
| CI/CD | ||
| 知识库 |
但说实话,对于一个小团队内部用的AI助手,云服务器+Docker+Nginx这套组合已经够用了。 上面那些是规模上去之后才需要考虑的事。
整个部署系列的核心思路
回顾一下从第12篇到这篇的完整路径:
第12篇:搭Agent(能干活) ↓ 第13篇:搭RAG(有知识) ↓ 第14篇:Agent+RAG合体(完整AI助手) ↓ 第15篇:部署上云(团队可用) ← 你在这里 前14篇解决的是"能不能用"的问题,这篇解决的是"别人能不能用"的问题。
一个AI助手,如果只有你自己能用,那它只是个玩具。部署上线、让团队都能访问,它才真正有了生产力。
完整部署代码已整理好,公众号回复「AgentDeploy」获取。
你打算把AI助手部署到哪里?云服务器、公司内网、还是Serverless?评论区聊聊 👇
下期预告:AI Agent成本控制实战——一个AI助手跑一个月到底花多少钱,怎么把账单砍到三分之一
💡 关注【AI搞事星球】
每周三篇AI实战干货,从Agent到多模态,陪你一起用AI搞大事 💪
点击上方蓝字关注,不错过下期实战案例 →
🔍 相关搜索:AI Agent · MCP协议 · Function Calling · AI工具实战 · 大模型
更多内容请在公众号对话框回复关键词获取资料
夜雨聆风