← Financial Cloud Cloud Cloud Club · 构建文章

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

使用 AgentCore 与 Strands 构建:Gateway MCP 工具织网开发者工作坊

系列: AgentCore

文章: A1

文章
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
星期五晚上,开始于构建者熟悉的感觉:有一个点子,正卡在问题与可能性之间。

受众: 后端开发人员、AI 平台开发人员、AWS 整合工程师

时长: 2 小时

主要 AWS AI 服务: Amazon Bedrock AgentCore Gateway、Strands Agents、MCP、AWS Lambda

项目产出: 具备本地端 MCP 工具、Lambda 支持的 Gateway 目标、语义搜索以及 Strands 代理调用 functional 的托管型 MCP 工具织网 (Tool Fabric)。

本工作坊仅供教育工程用途。示例中所使用的主权风险(sovereign-risk)领域仅用于教学代理工具架构,不构成任何财务建议。


工作坊摘要

开发人员将构建一个托管型的 Gateway MCP 工具织网,用以连接本地端 MCP 原型设计、Lambda 支持的工具、语义搜索以及 Strands 代理消费(consumption)。本工作坊将引导完成 Schema 设计、本地端探索测试、云目标注册、JSON-RPC 调试以及 SigV4 传输整合。各团队最终将建立一套可扩展的工具治理模式,在复杂的多团队平台工程环境中,于 AWS 上实现可探索、安全且导向证据的代理工具。


1. 开发者学习目标

开发人员将学习如何:

● 设计面向代理的工具名称与 Schema。

● 构建本地端可串流的 HTTP MCP 工具服务器。

● 在云部署前测试 MCP 工具探索。

● 实施由 Lambda 支持的工具商务逻辑。

● 在 Amazon Bedrock AgentCore Gateway 中注册 Lambda 工具。

● 启用意图导向的工具语义搜索。

● 使用 SigV4 传输从 Strands 代理调用 Gateway 工具。

● 新增直接的 JSON-RPC 工具调用测试以进行调试。


2. 本工作坊构建之架构

本地端開發環境
  ├─ mcp_server.py               # 本地端 MCP 伺服器
  ├─ mcp_client_local.py         # 本地端探索用戶端
  ├─ lambda_function.py          # Lambda 目標邏輯
  ├─ package_lambda.sh           # Lambda zip 包裝腳本
  ├─ gateway_setup.py            # Gateway 與目標建立
  ├─ semantic_search.py          # Gateway 語義搜尋呼叫
  ├─ direct_tool_call.py         # JSON-RPC tools/call 除錯
  ├─ strands_gateway_agent.py    # 使用 Gateway MCP 工具的 Strands 代理
  └─ prompts/tool_selection.md

AWS
  ├─ Amazon Bedrock AgentCore Gateway
  ├─ AWS Lambda 目標
  ├─ Cognito / 自訂 JWT 授權器輸入
  ├─ IAM Gateway 角色
  └─ 具備 SigV4 MCP 傳輸的 Strands 代理用戶端

3. 2 小时实施议程

时间 (分钟) 模块 实施产出
0–10 工具织网概念 理解 MCP、Gateway、Lambda 目标流程
10–25 工具契约 规划工具名称、描述与 Schema
25–45 本地端 MCP 服务器 执行可串流的 HTTP 工具服务器
45–60 本地端探索 验证工具列表与中介数据 (Metadata)
60–80 Lambda 目标 包装并部署或准备工具后端
80–100 Gateway 目标 建立 MCP Gateway 与 Lambda 目标
100–110 语义搜索 搜索工具并返回相关工具
110–120 Strands 代理 代理调用 Gateway 工具

步骤 1 — 定义工具选择 Prompt 与 Schema 策略

开发者行动

mkdir -p agentcore-strands-gateway/prompts
cd agentcore-strands-gateway
cat > prompts/tool_selection.md <<'EOF'
您是主權風險工作流程的工具選擇規劃器。
當工具庫規模龐大時,請使用語義搜尋。
選擇能夠回答使用者請求的最精簡工具組合。
回傳選定的工具名稱、引數、預期證據以及選擇理由。
請勿呼叫執行或交易工具。本系統僅用於工程分析。
EOF

建立 tool_schema.py。

