← 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 學習 App:提示詞優先的產品設計
Tagalog 練習室
T2 為 AWS Manila Community Day 打造 Tagalog 學習 App,採用教育優先的開發提示
Tagalog 練習室
T3 為 AWS Manila Community Day 打造 Tagalog 學習 App 的開發流程深度解析
Tagalog 練習室
T4 將 Tagalog 學習 App 在 AWS Manila Community Day 情境中在地化為中文版本
Tagalog 練習室
T5 為 AWS Manila Community Day 打造 Tagalog 卡片打造文法與發音補強流程
Tagalog 練習室
T6 為 AWS Manila Community Day 打造 Tagalog 學習 App 的 Extra Examples 更獨特且可審閱
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 純做多 (Long-Only) 回測代理
純做多 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 交易歷史工廠(Trade-History Factory)
把回測做成可稽核的交易歷史工廠。
B5 使用 Bedrock AgentCore 與 Strands Agents 建立智慧代理型 (Agentic) Amazon 回測營運模型 [Part 1]
先建立營運模型,再爭論結果。
B6 為 Amazon 擇時與部位管理建立客製化 Cerebro 程式碼說明 [第 2 部分]
先講 Cerebro 引擎,再講圖表。
B7 為 Amazon 策略結果與經驗教訓建立交易員審閱紀錄 [Part 3]
把策略排名寫成交易員審閱紀錄。
B8 使用 AgentCore 與 Strands 建立受治理的 FSI Amazon 部位管理 Playbook [Part 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 Weekend Creative Challenge: Leadership Card Game
瀏覽器版創意引導卡牌。
06 Full Stack Challenge: Community Day Board App
瀏覽器版活動溝通空間。
領導力卡牌
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 以及額外工具所帶來的效能成本。