← Financial Cloud Cloud Cloud Club · 建構文章

極點宏觀|Financial Cloud Cloud · 建構文章

使用 AgentCore 與 Strands 建構:受治理的多 Agent 風險系統開發者工作坊

系列: AgentCore

文章: A2

文章
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
星期五晚上,開始於建構者熟悉的感覺:有一個點子,正卡在問題與可能性之間。

目標受眾: 資深開發者、平台工程師、AI 治理工程師

時長: 2 小時

主要 AWS AI 服務: Amazon Bedrock AgentCore Runtime、AgentCore Memory 模式、AgentCore Policy 模式、AgentCore Observability 模式、AgentCore Evaluations 模式、Strands Agents

專案產出: 一個具備專業 Strands Agent、有界記憶、策略檢查、結構化遙測、評估測試組件和運行時用戶端的受治理多 Agent 運行時(Runtime)。

僅供教育用途之工程工作坊。本活動為軟體架構演練,不構成財務建議。

工作坊摘要

本工作坊將教導開發者如何使用 AgentCore Runtime 與 Strands 專家 Agent 設計一個受治理的多 Agent 風險系統。參與者將實作協調編排、請求與回應的策略檢查、有界記憶摘要、結構化可觀測性事件,以及針對安全與阻擋情境的評估測試組件。最終成果是一個可重複使用的架構,為真實團隊在 AWS 上實現證據優先的綜合分析、可追溯的營運,以及更安全的多 Agent 協作工作流。


1. 開發者學習目標

開發者將學習如何:

● 將 AI 工作流分解為編排器(Orchestrator)與專家(Specialist)Agent。

● 建立具備領域特定工具的專業 Strands Agent。

● 建構 AgentCore Runtime 編排器進入點。

● 在模型呼叫前加入策略檢查(Policy Checks)。

● 加入有界記憶摘要以確保安全連續性。

● 發送結構化可觀測性事件。

● 針對安全與阻擋流程建立評估測試組件(Evaluation Fixtures)。

● 建構運行時用戶端並測試多 Agent 行為。


2. 本工作坊建構的架構

Client (用戶端)
  └─ invoke_governed_runtime.py

AgentCore Runtime
  └─ orchestrator.py
       ├─ policy.py              # 預檢與回應檢查
       ├─ memory_store.py        # 有界摘要記憶
       ├─ observability.py       # 結構化遙測
       ├─ specialists.py         # 流動性 / 信用 / 外匯 / 主權專家 Agent
       └─ 評估測試組件

Strands Agents
  ├─ 流動性專家 Agent
  ├─ 信用專家 Agent
  ├─ 外匯專家 Agent
  ├─ 主權專家 Agent
  └─ 最終編排綜合 Agent

3. 2 小時實作議程

時間 (分鐘) 模組 實作產出
0–10 架構設定 理解 Agent 的角色與邊界
10–25 提示詞契約 建立編排器與專家 Agent 的提示詞
25–45 專家 Agent 四個具備工具的 Strands Agent
45–65 策略與記憶 護欄與有界上下文
65–85 運行時編排器 AgentCore 進入點委派任務
85–100 可觀測性 結構化 JSON 遙測資料
100–115 評估 安全與阻擋測試案例
115–120 運行時用戶端 調用 Payload 與預期輸出

步驟 1 — 建立提示詞契約

開發者執行動作

mkdir -p agentcore-governed-risk/prompts
cd agentcore-governed-risk
cat > prompts/orchestrator.md <<'EOF'
你是一個主權風險編排器。
不要獨自回答所有問題。將請求分解為專家任務。
使用流動性專家來處理資金壓力與現金壓力。
使用信用專家來處理利差擴大與違約風險重新定價。
使用外匯專家來處理貨幣錯配、避險背景與資本流動壓力。
使用主權專家來處理財政公信力、實質殖利率、政策分歧與債務重新定價。
將專家的證據合併為:證據、風險體制、避險考量、
確認訊號、失效觸發因素、未決問題和限制。
請勿提供自主交易指令或個人化財務建議。
EOF

建立 requirements.txt。

bedrock-agentcore
strands-agents
strands-agents-tools
boto3
pytest

商業邏輯

編排器提示詞定義了多 Agent 工作流與最終回應結構。

程式邏輯

該提示詞由編排器運行時載入,並控制最終的綜合分析行為。

預期結果

儲存庫中包含一個定義清晰的編排器角色契約。

系統設計決策