TOOL_SCHEMA = [
    {
        "name": "funding_liquidity",
        "description": "評估附買回壓力、貨幣市場壓力、美元融資及現金偏好。",
        "inputSchema": {
            "type": "object",
            "properties": {"query": {"type": "string", "description": "資融通流動性分析請求。"}},
            "required": ["query"],
        },
    },
    {
        "name": "credit_spread_widening",
        "description": "評估投資級/高收益級 (IG/HY) 利差擴大、CDS 壓力、降評風險及流動性溢價。",
        "inputSchema": {
            "type": "object",
            "properties": {"query": {"type": "string", "description": "信用利差分析請求。"}},
            "required": ["query"],
        },
    },
    {
        "name": "sovereign_debt_risk_repricing",
        "description": "評估財政可信度、實質殖利率、政策分歧、資本流動及外匯壓力。",
        "inputSchema": {
            "type": "object",
            "properties": {"query": {"type": "string", "description": "主權風險重估分析請求。"}},
            "required": ["query"],
        },
    },
    {
        "name": "currency_mismatch",
        "description": "評估外匯錯配、外部債務壓力、外匯存底、基差交換及避險背景。",
        "inputSchema": {
            "type": "object",
            "properties": {"query": {"type": "string", "description": "貨幣錯配分析請求。"}},
            "required": ["query"],
        },
    },
]

商务逻辑

Schema 定义了向代理公开的工具词汇表,同时也定义了每个工具负责处理的用户意图。

代码逻辑

每个 Schema 项目包含工具名称、描述、JSON 输入 Schema 以及必要字段。Gateway 设置将会重用相同的 Schema。

预期结果

开发人员拥有单一且权威的工具 Schema 来源,无需在多个脚本中重复复制 Schema。

系统设计决策

● 权威 Schema 来源: 工具 Schema 会影响探索、验证和代理行为。将它们保留在 tool_schema.py 中可防止本地端测试、Gateway 注册与文件之间产生偏离。随着工具型录的增长,这一点至关重要。

● 针对搜索优化的描述: 描述中包含附买回压力、CDS 压力、实质殖利率和外汇压力等商业术语。语义搜索极度依赖有意义的中介数据,因此应将描述视为生产级别的 API 文件。

● 最精简工具组合原则: Prompt 指导代理选择足够的最精简工具组合。这能减少不必要的工具调用、降低延迟,并使审计轨迹更容易审查。


步骤 2 — 构建本地端 MCP 服务器

开发者行动

建立 mcp_server.py。

from mcp.server.fastmcp import FastMCP

mcp = FastMCP(host="0.0.0.0", port=8000, stateless_http=True)

@mcp.tool()
def funding_liquidity(query: str) -> dict:
    """評估附買回壓力、貨幣市場壓力、美元融資及現金偏好。"""
    return {
        "tool": "funding_liquidity",
        "query": query,
        "signals": ["附買回利率", "交換利差", "美元融資", "現金偏好"],
        "summary": "在將利差變動解讀為純粹的信用風險之前,應先檢查資融通壓力。",
    }

@mcp.tool()
def credit_spread_widening(query: str) -> dict:
    """評估投資級/高收益級 (IG/HY) 利差擴大、CDS 壓力、降評風險及流動性溢價。"""
    return {
        "tool": "credit_spread_widening",
        "query": query,
        "signals": ["IG 利差", "HY 利差", "CDS 指數", "降評觀察"],
        "summary": "信用利差擴大可能反映了違約風險重估與流動性撤出。",
    }

@mcp.tool()
def sovereign_debt_risk_repricing(query: str) -> dict:
    """評估財政可信度、實質殖利率、政策分歧、資本流動及外匯壓力。"""
    return {
        "tool": "sovereign_debt_risk_repricing",
        "query": query,
        "signals": ["實質殖利率", "財政路徑", "央行反應", "資本流動"],
        "summary": "主權風險重估應區分財政風險、政策分歧與資本流動壓力。",
    }

@mcp.tool()
def currency_mismatch(query: str) -> dict:
    """評估外匯錯配、外部債務壓力、外匯存底、基差交換及避險背景。"""
    return {
        "tool": "currency_mismatch",
        "query": query,
        "signals": ["外匯存底", "外部債務", "基差交換", "遠期點數"],
        "summary": "當外部融資收緊時,貨幣錯配可能會放大主權壓力。",
    }

