图片编辑正在从“打开专业软件、找按钮、调参数”变成“上传照片,说一句要改什么,然后等结果”。这篇内容介绍的是一个基于 Amazon Bedrock AgentCore harness 的无服务器图片编辑 Agent:用户上传图片,用自然语言描述编辑需求,系统在几秒内返回处理后的图片。关键点不是单个模型调用,而是把认证、加密存储、三类图片编辑工具、Agent 运行时和 React 前端用 AWS CDK 统一部署起来。
AgentCore harness 解决的不是模型,而是编排负担
传统做法里,开发者通常要自己写一层编排代码:解析用户意图、选择工具、调用图片处理接口、管理中间文件、处理错误、返回结果。这个示例的核心变化是把 Agent 跑在 AgentCore harness 上,让 harness 承担工具调用和执行流的基础工作,应用代码更关注“有哪些工具可以用”和“用户体验如何闭环”。
在这个图片编辑场景里,Agent 至少要处理四类事情:
- 接收用户上传的原图;
- 理解自然语言编辑指令,例如“把背景换成海边”或“提高亮度并裁成正方形”;
- 在多个图片编辑工具之间选择合适动作;
- 把结果写入加密存储,并让前端拿到可展示的输出。
这类系统适合无服务器架构,因为请求天然是离散的:一次上传、一次编辑、一次返回。没有必要为了空闲时间维护固定服务器,但要认真处理冷启动、文件大小、调用超时和权限边界。
一条部署命令背后有哪些组件
来源摘要强调完整方案可以通过单条部署命令交付,基础设施用 AWS CDK 定义。这一点对团队落地很重要:图片编辑 Agent 不只是一个 Lambda 函数,它还需要一组配套资源。
通常可以这样拆解这个系统:
- 认证:限制谁能上传和编辑图片;
- 加密存储:保存原图、处理过程文件和最终结果;
- Agent 运行环境:托管自然语言到工具调用的执行流程;
- 图片编辑工具:暴露给 Agent 的三个可调用能力;
- 前端:React 页面负责上传、输入指令、轮询或接收结果。
CDK 的价值在这里很直接:把权限、存储桶、前端托管、函数或工具端点这些资源放在同一个版本库里。开发者可以 review 基础设施变更,也可以在不同环境里重复部署。
可以这样实践:用 CDK 固化部署入口
下面是一个可改造的最小项目骨架,用来表达“单命令部署”的工作方式。具体 AgentCore harness、图片工具和前端实现需要按你的 AWS 账号、区域和服务配置补齐;这里的重点是把部署入口、环境参数和资源边界固定下来。
运行前需要替换:
AWS_REGION:你的部署区域;PROJECT_NAME:项目名;- CDK stack 中的具体资源定义;
- 前端构建产物路径。
mkdir bedrock-image-agent
cd bedrock-image-agent
npm init -y
npm install aws-cdk-lib constructs
npm install -D aws-cdk typescript ts-node @types/node
npx cdk init app --language typescript
可以在 package.json 里放一个清晰的部署命令:
{
"scripts": {
"build": "tsc",
"deploy:dev": "PROJECT_NAME=image-agent AWS_REGION=us-east-1 npx cdk deploy --all",
"diff": "npx cdk diff --all",
"destroy:dev": "PROJECT_NAME=image-agent AWS_REGION=us-east-1 npx cdk destroy --all"
}
}
一个简化的 CDK Stack 可以这样组织。下面代码是可改造示例,展示加密存储和最小权限思路,不声称覆盖原方案中的全部 AgentCore 资源。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';
export class ImageAgentStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const projectName = process.env.PROJECT_NAME ?? 'image-agent';
const imageBucket = new s3.Bucket(this, 'EncryptedImageBucket', {
bucketName: `${projectName}-${this.account}-${this.region}`,
encryption: s3.BucketEncryption.S3_MANAGED,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
enforceSSL: true,
versioned: true,
lifecycleRules: [
{
prefix: 'tmp/',
expiration: cdk.Duration.days(1)
}
],
removalPolicy: cdk.RemovalPolicy.RETAIN
});
const agentToolRole = new iam.Role(this, 'AgentToolRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
});
imageBucket.grantReadWrite(agentToolRole);
new cdk.CfnOutput(this, 'ImageBucketName', {
value: imageBucket.bucketName
});
}
}
部署时先看 diff,再执行部署:
npm run build
npm run diff
npm run deploy:dev
如果你要把这个骨架扩展成完整方案,可以继续加入:认证资源、AgentCore harness 配置、三个图片编辑工具的执行端点、React 前端构建和静态托管资源。
工具设计决定 Agent 是否可靠
图片编辑 Agent 很容易做成“什么都能说,什么都不稳定”。更稳的做法是把工具定义得窄而清楚。比如三类工具可以分别覆盖:
- 调整类:亮度、对比度、裁剪、旋转;
- 生成类:替换背景、移除物体、扩展画布;
- 输出类:压缩、格式转换、生成缩略图。
每个工具都应该有明确输入和输出,而不是把一整段用户文本原样塞给后端。可以这样设计工具请求结构:
{
"image_key": "uploads/user-123/source.jpg",
"operation": "replace_background",
"parameters": {
"background_prompt": "a clean beach at sunset",
"preserve_subject": true
},
"output_key": "results/user-123/job-456.png"
}
这个结构有几个好处:前端能跟踪任务,后端能做权限校验,存储路径能审计,失败时也能重试某一步。Agent 可以负责把自然语言转成结构化调用,但真正执行工具时,仍然要用服务端规则兜底。
落地前的检查清单
这类方案适合快速做出可用体验,但生产化时要盯住边界。
- 权限:Agent 工具只能访问当前用户或当前任务允许的对象;
- 存储:原图和结果图要加密,临时文件要设置生命周期;
- 成本:图片生成和编辑可能比普通文本调用更贵,需要设置大小限制和频率限制;
- 延迟:几秒返回是体验目标,但大图、复杂编辑和冷启动都会拉长耗时;
- 安全:上传内容要校验类型和大小,输出链接不要公开裸奔;
- 可观测性:记录 job id、工具名、耗时、失败原因,但避免把敏感图片内容写入日志。
我的建议是先按“一个用户上传、一条编辑指令、一个结果页面”打通闭环,再扩展批量处理、历史记录和高级编辑。AgentCore harness 的价值在于减少自写编排代码,但工具边界、权限模型和存储策略仍然是工程质量的主战场。