本节导读:深入理解AutoGen与Docker集成的核心机制,掌握容器环境配置、网络管理、存储优化和监控体系,构建企业级容器化AI代码执行平台
Docker集成是AutoGen实现生产级代码执行的关键技术。通过容器化,AutoGen获得了环境隔离、资源控制、版本管理和快速部署的能力,为多智能体协作提供了稳定可靠的执行环境。
from autogen.code_executor import DockerCommandLineCodeExecutor # 基础Docker执行器配置 docker_executor = DockerCommandLineCodeExecutor( image="python:3.10-slim", # 基础镜像 timeout=600, # 10分钟超时 work_dir="/workspace", # 容器内工作目录 container_name="autogen-executor-{uuid}", # 容器名称模板 auto_remove=True, # 自动删除容器 network_mode="bridge", # 网络模式 port_bindings={8080: 8080}, # 端口映射 volume_mounts={ "/host/data": "/container/data", # 数据卷挂载 "/host/code": "/workspace/code" # 代码目录挂载 }, environment_vars={ "PYTHONPATH": "/workspace", "DATA_DIR": "/workspace/data", "AUTOKEN_VERSION": "1.0.0" }, resource_limits={ "memory": "2g", "cpu": "1.0", "pids": 100 } ) # 使用Docker执行器 async def docker_execution_example(): code = """ import pandas as pd import numpy as np import matplotlib.pyplot as plt # 生成数据分析代码 np.random.seed(42) data = pd.DataFrame({ 'timestamp': pd.date_range('2024-01-01', periods=100, freq='D'), 'value': np.random.randn(100).cumsum(), 'category': np.random.choice(['A', 'B', 'C'], 100) }) # 基础统计 print(data.head()) print(f"数据行数: {len(data)}") print(f"分类统计:\n{data['category'].value_counts()}") # 生成趋势图 plt.figure(figsize=(12, 6)) plt.plot(data['timestamp'], data['value'], label='趋势线') plt.title('时间序列数据分析') plt.xlabel('时间') plt.ylabel('数值') plt.legend() plt.grid(True) plt.tight_layout() plt.savefig('/workspace/trend_analysis.png') plt.close() print("分析完成,图表已保存") """ result = docker_executor.execute_code(code, "data_analysis.py") return result
import docker from typing import Dict, List, Optional from dataclasses import dataclass @dataclass class NetworkConfig: """网络配置""" name: str driver: str = "bridge" enable_ipv6: bool = False internal: bool = False labels: Optional[Dict[str, str]] = None options: Optional[Dict[str, str]] = None class DockerNetworkManager: """Docker网络管理器""" def __init__(self, docker_client: Optional[docker.DockerClient] = None): self.client = docker_client or docker.from_env() self.networks = {} def create_network(self, execution_id: str, config: Optional[NetworkConfig] = None) -> str: """创建网络""" if config is None: config = NetworkConfig(name=f"autogen-network-{execution_id}") try: network = self.client.networks.create( name=config.name, driver=config.driver, enable_ipv6=config.enable_ipv6, internal=config.internal, labels=config.labels or {}, options=config.options or {} ) self.networks[execution_id] = network.id return network.id except docker.errors.APIError as e: if "already exists" in str(e): return config.name raise def create_isolated_network(self, execution_id: str) -> Dict[str, Any]: """创建隔离网络""" # 创建主网络 main_network_id = self.create_network( execution_id, NetworkConfig( name=f"autogen-main-{execution_id}", driver="bridge", internal=False ) ) # 创建内部网络(容器间通信) internal_network_id = self.create_network( execution_id, NetworkConfig( name=f"autogen-internal-{execution_id}", driver="bridge", internal=True ) ) return { "main_network": main_network_id, "internal_network": internal_network_id }
import docker from typing import Dict, List, Optional, Any from dataclasses import dataclass import os @dataclass class VolumeConfig: """卷配置""" name: str driver: str = "local" driver_opts: Optional[Dict[str, str]] = None labels: Optional[Dict[str, str]] = None class DockerVolumeManager: """Docker卷管理器""" def __init__(self, docker_client: Optional[docker.DockerClient] = None): self.client = docker_client or docker.from_env() self.volumes = {} def create_volume(self, execution_id: str, config: Optional[VolumeConfig] = None) -> str: """创建卷""" if config is None: config = VolumeConfig(name=f"autogen-data-{execution_id}") try: volume = self.client.volumes.create( name=config.name, driver=config.driver, driver_opts=config.driver_opts or {}, labels=config.labels or {} ) self.volumes[execution_id] = volume.name return volume.name except docker.errors.APIError as e: if "already exists" in str(e): return config.name raise def create_persistent_storage(self, execution_id: str, storage_path: str = "/autogen/storage") -> Dict[str, Any]: """创建持久化存储""" # 创建主数据卷 main_volume = self.create_volume(f"{execution_id}-main") # 创建代码卷 code_volume = self.create_volume(f"{execution_id}-code") # 创建输出卷 output_volume = self.create_volume(f"{execution_id}-output") # 创建日志卷 log_volume = self.create_volume(f"{execution_id}-logs") return { "main_volume": main_volume, "code_volume": code_volume, "output_volume": output_volume, "log_volume": log_volume, "mounts": { main_volume: {"bind": storage_path, "mode": "rw"}, code_volume: {"bind": f"{storage_path}/code", "mode": "rw"}, output_volume: {"bind": f"{storage_path}/output", "mode": "rw"}, log_volume: {"bind": f"{storage_path}/logs", "mode": "rw"} } }
import docker from typing import Dict, List, Optional, Any from dataclasses import dataclass @dataclass class BaseImageConfig: """基础镜像配置""" python_version: str = "3.10" os_distro: str = "slim" additional_packages: Optional[List[str]] = None pip_packages: Optional[List[str]] = None environment_vars: Optional[Dict[str, str]] = None class DockerImageBuilder: """Docker镜像构建器""" def __init__(self): self.client = docker.from_env() def build_base_image(self, config: BaseImageConfig) -> str: """构建基础镜像""" # 生成Dockerfile内容 dockerfile_content = self._generate_dockerfile(config) # 创建临时目录和文件 import tempfile import os with tempfile.TemporaryDirectory() as temp_dir: dockerfile_path = os.path.join(temp_dir, "Dockerfile") with open(dockerfile_path, 'w') as f: f.write(dockerfile_content) # 构建镜像 image_name = f"autogen-python:{config.python_version}-{config.os_distro}" try: image, _ = self.client.images.build( path=temp_dir, tag=image_name, rm=True, force_rebuild=True ) return image.id except docker.errors.BuildError as e: raise RuntimeError(f"镜像构建失败: {e}") def _generate_dockerfile(self, config: BaseImageConfig) -> str: """生成Dockerfile""" dockerfile = f"""FROM python:{config.python_version}-{config.os_distro} """ # 设置环境变量 if config.environment_vars: for key, value in config.environment_vars.items(): dockerfile += f"ENV {key}={value}\\n" # 安装系统包 if config.additional_packages: dockerfile += f"""RUN apt-get update && apt-get install -y \\n""" for package in config.additional_packages: dockerfile += f" {package} \\\\n" dockerfile += f" && rm -rf /var/lib/apt/lists/*\\n" # 安装Python包 if config.pip_packages: dockerfile += f"""RUN pip install --no-cache-dir \\n""" for package in config.pip_packages: dockerfile += f" {package} \\\\n" dockerfile += f"&& pip cache purge\\n" # 创建工作目录 dockerfile += f"""WORKDIR /workspace RUN mkdir -p /workspace/code /workspace/output /workspace/data """ return dockerfile
class AutoGenImageBuilder(DockerImageBuilder): """AutoGen专用镜像构建器""" def build_autogen_image(self, version: str = "latest", include_gpu: bool = False) -> str: """构建AutoGen专用镜像""" # AutoGen基础依赖 base_packages = [ "build-essential", "git", "curl", "wget", "unzip", "zip", "vim", "nano", "htop", "tree", "jq", "yq" ] python_packages = [ "autogen[math-code-executor]", "pandas", "numpy", "matplotlib", "seaborn", "scikit-learn", "jupyter", "ipython", "requests", "openai", "anthropic" ] if include_gpu: python_packages.extend([ "torch", "torchvision", "transformers", "accelerate" ]) config = BaseImageConfig( python_version="3.10", os_distro="slim", additional_packages=base_packages, pip_packages=python_packages, environment_vars={ "PYTHONPATH": "/workspace", "AUTOGEN_VERSION": version, "LANG": "C.UTF-8" } ) return self.build_base_image(config)
import docker from typing import Dict, List, Optional, Any from dataclasses import dataclass from threading import Thread, Event import time import json @dataclass class ContainerMetrics: """容器指标""" container_id: str name: str cpu_percent: float memory_usage_mb: float memory_limit_mb: float memory_percent: float status: str uptime_seconds: float class DockerMonitor: """Docker监控器""" def __init__(self, monitoring_interval: int = 30): self.client = docker.from_env() self.monitoring_interval = monitoring_interval self.monitoring = False self.stop_event = Event() self.metrics_history = {} def start_monitoring(self) -> Thread: """开始监控""" self.monitoring = True self.stop_event.clear() monitor_thread = Thread(target=self._monitoring_loop) monitor_thread.start() return monitor_thread def stop_monitoring(self): """停止监控""" self.monitoring = False self.stop_event.set() def _monitoring_loop(self): """监控循环""" while self.monitoring and not self.stop_event.is_set(): try: # 获取所有容器 containers = self.client.containers.list(all=True) # 收集指标 for container in containers: if container.name.startswith("autogen-"): metrics = self._collect_container_metrics(container) self._save_metrics(metrics) time.sleep(self.monitoring_interval) except Exception as e: print(f"监控错误: {e}") time.sleep(5) def _collect_container_metrics(self, container) -> ContainerMetrics: """收集容器指标""" try: # 获取容器状态 stats = container.stats(stream=False) # 计算CPU使用率 cpu_percent = self._calculate_cpu_percent(stats) # 计算内存使用 memory_stats = stats['memory_stats'] memory_usage_mb = memory_stats['usage'] / 1024 / 1024 memory_limit_mb = memory_stats['limit'] / 1024 / 1024 memory_percent = (memory_usage_mb / memory_limit_mb) * 100 # 运行时间 uptime = time.time() - container.attrs['State']['StartedAt'] return ContainerMetrics( container_id=container.id[:12], name=container.name, cpu_percent=cpu_percent, memory_usage_mb=memory_usage_mb, memory_limit_mb=memory_limit_mb, memory_percent=memory_percent, status=container.status, uptime_seconds=uptime ) except Exception as e: # 返回错误指标 return ContainerMetrics( container_id=container.id[:12], name=container.name, cpu_percent=0.0, memory_usage_mb=0.0, memory_limit_mb=0.0, memory_percent=0.0, status=f"error: {str(e)}", uptime_seconds=0.0 ) def _calculate_cpu_percent(self, stats: Dict[str, Any]) -> float: """计算CPU使用率""" try: cpu_stats = stats['cpu_stats'] precpu_stats = stats['precpu_stats'] # 计算CPU使用时间差异 cpu_usage = cpu_stats['cpu_usage']['total_usage'] - precpu_stats['cpu_usage']['total_usage'] system_usage = cpu_stats['system_cpu_usage'] - precpu_stats['system_cpu_usage'] # 计算使用率 if system_usage > 0: cpu_percent = (cpu_usage / system_usage) * len(cpu_stats['cpu_usage']['percpu_usage']) * 100 return min(cpu_percent, 100.0) # 限制最大100% return 0.0 except: return 0.0
import asyncio import pandas as pd import matplotlib.pyplot as plt from autogen import AssistantAgent, UserProxyAgent from autogen.code_executor import DockerCommandLineCodeExecutor # 创建数据分析执行器 data_analysis_executor = DockerCommandLineCodeExecutor( image="python:3.10-slim", timeout=900, # 15分钟 work_dir="/workspace/data_analysis", auto_remove=True, environment_vars={ "PYTHONPATH": "/workspace", "MPLCONFIGDIR": "/workspace/matplotlib_config" } ) # 创建数据分析师智能体 data_analyst = AssistantAgent( name="data_analyst", model_client=OpenAIChatCompletionClient(model="gpt-4o"), code_execution_config={"executor": data_analysis_executor} ) # 创建用户代理 user_proxy = UserProxyAgent( name="user_proxy", human_input_mode="NEVER", code_execution_config=False ) # 定义数据分析任务 async def perform_data_analysis(): task = """ 请帮我分析以下数据: 1. 生成包含日期、销售额、产品类别的模拟数据(100行) 2. 计算各类别的总销售额和平均值 3. 创建销售额趋势图 4. 生成简要分析报告 """ # 开始对话 await user_proxy.initiate_chat( data_analyst, message=task ) return "数据分析任务完成" # 执行任务 asyncio.run(perform_data_analysis())
A:优化策略包括:
A:处理方法包括:
A:安全措施包括:
A:监控方案包括:
本节详细介绍了AutoGen Docker集成的核心机制,包括基础配置、网络管理、存储管理、镜像构建和监控体系。通过实际案例,我们学习了如何构建高性能、高可用的容器化AI代码执行环境。
关键要点:
下一节将深入探讨第4章安全控制,包括访问控制、输入验证、输出监控和安全审计等内容。
关键词:Docker集成, 容器化, 网络管理, 存储优化, 镜像构建, 监控系统
难度:高级
预计阅读:35分钟