亚马逊AWS官方博客

用 Hermes Agent 在 AWS 上搭建投研助手

摘要:本文完整记录了在 AWS EC2(Amazon Linux)上安装 Hermes Agent,通过 LiteLLM 代理 Amazon Bedrock 模型、连接飞书,并配置多市场金融数据源(A 股、美股、港股、外汇)和投研 Skill 的全过程。Hermes Agent 在本文写作时的版本(v0.8.0)尚未原生支持 Bedrock,本文通过 LiteLLM 代理提供了一个实际验证过的接入方案。所有数据源均基于开源免费接口,可直接复现。


⚠️ 风险提示:本文仅为技术演示,不构成任何投资建议,据此操作风险自担。金融数据的商业使用需确认数据源许可协议。

一、第一部分:AWS 部署与消息平台集成

1. Hermes Agent 简介

Hermes Agent 是 Nous Research 开发的开源自托管 AI Agent 平台,运行在用户自有服务器上,支持飞书、Telegram、Slack 等多种消息平台交互,具备跨会话记忆、定时任务和丰富的内置工具等能力。本文重点解决的问题是:Hermes Agent v0.8.0 尚未原生支持 Bedrock,需要通过 LiteLLM 代理接入。

2. 环境准备

2.1 运行环境

  • EC2 实例:Amazon Linux 2023(ARM / x86 均可)
  • IAM Role:需要 Bedrock 调用权限
  • 前置条件:Git 已安装(安装器会自动处理 Python、Node.js 等其他依赖)
2.2 IAM Role 权限