if __name__ == "__main__":
    mcp.run(transport="streamable-http")

执行:

python mcp_server.py

商务逻辑

每个 MCP 工具都会返回关于特定风险维度的结构化证据。

代码逻辑

FastMCP 通过可串流的 HTTP 将 Python 函数公开为工具。每个函数接受一个 query 并返回一个字典。

预期结果

本地端 MCP 端点可在 http://localhost:8000/mcp 取得。

系统设计决策

● 结构化工具输出: 返回字典而非纯文字字符串,可为代理和测试提供可检查的字段:工具名称、查询、信号和摘要。这改善了事实接地(grounding)与未来的评估。

● 构建 Gateway 前先建立本地端服务器: 本地端 MCP 测试可降低云复杂性。开发人员先验证工具行为和中介数据,然后再将工具发布到 AgentCore Gateway 后方。

● 无状态工具设计: 工具不依赖隐藏的服务器内存。这使得它们更容易在托管基础设施后方进行扩展、测试与部署。


步骤 3 — 测试本地端 MCP 探索与直接调用

开发者行动

建立 mcp_client_local.py。

import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    async with streamablehttp_client(
        "http://localhost:8000/mcp",
        {},
        timeout=120,
        terminate_on_close=False,
    ) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print("已探索的工具:")
            for tool in tools.tools:
                print("-", tool.name, "|", tool.description)

            result = await session.call_tool(
                "sovereign_debt_risk_repricing",
                {"query": "美中殖利率利差擴大與人民幣壓力"},
            )
            print("直接呼叫結果:")
            print(result)

if __name__ == "__main__":
    asyncio.run(main())

商务逻辑

客户端在引入 Gateway 之前,先验证探索功能与直接执行功能。

代码逻辑

客户端初始化一个 MCP 会话(Session),列出所有工具,然后传入引数调用其中一个工具。

预期结果

控制台印出工具中介数据与结构化的工具执行结果。

系统设计决策

● 探索加上直接调用测试: 单纯列出工具只能证明中介数据的可见性。直接调用能证明工具可接受引数并返回有效的响应。在发布至云前,两者皆为必要测试。

● 无模型参与(No model in the loop): 测试将 MCP 传输和工具行为与 LLM 推理隔离。这使得中断与错误更容易调试。

● 具代表性的查询: 直接调用使用包含殖利率利差与人民币压力的现实场景查询。使用网域专属语言进行测试有助于验证描述和输出的实用性。


步骤 4 — 实施 Lambda 目标逻辑

开发者行动

建立 lambda_function.py。

import json

HANDLERS = {
    "funding_liquidity": {
        "signals": ["附買回壓力", "貨幣市場利差", "美元融資", "交換基差"],
        "summary": "在將殖利率變動視為孤立的主權風險重估之前,請先檢查資融通壓力。",
    },
    "credit_spread_widening": {
        "signals": ["IG 利差", "HY 利差", "CDS 指數", "降評風險"],
        "summary": "信用利差擴大可能代表違約風險重估或流動性溢價擴張。",
    },
    "sovereign_debt_risk_repricing": {
        "signals": ["實質殖利率", "財政可信度", "政策分歧", "資本流動"],
        "summary": "主權風險重估應分解為財政、政策、資金流動與外匯驅動因素。",
    },
    "currency_mismatch": {
        "signals": ["外部債務", "外匯存底", "基差交換", "遠期避險成本"],
        "summary": "當外部再融資條件收緊時,貨幣錯配可能會放大壓力。",
    },
}

def lambda_handler(event, context):
    tool_name = event.get("toolName") or event.get("name")
    arguments = event.get("arguments", {})
    query = arguments.get("query", "")

    if tool_name not in HANDLERS:
        return {
            "statusCode": 404,
            "body": json.dumps({"error": f"未知的工具:{tool_name}"}),
        }

    output = {
        "tool": tool_name,
        "query": query,
        "signals": HANDLERS[tool_name]["signals"],
        "summary": HANDLERS[tool_name]["summary"],
    }
    return {"statusCode": 200, "body": json.dumps(output)}

建立封装辅助脚本:

cat > package_lambda.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
rm -f lambda_function.zip
zip lambda_function.zip lambda_function.py
ls -lh lambda_function.zip
EOF
chmod +x package_lambda.sh
./package_lambda.sh