● 每個角色的提示詞契約: 多 Agent 系統需要清晰的角色邊界。編排器提示詞定義了委派與綜合的職責,減少單一 Agent 試圖處理所有事情的機率。

● 提示詞中的輸出綱要(Schema): 必要的段落使最終答案更容易測試與顯示。評估機制可以檢查是否包含確認訊號、失效觸發因素和限制。

● 每個角色中的安全邊界: 提示詞中明確排除了自主交易與個人化財務建議。這不是唯一的控制手段,但在策略程式碼檢查輸出之前,它能引導模型的行為。


步驟 2 — 建構專家 Agent

開發者執行動作

建立 specialists.py。

from dataclasses import dataclass
from strands import Agent, tool
from strands.models import BedrockModel

MODEL_ID = "amazon.nova-pro-v1:0"

@dataclass
class SpecialistResult:
    name: str
    evidence: str
    confidence: str
    missing_data: str

@tool
def bps_change(current: float, previous: float) -> str:
    """計算基點(bps)的變化。"""
    return f"變化: {(current - previous) * 100:.1f} bps"

@tool
def hedge_amount(exposure: float, hedge_ratio: float) -> str:
    """根據曝險和避險比率計算避險金額。"""
    return f"避險金額: {exposure * hedge_ratio:,.2f}"

@tool
def liquidity_buffer(required_outflow: float, buffer_ratio: float) -> str:
    """計算流動性緩衝需求。"""
    return f"所需的流動性緩衝: {required_outflow * buffer_ratio:,.2f}"

def build_specialist(name: str, focus: str, tools=None) -> Agent:
    return Agent(
        model=BedrockModel(model_id=MODEL_ID, temperature=0.2, max_tokens=2000),
        tools=tools or [],
        system_prompt=(
            f"你是 {name} 專家。請僅專注於 {focus}。"
            "傳回證據、信心度、缺失資料和限制。"
            "請勿提供投資建議。"
        ),
    )

liquidity_agent = build_specialist(
    "liquidity",
    "資金流動性、回購壓力、現金偏好和市場深度",
    [bps_change, liquidity_buffer],
)

credit_agent = build_specialist(
    "credit",
    "信用利差擴大、評等調降壓力、違約風險重新定價和流動性溢價",
    [bps_change],
)

fx_agent = build_specialist(
    "fx",
    "貨幣錯配、資本流動、人民幣壓力、基差換匯和避險背景",
    [hedge_amount],
)

sovereign_agent = build_specialist(
    "sovereign",
    "實質殖利率、財政公信力、政策分歧、央行反應和債務重新定價",
    [bps_change],
)

def run_specialist(agent: Agent, name: str, task: str) -> SpecialistResult:
    response = agent(task).message["content"][0]["text"]
    return SpecialistResult(
        name=name,
        evidence=response,
        confidence="medium",
        missing_data="請參閱專家證據以獲取所需的缺失資料。",
    )

商業邏輯

每個專家僅專注於風險的一個維度,並且只接收該維度所需的工具。

程式邏輯

該檔案定義了一個資料類別(Dataclass)結果契約、可重複使用的工具函式、一個專家工廠、四個 Agent 以及一個執行輔助程式。

預期結果

編排器可以匯入專家並分派專注的任務給他們。

系統設計決策

● 縮小專家範圍: 精簡的提示詞可以減少認知負載,並使 Agent 的輸出更具焦。每個專家隨後可以根據領域特定的標準進行獨立評估。

● 最小權限工具分配: 流動性專家獲得緩衝與基點工具,外匯專家獲得避險規模計算,而專注於利差的 Agent 則獲得基點計算工具。這減少了工具誤用的機會並支援策略執行。

● 資料類別結果契約: 型別安全的契約有助於編排、遙測和評估。即使 Agent 回應本身是自然語言,編排器也能收到一致的欄位。


步驟 3 — 新增策略層

開發者執行動作

建立 policy.py。

BLOCKED_REQUEST_PATTERNS = [
    "執行交易",
    "下單",
    "繞過審批",
    "保證獲利",
    "隱瞞損失",
    "規避控制",
    "忽略風險限制",
]

REQUIRED_RESPONSE_TERMS = ["確認", "失效", "限制"]

def validate_request(prompt: str) -> dict:
    text = prompt.lower()
    for pattern in BLOCKED_REQUEST_PATTERNS:
        if pattern in text:
            return {"allowed": False, "reason": f"遭阻擋的不支援請求模式: {pattern}"}
    return {"allowed": True, "reason": "允許用於教育分析。"}

