多模态 Agent + Artifacts(E2B 沙盒)
教程:构建多模态 Agent,用 Seedream 生成图片、写分析代码、在 E2B 沙盒中执行、产出报告 Artifact。展示 SandBase 生态组合:多模态模型 + 沙盒 + LLM 一体化工作流。
结论先行 — 构建一个 Agent:接收创意 brief、用 Seedream 5 Pro 生成图片、写 Python 分析代码、在 E2B 沙盒中安全执行、产出完整报告 Artifact。本教程展示 SandBase 生态组合的工作方式:多模态生成 + 代码沙盒 + LLM 推理在单个 Agent 工作流中协同。含完整代码。
我们在构建什么
一个多模态 Agent:
- 接收创意 brief(如”为智能手机发布会生成主视觉”)
- 通过 SandBase 用 Seedream 5 Pro 生成图片
- 写分析代码评估图片(色彩分布、构图指标)
- 在 E2B 沙盒中安全执行代码
- 产出结构化报告 Artifact,组合图片、分析和建议
这展示了”生态组合”模式:一个 Agent 通过统一平台编排多种能力类型(生成、推理、执行)。
架构概览
创意 Brief
↓
┌─────────────────────────────────────────────┐
│ Agent(Claude Sonnet 5 / GPT-4.1) │
│ │
│ 1. 解析 brief → 生成提示词 │
│ 2. 调 Seedream 5 Pro → 图片 URL │
│ 3. 写分析代码 │
│ 4. 在 E2B 沙盒执行 → 结果 │
│ 5. 综合报告 Artifact │
└─────────────────────────────────────────────┘
↓ ↓ ↓
Seedream E2B 沙盒 最终报告
(图片生成) (代码执行) (Artifact)
三种能力(图片生成、代码执行、LLM 推理)全部通过 SandBase 统一 API 层访问。
前置要求
pip install openai e2b-code-interpreter httpx Pillow
需要的凭证:
- SandBase API key(用于 Seedream 5 Pro + LLM)
- E2B API key(用于沙盒执行)
完整 Agent 代码
"""
多模态 Agent + Artifacts — E2B 沙盒
生成图片、用代码分析、产出报告。
"""
import json
from pathlib import Path
from datetime import datetime
from openai import OpenAI
from e2b_code_interpreter import Sandbox
# --- 配置 ---
SANDBASE_API_KEY = "your-sandbase-api-key"
E2B_API_KEY = "your-e2b-api-key"
OUTPUT_DIR = Path("./artifacts")
OUTPUT_DIR.mkdir(exist_ok=True)
# --- 客户端 ---
client = OpenAI(
base_url="https://api.sandbase.ai/v1",
api_key=SANDBASE_API_KEY,
)
# --- 步骤 1:解析 Brief → 生成参数 ---
def parse_brief(brief: str) -> dict:
"""用 LLM 将创意 brief 转为结构化生成参数。"""
response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{"role": "system", "content": """你是创意总监 AI。
将 brief 转为结构化图片生成提示。
输出 JSON:
{
"prompt": "详细的图片生成提示(英文,描述性)",
"negative_prompt": "需要避免的内容",
"aspect_ratio": "16:9 或 1:1 或 9:16",
"style": "photographic 或 illustration 或 3d-render",
"analysis_focus": ["color", "composition", "text_readability", "brand_fit"]
}
只输出 JSON。"""},
{"role": "user", "content": brief}
]
)
return json.loads(response.choices[0].message.content)
# --- 步骤 2:用 Seedream 生成图片 ---
def generate_image(prompt: str, negative_prompt: str = "",
aspect_ratio: str = "16:9") -> str:
"""通过 SandBase 用 Seedream 5 Pro 生成图片。"""
dimensions = {
"16:9": (1280, 720),
"1:1": (1024, 1024),
"9:16": (720, 1280),
}
width, height = dimensions.get(aspect_ratio, (1280, 720))
response = client.images.generate(
model="seedream-5-pro",
prompt=prompt,
n=1,
size=f"{width}x{height}",
extra_body={"negative_prompt": negative_prompt}
)
image_url = response.data[0].url
print(f"✓ 图片已生成:{image_url}")
return image_url
# --- 步骤 3:写分析代码 ---
def write_analysis_code(image_url: str, analysis_focus: list[str]) -> str:
"""用 LLM 根据关注点写图片分析代码。"""
focus_str = ", ".join(analysis_focus)
response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{"role": "system", "content": f"""你是图片分析 Python 开发者。
写一个完整的 Python 脚本:
1. 从提供的 URL 下载图片
2. 分析:{focus_str}
3. 产出 JSON 格式的结构化结果
要求:
- 用 PIL/Pillow 做图片分析
- 用 numpy 做数值计算
- 用 httpx 下载图片
- 将最终 JSON 结果 print 到 stdout
- 包含色彩分布(前 5 主色 hex 值)
- 包含基本构图指标(三分法对齐)
- 包含亮度/对比度统计
- 优雅处理错误
脚本必须自包含、可直接执行。
只输出 Python 代码,不要 markdown 围栏。"""},
{"role": "user", "content": f"分析图片 URL:{image_url}"}
]
)
code = response.choices[0].message.content
if code.startswith("```"):
code = code.split("\n", 1)[1].rsplit("```", 1)[0]
return code
# --- 步骤 4:在 E2B 沙盒执行 ---
def execute_in_sandbox(code: str) -> dict:
"""在 E2B 沙盒中运行分析代码并返回结果。"""
sandbox = Sandbox(api_key=E2B_API_KEY)
try:
# 安装依赖
sandbox.commands.run("pip install Pillow numpy httpx colorthief", timeout=30)
# 写入并执行脚本
sandbox.files.write("/home/user/analyze.py", code)
result = sandbox.commands.run("python /home/user/analyze.py", timeout=60)
if result.exit_code != 0:
print(f"⚠ 沙盒执行错误:{result.stderr}")
return {"status": "error", "error": result.stderr, "stdout": result.stdout}
try:
analysis = json.loads(result.stdout)
print("✓ 分析完成")
return {"status": "success", "analysis": analysis}
except json.JSONDecodeError:
return {"status": "partial", "raw_output": result.stdout}
finally:
sandbox.kill()
# --- 步骤 5:产出报告 Artifact ---
def generate_report(brief: str, params: dict, image_url: str,
analysis: dict) -> str:
"""用 LLM 从所有组件综合最终报告。"""
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": """你是创意分析 AI。
产出 Markdown 格式的专业报告 Artifact:
1. 执行摘要
2. Brief 解读
3. 生成图片引用
4. 技术分析结果(来自代码执行)
5. 迭代建议
6. 成本明细
要具体、可操作。引用分析中的实际数字。"""},
{"role": "user", "content": f"""
创意 Brief:{brief}
生成参数:
{json.dumps(params, indent=2, ensure_ascii=False)}
图片 URL:{image_url}
代码分析结果:
{json.dumps(analysis, indent=2, ensure_ascii=False)}
产出最终报告 Artifact。"""}
]
)
return response.choices[0].message.content
# --- 编排器 ---
def run_multimodal_agent(brief: str) -> Path:
"""运行完整多模态 Agent 管道。"""
print(f"\n{'='*60}")
print(f"🎨 多模态 Agent — 处理 Brief")
print(f"{'='*60}")
print(f"Brief:{brief}\n")
# 步骤 1:解析 brief
print("📋 步骤 1:解析 brief...")
params = parse_brief(brief)
print(f" 提示词:{params['prompt'][:60]}...")
print(f" 比例:{params['aspect_ratio']}")
print(f" 分析焦点:{params['analysis_focus']}")
# 步骤 2:生成图片
print("\n🖼️ 步骤 2:用 Seedream 5 Pro 生成图片...")
image_url = generate_image(
prompt=params["prompt"],
negative_prompt=params.get("negative_prompt", ""),
aspect_ratio=params.get("aspect_ratio", "16:9")
)
# 步骤 3:写分析代码
print("\n💻 步骤 3:写分析代码...")
code = write_analysis_code(image_url, params["analysis_focus"])
print(f" 生成 {len(code.split(chr(10)))} 行 Python")
# 步骤 4:沙盒执行
print("\n🔒 步骤 4:在 E2B 沙盒执行...")
sandbox_result = execute_in_sandbox(code)
if sandbox_result["status"] == "error":
print(f" ⚠ 执行失败,尝试修复...")
# 自修正:让 LLM 根据错误修复代码
fix_response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[
{"role": "system", "content": "修复此 Python 脚本。错误是:"
+ sandbox_result.get("error", "unknown")},
{"role": "user", "content": code}
]
)
fixed_code = fix_response.choices[0].message.content
if fixed_code.startswith("```"):
fixed_code = fixed_code.split("\n", 1)[1].rsplit("```", 1)[0]
sandbox_result = execute_in_sandbox(fixed_code)
# 步骤 5:生成报告
print("\n📊 步骤 5:生成报告 Artifact...")
report = generate_report(brief, params, image_url, sandbox_result)
# 保存 Artifact
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
artifact_path = OUTPUT_DIR / f"report_{timestamp}.md"
artifact_path.write_text(report)
code_path = OUTPUT_DIR / f"analysis_{timestamp}.py"
code_path.write_text(code)
print(f"\n{'='*60}")
print(f"✅ Artifact 已保存:{artifact_path}")
print(f" 分析代码:{code_path}")
print(f" 图片:{image_url}")
print(f"{'='*60}\n")
return artifact_path
# --- 成本追踪 ---
def estimate_pipeline_cost() -> dict:
"""估算一次完整管道运行的成本。"""
return {
"Brief 解析 (GPT-4.1-mini)": "$0.002",
"图片生成 (Seedream 5 Pro)": "$0.03",
"代码编写 (GPT-4.1-mini)": "$0.003",
"沙盒执行 (E2B)": "$0.005",
"报告综合 (GPT-4.1)": "$0.015",
"总计估算": "$0.055"
}
# --- 主函数 ---
if __name__ == "__main__":
briefs = [
"为高端智能手机发布会创建主视觉。手机悬浮效果配戏剧性灯光。"
"目标受众:科技爱好者 25-40 岁。品牌色:深蓝和银色。",
"设计夏日咖啡系列的社媒 Banner。生活方式感,暖色调,户外咖啡馆场景。"
"需要同时适用 16:9 和 1:1 裁切。",
]
artifact = run_multimodal_agent(briefs[0])
print("\n💰 成本明细:")
for item, cost in estimate_pipeline_cost().items():
print(f" {item}:{cost}")
生态组合的工作方式
这个 Agent 使用三种不同能力类型,全部通过 SandBase:
1. LLM 推理(GPT-4.1-mini / GPT-4.1)
client.chat.completions.create(model="gpt-4.1-mini", ...)
用于:brief 解析、代码生成、报告综合。
2. 图片生成(Seedream 5 Pro)
client.images.generate(model="seedream-5-pro", ...)
用于:从提示词创建视觉资产。
关于 SandBase 上可用的图片生成 API,包括 Seedream、Qwen Image 等。
3. 代码执行(E2B 沙盒)
sandbox = Sandbox(api_key=E2B_API_KEY)
sandbox.commands.run("python analyze.py")
用于:安全运行不受信任的分析代码。
Agent 决定生成什么、分析什么、怎么呈现结果。平台提供能力。这种分离是生态组合的核心。
自修正模式
注意步骤 4 的错误处理:
if sandbox_result["status"] == "error":
# 让 LLM 根据错误消息修复代码
fix_response = client.chat.completions.create(...)
fixed_code = fix_response.choices[0].message.content
sandbox_result = execute_in_sandbox(fixed_code)
这是”生成 → 执行 → 修复 → 重执行”循环,让 Agent 比静态管道更强大。LLM 看到沙盒执行的实际错误并调整。实践中这能捕获:
- 导入错误(缺包 → 加 pip install)
- URL 访问问题(超时 → 加重试逻辑)
- 数据格式不匹配(意外图片格式 → 加转换)
成本分析
每次完整管道运行:
| 步骤 | 模型/服务 | 估算成本 |
|---|---|---|
| Brief 解析 | GPT-4.1-mini (~800 输入, 200 输出) | $0.002 |
| 图片生成 | Seedream 5 Pro (1 张) | $0.03 |
| 代码编写 | GPT-4.1-mini (~500 输入, 1000 输出) | $0.003 |
| 沙盒执行 | E2B (~30s 运行时) | $0.005 |
| 报告综合 | GPT-4.1 (~3000 输入, 800 输出) | $0.015 |
| 总计 | ~$0.055 |
规模化:
10 个 brief/天:$0.55/天 → $16.50/月
50 个 brief/天:$2.75/天 → $82.50/月
200 个 brief/天:$11/天 → $330/月
对比人类创意分析师:$80–150/小时。一个 brief 分析手动需 30–60 分钟。Agent 不到 2 分钟完成,成本 $0.055。
扩展到视频
同样的模式适用于视频生成——只需替换步骤 2:
def generate_video(prompt: str) -> str:
"""通过 SandBase 用 Kling 或 MiniMax 生成视频。"""
# 视频生成是 async(需 30-120s)
response = client.chat.completions.create(
model="kling-video-3-standard",
messages=[{"role": "user", "content": json.dumps({
"prompt": prompt,
"duration": 5,
"aspect_ratio": "16:9"
})}],
extra_body={"sandbase_api": "kling/video/generation"}
)
# 轮询等待完成...
return video_url
详细的视频生成 Agent 教程见广告创意 Agent 指南。
生产模式
批量处理
import asyncio
async def process_batch(briefs: list[str]) -> list[Path]:
"""并发处理多个 brief。"""
tasks = [asyncio.to_thread(run_multimodal_agent, brief) for brief in briefs]
results = await asyncio.gather(*tasks, return_exceptions=True)
return [r for r in results if isinstance(r, Path)]
Artifact 版本管理
class ArtifactStore:
def __init__(self, base_dir: Path):
self.base_dir = base_dir
def save(self, brief_id: str, version: int, report: str,
image_url: str, code: str) -> Path:
artifact_dir = self.base_dir / brief_id / f"v{version}"
artifact_dir.mkdir(parents=True, exist_ok=True)
(artifact_dir / "report.md").write_text(report)
(artifact_dir / "analysis.py").write_text(code)
(artifact_dir / "metadata.json").write_text(json.dumps({
"image_url": image_url,
"timestamp": datetime.now().isoformat(),
"version": version
}))
return artifact_dir
人在环中迭代
def iterate_with_feedback(brief: str, feedback: str,
previous_report: str) -> Path:
"""接入人类反馈重新运行 Agent。"""
enhanced_brief = f"""
原始 brief:{brief}
上一版输出摘要:{previous_report[:500]}
人类反馈:{feedback}
生成改进版本。
"""
return run_multimodal_agent(enhanced_brief)
展示的关键模式
- 生态组合: 一个 Agent 用 LLM + 图片生成 + 代码沙盒。无需分别集成。
- 自修正: Agent 用沙盒反馈修复自己的代码错误。
- Artifact 产出: 输出是结构化文档,不只是文本——包含引用、分析和建议。
- 成本可预测: 每步成本已知。总管道有界可追踪。
- 能力分离: Agent 决定做什么。平台提供怎么做。见自主 Agent 最佳模型的模型选择指导。
这个模式可扩展到任何组合 生成 + 分析 + 执行 的工作流。把”图片”替换为”视频”、“文档”或”数据可视化”,架构保持不变。