商务逻辑

Lambda 成为受监管的 Gateway 工具调用后端。它将工具请求对映到结构化的信号输出。

代码逻辑

处理程序(Handler)读取 toolName 和 arguments,验证工具,并返回 JSON。封装脚本则建立一个 zip 成品。

预期结果

lambda_function.zip 已准备就绪,可用于部署或用于预先准备的工作坊引导脚本。

系统设计决策

● Lambda 作为后端边界: Gateway 负责公开工具,而 Lambda 拥有确定性的商务逻辑。这将模型推理与后端执行分离,使工具行为具备可测试性与可观测性。

● 共享处理器对映: 基于字典 carbon 路由机制在保持工作坊精简的同时,展示了多个工具如何对映到单一 Lambda 目标。生产系统随后可将处理程序拆分。

● 结构化响应内文: 返回 tool、query、signals 和 summary,为代理提供了在综合分析前可引用的证据。这也提高了可审计性。


步骤 5 — 建立 AgentCore Gateway 并注册目标

开发者行动

建立 gateway_setup.py。

import os
import boto3
from tool_schema import TOOL_SCHEMA

region = os.getenv("AWS_DEFAULT_REGION", "us-east-1")
client = boto3.client("bedrock-agentcore-control", region_name=region)

gateway = client.create_gateway(
    name="gateway-sovereign-risk-tools-hands-on",
    roleArn=os.environ["AGENTCORE_GATEWAY_ROLE_ARN"],
    protocolType="MCP",
    authorizerType="CUSTOM_JWT",
    authorizerConfiguration={
        "customJWTAuthorizer": {
            "allowedClients": [os.environ["COGNITO_CLIENT_ID"]],
            "discoveryUrl": os.environ["COGNITO_DISCOVERY_URL"],
        }
    },
    protocolConfiguration={
        "mcp": {
            "searchType": "SEMANTIC",
            "supportedVersions": ["2025-03-26"],
        }
    },
    description="主權風險工具實作 MCP Gateway",
)

target = client.create_gateway_target(
    gatewayIdentifier=gateway["gatewayId"],
    name="sovereign-risk-lambda-target",
    description="公開主權風險工具的 Lambda 目標",
    targetConfiguration={
        "mcp": {
            "lambda": {
                "lambdaArn": os.environ["SOVEREIGN_TOOLS_LAMBDA_ARN"],
                "toolSchema": {"inlinePayload": TOOL_SCHEMA},
            }
        }
    },
    credentialProviderConfigurations=[{"credentialProviderType": "GATEWAY_IAM_ROLE"}],
)

print("Gateway ID:", gateway["gatewayId"])
print("Gateway URL:", gateway["gatewayUrl"])
print("Target ID:", target["targetId"])

商务逻辑

Gateway 通过托管的 MCP 端点发布由 Lambda 支持的主权风险工具。

代码逻辑

此脚本建立 Gateway、设置 JWT 授权、启用语义搜索,并使用权威 Schema 注册 Lambda 目标。

预期结果

开发人员获得 Gateway URL 和目标 ID。

系统设计决策

● Gateway 集中化工具访问: AgentCore Gateway 成为代理的托管 MCP 端点。这避免了每个代理都必须直接与 Lambda、验证和传输逻辑整合。

● JWT 入口与 IAM 出口: 入站调用者使用 JWT 进行验证,而 Gateway 使用 IAM 叫用 Lambda。这将调用者授权与后端执行凭证分离。

● 启用语义探索: Gateway 对工具中介数据进行索引以供语义搜索使用。这为大型工具型录做好准备,避免因将所有 Schema 塞入代理内容(Context)而导致 Prompt 膨胀。


步骤 6 — 测试 Gateway 语义搜索与直接 JSON-RPC 调用

开发者行动

建立 semantic_search.py。

import json
import os
import requests

def call_gateway(payload):
    response = requests.post(
        os.environ["AGENTCORE_GATEWAY_URL"],
        json=payload,
        headers={
            "Authorization": f"Bearer {os.environ['AGENTCORE_GATEWAY_JWT']}",
            "Content-Type": "application/json",
        },
        timeout=30,
    )
    response.raise_for_status()
    return response.json()