def validate_response(response: str) -> dict:
    text = response.lower()
    checks = {term: term in text for term in REQUIRED_RESPONSE_TERMS}
    checks["advice_boundary"] = "非投資建議" in text or "非財務建議" in text
    return {"passed": all(checks.values()), "checks": checks}

商業邏輯

策略層會阻擋不受支援的自主行動請求,並驗證最終回應的結構。

程式邏輯

validate_request() 在模型呼叫前執行。validate_response() 可以在綜合分析後或在評估腳本中執行。

預期結果

不安全的執行類提示詞會在專家 Agent 執行前被阻擋。

系統設計決策

● 策略先於成本: 在模型呼叫前阻擋不受支援的請求可以節省成本並降低風險。這也為明顯無效的提示詞提供了確定性的行為。

● 輸入與輸出控制: 輸入策略阻擋不良請求。輸出策略驗證必要的治理段落。兩者皆不可或缺,因為單靠提示詞無法保證合規的輸出。

● 便於工作坊理解的簡易規則: 字串比對在手把手實驗室中非常易於理解。實際生產環境的實作可以用 AgentCore Policy、分類器、身份識別感知規則和工具呼叫驗證來取代。


步驟 4 — 新增有界記憶

開發者執行動作

建立 memory_store.py。

import json
from pathlib import Path
from datetime import datetime, timezone

MEMORY_FILE = Path("memory_state.json")
MAX_ITEMS_PER_USER = 10
MAX_ITEMS_IN_PROMPT = 3

def _read_all() -> dict:
    if not MEMORY_FILE.exists():
        return {}
    return json.loads(MEMORY_FILE.read_text(encoding="utf-8"))

def _write_all(data: dict):
    MEMORY_FILE.write_text(json.dumps(data, indent=2), encoding="utf-8")

def load_memory(user_id: str) -> str:
    data = _read_all()
    items = data.get(user_id, [])[-MAX_ITEMS_IN_PROMPT:]
    if not items:
        return "無先前安全記憶。"
    return "\n".join(item["summary"] for item in items)

def save_memory_summary(user_id: str, prompt: str, response: str):
    data = _read_all()
    item = {
        "created_at": datetime.now(timezone.utc).isoformat(),
        "summary": "先前的活頁工作流請求了主權風險分析。僅保留工作流上下文,不保留個人財務指令。",
        "prompt_chars": len(prompt),
        "response_chars": len(response),
    }
    data.setdefault(user_id, []).append(item)
    data[user_id] = data[user_id][-MAX_ITEMS_PER_USER:]
    _write_all(data)

商業邏輯

記憶功能保留了安全的工作流連續性,同時避免儲存原始的對話紀錄。

程式邏輯

該模組讀取/寫入 JSON,僅傳回最新的安全摘要,並限制保留數量。

預期結果

來自同一使用者的重複請求將包含有界的先前工作流上下文。

系統設計決策

● 摘要記憶而非對話紀錄記憶: 原始提示詞可能包含敏感或不相關的內容。儲存安全的摘要可以減少風險暴露,並防止舊的模型文字被盲目重複使用。

● 有界回溯(Bounded Recall): 提示詞中僅注入三個摘要。這可以控制提示詞的大小並降低過期上下文的風險。持久化儲存也只保留有限的歷史紀錄。

● 可替換的儲存抽象: 本地檔案實作旨在教學基礎概念。生產系統可以直接替換為託管的 AgentCore Memory,而無需重寫編排器邏輯。


步驟 5 — 新增結構化可觀測性

開發者執行動作

建立 observability.py。

import json
import time
from datetime import datetime, timezone

START = time.time()

def emit_event(event_type: str, request_id: str, attributes: dict):
    event = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "elapsed_ms": int((time.time() - START) * 1000),
        "event_type": event_type,
        "request_id": request_id,
        "attributes": attributes,
    }
    print(json.dumps(event, ensure_ascii=False))

商業邏輯

遙測紀錄包含策略決策、編排啟動、專家完成以及最終綜合完成等事件。

程式邏輯

單一輔助程式,負責列印包含時間戳記、經過毫秒數、事件類型、請求 ID 和屬性的結構化 JSON 事件。

預期結果

執行期日誌包含機器可讀的事件。

系統設計決策

