第14讲:项目打包与容器化部署——Docker封装与可视化发布
欢迎来到《Python + AI Agent 实战开发完全指南》专栏!
在前面的课程中,我们已经成功打造了具备异步处理能力的多智能体协作系统(FastAPI + Celery + Redis)。但说实话,很多开发者在本地跑通代码后,一到服务器部署环节就会因为环境不一致、依赖冲突等问题抓狂。所以今天这一讲,我们不整虚的,直接带你把整个 Agent 后端工程进行Docker 容器化封装,并套上一个高颜值的 Streamlit 可视化界面,实现真正的“一键部署”。
一、 磨刀不误砍柴工:极简环境准备
在开始打包之前,我们需要确保你的电脑已经安装了 Docker 和 Docker Compose。同时,我们还需要为前端交互准备一个轻量级的 UI 库:
打开终端,执行以下命令安装必备库:
pip install streamlit requests
注:*streamlit** 是 Python 生态中最友好的数据应用框架,几行代码就能生成漂亮的 Web 界面,非常适合用来展示 Agent 的思考过程。*
在你的项目根目录下创建一个 .env 文件,确保里面包含了 LLM 的密钥和 Redis 的连接地址:
OPENAI_API_KEY=sk-xxxxxxxxxxxxx
BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
REDIS_URL=redis://localhost:6379/0
二、 核心架构拆解:容器化编排的本质
要让多组件的 Agent 系统在服务器上稳定运行,关键在于给它们提供一个隔离且标准化的运行环境。目前业界最经典的云原生范式就是 Docker Compose。
一个标准的 Agent 生产级部署包含三个步骤:
- 构建镜像(Build):将 Python 环境、系统依赖和业务代码打包成不可变的 Docker Image。
- 服务编排(Compose):通过 YAML 配置文件,统一调度 Web 服务、后台 Worker 和消息队列。
- 可视化接入(UI):将硬核的后端 API 包装成用户友好的交互界面。
三、 实战演练:一键部署你的 Agent 团队
接下来,我们把理论落地。这段配置展示了如何将复杂的分布式系统压缩到两个文件中。
1. 编写生产级 Dockerfile
在项目根目录创建 Dockerfile,定义我们的基础运行环境:
# ========== 1. 使用官方轻量级 Python 基础镜像 ==========
FROM python:3.10-slim
# ========== 2. 设置工作目录 ==========
WORKDIR /app
# ========== 3. 先复制依赖文件并安装(利用缓存层优化构建速度) ==========
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# ========== 4. 复制项目源码 ==========
COPY . .
# ========== 5. 暴露 FastAPI 默认端口 ==========
EXPOSE 8000
2. 终极武器:Docker Compose 一键编排
在项目根目录创建 docker-compose.yml,这是启动整个系统的核心:
version: '3.8'
services:
# 1. 消息中间件与结果存储
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
# 2. FastAPI Web 服务
web:
build: .
command: uvicorn main:app --host 0.0.0.0 --port 8000
ports:
- "8000:8000"
env_file:
- .env
depends_on:
- redis
# 3. Celery 后台 Worker (注意:它使用的是同一个镜像,但启动命令不同)
worker:
build: .
command: celery -A celery_app worker --loglevel=info
env_file:
- .env
depends_on:
- redis
volumes:
redis_data:
3. 让 Agent 拥有灵魂:Streamlit 可视化界面
新建 streamlit_ui.py,为你的 Agent 团队套上一层交互外壳:
import streamlit as st
import requests
import time
st.set_page_config(page_title="AI Agent Team", layout="wide")
st.title(" 多智能体协作工作台")
# 用户输入区
user_query = st.text_area("请输入你的复杂任务指令:", height=100)
max_rounds = st.slider("最大协作轮数", min_value=1, max_value=10, value=3)
if st.button(" 提交给 Agent 团队"):
if user_query:
# 1. 调用异步接口
response = requests.post(
"http://localhost:8000/api/v1/agents/collaborate/async",
json={"query": user_query, "max_rounds": max_rounds}
)
task_id = response.json()["task_id"]
# 2. 展示进度条
progress_bar = st.progress(0)
status_text = st.empty()
while True:
res = requests.get(f"http://localhost:8000/api/v1/tasks/{task_id}").json()
if res["status"] == "SUCCESS":
progress_bar.progress(100)
status_text.success(" 任务完成!")
st.subheader("最终报告:")
st.markdown(res["result"]["report"])
break
elif res["status"] == "FAILURE":
status_text.error(f" 发生错误: {res['error']}")
break
else:
status_text.info(f" 正在处理: {res.get('progress', 'Initializing...')}")
time.sleep(2)
需要注意的是,当你将这套代码推送到云服务器时,记得在终端执行 docker-compose up -d --build,加上 -d 参数可以让所有服务在后台静默运行。
四、 代码深度解析与避坑指南
运行上面的命令,你会看到终端里打印出各个容器的启动日志。在这个过程中,有几个工程细节值得注意:
- 镜像分层与缓存:我们在
Dockerfile中刻意将COPY requirements.txt和COPY . .分开。这样当你只修改了业务代码时,Docker 会直接命中依赖安装的缓存,避免每次都重新下载庞大的第三方库。 - 同镜像多角色复用:在
docker-compose.yml中,Web 服务和 Worker 都使用了build: .。这意味着它们共享同一份底层环境和代码,只是在启动时执行了不同的command,极大简化了维护成本。 - 网络通信机制:在 Compose 内部,容器之间可以直接通过服务名(如
redis)互相访问,无需使用 localhost。而 Streamlit 访问 FastAPI 时,如果不在同一个容器内,则需要映射宿主机的真实 IP 或端口。
本节小结
今天我们彻底摆脱了“在我的电脑上能跑”的环境地狱,用最底层的 Docker 实现了多智能体系统的标准化交付。理解了这套机制,你再去学 Kubernetes 或者云厂商的 Serverless 平台时,就会发现它们只是帮你把这里的 docker-compose.yml 管理得更自动化了而已。
下一讲,我们将迎来本专栏的最终章——性能优化与安全边界,看看如何控制 Token 成本并防止恶意 Prompt 注入,让你的 Agent 真正无懈可击!
更多推荐

所有评论(0)