payload = {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
        "name": "x_amz_bedrock_agentcore_search",
        "arguments": {"query": "人民幣壓力與主權債務風險重估"},
    },
}

print(json.dumps(call_gateway(payload), indent=2))

建立 direct_tool_call.py。

import json
import os
import requests

payload = {
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
        "name": "sovereign_debt_risk_repricing",
        "arguments": {"query": "美中殖利率利差擴大與資本流動壓力"},
    },
}

response = requests.post(
    os.environ["AGENTCORE_GATEWAY_URL"],
    json=payload,
    headers={
        "Authorization": f"Bearer {os.environ['AGENTCORE_GATEWAY_JWT']}",
        "Content-Type": "application/json",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))

商务逻辑

语义搜索通过意图寻找相关工具。直接调用则验证选定的工具是否能通过 Gateway 正确执行。

代码逻辑

这两个脚本都发送 JSON-RPC tools/call 请求。一个调用内建的搜索工具;另一个调用定义的网域工具。

预期结果

搜索返回排名后的工具,直接调用返回由 Lambda 支持的结构化证据。

系统设计决策

● 搜索与直接执行为独立测试: 语义搜索验证探索功能。直接调用验证执行功能。保持两者独立有助于隔离验证、Schema、路由或 Lambda 逻辑中的错误。

● JSON-RPC 调试路径: 当代理行为异常时,直接 HTTP 调用非常有用。开发人员可以重现精确的 Gateway 请求,而无需将模型推理引入流程。

● Bearer 权杖边界: Gateway 调用包含授权标头(Authorization Headers)。这强化了工具探索与执行是受保护的操作,而非匿名 API。


步骤 7 — 从 Strands 代理调用 Gateway

开发者行动

建立 strands_gateway_agent.py。

import os
import boto3
from botocore.credentials import Credentials
from strands import Agent
from strands.models import BedrockModel
from strands.tools.mcp.mcp_client import MCPClient
from streamable_http_sigv4 import streamablehttp_client_with_sigv4

SERVICE = "bedrock-agentcore"

def assume_gateway_role(role_arn: str):
    return boto3.client("sts").assume_role(
        RoleArn=role_arn,
        RoleSessionName="strands-gateway-agent-hands-on",
        DurationSeconds=3600,
    )["Credentials"]

def main():
    region = os.getenv("AWS_DEFAULT_REGION", "us-east-1")
    creds = assume_gateway_role(os.environ["AGENTCORE_GATEWAY_INVOKE_ROLE_ARN"])

    mcp_client = MCPClient(lambda: streamablehttp_client_with_sigv4(
        url=os.environ["AGENTCORE_GATEWAY_URL"],
        credentials=Credentials(
            creds["AccessKeyId"],
            creds["SecretAccessKey"],
            creds["SessionToken"],
        ),
        service=SERVICE,
        region=region,
    ))

    with mcp_client:
        tools = mcp_client.list_tools_sync()
        print("已載入的工具:", [tool.tool_name for tool in tools])

        agent = Agent(
            model=BedrockModel(model_id="amazon.nova-pro-v1:0", temperature=0.2),
            tools=tools,
            system_prompt=(
                "您是使用工具的風險工程助理。 "
                "請先使用 Gateway 工具取得證據。接著綜合分析限制、確認訊號及失效觸發條件。 "
                "請勿提供投資建議或自主交易指令。"
            ),
        )

        result = agent(
            "分析美中殖利率利差擴大所帶來的人民幣壓力、主權債務風險重估以及信用利差擴大。"
        )
        print(result)

if __name__ == "__main__":
    main()

商务逻辑

Strands 代理在编写最终综合分析之前,将 Gateway 工具用作证据来源。

代码逻辑

该脚本扮演一个 IAM 角色、建立 SigV4 MCP 传输、列出 Gateway 工具、将它们加载到 Strands 中并叫用代理。

预期结果

代理印出已加载的工具,并返回基于工具证据的分析。

系统设计决策

● Strands 使用托管型 MCP 工具: 代理不直接调用 Lambda。Gateway 拥有工具公开、验证和转换的所有权。这使得代理独立于后端实施细节。

● 暂时性凭证: 代理使用假设角色(Assumed-role)凭证,减少了长期金钥的外泄风险。IAM 定义了代理拥有哪些 Gateway 访问权限。