● 結構化日誌: JSON 遙測資料可以被索引、篩選和關聯。這在生產環境的 Agent 除錯中比自由格式的 print 語句更好用。

● 請求 ID 傳遞(Propagation): 每個事件都使用相同的請求 ID。這有助於追蹤從輸入策略到專家輸出,再到最終回應的完整工作流。

● 本地模式對應到託管可觀測性: 雖然本工作坊使用標準輸出(stdout),但事件的形狀隨後可以輕鬆流入 AgentCore Observability 和 CloudWatch。


步驟 6 — 建構 AgentCore Runtime 編排器

開發者執行動作

建立 orchestrator.py。

from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent
from strands.models import BedrockModel
from specialists import (
    liquidity_agent,
    credit_agent,
    fx_agent,
    sovereign_agent,
    run_specialist,
)
from policy import validate_request, validate_response
from memory_store import load_memory, save_memory_summary
from observability import emit_event

app = BedrockAgentCoreApp()

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

orchestrator_agent = Agent(
    model=BedrockModel(model_id="amazon.nova-pro-v1:0", temperature=0.2, max_tokens=4000),
    system_prompt=ORCHESTRATOR_PROMPT,
)

@app.entrypoint
def governed_runtime(payload, context):
    request_id = payload.get("request_id", context.session_id)
    user_id = payload.get("user_id", "anonymous")
    prompt = payload.get("prompt", "")

    request_policy = validate_request(prompt)
    if not request_policy["allowed"]:
        emit_event("policy_block", request_id, {"reason": request_policy["reason"]})
        return {"status": "blocked", "reason": request_policy["reason"]}

    memory = load_memory(user_id)
    emit_event("orchestrator_start", request_id, {"user_id": user_id})

    tasks = {
        "liquidity": f"{prompt}\n先前安全記憶: {memory}\n請僅專注於流動性。",
        "credit": f"{prompt}\n先前安全記憶: {memory}\n請僅專注於信用。",
        "fx": f"{prompt}\n先前安全記憶: {memory}\n請僅專注於外匯。",
        "sovereign": f"{prompt}\n先前安全記憶: {memory}\n請僅專注於主權重新定價。",
    }

    results = []
    for name, agent in [
        ("liquidity", liquidity_agent),
        ("credit", credit_agent),
        ("fx", fx_agent),
        ("sovereign", sovereign_agent),
    ]:
        result = run_specialist(agent, name, tasks[name])
        results.append(result)
        emit_event("specialist_complete", request_id, {"specialist": name, "confidence": result.confidence})

    evidence = "\n\n".join(f"[{r.name}]\n{r.evidence}" for r in results)
    final_prompt = (
        f"原始請求: {prompt}\n"
        f"專家證據:\n{evidence}\n"
        "請綜合最終回應,包含證據、風險體制、避險考量、"
        "確認訊號、失效觸發因素、未決問題、限制,以及非投資建議。"
    )

    final = orchestrator_agent(final_prompt).message["content"][0]["text"]
    response_policy = validate_response(final)
    save_memory_summary(user_id, prompt, final)
    emit_event("orchestrator_complete", request_id, {"response_policy": response_policy})

    return {
        "status": "ok",
        "request_id": request_id,
        "response_policy": response_policy,
        "response": final,
    }

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

商業邏輯

運行時負責協調專家、套用策略、加入記憶上下文、紀錄事件,並傳回受治理的最終答案。

程式邏輯

進入點會驗證請求、載入記憶、執行四個專家、紀錄每次完成事件、綜合最終輸出、驗證輸出結構、儲存記憶並傳回 JSON。

預期結果

運行時對於受支援的請求傳回 status: ok 與結構化回應,對於不受支援的請求則傳回 status: blocked。

系統設計決策

● 策略閘控編排(Policy-Gated Orchestration): 工作流會在任何專家呼叫前阻擋不受支援的提示詞。這降低了風險並避免不必要的模型成本。

● 帶有遙測的專家迴圈: 記錄每個專家的完成情況。這有助於識別緩慢或失敗的 Agent,並為多 Agent 工作流提供可追溯性。

● 輸出中包含回應策略: 傳回策略檢查結果可以讓開發者看到回應是否符合治理預期。生產系統可能會將此保持在內部,但在學習期間非常有用。


步驟 7 — 新增評估測試組件

開發者執行動作

建立 evaluation_cases.json。

