mcpField
A
agents-harden

agents-harden

github.com/aws安全3.3k2.0k 次安装1 天前更新
代码仓库

关于 agents-harden

agents-harden 是面向准备将 AgentCore Agent 部署到生产环境的开发者的技能。它读取项目配置,针对安全性、可靠性和性能生成检查清单。

主要功能

  1. 01生成项目专属的生产检查清单
  2. 02提供 IAM 权限范围收紧建议
  3. 03检查入站身份验证配置
  4. 04检查错误处理与输入验证
  5. 05提供密钥和速率限制建议

适用场景

  1. 01在发布前审查 AgentCore Agent
  2. 02限制可调用 Agent 的主体
  3. 03排查限流或配额错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/aws/agent-toolkit-for-aws --skill agents-harden

安装后在 Claude Code 中输入/agents-harden确认已加载。

附带文件references/limits.md

详细介绍

强化

让你的 AgentCore Agent 做好生产环境部署准备——提升安全性、可靠性和性能。

适用场景

  • 即将将 Agent 部署到生产环境
  • 想要一份上线前的检查清单
  • 想要限制哪些人可以调用 Agent
  • 想要缩减默认 IAM 权限
  • 遇到限流或配额错误(会加载 references/limits.md)
  • 需要针对工作负载调整会话生命周期
  • Agent 中运行着长时间的后台任务

输入

无需参数。此技能会读取项目配置,并生成针对项目的检查清单,其中包含具体发现。

流程

步骤 0:验证 CLI 版本

运行 agentcore --version。此技能要求版本为 v0.9.0 或更高。如果版本较旧,请告知开发者先运行 agentcore update。

步骤 1:读取项目

读取 agentcore/agentcore.json,了解:

  • 配置了哪些资源(memory、gateway、credentials、evaluators)
  • 使用了什么框架
  • 配置了哪种网络模式(PUBLIC 或 VPC)
步骤 2:逐项检查清单

逐类检查,并报告针对项目的发现。


IAM:缩减权限范围