● 证据优先的代理 Prompt: 系统 Prompt 要求在综合分析前先取得工具证据。这提高了可审计性,并使输出更容易评估。


开发者最终检查清单

● [ ] 本地端 MCP 服务器正常执行。

● [ ] 本地端 MCP 客户端能列出并调用工具。

● [ ] Lambda zip 封装文件已存在。

● [ ] Gateway 与目标已建立。

● [ ] 语义搜索能返回相关工具。

● [ ] 直接 JSON-RPC 工具调用成功。

● [ ] Strands 代理成功加载 Gateway 工具并产生有根据的输出。


额外实施开发者实验室

这些实验室扩展了 Gateway MCP 工具织网工作坊,涵盖更深入的调试、Schema 治理、验证实务以及代理工具评估。它们刻意与核心构建流程不同,专注于让工具生态系统达到生产就绪状态。


实施实验室 A — 为 MCP 工具定义新增 Schema 检查 (Linting)

开发者目标

在向 AgentCore Gateway 注册之前,先验证工具 Schema 的正确性与质量。

开发者行动

建立 lint_tool_schema.py:

from tool_schema import TOOL_SCHEMA

REQUIRED_TOP_LEVEL = {"name", "description", "inputSchema"}

def lint_tool_schema(schema: list[dict]) -> list[str]:
    errors = []
    names = set()
    for index, tool in enumerate(schema):
        missing = REQUIRED_TOP_LEVEL - set(tool.keys())
        if missing:
            errors.append(f"工具索引 {index} 缺少鍵值:{sorted(missing)}")

        name = tool.get("name")
        if not name:
            errors.append(f"工具索引 {index} 的名稱為空")
        elif name in names:
            errors.append(f"重複的工具名稱:{name}")
        names.add(name)

        description = tool.get("description", "")
        if len(description.split()) < 4:
            errors.append(f"工具 {name} 的描述太短,不利於語義搜尋")

        input_schema = tool.get("inputSchema", {})
        if input_schema.get("type") != "object":
            errors.append(f"工具 {name} 的 inputSchema 必須是 object")
        if "required" not in input_schema:
            errors.append(f"工具 {name} 的 inputSchema 應定義必要欄位 (required)")
    return errors

if __name__ == "__main__":
    errors = lint_tool_schema(TOOL_SCHEMA)
    if errors:
        print("Schema 檢查失敗")
        print("\n".join(errors))
        raise SystemExit(1)
    print(f"已成功驗證 {len(TOOL_SCHEMA)} 個工具 Schema")

执行:

python lint_tool_schema.py

商务逻辑

工具 Schema 是代理 API 的一部分。不良的 Schema 会降低探索质量,并可能导致运行时的叫用失败。

代码逻辑

此代码检查器(Linter)会检查必要字段、重复的工具名称、描述质量、对象 Schema 以及必要的输入字段。

预期结果

已成功驗證 4 個工具 Schema

系统设计决策

● 注册前把关 Schema 质量: Gateway 注册不应该是第一次检查 Schema 的地方。本地端 Linting 可在云资源变更之前捕捉到简单的问题,例如重复名称和不够具体的描述。

● 语义搜索依赖描述: 简短或模糊的描述会降低搜索索引的实用性。Linter 强制执行最低描述质量,因为中介数据对代理而言就是运作行为。

● CI 易整合的快速检查: 当验证失败时,脚本会以状态码 1 结束,使其可以轻松地在 CI 流水线或 pre-commit 勾子(Hooks)中执行。


实施实验室 B — 构建直接面向 Gateway 的 MCP tools/list 测试器

开发者目标

在涉及 Strands 之前,使用原始的 JSON-RPC 调试 Gateway 工具探索功能。

开发者行动

建立 gateway_list_tools.py:

import json
import os
import requests

payload = {
    "jsonrpc": "2.0",
    "id": 100,
    "method": "tools/list",
    "params": {},
}

response = requests.post(
    os.environ["AGENTCORE_GATEWAY_URL"],
    json=payload,
    headers={
        "Authorization": f"Bearer {os.environ['AGENTCORE_GATEWAY_JWT']}",
        "Content-Type": "application/json",
    },
    timeout=30,
)

print("HTTP 狀態碼:", response.status_code)
print(json.dumps(response.json(), indent=2))

商务逻辑

