# 给 AI agent 接入 BlockVectra：llms.txt、OpenAPI 与公开 JSON

> 原文地址: https://docs.blockvectra.com/zh/guides/ai-agents/

自动化 AI agent 与大语言模型（LLM）工具需要稳定的发现机制与机器可读的规格。BlockVectra 提供了机器可读的上下文文件、标准 OpenAPI 3.1 规格，以及无需 API key 的公开 JSON 接口，让 agent 能自行查看支持的链、检查运行状态并发起 RPC 调用。

## 1. 机器可读的上下文与规格文件 [#1-机器可读的上下文与规格文件]

BlockVectra 面向 LLM agent 与开发者工具提供以下文件：

### llms.txt 索引 [#llmstxt-索引]

遵循 [llmstxt.org](https://llmstxt.org) 规范，用于向 LLM 提供站点结构与端点概览：

* **官网索引**：[**WWW\_URL**/llms.txt](https://blockvectra.com/llms.txt) —— 汇总官网主页、公开链列表、计费与公开接口概览。
* **文档索引**：[**DOCS\_URL**/llms.txt](https://docs.blockvectra.com/llms.txt) —— 罗列文档站每个页面的标题与说明。

### 完整文档单文件（`llms-full.txt`） [#完整文档单文件llms-fulltxt]

* **文档全文**：[**DOCS\_URL**/llms-full.txt](https://docs.blockvectra.com/llms-full.txt) —— 聚合英文文档站每个页面的纯文本 Markdown 内容，并剔除前端交互组件。可作为系统提示词（System Prompt）载入，或注入检索增强生成（RAG）流程。

### 可下载的 OpenAPI 3.1 规范 [#可下载的-openapi-31-规范]

文档站提供两份 OpenAPI 3.1 格式的 YAML 文件，可直接导入 agent 框架、代码生成工具或 API 客户端：

* **JSON-RPC 接口规范**：[/openapi/json-rpc.yaml](https://docs.blockvectra.com/openapi/json-rpc.yaml) —— 包含支持的方法、各链方法策略、错误响应与计算单元计量。
* **Data API 接口规范**：[/openapi/data.yaml](https://docs.blockvectra.com/openapi/data.yaml) —— 包含已索引区块、交易、转账、余额、持有人及相关数据集的 REST 端点定义。

## 2. 免 Key 的公开 JSON 接口 [#2-免-key-的公开-json-接口]

Agent 可以先查看可用链、实时状态与套餐参数，再发起任何计费调用。以下接口都无需 API key：

* `GET /v1/status` 与 `GET /v1/chains` 免鉴权、不计费、不限流。
* `GET /v1/plans` 公开且免鉴权。

三者都返回 `Access-Control-Allow-Origin: *`。

### 服务状态（`GET /v1/status`） [#服务状态get-v1status]

返回服务就绪状态及各公开链的同步状态：

```bash
curl -s "$BLOCKVECTRA_API_BASE/v1/status"
```

返回字段：

* `checked_at`：状态快照生成时间（RFC 3339 / ISO 8601 UTC）。
* `gateway.status`：服务运行状态。`ok` 表示服务当前就绪；`degraded` 表示余额准入或 key 数据尚未就绪或已过期，付费请求会被拒绝，恢复后自动回到 `ok`。该状态与任何一条链的节点状态无关。
* `chains[]`：对外服务的链列表：
  * `chain`：链标识符（slug，如 `robinhood_mainnet`）。
  * `name`：人类可读的显示名。
  * `chain_id`：EIP-155 链 ID（十进制整数）。
  * `jsonrpc`：是否提供 JSON-RPC 服务。
  * `data`：是否提供 Data API 服务。
  * `data_features`：Data API 为该链提供的能力（`data` 为 `false` 时为空数组）。
  * `data_status`：Data API 运行状态（`ok` 或 `unavailable`，仅在 `data` 为 `true` 时出现）。
  * `status`：链节点状态（`ok` 或 `unavailable`）。
  * `head`：最新区块信息，包含 `block`（最新区块高度）、`time`（区块时间戳）与 `lag_seconds`（区块时间落后当前时间的秒数）；未知时为 `null`。

规格示例返回：

```json
{
  "checked_at": "2026-09-28T12:00:00Z",
  "gateway": {
    "status": "ok"
  },
  "chains": [
    {
      "chain": "robinhood_mainnet", "name": "Robinhood Chain", "chain_id": 4663,
      "jsonrpc": true,
      "data": true,
      "data_features": [
        "blocks",
        "transactions",
        "address_transactions",
        "transfers",
        "token_metadata",
        "freshness"
      ],
      "status": "ok",
      "head": {
        "block": 73017329,
        "time": "2026-09-28T11:59:58Z",
        "lag_seconds": 2
      }
    }
  ]
}
```

### 链列表与参数（`GET /v1/chains`） [#链列表与参数get-v1chains]

返回各公开链的静态参数与方法策略：

```bash
curl -s "$BLOCKVECTRA_API_BASE/v1/chains"
```

返回字段：

* `chains[]`：公开链及其静态参数：
  * `chain`：链标识符。
  * `name`：人类可读的显示名。
  * `chain_id`：EIP-155 链 ID。
  * `jsonrpc`：是否提供 JSON-RPC 服务。
  * `data`：是否提供 Data API 服务。
  * `methods`：方法策略：
    * `allow`：允许调用的方法或前缀通配符列表（如 `eth_*`、`debug_trace*`）。
    * `deny`：拒绝的方法或前缀通配符列表（如 `eth_newFilter`）。被拒绝的方法优先于允许的方法。
  * `max_logs_block_range`：单次 `eth_getLogs` 请求允许的最大区块跨度。
  * `state_window_blocks`：历史状态窗口大小（区块数）；可查全历史时为 `null`。
  * `info`：链的公网扩展信息（预留字段，当前为空对象 `{}`）。

规格示例返回：

```json
{
  "chains": [
    {
      "chain": "robinhood_mainnet", "name": "Robinhood Chain", "chain_id": 4663,
      "jsonrpc": true,
      "data": true,
      "methods": {
        "allow": [
          "eth_*",
          "net_*",
          "web3_*",
          "debug_trace*"
        ],
        "deny": [
          "eth_newFilter",
          "eth_newBlockFilter",
          "eth_newPendingTransactionFilter",
          "eth_getFilterLogs",
          "eth_getFilterChanges",
          "eth_uninstallFilter",
          "eth_subscribe",
          "eth_unsubscribe"
        ]
      },
      "max_logs_block_range": 1000,
      "state_window_blocks": 900,
      "info": {}
    }
  ]
}
```

### 计费计划与权重（`GET /v1/plans`） [#计费计划与权重get-v1plans]

计费计划接口由控制台后端提供：`GET https://dev-console-api.blockvectra.network/v1/plans`。Agent 可在运行时查询当前生效的免费套餐限制与各方法的计算单元（CU）权重：

* `free`：免费套餐参数 —— `signup_units`（注册赠送额度，单位为 unit）、`monthly_units`（周期补足水位，单位为 unit）、`window_days`（用量周期天数）与 `max_calls_per_sec`（免费套餐每秒调用次数上限）。
* `pricing`：付费方案参数 —— `units_per_usd`（每 1 USD 兑换的计费单位数）、`cu_per_unit`（每个计费单位对应的 CU 数）与 `min_topup_usd`（最低充值金额，USD）。
* `method_weights`：每次调用的 CU 权重数组，每项为 `{ "method": string, "cu_weight": number }`。`method` 可以是精确的 JSON-RPC 方法名、以 `*` 结尾的前缀规则（如 `debug_trace*`）、用于未列出方法的 `*` 行，或 Data API 操作（如 `data.<op>`）。权重按方法计，不按链拆分。

## 3. Agent 鉴权与密钥安全 [#3-agent-鉴权与密钥安全]

Agent 发起 RPC 调用时需遵循以下规则：

* **鉴权方式**：使用 `x-api-key` 请求头传递 API key，格式为 `x-api-key: <your_api_key>`；也可放在路径中：`POST /v1/{chain}/{api_key}`。同一个 key 可用于所有已支持的链，也可用于相应链已提供的 Data API。
* **保护密钥**：API key 只放在服务端环境变量（如 `BLOCKVECTRA_API_KEY`）或密钥管理服务中，切勿写入浏览器代码或任何客户端产物。接口虽然返回 `Access-Control-Allow-Origin: *`，但设计为由后端服务调用，而不是在浏览器中直接调用。
* **计量与付费**：按计算单元（CU）计量：每个方法按其权重消耗 CU；余额、CU 令牌桶与免费套餐限流在所有链上合并计算。付费充值后，免费套餐的每秒调用次数上限不再适用；每个 key 仍有 CU 速率上限与突发上限。尚未用完的免费额度保留在服务额度中，可以继续使用。详见[定价页](https://blockvectra.com/zh/pricing/)。

## 4. Agent 动态选链流程 [#4-agent-动态选链流程]

发起调用前，Agent 可以按以下步骤决策：

1. **查验链与方法策略**：调用 `GET /v1/chains`，确认目标链存在且 `jsonrpc` 为 `true`，计划调用的方法在 `methods.allow` 中且未被 `methods.deny` 拒绝（拒绝优先）。
2. **查验实时状态**：调用 `GET /v1/status`，确认 `gateway.status` 为 `ok`、目标链的 `status` 为 `ok`；用 `head.lag_seconds` 判断链上数据是否足够新。某条链的节点未同步时，除 `eth_chainId` 外的所有方法都返回 JSON-RPC 错误 `-32010`（HTTP 200，不计费），Agent 可以等待后重试，或改选其他链。
3. **发起请求**：`POST /v1/{chain}`，带上 `x-api-key` 请求头，发送标准 JSON-RPC 请求体。

## 5. 最小实现示例 [#5-最小实现示例]

以下示例先读取 `/v1/chains` 选出一条允许 `eth_blockNumber` 的链，再确认 `/v1/status`，最后调用一次 `eth_blockNumber`。

<Tabs groupId="code-lang" items="['cURL', 'TypeScript', 'Python']">
  <Tab value="cURL">
    ```bash
    # API 主机地址，结尾不带 /v1
    export BLOCKVECTRA_API_BASE="<your_api_base_url>"
    export BLOCKVECTRA_API_KEY="rgw_your_api_key"

    # 1. 查询公开链列表与方法策略
    curl -s "$BLOCKVECTRA_API_BASE/v1/chains"

    # 2. 查询服务与各链状态
    curl -s "$BLOCKVECTRA_API_BASE/v1/status"

    # 3. 对选中的链调用 eth_blockNumber
    curl -s "$BLOCKVECTRA_API_BASE/v1/robinhood_mainnet" \
      -H "x-api-key: $BLOCKVECTRA_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
    ```
  </Tab>

  <Tab value="TypeScript">
    ```typescript
    const apiBase = process.env.BLOCKVECTRA_API_BASE;
    const apiKey = process.env.BLOCKVECTRA_API_KEY;

    if (!apiBase || !apiKey) {
      throw new Error("Missing BLOCKVECTRA_API_BASE or BLOCKVECTRA_API_KEY");
    }

    type ChainFacts = {
      chain: string;
      jsonrpc: boolean;
      methods: { allow: string[]; deny: string[] };
    };

    function matches(pattern: string, method: string): boolean {
      if (pattern === "*") return true;
      if (pattern.endsWith("*")) return method.startsWith(pattern.slice(0, -1));
      return pattern === method;
    }

    // 1. 查询公开链列表
    const chainsRes = await fetch(`${apiBase}/v1/chains`);
    const { chains } = (await chainsRes.json()) as { chains: ChainFacts[] };

    // 2. 选出一条支持 JSON-RPC 且允许 eth_blockNumber 的链
    const selected = chains.find(
      (chain) =>
        chain.jsonrpc &&
        !chain.methods.deny.some((pattern) => matches(pattern, "eth_blockNumber")) &&
        chain.methods.allow.some((pattern) => matches(pattern, "eth_blockNumber")),
    );

    if (!selected) {
      throw new Error("No chain found that allows eth_blockNumber");
    }

    // 3. 确认服务与所选链就绪
    const statusRes = await fetch(`${apiBase}/v1/status`);
    const status = await statusRes.json();
    const chainStatus = status.chains?.find(
      (chain: { chain: string }) => chain.chain === selected.chain,
    );

    if (status.gateway?.status !== "ok" || chainStatus?.status !== "ok") {
      throw new Error(`Chain ${selected.chain} is currently unavailable`);
    }

    // 4. 对选中的链调用 eth_blockNumber
    const rpcRes = await fetch([apiBase, "v1", selected.chain].join("/"), {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": apiKey,
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: 1,
        method: "eth_blockNumber",
        params: [],
      }),
    });

    console.log("Response:", await rpcRes.json());
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import os
    import requests

    api_base = os.environ["BLOCKVECTRA_API_BASE"]
    api_key = os.environ["BLOCKVECTRA_API_KEY"]


    def matches(pattern: str, method: str) -> bool:
        if pattern == "*":
            return True
        if pattern.endswith("*"):
            return method.startswith(pattern[:-1])
        return pattern == method


    # 1. 查询公开链列表
    chains = requests.get(f"{api_base}/v1/chains").json()["chains"]

    # 2. 选出一条支持 JSON-RPC 且允许 eth_blockNumber 的链
    selected = next(
        (
            chain
            for chain in chains
            if chain["jsonrpc"]
            and not any(matches(p, "eth_blockNumber") for p in chain["methods"]["deny"])
            and any(matches(p, "eth_blockNumber") for p in chain["methods"]["allow"])
        ),
        None,
    )

    if selected is None:
        raise RuntimeError("No chain found that allows eth_blockNumber")

    # 3. 确认服务与所选链就绪
    status = requests.get(f"{api_base}/v1/status").json()
    chain_status = next(
        (c for c in status["chains"] if c["chain"] == selected["chain"]),
        None,
    )

    if (
        status["gateway"]["status"] != "ok"
        or chain_status is None
        or chain_status["status"] != "ok"
    ):
        raise RuntimeError(f"Chain {selected['chain']} is currently unavailable")

    # 4. 对选中的链调用 eth_blockNumber
    rpc_response = requests.post(
        "/".join([api_base, "v1", selected["chain"]]),
        headers={"Content-Type": "application/json", "x-api-key": api_key},
        json={"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []},
    ).json()

    print("Response:", rpc_response)
    ```
  </Tab>
</Tabs>

调用成功返回标准 JSON-RPC 响应对象（规格示例）：

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x45a27f1"
}
```

## 下一步 [#下一步]

* [浏览数据集目录](https://blockvectra.com/zh/data/)，查看 BlockVectra 索引的全部数据集。
* [查看免费额度与定价](https://blockvectra.com/zh/pricing/#free)，确认账户可用的方案。
* [登录控制台](https://console.blockvectra.com/zh/login/?next=%2Fzh%2Fkeys%2F)创建 API key。