EC2 的 IAM Role 需要有 Bedrock 模型调用权限。基础权限策略示例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "BedrockInvoke",
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": "arn:aws:bedrock:*::foundation-model/*"
    }
  ]
}

生产环境建议将 Resource 收窄到实际使用的模型 ARN,例如 arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-sonnet-4-6。

3. 安装 LiteLLM 代理 Bedrock

Hermes Agent v0.8.0 尚未支持原生 Bedrock 调用。如需使用 Claude 等 Bedrock 上的模型,需要通过 LiteLLM 搭建一层 OpenAI 兼容的代理。AWS 已经提供了生产级的 LiteLLM 部署方案——Guidance for Multi-Provider Generative AI Gateway on AWS,基于 ECS/EKS,包含 WAF、监控和多租户支持。本文以快速验证为目的,采用最简单的本地部署方式,不建议直接用于生产环境。

3.1 安装并配置

pip3 install 'litellm[proxy,bedrock]'

创建 litellm_config.yaml

model_list:
  - model_name: claude-sonnet-4-6
    litellm_params:
      model: bedrock/global.anthropic.claude-sonnet-4-6
      aws_region_name: us-west-2
3.2 启动并验证

nohup litellm --config litellm_config.yaml --port 4000 > litellm.log 2>&1 &

验证:

curl http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [{"role": "user", "content": "你好"}],
    "max_tokens": 100
  }'

收到正常的 JSON 响应即表示代理运行正常。

生产环境建议直接使用上述Guidance for Multi-Provider Generative AI Gateway on AWS 官方方案。

4. 安装与配置 Hermes Agent

4.1 一键安装

# 确保 git 已安装
sudo dnf install -y git

# 一键安装
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
⚠️ 安全提示:上述命令会直接执行远程脚本。建议先下载脚本审查内容后再运行,或在隔离环境中执行。

安装过程大约需要 10 分钟,安装器会自动处理 Python、Node.js、ripgrep、ffmpeg 等所有依赖。

[图1:安装过程]

安装完成后,重新加载 shell:

source ~/.bashrc
4.2 配置模型(关键步骤)

安装完成后运行 hermes setup,会进入初始化向导,主要需要配置模型和消息平台。消息平台(飞书、Telegram 等)的接入配置请参考 Hermes Agent 官方文档,本文不再赘述。

由于 Hermes Agent v0.8.0 尚未原生支持 Bedrock,在模型配置环节选择 Custom Endpoint,填入 LiteLLM 的地址:

[图2:模型配置——选择 Custom Endpoint]

  • Base URL:http://localhost:4000/v1
  • Model:claude-sonnet-4-6
  • API Key:如未在 LiteLLM 中设置 API Key,可留空

也可以通过命令行直接配置:

hermes model
4.3 验证安装

hermes doctor    # 诊断检查
hermes status    # 查看配置状态

Hermes Agent 和 OpenClaw 可以共存部署在同一台 EC2 上。若已部署 OpenClaw,hermes claw migrate 可一键导入已有的记忆、Skill 和配置(建议先用 --dry-run 预览)。

二、第二部分:FSI 数据源接入与投研 Skill 配置

5. 整体架构

飞书用户 ──WebSocket──▶ Hermes Agent ──▶ LiteLLM ──▶ Bedrock Claude
                              │
                              ├── Skill: A 股查询    ──▶ AKShare (免费)
                              ├── Skill: 美股查询    ──▶ yfinance (免费)
                              ├── Skill: 港股查询    ──▶ AKShare (免费)
                              ├── Skill: 外汇追踪    ──▶ AKShare + exchangerate-api (免费)
                              ├── Skill: 研报摘要    ──▶ Bedrock Claude
                              ├── Skill: 量化因子    ──▶ AKShare (免费)
                              └── Skill: 深度分析    ──▶ Claude + 多数据源聚合
前置条件:已完成第一部分的全部部署, hermes doctor 检查通过,消息平台收发正常。

6. 开源金融数据源总览

本文所有数据源均基于开源库或免费接口,无需 API Key 即可用于技术验证(部分有频率限制)。商业使用前请确认各数据源的许可协议和服务条款。

数据源 覆盖市场 Python 包 特点
AKShare A 股、港股、期货、外汇、宏观 akshare 国内全面的开源金融数据接口
yfinance 美股、全球主要市场 yfinance Yahoo Finance 非官方接口,全球覆盖,商业使用需评估 ToS
exchangerate-api 全球外汇 requests 免费汇率 API,每日更新
pandas-datareader 美股、宏观经济 pandas-datareader FRED、World Bank 等宏观数据
付费数据源(Tushare Pro、Wind、Bloomberg)可通过相同的 Skill 框架接入,本文不展开。
6.1 一键安装所有依赖

pip3 install akshare yfinance pandas-datareader PyMuPDF requests

7. 数据源接入与 API 速查

7.1 A 股(AKShare)

pip3 install akshare
import akshare as ak

# 验证:获取 A 股实时行情
df = ak.stock_zh_a_spot_em()
print(df[['代码', '名称', '最新价', '涨跌幅', '成交额']].head(5))

# 个股历史 K 线
df_hist = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="20260101", end_date="20260414", adjust="qfq")

# 财务报表
df_balance = ak.stock_financial_abstract_ths(symbol="000001", indicator="按年度")

# 北向资金(沪股通+深股通)
df_north = ak.stock_hsgt_north_net_flow_in_em(symbol="北上")

# 板块行情(行业/概念)
df_sector = ak.stock_board_industry_name_em()

# 指数行情
df_index = ak.stock_zh_index_daily_em(symbol="sh000001")  # 上证指数
7.2 其他市场

市场 Python 包 关键调用示例
美股 yfinance yf.Ticker(“AAPL”).info — 实时报价、市值、PE、EPS
美股 yfinance yf.Ticker(“AAPL”).history(period=”3mo”) — K 线
美股 yfinance yf.Ticker(“AAPL”).income_stmt — 财务报表
美股 yfinance yf.Ticker(“^VIX”).history(period=”2d”) — VIX 恐慌指数
港股 akshare ak.stock_hk_spot_em() — 港股实时行情
港股 akshare ak.stock_hk_hist(symbol=”00700″, period=”daily”, …) — K 线
港股 yfinance yf.Ticker(“0700.HK”).info — 港股代码格式:数字.HK
外汇 akshare ak.currency_boc_sina(symbol=”美元”, …) — 中国银行牌价
外汇 requests requests.get(“https://open.er-api.com/v6/latest/USD”) — 免费全球汇率
外汇 yfinance yf.Ticker(“USDCNY=X”).history(period=”1d”) — 实时汇率
以上数据源均可免费用于个人学习和技术验证。yfinance 为 Yahoo Finance 非官方接口,商业使用需自行评估合规性。部分 API免费版有频率限制,高频调用可能被限流。

8. 投研 Skill 配置

Hermes Agent 的 Skill 采用 agentskills.io 定义的 SKILL.md 格式。所有技能位于 ~/.hermes/skills/ 目录下,每个 Skill 是一个包含 SKILL.md(主文件)和可选 scripts/(辅助脚本)的目录。

技能采用渐进披露模式加载:Agent 先看到技能列表(Level 0),需要时才加载完整内容(Level 1),有效节省 token。

前置条件:Python 虚拟环境已创建并安装依赖:

python3 -m venv ~/myenv
source ~/myenv/bin/activate
pip3 install akshare yfinance pandas-datareader PyMuPDF requests

后续所有 Skill 脚本通过 ~/myenv/bin/python3 调用,无需 activate。

8.1 Skill:全球市场速查(多市场聚合)

这是核心 Skill,聚合 A 股、美股、港股、外汇,一条命令查询全球市场。

目录结构:

~/.hermes/skills/fsi/global-market/
├── SKILL.md
└── scripts/
    └── run.py

8.1.1 SKILL.md

---
name: global-market
description: 全球金融市场速查,支持 A 股、美股、港股、外汇,自动识别市场并路由到对应数据源
version: 1.0.0
platforms: [linux]
metadata:
  hermes:
    tags: [finance, market-data, fsi]
    category: fsi
    requires_toolsets: [terminal]
---
# 全球市场速查## When to Use- 用户查询任何股票、货币的行情
- 用户说"查一下 XXX"、"XXX 行情"、"XXX 最新价"
- 用户说"全球市场"查看概览

## Procedure1. 接收用户查询关键词
2. 执行脚本自动识别市场类型(A 股/美股/港股/外汇)并返回行情:
   ```bash
   ~/myenv/bin/python3 ~/.hermes/skills/fsi/global-market/scripts/run.py "用户查询内容"
   ```3. 将结果格式化后返回给用户

## Pitfalls- AKShare 接口在非交易时间可能返回上一交易日数据
- yfinance 偶尔被 Yahoo 限流,重试即可
- 港股代码需 5 位数字(如 00700),美股代码为 1-5 位英文字母

## Verification
脚本返回包含价格、涨跌幅等信息的格式化文本,无报错即成功。

8.1.2 scripts/run.py

#!/usr/bin/env python3"""全球市场速查 Skill — 自动识别市场并路由到对应数据源"""import sys
import re

def detect_market(query):
    """根据输入自动判断市场类型"""
    q = query.upper().strip()
    
    # 外汇
    fx_keywords = ['汇率', '美元', '欧元', '日元', '英镑', '比索', '印尼盾', '新加坡元', '澳元', '加元', '港币']
    for kw in fx_keywords:
        if kw in query:
            return 'fx', query
    if re.match(r'^[A-Z]{6}$', q):  # USDCNY 格式return 'fx', q
    
    # 港股if q.endswith('.HK') or q.startswith('0') and len(q) == 5:
        return 'hk', q.replace('.HK', '')
    
    # 美股(纯英文字母,2-5 位)if re.match(r'^[A-Z]{1,5}$', q) and q not in ['SH', 'SZ', 'HK']:
        return 'us', q
    
    # A 股(默认)return 'a', query

def query_a_stock(query):
    import akshare as ak
    df = ak.stock_zh_a_spot_em()
    match = df[df['名称'].str.contains(query) | df['代码'].str.contains(query)]
    if match.empty:
        return f"A 股未找到「{query}」"
    row = match.iloc[0]
    lines = [
        f" {row['名称']}({row['代码']})",
        f"最新价: ¥{row['最新价']}  涨跌幅: {row['涨跌幅']}%",
        f"成交额: {float(row['成交额'])/1e8:.2f}亿  换手率: {row['换手率']}%",
        f"PE: {row.get('市盈率-动态', 'N/A')}  PB: {row.get('市净率', 'N/A')}",
    ]
    return "\n".join(lines)

def query_us_stock(symbol):
    import yfinance as yf
    ticker = yf.Ticker(symbol)
    info = ticker.info
    if 'currentPrice' not in info:
        return f"美股未找到「{symbol}」"
    lines = [
        f" {info.get('shortName', symbol)}({symbol})",
        f"最新价: ${info['currentPrice']}  市值: ${info.get('marketCap', 0)/1e9:.1f}B",
        f"PE: {info.get('trailingPE', 'N/A')}  EPS: ${info.get('trailingEps', 'N/A')}",
        f"52周范围: ${info.get('fiftyTwoWeekLow', 'N/A')} - ${info.get('fiftyTwoWeekHigh', 'N/A')}",
    ]
    return "\n".join(lines)

def query_hk_stock(code):
    import akshare as ak
    df = ak.stock_hk_spot_em()
    match = df[df['代码'] == code]
    if match.empty:
        match = df[df['名称'].str.contains(code)]
    if match.empty:
        return f"港股未找到「{code}」"
    row = match.iloc[0]
    lines = [
        f" {row['名称']}({row['代码']}.HK)",
        f"最新价: HK${row['最新价']}  涨跌幅: {row['涨跌幅']}%",
    ]
    return "\n".join(lines)

def query_fx(query):
    import requests
    resp = requests.get("https://open.er-api.com/v6/latest/USD", timeout=10)
    data = resp.json()
    
    currency_map = {
        "美元": "CNY", "人民币": "CNY", "欧元": "EUR", "日元": "JPY",
        "英镑": "GBP", "比索": "MXN", "墨西哥": "MXN",
        "印尼盾": "IDR", "印尼": "IDR", "菲律宾": "PHP",
        "新加坡": "SGD", "澳元": "AUD", "加元": "CAD",
        "港币": "HKD", "新台币": "TWD",
    }
    
    target = Nonefor kw, code in currency_map.items():
        if kw in query:
            target = code
            breakif target:
        rate = data['rates'].get(target, 'N/A')
        cny_rate = data['rates'].get('CNY', 1)
        lines = [f" 1 USD = {rate} {target}", f" 1 USD = {cny_rate} CNY"]
        return "\n".join(lines)
    
    # 显示所有出海相关汇率
    pairs = {"CNY": "人民币", "MXN": "墨西哥比索", "IDR": "印尼盾",
             "PHP": "菲律宾比索", "SGD": "新加坡元", "HKD": "港币"}
    lines = [" 出海汇率速查(基准: 1 USD)"]
    for code, name in pairs.items():
        lines.append(f"  {name}({code}): {data['rates'].get(code, 'N/A')}")
    return "\n".join(lines)

def main(query):
    market, parsed = detect_market(query)
    
    handlers = {
        'a': query_a_stock,
        'us': query_us_stock,
        'hk': query_hk_stock,
        'fx': query_fx,
    }
    
    return handlers[market](parsed)

if __name__ == "__main__":
    query = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "全球市场"print(main(query))

[图3:全球市场速查]

8.2 Skill:市场情绪因子监控

目录结构:

~/.hermes/skills/fsi/quant-monitor/
├── SKILL.md
└── scripts/
    └── run.py

8.2.1 SKILL.md

---
name: quant-monitor
description: 量化市场因子监控——A 股涨跌统计、北向资金、VIX、美股指数,一键获取市场情绪快照
version: 1.0.0
platforms: [linux]
metadata:
  hermes:
    tags: [finance, quant, monitoring, fsi]
    category: fsi
    requires_toolsets: [terminal]
---
# 量化因子监控## When to Use- 用户说"市场因子"、"北向资金"、"量化日报"、"市场情绪"
- 每日开盘前/收盘后获取市场全景快照
- 配合定时任务(cron)自动推送到飞书

## Procedure1. 执行量化因子快照脚本:
   ```bash
   ~/myenv/bin/python3 ~/.hermes/skills/fsi/quant-monitor/scripts/run.py
   ```2. 脚本自动采集以下因子并汇总:
   -  A 股涨跌家数、涨停/跌停数
   - 北向资金净流入
   -  VIX 恐慌指数(<20 / <30 / ≥30)
   - S&P 500、NASDAQ 指数涨跌
3. 将快照结果返回给用户

## Pitfalls- A 股数据仅交易时间实时,非交易时间为上一交易日收盘数据
- 北向资金接口偶尔延迟,可能返回前一日数据
- 各数据源独立 try/except,单个失败不影响整体输出

## Verification
脚本输出包含时间戳和至少 3 个市场板块的因子数据

8.2.2 scripts/run.py

#!/usr/bin/env python3"""量化因子监控 Skill — A 股 + 美股联动"""import akshare as ak
import yfinance as yf
from datetime import datetime

def get_quant_snapshot():
    result = [f" 量化因子快照 — {datetime.now().strftime('%Y-%m-%d %H:%M')}"]
    result.append("=" * 40)
    
    # A 股指数try:
        df = ak.stock_zh_a_spot_em()
        up = len(df[df['涨跌幅'] > 0])
        down = len(df[df['涨跌幅'] < 0])
        limit_up = len(df[df['涨跌幅'] >= 9.9])
        limit_down = len(df[df['涨跌幅'] <= -9.9])
        result.append(f"\n A 股")
        result.append(f"  涨跌家数: {up}↑ / {down}↓  涨停/跌停: {limit_up}/{limit_down}")
    except Exception:
        pass# 北向资金try:
        df_n = ak.stock_hsgt_north_net_flow_in_em(symbol="北上")
        if not df_n.empty:
            latest = df_n.iloc[-1]
            result.append(f"  北向净流入: {latest['当日净流入']:.2f}亿")
    except Exception:
        pass# 美股 VIXtry:
        vix = yf.Ticker("^VIX")
        hist = vix.history(period="2d")
        if not hist.empty:
            current = hist['Close'].iloc[-1]
            prev = hist['Close'].iloc[-2] if len(hist) > 1 else current
            change = (current - prev) / prev * 100
            emoji = "LOW" if current < 20 else "MID" if current < 30 else "HIGH"
            result.append(f"\n 美股")
            result.append(f"  {emoji} VIX: {current:.2f} ({change:+.1f}%)")
    except Exception:
        pass# 美股主要指数try:
        for name, sym in [("S&P 500", "^GSPC"), ("NASDAQ", "^IXIC")]:
            t = yf.Ticker(sym)
            h = t.history(period="2d")
            if len(h) >= 2:
                chg = (h['Close'].iloc[-1] - h['Close'].iloc[-2]) / h['Close'].iloc[-2] * 100
                result.append(f"  {name}: {h['Close'].iloc[-1]:,.0f} ({chg:+.2f}%)")
    except Exception:
        passreturn "\n".join(result)

if __name__ == "__main__":
    print(get_quant_snapshot())
8.3 从 Skills Hub 安装第三方技能

除了自己编写 Skill,Hermes 还支持直接安装社区或官方发布的技能。例如,安装一个新闻资讯类 Skill,配合前面的行情数据,就能让 Agent 自动分析股票涨跌背后的原因。

8.3.1 搜索与安装

# 搜索资讯/新闻相关技能
hermes skills search news
hermes skills search finance --source skills-sh

# 浏览官方可选技能
hermes skills browse --source official

# 安装(以某个资讯技能为例)
hermes skills install <source>/<skill-name>

# 查看已安装的技能
hermes skills list --source hub

8.3.2 组合使用示例

安装资讯类 Skill 后,就可以在对话中将多个 Skill 串联使用。

用户:XXX 今天为什么跌了?

Agent 执行流程:
  1. /global-market XXX          → 获取实时行情,确认跌幅
  2. /news-search XXX            → 抓取近期相关新闻(第三方 Skill)
  3. Agent 综合行情 + 新闻,输出分析结论

自建 Skill 负责拉行情数据,第三方 Skill 负责补资讯,Agent 把两边结果综合起来给出分析——不需要用户手动调度,Skill 之间的编排由 Agent 根据上下文自动判断。

[图4:交易建议]

安装第三方技能时,请注意识别技能来源。

9. 安全与合规

建议在部署时参考以下安全措施:

安全措施 说明
飞书 WebSocket 出站连接,无需开放入站端口
Bedrock VPC Endpoint 配置后模型调用走内网(需额外配置)
SSM Session Manager 服务器管理走内网,无需 SSH
用户白名单 FEISHU_ALLOWED_USERS 限制授权用户
IAM 最小权限 仅 bedrock:InvokeModel,生产环境建议收窄 Resource 到实际使用的模型 ARN
非 root 运行 专用用户运行 Hermes Agent
如果使用 sample-OpenClaw-on-AWS-with-Bedrock 方案部署 EC2,VPC Endpoint 和 SSM 配置已自动包含。
⚠️ 风险提示:本文仅为技术演示,不构成任何投资建议,据此操作风险自担。金融数据的商业使用需确认数据源许可协议。

三、结语

➡️ 下一步行动:

相关产品:

  • Amazon Bedrock — 用于构建生成式人工智能应用程序和代理的端到端平台
  • Amazon EC2 — 安全且可调整大小的计算容量
  • Amazon IAM — 身份管理和访问权限
  • Amazon VPC — 隔离云网络
  • Amazon ECS — 完全托管的容器编排服务

相关文章:

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

刘振华

亚马逊云科技高级解决方案架构师。在加入 AWS 之前,曾在埃森哲、众安保险、华为等企业担任核心技术岗位,主导过多个大型软件系统的架构设计、研发交付与项目管理,积累了丰富的企业级实战经验。深耕 SaaS 与企业数智化转型领域,为金融、医疗健康与生命科学(HCLS)等行业客户提供云架构规划、迁移上云及现代化改造等技术咨询与赋能服务。当前聚焦于生成式 AI 技术在中国企业的落地实践,围绕 AI 编程助手、智能数据分析、AI for Science 等方向,帮助客户探索创新路径,加速业务智能化升级。

陈春辉

亚马逊云科技解决方案架构师,在架构与开发领域有非常丰富的实践经验。


AWS 架构师中心:云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用