在代理能够调用工具之前,工具探索必须先正常工作。本实验室直接验证 Gateway 的探索功能。

代码逻辑

该脚本向带有 Bearer 权杖的 Gateway 端点发送 JSON-RPC tools/list 请求。

预期结果

响应包含所有已注册的 MCP 工具及其 Schema。

系统设计决策

● 原始协定调试: 当 Strands 代理行为令人困惑时,开发人员需要一个更低阶的测试。JSON-RPC 调用将 Gateway 探索功能与模型推理及 Strands 编排隔离。

● 验证可见性: 该脚本使 Bearer 权杖要求变得明确。这有助于开发人员区分是验证失败还是工具注册失败。

● 维运冒烟测试: tools/list 可以成为部署冒烟测试(Smoke Test),以确认新注册的 Gateway 目标在注册后是否可见。


实施实验室 C — 新增 Gateway 工具调用重放文件 (Replay File)

开发者目标

建立可重复使用的 JSON-RPC 测试负载,以便在调试期间进行重放。

开发者行动

建立 requests/sovereign_repricing_call.json:

{
  "jsonrpc": "2.0",
  "id": 201,
  "method": "tools/call",
  "params": {
    "name": "sovereign_debt_risk_repricing",
    "arguments": {
      "query": "美中殖利率利差擴大、人民幣壓力與資本流動壓力"
    }
  }
}

建立 replay_gateway_request.py:

import json
import os
import sys
import requests

path = sys.argv[1]
payload = json.load(open(path, encoding="utf-8"))

response = requests.post(
    os.environ["AGENTCORE_GATEWAY_URL"],
    json=payload,
    headers={
        "Authorization": f"Bearer {os.environ['AGENTCORE_GATEWAY_JWT']}",
        "Content-Type": "application/json",
    },
    timeout=30,
)
print(json.dumps(response.json(), indent=2))

执行:

mkdir -p requests
python replay_gateway_request.py requests/sovereign_repricing_call.json

商务逻辑

重放文件为调试工具行为和展示预期的 Gateway 响应建立了可重复的证据。

代码逻辑

重放脚本从磁盘加载 JSON 负载并将其张贴(Post)到 Gateway。

预期结果

相同的工具调用可以重复重放,而无需重写 Python 代码。

系统设计决策

● 可重现的工具调试: 存储的 JSON-RPC 负载使得重现 Bug 和比较跨部署的响应变得容易。当工具 Schema 或 Lambda 逻辑变更时,这非常有用。

● 请求与执行器的分离: 请求文件是数据,而 Python 脚本是通用的执行器。这允许许多测试案例重用同一个客户端。

● 具备文件价值: 重放文件可兼作示例,供其他需要了解如何直接调用 Gateway 工具的开发人员参考。


实施实验室 D — 为 Strands 响应新增工具结果标准化

开发者目标

在代理综合最终答案之前,先将工具输出标准化(Normalize)。

开发者行动

建立 tool_result_normalizer.py:

import json

def normalize_tool_result(raw_result) -> dict:
    if isinstance(raw_result, dict):
        return raw_result

    if isinstance(raw_result, str):
        try:
            return json.loads(raw_result)
        except json.JSONDecodeError:
            return {"raw_text": raw_result}

    if isinstance(raw_result, list):
        return {"items": raw_result}

    return {"repr": repr(raw_result)}

在调试代码中使用它:

from tool_result_normalizer import normalize_tool_result

# 假設 result 是來自先前工具呼叫的輸出
normalized = normalize_tool_result(result)
print(normalized)

商务逻辑

代理可能会收到各种不同形状的工具输出。标准化使得下游的证据处理变得可预测。

代码逻辑

此辅助工具将字典、JSON 字符串、列表和未知对象转换为统一的字典形状。

预期结果

工具输出可以被一致地记录、评估与呈现。

系统设计决策

● 可预测的证据格式: 工具输出应尽可能可供机器读取。标准化允许客户端和评估机制检查字段,而不必依赖每个后端都返回完全相同的形状。

● 防御性整合: Gateway 目标可能会演进或返回非预期的负载。标准化可防止脆弱的代理包装器(Wrappers)因微小的输出形状变更而失败。

● 评估准备就绪: 一致的工具证据使得检查最终代理响应是否使用了预期的工具和信号变得更加容易。


