3. 数据源接入基础

在金融智能体的工程实践中,数据源接入是决定智能体“能否看到真实世界”的第一道关口。无论是行情数据、财报公告、宏观经济指标,还是舆情与研报,最终都要通过 API 或文件接口进入智能体的检索增强链路。本节聚焦接入层最核心的五个问题:请求如何发出、身份如何证明、频率如何控制、数据如何解析、异常如何兜底。

一、API 接入原理:一次请求的完整生命周期

金融数据 API 大多基于 HTTP/HTTPS 协议,采用 RESTful 风格。一次典型调用包含四个阶段:构造请求、建立连接、服务端处理、返回响应。理解这条链路,才能在出错时快速定位是网络层、认证层还是业务层的问题。

  • 请求构造:确定 URL、方法(GET/POST)、请求头(Header)、查询参数(Query)或请求体(Body)。
  • 连接与传输:DNS 解析、TLS 握手、发送请求,金融场景通常强制 HTTPS。
  • 服务端处理:网关鉴权、限流、路由到业务服务、查询数据库或行情源。
  • 响应返回:状态码、响应头(含限流信息)、响应体(JSON/XML/CSV)。

下面是一个使用 Python requests 调用行情接口的最小示例,注意请求头中携带了认证信息:

import requests

url = "https://api.example-finance.com/v1/quote"
headers = {
    "Authorization": "Bearer eyJhbGciOiJIUzI1NiIs...",
    "Accept": "application/json"
}
params = {"symbol": "600519.SH", "fields": "open,close,volume"}

resp = requests.get(url, headers=headers, params=params, timeout=5)
print(resp.status_code, resp.headers.get("X-RateLimit-Remaining"))

二、认证方式:从 到 OAuth 2.0

金融数据通常具有商业价值,认证是接入的前提。常见方式有以下几类,选择时需权衡安全性与实现成本。

认证方式典型场景优点风险点
(Header/Query)公开行情、内部服务实现简单易泄露,需配合 HTTPS
Basic Auth传统数据商接口兼容性好Base64 非加密,必须走 TLS
Bearer / JWT多数现代金融 API可携带过期与权限声明需处理刷新与时钟偏移
OAuth 2.0第三方授权、券商开放平台权限粒度细、可撤销流程复杂,需管理 生命周期
签名(HMAC/RSA)交易所、支付类接口防篡改、防重放实现与调试成本高
密钥管理建议:绝不将 硬编码在代码或 Notebook 中,应使用环境变量或密钥管理服务(如 Vault、KMS),并在日志中对密钥做脱敏处理。

三、请求频率限制:限流模型与应对策略

数据提供方为了保护服务稳定,通常会对调用频率设限。常见限流模型包括:固定窗口、滑动窗口、令牌桶与漏桶。响应头中常出现 X-RateLimit-Limit、X-RateLimit-Remaining、Retry-After 等字段,是判断是否触发限流的关键信号。

应对限流的工程手段主要有四种:

  1. 客户端节流:在请求间加入固定间隔,如每秒不超过 5 次。
  2. 指数退避重试:遇到 429 时按 1s、2s、4s 递增等待,避免雪崩。
  3. 批量与缓存:合并多标的请求,对不常变的数据做本地缓存。
  4. 多密钥轮换:在合规前提下分散配额,但需注意服务商条款。
import time, random

def call_with_backoff(fn, max_retry=5):
    for i in range(max_retry):
        resp = fn()
        if resp.status_code == 429:
            wait = (2 ** i) + random.uniform(0, 0.5)
            time.sleep(wait)
            continue
        return resp
    raise RuntimeError("rate limit exceeded after retries")

四、数据格式解析:JSON、XML 与 CSV

金融数据源的返回格式差异很大。JSON 是现代 API 的主流,结构灵活;XML 常见于老牌数据商与监管报送;CSV 多用于批量下载与历史数据。解析时要关注编码、缺失值、时间格式与数值精度。

  • JSON:使用 json.loads 或 resp.json(),注意嵌套层级与 null 值。
  • XML:使用 xml.etree.ElementTree 或 lxml,注意命名空间。
  • CSV:使用 pandas.read_csv,指定 encoding 与 dtype 防止精度丢失。
import pandas as pd

# CSV 解析:指定编码与数值类型
df = pd.read_csv("history.csv", encoding="utf-8",
                 dtype={"symbol": str, "close": float},
                 parse_dates=["trade_date"])
print(df.head())
金融数值务必避免用浮点数直接做金额运算,建议使用 Decimal 或整数分单位;时间字段要统一时区,避免跨市场对齐错误。

五、错误处理与复盘:构建健壮的接入层

接入层的错误可分为四类:网络错误(超时、连接失败)、认证错误(401/403)、限流错误(429)、业务错误(参数非法、标的不存在)。一个健壮的接入层应当对每类错误有明确的处理策略,并记录足够的上下文用于复盘。

下面这张图展示了从请求发出到结果落库的完整判断路径,包括认证、限流、解析与重试分支,可作为接入层设计的参考蓝图。

金融数据源接入:请求生命周期与错误分支 构造请求 URL/Header/Params 认证校验 Key//签名 限流检查 429 / Retry-After 服务端处理 查询/聚合 响应返回 JSON/XML/CSV 格式解析 编码/精度/时区 入库/缓存 结构化存储 认证失败 401/403 刷新 / 检查签名 限流 429 指数退避 + 重试 网络超时 重连 / 降级数据源 业务错误 参数/标的校验 统一日志:request_id / status / latency / retry_count / error_code 用于限流分析、故障定位与数据质量复盘

复盘时建议关注三个指标:成功率、平均延迟、重试占比。若某数据源成功率骤降,优先检查密钥是否过期、配额是否耗尽、接口是否变更字段。常见误区包括:把 429 当成普通失败直接丢弃、忽略响应头中的限流信息、解析 CSV 时不指定编码导致中文乱码、以及对时间字段不做时区统一,最终在检索增强阶段造成数据错配。

接入层的目标不是“能调通”,而是“稳定、可观测、可恢复”。把认证、限流、解析、错误处理做成可复用的客户端模块,后续接入新数据源时只需替换配置,而不是重写逻辑。