← Financial Cloud Cloud Cloud Club · 构建文章

极点宏观|Financial Cloud Cloud · 构建文章

使用 AgentCore 与 Strands 构建:运行时主权风险代理人开发者工作坊

系列: AgentCore

文章: A3

文章
Kiro 工作坊
01 使用 Kiro 构建:他加禄语学习 App 的提示优先产品设计工作坊
Kiro 工作坊
02 使用 Kiro 构建:他加禄语 学习 App 的教育优先开发技巧工作坊
Kiro 工作坊
03 使用 Kiro 构建:他加禄语 学习 App 的深入开发流程工作坊
Kiro 工作坊
04 使用 Kiro 构建:将 他加禄语 学习 App 本地化为中文变体工作坊
Kiro 工作坊
05 使用 Kiro 构建:他加禄语 卡片的语法与发音补强流水线工作坊
Kiro 工作坊
06 使用 Kiro 构建:他加禄语 学习 App 中可审查的独特额外例句工作坊
Kiro 工作坊
07 与 Kiro 同行:晶圆厂工程健康度 Hook 工作坊
Kiro 工作坊
08 与 Kiro 同行:蚀刻工艺窗口风险测试自动化工作坊
Kiro 工作坊
09 与 Kiro 同行:黄光微影漂移风险开发工作坊
Kiro 工作坊
10 工程团队入门 — 日常工厂值班使用 fab spc drift sync portal
Kiro 工作坊
11 工程团队附录 — fab spc drift sync portal 的日常工厂值班使用
Kiro 工作坊
12 Kiro:规格驱动工厂软件的现场工程工作坊
Kiro 工作坊
13 Kiro:实施 Lab — 从零构建具类型的 Factory Risk Portal
Kiro 工作坊
14 Kiro:工程开发人员的提示、代码和类型标准手册
Kiro 工作坊
15 Kiro:为什么强 React 提示可以防止类型宣告错误启动
Kiro 工作坊
17 与 Kiro 一起构建:建立工厂自动化门户 React UI
Kiro 工作坊
18 与 Kiro 一同构建:打造工厂自动化门户背后的自动化分析引擎
Kiro 工作坊
19 与 Kiro 一起实施:将 AI 工厂自动化辅助程序新增至工厂自动化门户
Kiro 工作坊
21 Kiro:2 小时专业开发人员工作坊指南
Kiro 工作坊
22 Kiro:从零建置 Fab SPC Drift Synchronization Portal
Kiro 工作坊
23 Kiro:提示词库与深度代码说明附录
Kiro 工作坊
30 与 Kiro 一起构建:建立工厂自动化门户 UI
Kiro 工作坊
31 与 Kiro 一起构建:打造工厂自动化门户背后的自动化分析引擎
Kiro 工作坊
32 与 Kiro 一起实施:为工厂自动化门户添加 AI 工厂自动化辅助程序
Kiro 工作坊
33 与 Kiro 一起开发:重建 CME Direct 风格的量化损益排行榜 UI
Kiro 工作坊
34 与 Kiro 一起开发:重建损益排行榜背后的量化分析引擎
Kiro 工作坊
35 与 Kiro 一起构建:适用于量化排行榜的 AWS AI 驱动交易台助理
Kiro 工作坊
36 单页交易平台 SOP
Kiro 工作坊
AgentCore
A1 使用 AgentCore 与 Strands 构建:Gateway MCP 工具织网开发者工作坊
AgentCore
A2 使用 AgentCore 与 Strands 构建:受治理的多 Agent 风险系统开发者工作坊
AgentCore
A3 使用 AgentCore 与 Strands 构建:运行时主权风险代理人开发者工作坊
AgentCore
模拟考场
E1 用 Vibe Coding 打造多语言 AWS 认证模拟题上线系统
模拟考场
E2 利用 Vibe Coding 开发技巧打造 AWS 认证模拟练习室
模拟考场
E3 打造静态 AWS 模拟考场背后的练习引擎
模拟考场
Amazon Q
Q1 Amazon Q:面向 ACM 证书自动续订的 CloudShell 优先开发人员工作坊
Amazon Q
Tagalog 练习室
T1 用提示词优先的产品设计,为 AWS Manila Community Day 构建 Tagalog 学习应用
Tagalog 练习室
T2 用教育优先的开发提示,为 AWS Manila Community Day 构建 Tagalog 学习应用
Tagalog 练习室
T3 面向 AWS Manila Community Day 的 Tagalog 学习应用深度开发流程
Tagalog 练习室
T4 为 AWS Manila Community Day 将 Tagalog 学习应用本地化为中文变体
Tagalog 练习室
T5 为 AWS Manila Community Day 的 Tagalog 卡片构建语法与发音增强流水线
Tagalog 练习室
T6 在 AWS Manila Community Day 的 Tagalog 学习应用中,让额外示例唯一且可审查
Tagalog 练习室
路线图
R1 企业级 Data Analytics Roadmap 一百个深度情境题
路线图
R2 前端开发路线图:真实企业场景
路线图
香港 Community Day
C1 与 AWS Community Day 共度香港周末:从云端议程到维港灯火
香港 Community Day
C2 演讲者的奢华周末:讲述你的 AWS 故事,再让香港登场
香港 Community Day
C3 在香港的七十二小时:AWS Community Day 演讲者的深度行程
香港 Community Day
马尼拉 Community Day
C4 AWS Community Day Manila:一场连接云技术、城市文化与真挚友谊的快乐周末
马尼拉 Community Day
C5 AWS Community Day Manila:云端建设者在菲律宾感受最幸福的精神
马尼拉 Community Day
C6 AWS Community Day Manila:在快乐之城构建、打破、重来,并找到归属
马尼拉 Community Day
C7 菲律宾马尼拉初次到访建议
马尼拉 Community Day
菲律宾 × 香港
C8 菲律宾香港资本市场升级
菲律宾 × 香港
回测
B1 使用 Bedrock AgentCore 和 Strands Agents 构建机构级 Amazon 只做多回测代理
只做多 AMZN 代理:AgentCore、Strands 与可审计的 Backtrader 台账。
B2 使用 Backtrader、AgentCore 和 Strands Agents 构建具备市场状态感知能力的 Amazon 头寸管理
把市场状态当成头寸控制,而不是图表注释。
B3 使用 Nasdaq、S&P 500、Dow、AgentCore 与 Strands 构建相对基准的 Amazon 择时系统
相对 Nasdaq、S&P 500 与道琼斯判断 AMZN 时机。
B4 使用 Bedrock AgentCore、Strands Agents 与 Backtrader 构建受治理的 Amazon 交易历史工厂
把回测做成可审计的交易历史工厂。
B5 使用 Bedrock AgentCore 与 Strands Agents 构建代理式 Amazon 回测运营模型 [Part 1]
先建立运营模型,再争论结果。
B6 为 Amazon 择时与头寸管理构建自定义 Cerebro 代码解读 [第 2 部分]
先讲 Cerebro 引擎,再讲图表。
B7 为 Amazon 策略结果与经验教训构建交易员复盘记录 [Part 3]
把策略排名写成交易员复盘记录。
B8 使用 AgentCore 和 Strands 构建受治理的 FSI Amazon 头寸管理手册 [第 4 部分]
受治理的 FSI Amazon 头寸管理手册。
B9 使用 Amazon Bedrock AgentCore 构建主权风险交易代理,分析收益率差、FX 对冲与债务重新定价
主权风险代理:收益率差、外汇对冲与债务重定价。
B11 构建现代波动率交易与合法泰国恢复规划智能体:内存驱动的 Strands 多智能体风险保护系统
记忆驱动的 Strands 智能体:波动率与泰国恢复规划。
B12 使用 Amazon Bedrock AgentCore Memory 构建做空跨式交易风险治理
做空跨式的交易风险治理。
B13 在 Amazon EKS 上构建生产环境就绪的信用与收益质押 AI 智能体
在 EKS 上跑生产级信用与收益质押智能体。
挑战
01 周末生产力挑战:Fab SPC 漂移同步门户
Fab SPC 漂移审查与建议门户。
02 周末生产力挑战:Quant P&L Commander — AWS 上由 AI 驱动的交易生产力门户
AWS 上由 AI 驱动的交易生产力门户。
03 周末烦人任务挑战:交易台在云端、链上、空中执行摘要
DeskPulse 日常交易执行摘要。
04 周末 Agent 挑战:早上 6 点交易风险审查
无人值守、以证据为基础的早间交易风险简报。
05 周末创意挑战:领导力卡牌游戏
浏览器版创意引导卡牌。
06 全栈挑战:社区日留言板应用程序
浏览器版活动通信空间。
领导力卡牌
01 Leadership Card Game: 云没有自动化的最后一项技能:像领导者一样说话
写给 构建者的一篇现场随笔:语言、勇气,以及 Leadership Card Game
02 领导力回合解剖:Leadership Card Game 究竟如何玩
写给 构建者的引导员实地指南:如何把演练嵌进真实会议
03 Leadership Card Game: 当机会不再属于组织者
写给 构建者的田野随笔:权力转移、多语言领导力练习夜,以及走完入口、资源与叙事的职业弧线
04 周末创意挑战:Leadership Card Game
一篇构建者手记:愿景、架构,以及周末创意挑战教会我的事
05 从周末挑战项目到 $1,386 众筹:改变你在职场现身方式的领导力练习
一个周末做出的作品,变成 600 张卡的在线领导力练习室,并筹到 $1,386。
06 从周末挑战项目到 $1,386 众筹:进入科技产业的第一天路径
一个周末挑战如何变成具备 600 张卡、由 AWS 驱动的多语产品,并筹到 $1,386?
07 从周末挑战项目到 $1,386 众筹:用转移机会建立专业品牌
一个周末挑战把领导想法做成能跑的多语产品,并筹到 $1,386。
08 Leadership Card Game — 众筹活动
筹款目标: HKD 5,000 已筹金额: HKD 1,386 距目标还差: HKD 3,614 进度: 28% 创作者: D.C. Dan · L.L. Diana · L.K. Lva 所在地: 日本、香港、新加坡 投资人权益: 即期价值、私密会员卡牌编辑器云(Private Membership Card…
09 PR/FAQ 01 — Leadership Card Game 面向社区构建者正式推出
「逆向工作法」文档 · 对外新闻稿 + FAQ 产品: Leadership Card Game 受众: 社区经理、志愿组织者、早期职业构建者
10 PR/FAQ 02 — 企业引导员采用 Leadership Card Game 开展现场领导力演练
「逆向工作法」文档 · 对外新闻稿 + FAQ 产品: Leadership Card Game 受众: 学习与发展负责人、人员管理者、敏捷教练、企业引导员
10 PR/FAQ 03 — 多语言 Leadership Card Game 为构建者归属开放全球练习室
「逆向工作法」文档 · 对外新闻稿 + FAQ 产品: Leadership Card Game 受众: 全球 构建者、双语社区、跨境产品团队、开源导师
AWS Builder Center
01 AWS Builder Center、社区精神与 AWS Builder Jacket
霓虹信号、共享创意,以及为构建者打造的外套。
02 走进 AWS Builder Center:一座能学习、贡献,也让人有归属感的全球技术平台
一段精彩旅程,不一定从机场开始。
03 AWS Community Builder 的巨大成功
当构建者公开分享,整个社区就会一起前进。
04 AWS Builder Center 的巨大成功
一座为好奇心打造、充满活力的全球街区。
05 周末走进 AWS Builder Center:从社区灵感到令人难忘的 AWS Builder Jacket
星期五晚上,开始于构建者熟悉的感觉:有一个点子,正卡在问题与可能性之间。

目标受众: 专业 Python/AWS 开发者

时长: 2 小时

主要 AWS AI 服务: Amazon Bedrock AgentCore Runtime、Strands Agents、Amazon Bedrock 模型

工作坊风格: 开发者实战动手构建,无需演示

项目输出: 一个具备本地验证、部署脚本、boto3 调用客户端、串流变体、会话清理以及大容量 Payload 处理器的全功能运行时代理人(Runtime Agent)。

本工作坊仅供教育工程教学使用。示例领域为主权风险分析,但输出内容不构成任何财务、投资、法律、税务或交易建议。

工作坊摘要

开发者将使用 Strands 与 AgentCore Runtime 构建一个生产级的主权风险代理人。工作坊内容涵盖决定性(Deterministic)计算工具、Payload 验证、冒烟测试、部署、boto3 客户端调用、串流响应、大容量 base64 Payload 处理以及会话清理。参与者在结束时将获得可重复使用的运行时模式,用于构建安全、具备可观测性且感知会话(Session-aware)的 AI 服务,并在 AWS 上将模型推理与可测试的 Python 逻辑相结合,以满足现代企业开发者的工作流程。


1. 开发者学习目标

在本工作坊结束时,开发者将能够:

● 构建一个由 Amazon Bedrock 模型支持的 Strands 代理人。

● 为以 LLM 驱动的代理人添加决定性的 Python 工具。

● 将代理人封装至 Amazon Bedrock AgentCore Runtime 进入点(Entrypoint)。

● 使用 AgentCore 入门工具包(Starter Toolkit)封装并启动运行时。

● 使用稳定的会话 ID(Session ID)通过 boto3 调用运行时。

● 为需要实时响应的客户端实施串流运行时进入点。

● 构建一个可处理 base64 编码的 Excel 和图片输入的大容量 Payload 进入点。

● 在部署前加入本地 Payload 契约验证与冒烟测试。


2. 本工作坊构建的架构

開發者筆記型電腦
  ├─ app.py                         # 同步 AgentCore Runtime 進入點
  ├─ app_streaming.py               # 串流 Runtime 進入點
  ├─ app_large_payload.py           # 多模態 / 大容量 Payload Runtime 進入點
  ├─ deploy_runtime.py              # 封裝並啟動執行期
  ├─ invoke_runtime.py              # boto3 用戶端呼叫
  ├─ stop_session.py                # 顯式工作階段清理
  ├─ validate_payload.py            # 本地 Payload 合約驗證
  ├─ smoke_test.py                  # 本地冒煙測試
  ├─ prompts/system.md              # 受控的系統提示詞
  └─ requirements.txt

AWS
  ├─ 透過 Strands 存取的 Amazon Bedrock 模型
  ├─ Amazon Bedrock AgentCore Runtime
  ├─ 由工具包建立的 Amazon ECR 映像檔
  ├─ IAM 執行角色
  └─ 雲端日誌 / 執行期輸出

3. 2 小时实战议程

时间(分钟) 模块 实战输出
0–10 环境检查 确认 AWS 身份、区域与 Python 环境
10–25 项目基础架构 建立文件、依赖项目与提示词契约
25–45 Strands 代理人 代理人使用 Bedrock 模型与决定性工具
45–60 本地验证 在本地执行 Payload 验证器与冒烟测试
60–80 AgentCore Runtime 部署 产生运行时 ARN
80–95 运行时调用 boto3 客户端调用感知会话的代理人
95–110 串流变体 实施非同步串流进入点
110–120 大容量 Payload 与清理 新增 base64 文件 Payload 与停止会话脚本

4. 先决条件

python --version     # 建議版本:3.11+
aws --version
aws sts get-caller-identity
export AWS_DEFAULT_REGION=us-east-1

建立并启用虚拟环境:

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

步骤 1 — 建立项目基础架构

开发者操作

mkdir -p agentcore-strands-runtime/prompts
cd agentcore-strands-runtime
cat > requirements.txt <<'EOF'
bedrock-agentcore
bedrock-agentcore-starter-toolkit
strands-agents
strands-agents-tools
boto3
botocore
pytest
EOF

建立系统提示词:

cat > prompts/system.md <<'EOF'
您是一位專業的主權風險工程助理。
請分析殖利率價差、信用利差擴大、主權債務重新定價、外匯壓力、
資金流動性、存續期間需求、資本流動以及防禦性輪動。
請務必包含以下章節:
1. 觀察 (Observation)
2. 推理 (Reasoning)
3. 風險隱含意義 (Risk implication)
4. 避險考量 (Hedge consideration)
5. 確認訊號 (Confirmation signals)
6. 失效觸發條件 (Invalidation triggers)
7. 限制 (Limitations)
請使用工具進行數值計算。請勿提供投資建議或自主交易指令。
EOF

安装依赖项目:

pip install -r requirements.txt

系统设计决策

● 提示词文件作为版本控制的行为: 系统提示词是运行时契约的一部分。将其保存在 prompts/system.md 中,可让开发者像审查代码变更一样审查行为变更。这非常重要,因为代理人的输出风格、安全边界和必要章节会直接影响下游客户端、测试与评估。

● 明确的依赖文件: 运行时部署必须具备可重复性。requirements.txt 定义了运行时所需的精确 Python 软件包界面。这也简化了部署封装、容器构建以及会话的疑难排解,因为每位参与者安装的依赖项目完全相同。

● 云部署前的微型架构: 开发者先在本地建立文件并验证行为,然后才部署到云。这减少了云调试的杂音。如果缺少提示词文件或 Python 导入失败,错误会在运行时被封装和启动之前在本地被提取到。

预期结果

项目中包含一个依赖文件和一个受控的系统提示词,该提示词将由 Strands 代理人读取。


步骤 2 — 构建同步 Strands 代理人运行时

开发者操作

建立 app.py。

from strands import Agent, tool
from strands.models import BedrockModel
from strands_tools import calculator
from bedrock_agentcore.runtime import BedrockAgentCoreApp

app = BedrockAgentCoreApp()

with open("prompts/system.md", "r", encoding="utf-8") as f:
    SYSTEM_PROMPT = f.read()

@tool
def yield_spread_bps(us_yield: float, peer_yield: float) -> str:
    """計算兩個殖利率之間的基點(bps)價差。"""
    spread = (us_yield - peer_yield) * 100
    return f"殖利率價差為 {spread:.1f} 基點。"

@tool
def fx_hedge_notional(exposure_usd: float, hedge_ratio: float) -> str:
    """根據 USD 風險敞口和避險比率計算避險名目本金。"""
    hedge = exposure_usd * hedge_ratio
    return f"外匯避險名目本金為 USD {hedge:,.2f}。"

@tool
def stress_loss_notional(position_notional: float, spread_move_bps: float, duration: float) -> str:
    """估算由價差變動引起的存續期間驅動價格影響。"""
    loss = position_notional * duration * (spread_move_bps / 10000)
    return f"預估存續期間影響為 USD {loss:,.2f}。"

agent = Agent(
    model=BedrockModel(
        model_id="amazon.nova-pro-v1:0",
        temperature=0.2,
        max_tokens=4000,
    ),
    tools=[calculator, yield_spread_bps, fx_hedge_notional, stress_loss_notional],
    system_prompt=SYSTEM_PROMPT,
)

@app.entrypoint
def sovereign_runtime(payload, context):
    prompt = payload.get("prompt", "")
    if not prompt.strip():
        return {"error": "缺少必要欄位:prompt"}

    request_id = payload.get("request_id", context.session_id)
    request = (
        f"請求 ID: {request_id}\n"
        f"執行期工作階段: {context.session_id}\n"
        f"使用者請求: {prompt}"
    )
    response = agent(request)
    return response.message["content"][0]["text"]

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

商业逻辑

代理人分析主权风险提示词,并使用工具计算基点价差、外汇避险名目本金以及存续期间压力影响。模型处理定性综合分析,而决定性计算则留在 Python 中执行。

代码逻辑

● BedrockAgentCoreApp() 建立运行时应用程序包装器。

● BedrockModel() 设置 Strands 所使用的 Amazon Bedrock 模型。

● @tool 将 Python 函数公开给 Strands 代理人。

● @app.entrypoint 标记可调用的运行时处理器(Handler)。

● 处理器验证 prompt,加入请求与会话上下文,调用代理人,并返回最终文字。

预期结果

执行 python app.py 会启动一个本地与 AgentCore 兼容的运行时处理程序。部署后,同一个进入点将接收来自 AgentCore Runtime 的 JSON Payload。

系统设计决策

● 用于定量逻辑的决定性工具: LLM 非常适合用于综合分析,但财务计算应该是决定性且可测试的。通过将殖利率价差、避险名目本金和存续期间压力数学运算移至 Python 工具中,开发者可以获得可重复的输出,并能独立于模型行为之外对计算进行单元测试。

● 请求 ID 与会话上下文: 进入点将请求与会话 ID 注入模型提示词中。这为响应提供了运作上下文,并有助于工程师关联运行时日志、客户端调用和用户工作流程。这也为生产环境的追踪(Tracing)建立了一个乾净的模式。

● 低温度的 Bedrock 模型: 代理人使用 temperature=0.2 来减少响应的变异性。专业的开发者工作坊应该教授稳定的工程模式,而非创意的提示词实验。较低的变异性有助于改善冒烟测试、展示以及未来的评估基准。


步骤 3 — 加入本地 Payload 验证

开发者操作

建立 validate_payload.py。

REQUIRED_FIELDS = ["prompt"]
OPTIONAL_FIELDS = ["request_id", "user_id", "excel_data", "image_data"]

def validate_payload(payload: dict) -> tuple[bool, list[str]]:
    errors = []
    for field in REQUIRED_FIELDS:
        if field not in payload or not str(payload[field]).strip():
            errors.append(f"缺少必要欄位:{field}")

    unknown = set(payload.keys()) - set(REQUIRED_FIELDS) - set(OPTIONAL_FIELDS)
    for field in sorted(unknown):
        errors.append(f"未知欄位:{field}")

    return len(errors) == 0, errors

if __name__ == "__main__":
    sample = {"prompt": "分析美中殖利率價差", "request_id": "demo-001"}
    ok, errors = validate_payload(sample)
    print("有效性", ok)
    print("錯誤", errors)

商业逻辑

验证器在运行时调用之前强制执行请求契约。这可以防止客户端传送格式错误的请求,并使调试更容易。

代码逻辑

该函数检查必要字段、拒绝未知字段,并返回一个布尔值与错误列表。它可以被测试、客户端或运行时代码导入。

预期结果

python validate_payload.py
# 有效性 True
# 錯誤 []

系统设计决策

● 部署前的 Payload 契约: 开发者应在调用云运行时之前在本地验证 API 契约。这减少了因缺少提示词或字段拼错而导致的运行时调用失败。这也为以后建立更强大的纲要(Schema)奠定了基础。

● 明确的未知字段检测: 拒绝未知字段有助于及早发现整合错误。如果没有这项机制,客户端可能会误以为元数据(Metadata)已被使用,而运行时其实默默忽略了它。清晰的验证能改善开发者反馈。

● 可重复使用的验证模块: 验证器是一个模块,而不仅仅是一个脚本。它可以在单元测试、CLI 客户端和运行时进入点中重复使用。这避免了在多个文件中重复编写契约逻辑。


步骤 4 — 加入冒烟测试

开发者操作

建立 smoke_test.py。

from validate_payload import validate_payload
from app import yield_spread_bps, fx_hedge_notional, stress_loss_notional

def test_payload_validation():
    ok, errors = validate_payload({"prompt": "分析價差"})
    assert ok
    assert errors == []

def test_missing_prompt_fails():
    ok, errors = validate_payload({"request_id": "x"})
    assert not ok
    assert "缺少必要欄位:prompt" in errors

def test_tool_outputs():
    assert "210.0" in yield_spread_bps(4.25, 2.15)
    assert "15,000,000.00" in fx_hedge_notional(25_000_000, 0.6)
    assert "125,000.00" in stress_loss_notional(10_000_000, 25, 5)

执行:

pytest -q

商业逻辑

冒烟测试在部署代理人之前,验证请求契约与决定性计算工具。

代码逻辑

测试直接导入验证与工具函数。它们不会调用模型,从而保持测试的高速与决定性。

预期结果

3 passed

系统设计决策

● 优先测试决定性部分: 模型的输出可能会有所不同,但工具数学运算和 Payload 验证不应该改变。测试决定性组件可以为开发者提供快速反馈,并在云部署前隔离错误。

● 冒烟测试中无模型依赖: 冒烟测试不会调用 Amazon Bedrock。这避免了成本、凭证、模型延迟和非决定性断言(Assertions)的问题。其目标是验证本地软件契约。

● 工作坊友善的失败消息: 简单的断言使失败原因一目了然。在两小时的工作坊中,调试必须快速且集中。这些测试能及早发现常见的设置与逻辑错误。


步骤 5 — 部署 AgentCore Runtime

开发者操作

建立 deploy_runtime.py。

from boto3.session import Session
from bedrock_agentcore_starter_toolkit import Runtime

region = Session().region_name or "us-east-1"

runtime = Runtime()
runtime.configure(
    entrypoint="app.py",
    auto_create_execution_role=True,
    auto_create_ecr=True,
    requirements_file="requirements.txt",
    region=region,
    agent_name="sovereign-runtime-hands-on",
)

result = runtime.launch()
print("AGENTCORE_RUNTIME_ARN=", result.agent_arn)
print("AGENTCORE_RUNTIME_ID=", result.agent_id)

执行:

python deploy_runtime.py
export AGENTCORE_RUNTIME_ARN="貼上代理人執行期 ARN"

商业逻辑

本地代理人成为一个受管的运行时端点,应用程序可以调用该端点。

代码逻辑

Runtime().configure() 封装进入点与依赖项目。launch() 部署运行时并返回标识符。

预期结果

脚本印出 AgentCore Runtime ARN 与运行时 ID。

系统设计决策

● 利用工具包提高实战速度: 入门工具包处理了部署机制,使工作坊能够专注于运行时设计,而非容器内部细节。开发者仍然可以看到产生的运行时 ARN,并可以在事后检查生成的 AWS 资源。

● 先部署单一运行时进入点: 仅部署 app.py 可以保持首次云部署的简单性。一旦同步调用正常运作,开发者就可以在减少未知变量的情况下部署串流或大容量 Payload 变体。

● 使用环境变量存储 ARN: 将运行时 ARN 导出为环境变量,可以将部署与调用脚本解耦。这模拟了生产环境模式,其中部署输出会提供给客户端设置或 CI/CD 变量。


步骤 6 — 使用 boto3 调用运行时

开发者操作

建立 invoke_runtime.py。

import json
import os
import uuid
import boto3
from validate_payload import validate_payload

region = os.getenv("AWS_DEFAULT_REGION", "us-east-1")
agent_arn = os.environ["AGENTCORE_RUNTIME_ARN"]
session_id = os.getenv("RUNTIME_SESSION_ID", str(uuid.uuid4()))

payload = {
    "request_id": "hands-on-001",
    "prompt": (
        "分析美國 10 年期 4.25 對比中國 10 年期 2.15。"
        "USD 風險敞口為 25000000 且避險比率為 0.60。"
        "部位名目本金為 10000000,價差變動為 25 bps,存續期間為 5。"
        "請包含確認訊號與失效觸發條件。"
    ),
}

ok, errors = validate_payload(payload)
if not ok:
    raise ValueError(errors)

client = boto3.client("bedrock-agentcore", region_name=region)
res = client.invoke_agent_runtime(
    agentRuntimeArn=agent_arn,
    runtimeSessionId=session_id,
    qualifier="DEFAULT",
    payload=json.dumps(payload).encode("utf-8"),
)

body = b"".join(res["response"]).decode("utf-8")
print(body)
print("工作階段 ID:", session_id)

执行:

python invoke_runtime.py

商业逻辑

客户端请求结构化的主权风险分析,并提供应触发计算工具的数值。

代码逻辑

脚本验证 Payload、建立 boto3 AgentCore 客户端、传送 JSON 位元组、组合运行时响应区块(Chunks),并印出会话 ID。

预期结果

响应包含分析内容以及计算出的数值,例如基点价差、避险名目本金或存续期间影响。

系统设计决策

● 客户端验证: 客户端在传送请求前进行验证。这可以及早发现错误,并避免不必要的运行时调用。生产环境的客户端可以共用相同的验证逻辑或使用正式的 JSON Schema。

● 会话 ID 重复使用: 脚本会印出会话 ID,以便开发者可以将其重复用于多轮(Multi-turn)测试。这展示了 AgentCore 会话如何支持跨调用的上下文工作流程。

● 响应正规化: 脚本将响应区块组合成单一字符串。这种抽象化保持了下游客户端的简单性,同时仍能与事件风格的运行时响应兼容。


步骤 7 — 加入串流运行时变体

开发者操作

建立 app_streaming.py。

from strands import Agent, tool
from strands.models import BedrockModel
from bedrock_agentcore.runtime import BedrockAgentCoreApp

app = BedrockAgentCoreApp()

@tool
def credit_spread_widening() -> str:
    """回傳信用利差擴大的核心驅動因素。"""
    return "驅動因素包括資金壓力、流動性撤出、調降評級風險以及防禦性部位輪動。"

agent = Agent(
    model=BedrockModel(model_id="amazon.nova-pro-v1:0", temperature=0.2, max_tokens=4000),
    tools=[credit_spread_widening],
    system_prompt="串流輸出簡明的主權風險分析,包含證據、確認與失效章節。",
)

@app.entrypoint
async def stream_runtime(payload, context):
    prompt = payload.get("prompt", "")
    if not prompt:
        yield {"type": "error", "message": "缺少 prompt"}
        return

    request = f"工作階段: {context.session_id}\n{prompt}"
    async for event in agent.stream_async(request):
        if "data" in event:
            yield event["data"]

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

商业逻辑

串流功能允许客户端在分析内容生成时同步显示,这对分析师仪表板和对话界面非常有用。

代码逻辑

进入点为 async(非同步),调用 agent.stream_async(),并产出(Yield)数据区块。

预期结果

支持串流的运行时可以返回部分区块,而不需要等待完整响应生成完毕。

系统设计决策

● 用于部分输出的非同步进入点: 串流需要一个能产出区块的非同步进入点。这改善了用户界面的感知延迟(Perceived latency),并向开发者展示了不同的运行时响应模式。

● 独立的串流文件: 将串流代码与同步运行时分开,可以轻松进行对比。开发者可以清楚地看到改变了什么:改变的是进入点风格与响应处理方式,而非整个架构。

● 工具支持依然可用: 串流代理人仍然保有工具。这证明了串流是一种传输选择,并不会削弱代理人的能力。


步骤 8 — 加入大容量 Payload 处理器

开发者操作

建立 app_large_payload.py。

import base64
from strands import Agent
from strands.models import BedrockModel
from bedrock_agentcore.runtime import BedrockAgentCoreApp

app = BedrockAgentCoreApp()

agent = Agent(
    model=BedrockModel(model_id="amazon.nova-pro-v1:0", temperature=0.2, max_tokens=8000),
    system_prompt=(
        "分析提供的財務文件與圖表以評估主權風險、殖利率價差、信用利差、"
        "外匯壓力、流動性、資本流動、避險考量、確認訊號與失效觸發條件。"
        "請勿提供投資建議。"
    ),
)

@app.entrypoint
def large_payload_runtime(payload, context):
    content = [{"text": f"工作階段: {context.session_id}\n{payload.get('prompt', '分析提供的資料')}"}]

    if payload.get("excel_data"):
        content.insert(0, {
            "document": {
                "format": "xlsx",
                "name": "sovereign_dataset",
                "source": {"bytes": base64.b64decode(payload["excel_data"])},
            }
        })

    if payload.get("image_data"):
        content.insert(0, {
            "image": {
                "format": "png",
                "source": {"bytes": base64.b64decode(payload["image_data"])},
            }
        })

    response = agent(content)
    return response.message["content"][0]["text"]

商业逻辑

运行时将用户提示词、试算表数据和图表影像信号整合到单一分析流程中。

代码逻辑

处理器对 base64 Payload 字段进行解码,并构建具备类型的 Bedrock 内容区块:document、image 和 text。

预期结果

客户端可以传送选填的 excel_data 和 image_data 字段,并接收整合后的分析结果。

系统设计决策

● 用于 JSON 传输的 Base64: 二进位文件经过编码,以便通过 JSON Payload 传输。这保持了客户端契约的简单性,并避免了工作坊期间多部分上传(Multipart upload)的复杂性。

● 具备类型的内容区块: 传入 document 和 image 区块可以保留模态性(Modality)。这比将所有内容转换为文字更具维护性,并能让模型利用文件/影像特定的专属能力。

● 选填的 Payload 字段: 处理器可与纯文字、纯文件、纯影像或组合请求协同运作。这使得运行时对于多种客户端类型更具弹性。


步骤 9 — 加入显式会话清理

# stop_session.py
import os
import boto3

client = boto3.client("bedrock-agentcore", region_name=os.getenv("AWS_DEFAULT_REGION", "us-east-1"))
client.stop_runtime_session(
    agentRuntimeArn=os.environ["AGENTCORE_RUNTIME_ARN"],
    runtimeSessionId=os.environ["RUNTIME_SESSION_ID"],
    qualifier="DEFAULT",
)
print("已停止工作階段", os.environ["RUNTIME_SESSION_ID"])

系统设计决策

● 会话是受管资源: 代理人会话可以保留上下文并消耗资源。开发者应该在工作流程结束时显式停止会话,而不是仅依赖闲置过期。

● 清理脚本化: 一个小脚本很容易在展示、测试和 CI 工作结束后执行。这鼓励了规范的运行时维护习惯。

● 运作控制把手: 会话 ID 成为调试、追踪与清理的运作控制把手(Operational handle)。


开发者最终检查清单

● [ ] pytest -q 在本地通过。

● [ ] python deploy_runtime.py 返回运行时 ARN。

● [ ] python invoke_runtime.py 返回结构化分析。

● [ ] 串流进入点编译成功且可单独部署。

● [ ] 大容量 Payload 进入点接受选填的 excel_data 和 image_data。

● [ ] 会话清理脚本已通过测试。


额外开发者实战实验室

以下实验室扩展了运行时工作坊,提供了更深入的开发者实施练习。它们被设计为核心两小时构建后的选修模块,或适合希望加强部署、测试和运营规范的专业团队的后续练习。


实战实验室 A — 为运行时 Payload 新增 JSON Schema 验证

开发者目标

将简单的字段验证器替换为可重复使用的 JSON Schema 验证器,该验证器可由客户端、测试和运行时处理器共用。

开发者操作

安装 jsonschema:

pip install jsonschema

建立 payload_schema.py:

RUNTIME_PAYLOAD_SCHEMA = {
    "type": "object",
    "properties": {
        "request_id": {"type": "string", "minLength": 1},
        "user_id": {"type": "string", "minLength": 1},
        "prompt": {"type": "string", "minLength": 1},
        "excel_data": {"type": "string"},
        "image_data": {"type": "string"},
        "metadata": {
            "type": "object",
            "additionalProperties": {"type": ["string", "number", "boolean", "null"]},
        },
    },
    "required": ["prompt"],
    "additionalProperties": False,
}

建立 validate_schema.py:

from jsonschema import Draft202012Validator
from payload_schema import RUNTIME_PAYLOAD_SCHEMA

validator = Draft202012Validator(RUNTIME_PAYLOAD_SCHEMA)

def validate_payload_schema(payload: dict) -> tuple[bool, list[str]]:
    errors = sorted(validator.iter_errors(payload), key=lambda e: e.path)
    messages = [f"{list(error.path)}: {error.message}" for error in errors]
    return len(messages) == 0, messages

if __name__ == "__main__":
    sample = {"prompt": "分析價差", "metadata": {"source": "lab"}}
    ok, messages = validate_payload_schema(sample)
    print(ok)
    print(messages)

商业逻辑

Schema 正式确立了运行时 API 契约。这有助于前端开发者、后端服务和测试软件包在运行时支持的确切字段上达成共识。

代码逻辑

Draft202012Validator 检查 Payload 的形状、必要字段、数据类型与未知字段。辅助程序返回一个布尔值与人类可读的错误消息。

预期结果

python validate_schema.py
# True
# []

系统设计决策

● Schema 作为共享 API 契约: JSON Schema 比手写验证更精确,因为它在一个可重复使用的构件中定义了类型、必要字段与未知字段的行为。这允许客户端、测试软件包和运行时处理器在调用 AgentCore Runtime 之前验证相同的契约。

● 在模型调用前快速失败: 运行时调用可能会涉及模型延迟与成本。在调用代理人之前验证 Payload 可以防止本可避免的失败,并为开发者提供实时反馈。它还减少了由格式错误的客户端 Payload 引起的异常运行时日志。

● 可扩展的元数据对象: Schema 允许使用 metadata 对象来提供安全的运营上下文,同时封锁任意的最上层字段。这使得团队在保持弹性的同时,不会让运行时契约变得不受控制。


实战实验室 B — 构建可重复使用的运行时客户端类别

开发者目标

将 boto3 调用、会话 ID、Payload 验证和响应正规化封装到一个可重复使用的客户端类别中。

开发者操作

建立 runtime_client.py:

import json
import os
import uuid
import boto3
from validate_schema import validate_payload_schema

class AgentCoreRuntimeClient:
    def __init__(self, runtime_arn: str, region: str | None = None):
        self.runtime_arn = runtime_arn
        self.region = region or os.getenv("AWS_DEFAULT_REGION", "us-east-1")
        self.client = boto3.client("bedrock-agentcore", region_name=self.region)

    def invoke(self, prompt: str, session_id: str | None = None, **kwargs) -> dict:
        payload = {"prompt": prompt, **kwargs}
        ok, errors = validate_payload_schema(payload)
        if not ok:
            raise ValueError({"payload_errors": errors})

        runtime_session_id = session_id or str(uuid.uuid4())
        response = self.client.invoke_agent_runtime(
            agentRuntimeArn=self.runtime_arn,
            runtimeSessionId=runtime_session_id,
            qualifier="DEFAULT",
            payload=json.dumps(payload).encode("utf-8"),
        )
        body = b"".join(response["response"]).decode("utf-8")
        return {"session_id": runtime_session_id, "body": body}

建立 use_runtime_client.py:

import os
from runtime_client import AgentCoreRuntimeClient

client = AgentCoreRuntimeClient(os.environ["AGENTCORE_RUNTIME_ARN"])
result = client.invoke(
    prompt="分析美中殖利率價差變動,並包含確認與失效訊號。",
    request_id="client-lab-001",
    metadata={"application": "developer-lab"},
)
print(result["session_id"])
print(result["body"])

商业逻辑

应用程序团队需要一个乾净的运行时整合层,而不是在每个服务中重复编写 boto3 代码。

代码逻辑

该类别验证 Payload、建立或重复使用会话 ID、调用 AgentCore Runtime、组合响应事件,并返回正规化的输出。

预期结果

开发者只需两行应用程序代码即可调用运行时。

系统设计决策

● 客户端抽象化: 可重复使用的类别可以防止在各个应用程序中重复编写 boto3 样板代码。它还集中了验证、响应正规化和会话处理,从而使整合行为保持一致。

● 设计上的会话连续性: 客户端允许调用者传入会话 ID 或建立一个新的会话 ID。这使得多轮工作流程变得明确,同时保留了简单的单次(One-shot)调用。

● 正规化的返回形状: 返回 {session_id, body} 使应用程序代码更容易测试,并避免了将底层 boto3 事件详细信息泄露给每个调用者。


实战实验室 C — 加入运行时错误分类法

开发者目标

为运行时客户端和运营人员提供一致的错误类型,以应对缺少字段、模型失败和非预期异常。

开发者操作

建立 errors.py:

class RuntimeErrorCode:
    MISSING_PROMPT = "MISSING_PROMPT"
    VALIDATION_ERROR = "VALIDATION_ERROR"
    AGENT_FAILURE = "AGENT_FAILURE"
    UNEXPECTED_ERROR = "UNEXPECTED_ERROR"

def error_response(code: str, message: str, request_id: str | None = None) -> dict:
    return {
        "status": "error",
        "error": {
            "code": code,
            "message": message,
            "request_id": request_id,
        },
    }

修改运行时进入点模式:

from errors import RuntimeErrorCode, error_response

@app.entrypoint
def sovereign_runtime(payload, context):
    request_id = payload.get("request_id", context.session_id)
    try:
        prompt = payload.get("prompt", "")
        if not prompt.strip():
            return error_response(RuntimeErrorCode.MISSING_PROMPT, "提示詞 (prompt) 為必要欄位", request_id)
        response = agent(f"請求 ID: {request_id}\n工作階段: {context.session_id}\n{prompt}")
        return {"status": "ok", "request_id": request_id, "response": response.message["content"][0]["text"]}
    except Exception as exc:
        return error_response(RuntimeErrorCode.UNEXPECTED_ERROR, str(exc), request_id)

商业逻辑

运营系统需要可预测的错误,以便安全地进行路由、告警、重试或显示。

代码逻辑

错误辅助程序返回一个包含状态、错误码、消息和请求 ID 的一致对象。

预期结果

格式错误的请求会返回结构化错误,而不是不一致的字符串或堆叠追踪(Stack traces)。

系统设计决策

● 用于运营的错误分类法: 生产环境的客户端需要区分验证失败与代理人失败。基于代码的分类法允许仪表板、重试逻辑和告警规则做出相应的反应。

● 每个错误中都包含请求 ID: 在错误中包含请求 ID 有助于将客户端失败与运行时日志和会话 ID 相关联。这减少了工作坊与生产事件期间的调试时间。

● 安全的异常处理: 运行时提取非预期错误并返回一个受控的响应。这可以防止原始堆叠追踪泄露给调用者,同时仍为开发者调试保留足够的详细信息。


实战实验室 D — 构建串流 CLI 消费者

开发者目标

建立一个客户端,可以解析服务器传送事件(Server-Sent Event, SSE)风格的串流响应并逐步印出区块。

开发者操作

建立 invoke_streaming_runtime.py:

import json
import os
import uuid
import boto3

client = boto3.client("bedrock-agentcore", region_name=os.getenv("AWS_DEFAULT_REGION", "us-east-1"))
session_id = str(uuid.uuid4())

response = client.invoke_agent_runtime(
    agentRuntimeArn=os.environ["AGENTCORE_STREAMING_RUNTIME_ARN"],
    runtimeSessionId=session_id,
    qualifier="DEFAULT",
    payload=json.dumps({
        "prompt": "串流分析信用利差擴大與主權重新定價訊號。"
    }).encode("utf-8"),
)

print("工作階段:", session_id)
for event in response["response"]:
    chunk = event.decode("utf-8") if isinstance(event, bytes) else str(event)
    print(chunk, end="", flush=True)
print()

商业逻辑

串流客户端允许开发者查看渐进式的模型输出,这对于聊天 UI 和分析师仪表板非常有用。

代码逻辑

脚本调用串流运行时,并在响应事件到达时对其进行反覆运算。

预期结果

终端机会渐进式地印出内容,而不是等待完整响应。

系统设计决策

● 渐进式转译客户端: 只有当客户端正确使用区块时,串流功能才有帮助。本实验室教授的是串流的调用端,而不仅仅是运行时端。

● 独立的串流运行时 ARN: 脚本使用独立的环境变量,以避免混淆同步与串流部署。这保持了测试的明确性。

● 立即排空输出: flush=True 模拟了 UI 的渐进式转译,并有助于开发者在终端机中观察串流行为。


实战实验室 E — 加入本地成本与延迟日志包装器

开发者目标

在应用程序层提取模型调用延迟,以便进行工作坊调试和未来的可观测性构建。

开发者操作

建立 timed_agent.py:

import time
import json
from datetime import datetime, timezone

class TimedAgent:
    def __init__(self, agent, name: str):
        self.agent = agent
        self.name = name

    def __call__(self, prompt):
        start = time.time()
        response = self.agent(prompt)
        elapsed_ms = int((time.time() - start) * 1000)
        print(json.dumps({
            "timestamp": datetime.now(timezone.utc).isoformat(),
            "event_type": "agent_invocation_latency",
            "agent": self.name,
            "elapsed_ms": elapsed_ms,
        }))
        return response

包装代理人:

from timed_agent import TimedAgent
agent = TimedAgent(agent, "sovereign-runtime-agent")

商业逻辑

在新增受管的可观测性仪表板之前,开发者需要对缓慢的模型调用和运行时行为具备可见性。

代码逻辑

TimedAgent 装饰(Decorate)一个现有的 Strands 代理人,并为每次调用记录耗费的毫秒数。

预期结果

每次调用都会印出一个 JSON 延迟事件。

系统设计决策

● 使用装饰器而非侵入式修改: 包装代理人可以避免更改代理人的构建或商业逻辑。这保持了可观测性的模块化,且易于移除或替换。

● 结构化延迟日志: JSON 延迟日志可以被搜索与汇整。它们还建立了与 AgentCore Observability 和 CloudWatch 的自然桥梁。

● 开发者反馈循环: 延迟数据有助于开发者在实战实验期间,了解较长提示词、较大 Payload 以及额外工具所带来的性能成本。