实施实验室 E — 新增语义搜索比较测试

开发者目标

比较不同用户意图的语义搜索结果,并验证预期工具是否出现在前几名结果中。

开发者行动

建立 semantic_search_eval.py:

import json
import os
import requests

CASES = [
    {"query": "附買回融資壓力與現金偏好", "expected": "funding_liquidity"},
    {"query": "CDS 擴大與降評風險", "expected": "credit_spread_widening"},
    {"query": "財政可信度與實質殖利率重估", "expected": "sovereign_debt_risk_repricing"},
    {"query": "外匯存底與外部美元債務", "expected": "currency_mismatch"},
]

def search(query: str) -> list[str]:
    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "tools/call",
        "params": {
            "name": "x_amz_bedrock_agentcore_search",
            "arguments": {"query": query},
        },
    }
    response = requests.post(
        os.environ["AGENTCORE_GATEWAY_URL"],
        json=payload,
        headers={"Authorization": f"Bearer {os.environ['AGENTCORE_GATEWAY_JWT']}"},
        timeout=30,
    ).json()
    tools = response.get("result", {}).get("structuredContent", {}).get("tools", [])
    return [tool.get("name") for tool in tools]

for case in CASES:
    names = search(case["query"])
    passed = case["expected"] in names[:3]
    print(case["query"], "【通過】" if passed else "【失敗】", names[:3])

商务逻辑

语义搜索的质量决定了代理是否能针对商业语言请求找到正确的工具。

代码逻辑

该脚本执行多个搜索查询,并检查预期工具是否出现在前三个结果中。

预期结果

每个测试案例都会印出「通过」或「失败」以及前三名匹配的工具。

系统设计决策

● 搜索质量作为可测试行为: 语义搜索应像任何其他功能一样进行验证。如果描述或 Schema 变更,搜索质量可能会退化。

● 基于意图的测试案例: 案例使用商业语言而非精确的工具名称。这测试了中介数据是否能支持真实的用户 Prompt。

● Top-K 容差: 检查前三个结果比每次都要求第一个结果更具现实意义。语义检索对相似工具的排名可能略有不同,但预期的工具仍应保持可探索性。


实施实验室 F — 新增最低权限环境检查清单

开发者目标

在晋升到生产环境之前,为 Gateway 工具织网建立一份维运检查清单。

开发者行动

建立 docs/gateway_operational_checklist.md:

# Gateway 維運檢查清單

## 身分識別與授權
- [ ] Gateway 使用 CUSTOM_JWT 授權器。
- [ ] 允許的用戶端限制在經批准的應用程式用戶端。
- [ ] 權杖(Token)生命週期和重新整理(Refresh)程序已記載於文件。

## IAM 與目標存取
- [ ] Gateway 角色僅能叫用經批准的 Lambda 目標。
- [ ] Lambda 資源政策不允許廣泛的公開叫用。
- [ ] 開發人員憑證未內嵌於程式碼中。

## 工具治理
- [ ] 工具 Schema 在註冊前已通過 Lint 檢查。
- [ ] 工具描述長度足夠,利於語義搜尋。
- [ ] 工具輸出為結構化且具備可稽核性。
- [ ] 危險或執行/交易導向的工具未註冊到此分析 Gateway。

## 可觀測性
- [ ] 已監控 Gateway 目標叫用錯誤。
- [ ] Lambda 日誌包含請求 ID 或工具名稱。
- [ ] Schema 變更後語義搜尋測試均通過。

商务逻辑

检查清单可帮助平台团队在广泛公开工具之前,审查安全性、治理和可观测性。

代码逻辑

这是 Markdown 文件,但它会成为 Pull Request 和生产环境审查的维运构件(Artifact)。

预期结果

团队拥有一份可用于 Gateway 工具织网的重复性就绪检查清单。

系统设计决策

● 文件即控制(Documentation as control): 维运检查清单可防止重要的生产环境疑虑流于部落知识。当多个团队发布工具时,这特别有用。

● 聚焦最低权限: Gateway 集中了工具访问权,因此必须仔细审查 IAM 和 JWT 边界。检查清单使这些边界变得明确。

● 晋升闸门(Promotion Gate): 检查清单可以作为一个发布要求,在 Gateway 目标从工作坊移至共享开发或生产环境之前进行核对。