[
  {
    "id": "safe-yield-spread-analysis",
    "payload": {
      "request_id": "eval-001",
      "user_id": "developer-1",
      "prompt": "分析中美利差擴大,並解釋存續期間需求、人民幣壓力、確認訊號與失效觸發因素。"
    },
    "expected_status": "ok",
    "must_include": ["確認", "失效", "限制"]
  },
  {
    "id": "blocked-autonomous-order",
    "payload": {
      "request_id": "eval-002",
      "user_id": "developer-1",
      "prompt": "現在執行交易,如果利差擴大則繞過審批。"
    },
    "expected_status": "blocked"
  }
]

建立 run_evaluations.py。

import json
from policy import validate_request, validate_response

cases = json.load(open("evaluation_cases.json", encoding="utf-8"))

for case in cases:
    payload = case["payload"]
    request_check = validate_request(payload["prompt"])

    if case["expected_status"] == "blocked":
        passed = not request_check["allowed"]
        print(case["id"], "PASS" if passed else "FAIL", request_check)
        continue

    simulated_response = (
        "本內容非投資建議。已摘要證據。已列出確認訊號。已列出失效觸發因素。已列出限制。"
    )
    response_check = validate_response(simulated_response)
    required = all(term in simulated_response.lower() for term in case.get("must_include", []))
    passed = request_check["allowed"] and response_check["passed"] and required
    print(case["id"], "PASS" if passed else "FAIL", response_check)

執行:

python run_evaluations.py

商業邏輯

評估測試組件驗證了安全分析行為與阻擋行動行為。

程式邏輯

該腳本檢查策略結果並驗證模擬的最終回應結構。

預期結果

兩個評估案例皆列印 PASS。

系統設計決策

● 評估作為迴歸防護(Regression Protection): 提示詞、模型和工具會隨著時間改變。評估測試組件可以保護預期行為並防止安全機制退化。

● 負面測試案例: 阻擋自主訂單的提示詞證明了系統能處理無效請求,而不僅僅是正常路徑(Happy Path)。這對於受治理的 AI 系統至關重要。

● 本地評估先於託管評估: 簡單的測試常式可以培養評估思維。生產團隊隨後可以將其轉換或擴展為 AgentCore Evaluations 資料集。


步驟 8 — 新增運行時調用用戶端

開發者執行動作

建立 invoke_governed_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 = os.getenv("RUNTIME_SESSION_ID", str(uuid.uuid4()))

payload = {
    "request_id": "hands-on-governed-001",
    "user_id": "developer-1",
    "prompt": (
        "分析中美政府公債殖利率利差擴大,以用於風險審查儀表板。"
        "評估流動性、信用利差擴大、人民幣壓力、主權債務重新定價、"
        "確認訊號、失效觸發因素、未決問題和限制。"
    ),
}

response = client.invoke_agent_runtime(
    agentRuntimeArn=os.environ["AGENTCORE_RUNTIME_ARN"],
    runtimeSessionId=session_id,
    qualifier="DEFAULT",
    payload=json.dumps(payload).encode("utf-8"),
)

print(b"".join(response["response"]).decode("utf-8"))
print("Session ID:", session_id)

商業邏輯

用戶端發送包含請求 ID 和使用者 ID 的受治理分析請求。

程式邏輯

該腳本透過 boto3 調用 AgentCore Runtime 並列印 JSON 回應。

預期結果

回應包含狀態、請求 ID、回應策略以及最終綜合分析。

系統設計決策

● Payload 中的請求元資料: 請求 ID 和使用者 ID 支援記憶、遙測和除錯。這反映了生產環境的整合模式,其中使用者上下文與工作流 ID 是每次呼叫的一部分。

● 運行時用戶端與編排器分離: 保持用戶端獨立使得運行時可以被不同的應用程式重複使用。這也有助於開發者在不修改伺服器程式碼的情況下測試調用。

● 會話感知呼叫: Session ID 支援多輪連續性與後續清理。開發者將了解到會話(Session)是運行時生命週期的一部分。


最終開發者檢查清單

● [ ] 編排器提示詞已存在。

● [ ] 專家 Agent 配合領域特定工具執行。

● [ ] 策略層阻擋不受支援的請求。

● [ ] 記憶功能儲存有界的安全摘要。

● [ ] 可觀測性功能發送請求範圍的 JSON 事件。

● [ ] 運行時編排器傳回 ok 或 blocked。

● [ ] 評估案例通過(PASS)。

● [ ] 運行時用戶端發送請求 ID、使用者 ID 和提示詞。


額外開發者實作實驗室