自动创建的执行角色拥有广泛的 Bedrock 访问权限(arn:aws:bedrock:*::foundation-model/*)。对于生产环境,应将权限范围缩减至 Agent 使用的特定模型。

检查当前执行角色:

agentcore status --json | jq -r '.runtimes[0].executionRoleArn'

推荐的生产环境 Bedrock 策略:

{
  "Effect": "Allow",
  "Action": [
    "bedrock:InvokeModel",
    "bedrock:InvokeModelWithResponseStream"
  ],
  "Resource": [
    "arn:aws:bedrock:<REGION>::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0"
  ]
}

将资源 ARN 替换为 Agent 使用的特定模型 ARN。

**ECR 访问权限:**将范围缩减至特定存储库:

{
  "Effect": "Allow",
  "Action": ["ecr:BatchGetImage", "ecr:GetDownloadUrlForLayer"],
  "Resource": "arn:aws:ecr:<REGION>:<YOUR_ACCOUNT_ID>:repository/bedrock-agentcore-<AGENT_NAME>-*"
}

**信任策略:**确认执行角色的信任策略已限定为你的账户:

{
  "Principal": {"Service": "bedrock-agentcore.amazonaws.com"},
  "Action": "sts:AssumeRole",
  "Condition": {
    "StringEquals": {"aws:SourceAccount": "<YOUR_ACCOUNT_ID>"},
    "ArnLike": {"aws:SourceArn": "arn:aws:bedrock-agentcore:<REGION>:<YOUR_ACCOUNT_ID>:*"}
  }
}

运行时基于资源的策略(仅限 API):如需精细控制哪些主体可以调用运行时(超出 IAM 角色和 JWT 身份验证所能提供的控制范围),请通过 boto3 使用 PutAgentRuntimeResourcePolicy。CLI 和 agentcore.json 中均未提供此功能。如有可用的 awsknowledge MCP 服务,可用它查询当前 API 格式。


Shell 访问:单独限制 InvokeAgentRuntimeCommand 的权限范围

如果项目使用了 InvokeAgentRuntimeCommand(参见 agents-build/references/integrate.md),请将其 IAM 权限与 InvokeAgentRuntime 分开审查。这两个操作的影响范围不同:InvokeAgentRuntimeCommand 可在运行中的 microVM 内执行任意 Shell 命令,并拥有运行时的全部执行角色权限——调用方可以读取或写入文件系统、访问 Agent 能访问的任何网络资源,以及使用执行角色的凭证。

检查哪些主体拥有此权限:

# List customer-managed policies in your account, then inspect each for InvokeAgentRuntimeCommand
aws iam list-policies --scope Local \
  --query 'Policies[*].[PolicyName, Arn, DefaultVersionId]' \
  --output table
# Then for each policy of interest:
aws iam get-policy-version \
  --policy-arn <POLICY_ARN> \
  --version-id <VERSION_ID> \
  --query 'PolicyVersion.Document'

或者使用 IAM 控制台:IAM → Policies → 按类型筛选:Customer managed → 在策略 JSON 编辑器中搜索 InvokeAgentRuntimeCommand。

为命令调用方创建单独的 IAM 策略——将此策略与授予 InvokeAgentRuntime 权限的策略分开:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "bedrock-agentcore:InvokeAgentRuntimeCommand",
    "Resource": "arn:aws:bedrock-agentcore:<REGION>:<YOUR_ACCOUNT_ID>:runtime/<RUNTIME_NAME>-*"
  }]
}

**启用 CloudTrail 告警。**创建 EventBridge 规则,在调用 InvokeAgentRuntimeCommand 时通知安全团队:

aws events put-rule \
  --name AgentCoreCommandExecution \
  --event-pattern '{"source":["aws.bedrock-agentcore"],"detail-type":["AWS API Call via CloudTrail"],"detail":{"eventName":["InvokeAgentRuntimeCommand"]}}' \
  --state ENABLED

**如果调用代码中的任何位置会根据用户输入构造命令:**传递命令前先进行验证——拒绝包含 &&、;、$(...)、反引号、| 或其他 Shell 元字符的字符串。


入站身份验证:控制哪些人可以调用你的 Agent

默认情况下,Agent 使用 AWS IAM(SigV4)进行入站身份验证。对于生产环境,请确认配置正确。

检查当前身份验证配置:

agentcore status --runtime <AgentName> --json | jq '.runtimes[0].authorizerConfig'

选项:

AWS_IAM(默认)— 调用方必须使用 SigV4 对请求签名。适用于内部服务和原生支持 AWS 的客户端。

CUSTOM_JWT — 调用方提供来自身份提供商的 JWT。适用于 Web/移动应用和外部客户端。

agentcore add agent \
  --name MyAgent \
  --authorizer-type CUSTOM_JWT \
  --discovery-url https://your-idp.example.com/.well-known/openid-configuration \
  --allowed-audience my-api \
  --allowed-clients my-client-id

警告

切勿在生产环境中使用 --authorizer-type NONE。这会允许未经身份验证的访问 你的 Agent — 任何知道端点 URL 的人都可以调用它。始终使用 AWS_IAM 或 CUSTOM_JWT。如果你在生产环境中看到 NONE,请立即更改。

选择 allowedClients 还是 allowedAudience

这是最常见的 JWT 配置错误。正确选择取决于身份提供商签发的令牌中包含哪些内容。

解码一个示例令牌(在身份提供商处或使用 jwt.io),并查看载荷:

  • 令牌包含 client_id 声明,但不包含 aud 声明 → 在运行时配置 allowedClients
  • 令牌包含 aud 声明 → 在运行时配置 allowedAudience
  • 令牌同时包含两者 → 使用 allowedAudience。aud 声明是标准的 OIDC 受众字段;将其作为主要检查项。

如果选择错误,即使令牌有效,调用也会返回 403 — 运行时正在根据令牌中不存在的声明进行验证。

颁发者 ↔ 发现 URL 前缀要求

AgentCore 强制执行 OIDC 发现规范(RFC 8414 §3):发现文档中的 issuer 值必须是发现端点 URL 的前缀。

这意味着,如果你的发现 URL 是 https://qa.example.com/.well-known/openid-configuration,该文档中的 issuer 字段必须以 https://qa.example.com 开头。如果文档公布的颁发者类似 https://example.com(没有子域名),验证就会失败。

一些企业身份提供商(PingFederate、Paylocity 和某些 Keycloak 配置)会将发现端点托管在特定环境的子域名上,同时公布生产级颁发者。这种模式与 RFC 8414 的前缀规则不兼容。

修复选项:

  1. 让身份提供商的发现端点与其颁发者保持一致 — 从与颁发者相同的源提供发现文档。
  2. 将运行时指向实际的发现 URL 域名 — 使用与令牌颁发者相匹配的子域名配置运行时的发现 URL。
调试 JWT 身份验证失败

调用返回 403 时,请逐步确定是哪项检查失败。

Authorization method mismatch — 运行时的身份验证类型与请求的身份验证类型不匹配。分两种情况:

  • 运行时配置为 AWS_IAM(或未配置授权器),但调用方发送了 Bearer 令牌 → 将运行时重新配置为 CUSTOM_JWT,或让调用方使用 SigV4。
  • 运行时配置为 CUSTOM_JWT,但调用方的请求由 SigV4 签名 → SDK 或环境可能在 Bearer 令牌旁注入了 SigV4 标头。检查发出的请求中是否包含 X-Amz-Date、X-Amz-Security-Token 或 Authorization: AWS4-HMAC-SHA256。移除 SigV4 路径,只发送 Bearer 令牌。

Invalid inbound token(或类似错误)— JWT 验证器拒绝了令牌。按以下顺序逐项检查:

  1. 颁发者 ↔ 发现 URL 前缀(见上文)— 确认令牌的 iss 声明与发现 URL 的源匹配
  2. allowedClients 还是 allowedAudience — 运行时是否根据令牌格式配置了正确的声明?
  3. JWKS 可访问性 — AgentCore 是否能访问发现文档中列出的 jwks_uri?该地址必须可公开访问。
  4. 令牌已过期 — 解码令牌,检查 exp 是否早于当前时间
  5. 签名算法支持情况 — 某些身份提供商使用并非普遍支持的算法(PS256、ES384 等)签名。检查身份提供商支持的算法;如果兼容性是问题,请切换到 RS256。

只有排除以上所有原因后,才应将其视为服务端问题。


错误处理:优雅地处理错误

检查 Agent 代码能否在不暴露内部细节的情况下处理错误:

from bedrock_agentcore.runtime import BedrockAgentCoreApp

app = BedrockAgentCoreApp()

@app.entrypoint
def invoke(payload, context):
    try:
        # your agent logic
        return {"response": result}
    except Exception as e:
        # Log the full error internally
        app.logger.error(f"Agent error: {e}", exc_info=True)
        # Return a safe message to the caller
        return {"error": "An error occurred. Please try again."}

if __name__ == "__main__":
    app.run()

检查内容: 会静默吞掉错误的裸 except 块、向调用者暴露堆栈跟踪或内部细节的错误消息、工具调用代码中缺少错误处理。


输入验证和速率限制

Agent 入口点会收到调用者发送的任意负载。处理前请验证输入:

@app.entrypoint
def invoke(payload, context):
    prompt = payload.get("prompt", "")

    # Validate input
    if not prompt or not isinstance(prompt, str):
        return {"error": "Missing or invalid 'prompt' field"}
    if len(prompt) > 10000:
        return {"error": "Prompt exceeds maximum length (10,000 characters)"}

    # Sanitize — strip control characters, excessive whitespace
    prompt = " ".join(prompt.split())

    # Proceed with validated input
    result = agent(prompt)
    return {"response": str(result)}

验证内容:

  • 必填字段是否存在,且类型是否符合预期
  • 字符串输入是否超过合理的长度限制(防止模型遭到令牌轰炸)
  • 数值输入是否在预期范围内
  • 用户提供的 ID(actor_id、session_id)是否符合预期格式

速率限制: AgentCore Runtime 内置调用速率限制(每个 Agent 默认 25 TPS;参见 references/limits.md)。如需应用级速率限制(按用户、按租户),请在调用应用或 API Gateway 层实现,而不要在 Agent 代码本身中实现。请求到达 Agent 时,Agent 应假定请求已经过速率限制。


密钥:代码中不得包含凭据,运行时环境变量中不得包含密钥

请检查以下两种失误:

1. Agent 代码中的硬编码密钥
# Search for common secret patterns in agent code
grep -r "sk-\|api_key\s*=\s*['\"]" app/ --include="*.py"
grep -r "password\s*=\s*['\"]" app/ --include="*.py"
2. 从运行时环境变量中读取的密钥

AgentCore Runtime 环境变量不受保险库保护。开发者通过 CDK、boto3 UpdateAgentRuntime 或类似方式写入运行时环境的任何内容,都是明文配置值,而不是密钥。检查以下模式:

# Flag any os.getenv / os.environ call whose name implies a secret
grep -rE "os\.(getenv|environ).*(TOKEN|SECRET|KEY|PASSWORD|CREDENTIAL)" app/ --include="*.py"

平台注入的非敏感标识符不受影响,不应与允许列表匹配(例如,MEMORY_*_ID、AGENTCORE_GATEWAY_*_URL、AWS_REGION、下游 Agent ARN)。请检查匹配项,并确认其中不包含密钥。

正确做法: 使用 agentcore add credential 注册每个出站凭据,然后通过集成的凭据提供方在代码中获取:

from bedrock_agentcore.identity.auth import requires_api_key, requires_access_token

@requires_api_key(provider_name="MyAPI")
def call_api(payload: dict, *, api_key: str) -> dict:
    ...

@requires_access_token(provider_name="MyOAuthProvider", scopes=["read"], auth_flow="M2M")
async def call_downstream(data: dict, *, access_token: str) -> dict:
    ...

装饰器会在调用时从 Secrets Manager 获取凭据,并处理缓存和刷新。以这种方式注册的凭据在静态存储时会加密,并且可以在无需重新部署的情况下轮换。

本地开发: agentcore/.env.local(已加入 gitignore)会由 agentcore dev 读取,以便装饰器在本地解析凭据。部署时不会将此文件上传到运行时;生产凭据由凭据提供方管理。


工具范围:在 Agent 代码中优先使用 Gateway 目标,而非直接 HTTP 调用

相关审计——对于 Agent 调用的每项外部服务,都要确认是否应将其设为 Gateway 目标,而不是在 Agent 代码中埋入直接 HTTP 调用。Gateway 的凭证提供程序会在边缘注入身份验证信息(因此 Agent 进程永远不会接触密钥),工具目录可通过策略强制执行;而且,即使 Agent 代码中的堆栈跟踪或日志行泄露,也无法泄露从未传到其中的凭证。

# Find direct outbound HTTP calls in agent code
grep -rEn 'httpx\.|requests\.|aiohttp\.' app/ --include="*.py"

对于每个匹配项,请按以下方式判断:

匹配项操作
调用外部 REST API,且 Agent 将其视为工具将其设为 Gateway 目标(agentcore add gateway-target --type open-api-schema 或 api-gateway)。加载 agents-connect/SKILL.md 路径 C。
直接调用 MCP 服务将其设为 Gateway 目标(--type mcp-server)。加载 agents-connect/SKILL.md 路径 A。
调用 AWS 服务(S3、DynamoDB 等)——不适合归入此行,应使用 boto3将 requests/httpx 迁移为 boto3 客户端,并使用运行时的执行角色进行 IAM 身份验证。无需凭证。
调用流式服务(SSE 实时输出、WebSocket、WebRTC)可以保留直接调用——Gateway 目前还不支持这些服务。确认任何身份验证都使用 @requires_*,而非 os.getenv。
通过 A2A 调用其他 Agent可以保留直接调用——A2A 的设计本就基于 HTTP。确认它使用 @requires_access_token 获取承载令牌。
调用经测量确认为延迟热点且团队选择保留的路径可以保留,但要确认已有测量,并且身份验证使用 @requires_*。

如果某个匹配项不符合任何“可以保留直接调用”的行,请创建工单,将其转换为 Gateway 目标。对于大多数框架集成,无需修改 Agent 代码即可添加 Gateway 目标(MCP 工具发现会处理绑定)。


可观测性:验证跟踪已启用

AgentCore 会自动启用 X-Ray 跟踪和 CloudWatch 日志记录。请验证:

agentcore status --runtime <AgentName> --json | jq '.runtimes[0].observabilityConfig'

CloudWatch 控制面板: AWS 控制台 → CloudWatch → GenAI Observability → Bedrock AgentCore

日志保留: 默认情况下,日志会无限期保留。设置保留策略以控制成本:

aws logs put-retention-policy \
  --log-group-name /aws/bedrock-agentcore/runtimes/<AGENT_ID>-DEFAULT \
  --retention-in-days 30

评估基线:上线前了解质量水平

投入生产前,先建立质量基线,以便检测回归:

# Run a baseline eval
agentcore run eval \
  --evaluator "Builtin.Helpfulness" \
  --evaluator "Builtin.GoalSuccessRate"

# Set up continuous monitoring
agentcore add online-eval \
  --name production_monitor \
  --runtime <AgentName> \
  --evaluator "Builtin.Helpfulness" \
  --sampling-rate 5
agentcore deploy -y

记录基线分数。如果变更后分数大幅下降,请先调查再继续。


网络:为私有资源配置 VPC

如果 Agent 需要访问私有 AWS 资源(RDS、内部 API),请配置 VPC:

agentcore add agent \
  --name MyAgent \
  --network-mode VPC \
  --subnets subnet-abc,subnet-def \
  --security-groups sg-123

完整的 VPC 配置指南请参阅 agents-build(加载 references/vpc.md)。


初始化时间:优化冷启动性能

Agent 初始化缓慢会导致超时、424 错误和糟糕的用户体验,尤其是在一段时间未活动后首次调用时。Agent 在准备好处理请求前执行的所有操作,都会延长用户的等待时间。

冷启动时间实际花在哪里

新环境的典型冷启动时间约为 20–30 秒。大致分解如下:

  • 容器映像拉取——对于基于 Container 的构建,这是最主要的耗时。100 MB 的映像需要几秒;500 MB 的映像可能需要 15 秒以上。
  • 应用程序启动——代码的导入时间、框架初始化、模块级设置。通常需要 5–10 秒;如果在导入时加载模型或建立连接,耗时可能会长得多。
  • 平台开销(microVM 启动、网络连接、容器启动)——不到一秒到几秒不等。

你能控制的两项是映像大小和应用程序启动时间。优化其中任意一项都能直接缩短首次响应时间。

会话复用是最具杠杆效应的优化

同一会话中的请求会路由到已初始化的现有环境,无需冷启动。每个会话的首次请求需要承担冷启动开销;该会话后续的每个请求都能快速处理。

具体模式:

  • 多轮对话: 在各轮之间复用同一个 session_id。不要每轮都生成新的 UUID。
  • 批处理: 在批次中的各项之间复用同一个 session_id。
  • 面向用户的应用: 将会话范围限定为一次用户交互(例如,每次聊天对话使用一个会话),而不是每条消息使用一个会话。

跨 SDK 提示:如果使用 MCP,请传递一个会话标识符,不要同时传递 runtimeSessionId 和 mcpSessionId。同时发送两者可能导致平台将两个独立环境绑定到同一个逻辑会话,使冷启动开销翻倍。

软件包大小预算

部署软件包每增加 1 MB,都会增加冷启动时间。

  • 目标: 小于 200 MB。如果可以,尽量控制在 100 MB 以下。
  • 对于 Container 构建: 使用多阶段 Dockerfile、精简或 distroless 基础映像,移除构建工具和测试文件,并添加 .dockerignore。
  • 对于 CodeZip 构建: 从 pyproject.toml / requirements.txt 中删减开发依赖项。不要打包 tests/、docs/、.git/ 和本地缓存。
  • 定期审查: pip list(Python)或 npm ls(Node)可以显示实际安装的内容。移除所有不再使用的内容。
延迟繁重的初始化操作

不要在模块导入时加载大型模型、连接数据库或初始化 MCP 客户端。模块导入耗费的每一秒,都会让 Agent 多一秒无法响应请求。

# ❌ Slow — runs at import time, before the agent can handle requests
import heavy_library
client = heavy_library.Client(config)

# ✅ Fast — defers until first request
_client = None
def get_client():
    global _client
    if _client is None:
        import heavy_library
        _client = heavy_library.Client(config)
    return _client
根据流量模式选择部署类型,而不是默认选择

该技能之前建议尽可能优先选择 CodeZip,而不是 Container。这种说法过于简单。实际的权衡如下:

  • CodeZip: 迭代更简单,涉及范围更小。冷启动包括下载和解压代码——一个约 95 MB 的软件包会增加约 1.3 秒的平台下载时间,之后应用才会开始启动。
  • Container: 可以完全控制映像,需要自定义系统依赖项时必须使用。较大的映像会增加每次冷启动的成本,但可以通过多阶段构建进行大幅优化。

两者并非在所有情况下都各有优劣。两者都能同样受益于会话复用和缩小软件包。如果流量模式中有大量突发的冷会话,请投入精力缩小所用的部署制品。如果流量模式会复用会话,部署类型的重要性就小得多。

对于 Gateway 后面的 Lambda 目标

在 Lambda 函数上使用预置并发,以消除 Lambda 冷启动。这与 Runtime 初始化不同——首次调用冷 Lambda 时,是 Lambda 本身增加了延迟。


会话生命周期管理

会话管理与成本、性能以及 maxVms 配额密切相关。正确管理会话,往往是顺利上线生产环境与被配额阻塞之间的关键区别。

默认生命周期

收到带有新会话 ID 的请求时,Runtime 会为其初始化一个全新环境。该环境会一直运行,直到发生以下情况之一:

  1. 会话被显式停止,通过 StopRuntimeSession 实现。
  2. 空闲超时到期。 Runtime 会回收在 idleRuntimeSessionTimeout 指定的时间内(默认为 900 秒)未收到请求的环境。
  3. 达到最长生命周期(maxLifetime,默认为 8 小时)。

空闲环境在被回收之前仍会占用 maxVms 配额,即使它们没有处理流量。这是意外出现 maxVms 错误的首要原因。

根据工作负载特点选择超时

生产环境不要使用默认值。应根据工作负载实际使用会话的方式选择合适的值:

工作负载idleRuntimeSessionTimeoutmaxLifetime原因
交互式聊天 / 支持 Agent600–900s(默认)3600–7200s用户会暂停阅读或思考。用户离开后应快速回收。
无后续请求的请求/响应 API60–120s1800s每次调用都独立完成,因此应尽快释放 VM。
批处理,每项作业使用一个会话120s与作业时长相符,并留出缓冲批次中各项任务之间的空闲间隔很短;应在作业之间积极回收。
后台 / 长时间运行的任务(使用 add_async_task)120–300s最长 28800s(8h)异步任务 API 会在受跟踪的工作期间保持 VM 运行;空闲超时适用于任务之间。

权衡一览:

  • 较短的空闲超时 = maxVms 下有更多余量,成本更低。风险: 会话中途被回收,导致下一轮需要冷启动。
  • 较长的空闲超时 = 会话保持预热,延迟更低。风险: 空闲 VM 会占用配额;突发流量时可能出现 maxVms 错误。
  • 较短的最长生命周期 = 可预测地回收,可限制内存泄漏 / 过时状态。风险: 活跃的长会话可能在流程中途被终止。
  • 较长的最长生命周期 = 会话保持稳定,可大幅节省预热状态的开销。风险: 状态漂移、内存中的状态过时,且更难逐步发布。
最佳实践

工作完成后调用 StopRuntimeSession。 如果 Agent 已完成任务,且预计该会话不会再收到请求,请主动停止会话。这样可以立即释放环境,而不是等待空闲超时。

# After your invocation logic completes and you know the session is done:
client.stop_runtime_session(
    agentRuntimeArn=runtime_arn,
    runtimeSessionId=session_id,
)

为相关工作复用会话 ID。 每个 HTTP 请求都使用新的会话 ID,就意味着每个 HTTP 请求都会创建新环境。对于多轮对话、批处理作业或面向用户的交互,每个对话 / 批次 / 用户交互使用一个会话 ID,并将所有相关请求路由到该 ID。

根据工作负载调整 idleRuntimeSessionTimeout。 默认值 900 秒适用于预期会快速收到后续请求的交互式工作负载。对于会话生命周期较短的请求/响应工作负载,应调低该值。

编辑 agentcore/agentcore.json 中运行时对应的条目:

{
  "runtimes": [
    {
      "name": "MyAgent",
      "lifecycleConfiguration": {
        "idleRuntimeSessionTimeout": 120,
        "maxLifetime": 3600
      }
    }
  ]
}

然后运行 agentcore deploy 以应用更改。CLI 和 CDK 会为你处理底层的 UpdateAgentRuntime 调用。

如果你更倾向于使用 CLI,agentcore add agent ... --idle-timeout 120 --max-lifetime 3600 会将相同字段写入 agentcore.json。该文件是唯一可信来源,其中的每个字段都可通过文件顶部的 $schema URL(https://schema.agentcore.aws.dev/v1/agentcore.json)获得 IDE 自动补全。

超时越短 = VM 回收越快 = maxVms 下有更多余量。超时过短 = 环境会在会话中途被回收,导致下一轮需要冷启动。

不要同时传入 runtimeSessionId 和 mcpSessionId。 对于 MCP Agent,只使用其中一个。同时传入两者可能会将两个独立的 VM 绑定到同一个逻辑会话。

诊断 maxVms 问题

如果遇到 ServiceQuotaExceededException: maxVms limit exceeded,请不要先申请提高配额。CloudWatch 的并发会话指标不等同于运行中的 VM 数量——环境在被回收之前,即使处于空闲状态也会占用配额。

请按以下顺序排查:

  1. 在每个逻辑请求完成后调用 StopRuntimeSession
  2. 检查会话 ID 的生成方式——是否为本应复用 ID 的每个请求都创建了新 ID?
  3. 如果会话生命周期较短,请调低 idleRuntimeSessionTimeout
  4. 只有在完成以上所有步骤后仍达到上限,才申请提高配额

有关提高配额的流程(通过 Service Quotas 控制台)和理由模板,请参阅 references/limits.md。


长时间运行的后台任务

如果 Agent 启动的工作会在 /invocations 响应返回后继续运行——例如后台处理、异步作业或长工具链——仅采用发后即忘模式是不够的。即使后台任务仍在运行,环境也可能在 idleRuntimeSessionTimeout 时被回收,因为运行时会在发送调用响应后将会话视为闲置。

使用 SDK 的异步任务 API 表示“仍在忙碌”

bedrock-agentcore SDK 提供了任务注册功能,可在受跟踪的工作运行期间保持环境存活。在 Python 中:

from bedrock_agentcore.runtime import BedrockAgentCoreApp

app = BedrockAgentCoreApp()

@app.entrypoint
def invoke(payload, context):
    # Register the task BEFORE starting it
    task_id = app.add_async_task("background_work")

    # Kick off the work (in a thread, asyncio, etc.)
    start_background_work(task_id, payload)

    # Return the invocation response — the task is still tracked
    return {"status": "processing", "taskId": task_id}


def start_background_work(task_id, payload):
    try:
        # Long-running work here
        do_the_work(payload)
    finally:
        # Mark the task complete when done — this releases the "busy" signal
        app.complete_async_task(task_id)

if __name__ == "__main__":
    app.run()

只要至少有一个已注册任务处于活动状态,运行时就会认为环境处于忙碌状态,不会在 idleRuntimeSessionTimeout 时回收环境。maxLifetime(默认值为 8 小时)仍是硬性上限。

请查阅 bedrock-agentcore SDK 对应语言的文档,了解等效 API——TypeScript SDK 也有类似模式。

无法使用异步任务 API 时的替代方案
  • 将 idleRuntimeSessionTimeout 调高至与预期任务时长相匹配。 如果你知道任务最长运行 10 分钟,可将超时设为 12 分钟。确保远低于 maxLifetime。
  • 保持 HTTP 连接打开,使用流式响应并定期发送心跳事件。适用于希望调用方等待结果而不是轮询的情况。请参阅 agents-debug/SKILL.md 中的 SSE 保活模式(“Connection drops mid-stream”一节)。
  • 将长时间运行的工作拆分为同一会话上的多次调用。 每次调用都会重置闲置计时器。

配额和限制

如果你遇到限流、ServiceQuotaExceededException 或其他与配额相关的错误——或者即将发布,希望确保配额不会造成阻碍——请加载 references/limits.md。

该参考资料涵盖:

  • 各错误对应的配额
  • 请求提高配额前可尝试的缓解措施(至关重要——大多数“配额”错误实际上是会话生命周期问题)
  • 如何通过 Service Quotas 控制台请求提高配额(需要直接提交 Support 工单的情况很少见)
  • 可直接复制粘贴的说明模板,包含审核者批准请求所需的全部信息

生产环境检查清单摘要

生成一份针对该项目的检查清单:

Production Readiness Checklist for <AgentName>

IAM
[ ] Execution role Bedrock access scoped to specific model ARNs
[ ] ECR access scoped to specific repository
[ ] Trust policy scoped to your account ID

Authentication
[ ] Inbound auth is AWS_IAM or CUSTOM_JWT (not NONE)
[ ] If CUSTOM_JWT: discovery URL, audience, and client IDs configured

Shell Access (if using InvokeAgentRuntimeCommand)
[ ] InvokeAgentRuntimeCommand permission granted only to identities that need it
[ ] Separate IAM policy from InvokeAgentRuntime policy
[ ] CloudTrail / EventBridge alert configured for InvokeAgentRuntimeCommand calls
[ ] If commands constructed from user input: shell injection validation implemented

Code quality
[ ] Error handling wraps all agent logic
[ ] Input validation on payload fields (type, length, format)
[ ] No secrets hardcoded in agent code
[ ] Credentials registered via agentcore add credential

Observability
[ ] X-Ray tracing enabled (auto-configured)
[ ] CloudWatch log retention policy set
[ ] Eval baseline established

Performance
[ ] Agent initialization time measured and optimized
[ ] Deployment package size under 200 MB (target under 100 MB)
[ ] Dependencies audited — no unused packages
[ ] Heavy initialization deferred to request time
[ ] Session reuse strategy chosen for multi-turn / batch workloads
[ ] `StopRuntimeSession` called after work completes where applicable
[ ] `idleRuntimeSessionTimeout` tuned to workload (default 900s)
[ ] For long-running background tasks: `add_async_task` / `complete_async_task` used

Resources
[ ] Memory strategies appropriate for use case (if using memory)
[ ] Gateway auth configured (if using gateway)
[ ] Policy engine attached (if restricting tool access)

Testing
[ ] Agent tested with production-representative inputs
[ ] Error cases tested (tool failures, model errors)
[ ] Memory cross-session tested (if using LTM)

输出

  • 包含项目具体发现的检查清单
  • 用于修复发现问题的具体命令
  • 针对检测到的模型和资源推荐的 IAM 策略

评论

支持 Markdown