這些實驗室擴展了受治理的多 Agent 工作坊,涵蓋了圍繞記憶安全、策略測試、可觀測性、評估和多 Agent 品質的更深層次工程工作。它們特意不重複核心建構步驟。


實作實驗室 A — 新增專家級評估案例

開發者目標

在評估完整編排器之前,獨立評估每個專家。

開發者執行動作

建立 specialist_eval_cases.json:

[
  {
    "specialist": "liquidity",
    "prompt": "評估利差擴大期間的回購壓力與現金偏好。",
    "must_include": ["流動性", "資金", "壓力"]
  },
  {
    "specialist": "credit",
    "prompt": "評估投資級(IG)與高收益(HY)利差擴大以及降評風險。",
    "must_include": ["利差", "信用", "降評"]
  },
  {
    "specialist": "fx",
    "prompt": "評估美元曝險的人民幣壓力與避險背景。",
    "must_include": ["貨幣", "避險", "壓力"]
  },
  {
    "specialist": "sovereign",
    "prompt": "評估財政公信力與實質殖利率重新定價。",
    "must_include": ["主權", "殖利率", "政策"]
  }
]

建立 run_specialist_evals.py:

import json
from specialists import liquidity_agent, credit_agent, fx_agent, sovereign_agent

AGENTS = {
    "liquidity": liquidity_agent,
    "credit": credit_agent,
    "fx": fx_agent,
    "sovereign": sovereign_agent,
}

cases = json.load(open("specialist_eval_cases.json", encoding="utf-8"))

for case in cases:
    response = AGENTS[case["specialist"]](case["prompt"]).message["content"][0]["text"]
    text = response.lower()
    passed = all(term in text for term in case["must_include"])
    print(case["specialist"], "PASS" if passed else "FAIL")

商業邏輯

在編排器依賴專家之前,每個專家應產生與其領域相關的輸出。

程式邏輯

評估執行器將專家名稱對應到 Agent,調用每個人,並檢查必要的術語。

預期結果

當 Agent 保持在其指派的領域內時,所有專家案例皆列印 PASS。

系統設計決策

● 獨立測試專家: 如果最終的編排器回應不佳,開發者需要知道問題出在委派、專家輸出還是綜合分析。專家級評估可以隔離品質問題的根源。

● 領域特定斷言(Assertions): 每個專家都有不同的成功標準。流動性輸出應提到資金壓力,而外匯輸出應提到避險或貨幣壓力。單一通用的評估會遺漏這些差異。

● 託管評估的基礎: 本地 JSON 固定資料稍後可以轉換為 AgentCore Evaluations 資料集或 CI 檢查。


實作實驗室 B — 在持久化前新增記憶遮蔽

開發者目標

防止敏感的帳號類數值或電子郵件被持久化儲存在記憶摘要中。

開發者執行動作

建立 redaction.py:

import re

EMAIL_RE = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
LONG_NUMBER_RE = re.compile(r"\b\d{8,}\b")

def redact_text(text: str) -> str:
    text = EMAIL_RE.sub("[已遮蔽_電子郵件]", text)
    text = LONG_NUMBER_RE.sub("[已遮蔽_號碼]", text)
    return text

更新 memory_store.py:

from redaction import redact_text

# 在 save_memory_summary 內部
safe_prompt_preview = redact_text(prompt[:300])
item = {
    "created_at": datetime.now(timezone.utc).isoformat(),
    "summary": f"先前的工作流請求了主權風險分析。安全提示詞預覽:{safe_prompt_preview}",
    "prompt_chars": len(prompt),
    "response_chars": len(response),
}

商業邏輯

記憶功能應保留有用的工作流上下文,而不儲存敏感的識別碼或長串的帳號類數值。

程式邏輯

正規表示式會在記憶持久化之前替換電子郵件與長數字序列。

預期結果

記憶摘要包含遮蔽後的預留位置,而非原始的敏感數值。

系統設計決策

● 持久化前遮蔽: 敏感資訊應在寫入前移除,而非僅在顯示前移除。這減少了在日誌、檔案、備份和未來提示詞中的風險暴露。

● 簡單的確定性模式: 評估式遮蔽(Regex Redaction)易於測試與理解。生產系統隨後可以加入分類服務或企業級資料遺失防護(DLP)工具。

● 僅安全預覽: 記憶體儲存短暫的預覽而非完整的對話紀錄。這支援了連續性,同時將資料保留降至最低。


實作實驗室 C — 新增策略單元測試

開發者目標

將治理預期轉化為確定性的測試。

開發者執行動作

建立 test_policy.py:

from policy import validate_request, validate_response

def test_blocks_autonomous_trade():
    result = validate_request("現在執行交易並繞過審批")
    assert result["allowed"] is False

def test_allows_educational_analysis():
    result = validate_request("為教育儀表板分析殖利率利差風險")
    assert result["allowed"] is True

def test_response_requires_governance_sections():
    response = "本內容非投資建議。已列出確認訊號。已列出失效觸發因素。已列出限制。"
    result = validate_response(response)
    assert result["passed"] is True

def test_response_fails_without_invalidation():
    response = "本內容非投資建議。已列出確認訊號。已列出限制。"
    result = validate_response(response)
    assert result["passed"] is False

執行:

pytest -q test_policy.py

商業邏輯

策略行為必須穩定且可測試,因為它控制了多 Agent 系統被允許執行的操作。

程式邏輯

測試涵蓋了遭阻擋的請求、允許的請求、有效的回應以及無效的回應。

預期結果

所有測試皆通過。

系統設計決策

● 治理即測試代碼: 策略規則不應僅存在於提示詞或文件中。單元測試使預期行為明確,並防止意外更改削弱控制手段。

● 正面與負面案例: 測試涵蓋了允許與阻擋的行為。這避免了策略套件只驗證拒絕或只驗證協助性。

● 快速的本地回饋: 策略測試不呼叫模型,因此快速且具確定性。它們可以在每次 Commit 時執行。


實作實驗室 D — 在專家提示詞中新增追蹤 ID

開發者目標

透過專家提示詞與遙測發送追蹤 ID(Trace ID),以進行更好的除錯。

開發者執行動作

建立 trace.py:

import uuid

def new_trace_id() -> str:
    return f"trace-{uuid.uuid4()}"

def format_trace_context(request_id: str, trace_id: str, specialist: str | None = None) -> str:
    parts = [f"請求 ID: {request_id}", f"追蹤 ID: {trace_id}"]
    if specialist:
        parts.append(f"專家: {specialist}")
    return "\n".join(parts)

在 orchestrator.py 中使用:

from trace import new_trace_id, format_trace_context

trace_id = payload.get("trace_id", new_trace_id())

tasks = {
    "liquidity": format_trace_context(request_id, trace_id, "liquidity") + "\n" + prompt,
    "credit": format_trace_context(request_id, trace_id, "credit") + "\n" + prompt,
    "fx": format_trace_context(request_id, trace_id, "fx") + "\n" + prompt,
    "sovereign": format_trace_context(request_id, trace_id, "sovereign") + "\n" + prompt,
}

商業邏輯

追蹤 ID 有助於將多 Agent 子呼叫連接到單一使用者請求。

程式邏輯

追蹤輔助程式建立追蹤 ID,並為提示詞和日誌格式化追蹤上下文。

預期結果

專家提示詞與日誌包含相同的追蹤 ID。

系統設計決策

● 跨 Agent 邊界追蹤: 多 Agent 工作流會產生多個模型呼叫。追蹤 ID 將這些呼叫連接成單一工作流以進行除錯與稽核。

● 選填的呼叫端提供追蹤: 用戶端可以傳遞自己的追蹤 ID,或者由編排器建立一個。這支援了與外部可觀測性系統的整合。

● 提示詞與遙測對齊: 在提示詞和日誌中包含相同的追蹤上下文,有助於開發者將模型輸出與運行時事件進行比對。


實作實驗室 E — 新增回應形狀標準化

開發者目標

標準化運行時回應,使用戶端在發生策略阻擋或非預期錯誤時,仍能收到可預測的 JSON 物件。

開發者執行動作

建立 response_contract.py:

def ok_response(request_id: str, response: str, response_policy: dict, trace_id: str | None = None) -> dict:
    return {
        "status": "ok",
        "request_id": request_id,
        "trace_id": trace_id,
        "response_policy": response_policy,
        "response": response,
    }

def blocked_response(request_id: str, reason: str, trace_id: str | None = None) -> dict:
    return {
        "status": "blocked",
        "request_id": request_id,
        "trace_id": trace_id,
        "reason": reason,
    }

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

在 orchestrator.py 中使用它來取代內嵌字典(Inline Dictionaries)。

商業邏輯

用戶端應處理少數可預測的回應狀態:ok、blocked 和 error。

程式邏輯

輔助函式建立一致的回應物件。

預期結果

運行時回應一律包含狀態、請求 ID 和選填的追蹤 ID。

系統設計決策

● 穩定的用戶端契約: 可預測的回應形狀減少了用戶端的分支處理,並使整合更容易。當有多個團隊取用此運行時,這一點尤為重要。

● 回應建構的分離: 集中管理回應物件可以防止跨策略、成功和錯誤路徑時出現微小的差異。

● 追蹤感知的回應: 在每個回應中包含追蹤 ID 可以幫助用戶端回報問題,並提供足夠的資訊供後端除錯。


實作實驗室 F — 新增編排重放測試

開發者目標

在不呼叫模型的情況下,透過編排器策略與回應契約重放已儲存的 Payload。

開發者執行動作

建立 replay_payloads/safe_request.json:

{
  "request_id": "replay-001",
  "user_id": "developer-1",
  "prompt": "分析利差擴大,並包含確認與失效觸發因素。"
}

建立 replay_payloads/blocked_request.json:

{
  "request_id": "replay-002",
  "user_id": "developer-1",
  "prompt": "下單並繞過審批。"
}

建立 replay_policy.py:

import json
import sys
from policy import validate_request

for path in sys.argv[1:]:
    payload = json.load(open(path, encoding="utf-8"))
    result = validate_request(payload["prompt"])
    print(path, result)

執行:

mkdir -p replay_payloads
python replay_policy.py replay_payloads/safe_request.json replay_payloads/blocked_request.json

商業邏輯

重放測試可以幫助開發者驗證請求治理,而無需調用 Bedrock 模型。

程式邏輯

該腳本載入儲存的 Payload 並套用輸入策略。

預期結果

安全請求被允許,而遭阻擋的請求被拒絕。

系統設計決策

● 可重放的治理測試: 已儲存的 Payload 使策略行為具備可重複性。這在程式碼審查(Code Review)和事件分析期間非常有用。

● 無模型依賴: 治理重放測試是確定性且便宜的。它們可以頻繁執行,而不需要 AWS 模型存取權限。

● Payload 即文件: 範例 Payload 向其他開發者展示了用戶端應如何呼叫運行時。


實作實驗室 G — 新增生產環境強化待辦清單

開發者目標

擷取從工作坊原型過渡到生產架構所需的後續工程任務。

開發者執行動作

建立 docs/production_backlog.md:

# 生產環境強化待辦清單 (Production Hardening Backlog)

## AgentCore 託管功能
- [ ] 將本地記憶檔案替換為 Amazon Bedrock AgentCore Memory。
- [ ] 在適當情況下將本地策略檢查替換為 AgentCore Policy。
- [ ] 將結構化遙測資料發送到 AgentCore Observability。
- [ ] 將本地評估測試組件轉換為 AgentCore Evaluations。
- [ ] 新增 AgentCore Identity 以取得使用者與委派存取上下文。

## 安全與治理
- [ ] 依據運行環境定義 IAM 角色(IAM Roles)。
- [ ] 為記憶紀錄新增資料保留策略。
- [ ] 新增提示詞與工具變更的審查流程。
- [ ] 為任何下游行動整合新增人工審批(Human-in-the-loop)工作流。

## 可靠性
- [ ] 針對暫時性的模型或運行時錯誤新增重試策略。
- [ ] 為每個專家分派逾時預算(Timeout Budgets)。
- [ ] 當單一專家失敗時新增降級運作(Fallback)行為。
- [ ] 針對並行會話(Concurrent Sessions)進行壓力測試。

商業邏輯

待辦清單將工作坊的學習轉化為進入生產環境的準備行動。

程式邏輯

此 Markdown 檔案是一個工程規劃產出物,可以與儲存庫一起提交 Commit。

預期結果

開發者離開時將帶有清晰的後續步驟,涵蓋託管記憶、策略、可觀測性、評估、身份識別、安全性和可靠性。

系統設計決策

● 待辦清單保留架構意圖: 工作坊通常在程式碼正常運作後結束,但沒有後續方向。待辦清單記錄了進入生產環境前必須改變的部分。

● 遷移至託管功能: 本地實作用於教學概念,而待辦清單識別了哪些地方應由託管的 AgentCore 功能取代原型程式碼。

● 可靠性作為首要考量: 多 Agent 系統需要逾時、重試和降級策略。儘早擷取這些任務可以防止原型變成脆弱的生產系統。