# 怎么防止 AI 智能体调用付费数据接口时花超预算？

> 智能体会死循环、反复重试、越翻越多页。给小红书、抖音等社媒数据调用加预算护栏：免费查价、翻页上限、预付余额兜底，附代码。

网页版：https://okdata.online/zh/answers/cap-ai-agent-spend-data-api/

**简短回答：**先让智能体报价再动手（在 okdata 查接口和价格是免费的），在你自己的代码里按每次调用返回的实际扣费设翻页上限和金额预算，只重试值得重试的失败。余额是预充值的，最坏情况就是把余额花完：失控连搜 500 次小红书是 $10.00，之后调用直接停。

一夜之间账单爆掉，多半是智能体陷进了循环：工具调用失败，再试一次，多翻一页，再试一次，上千遍。OpenAI 论坛上有开发者说，账户级限额、try/except 包一层，都没能在扣费发生前拦住它。护栏必须放在真正发请求的那段代码里，而且得知道每次调用花了多少钱。

## 四道护栏，从最省事的开始

1. **先报价，再执行。** 走 MCP 时，`find` 和 `describe` 两个工具不花钱、不需要 key，`describe` 会列出接口价格。让智能体在第一次付费 `call` 之前先说一句"大约 12 次调用，约多少钱"。走 HTTP 的话，价格在各接口页上，比如[小红书笔记搜索](/zh/apis/xiaohongshu/notes/search/)和[抖音视频搜索](/zh/apis/douyin/videos/search/)。
2. **翻页上限写进代码。** 每翻一页都单独计费。一个模型改不了的 `max_pages` 参数，比提示词里写一百遍"别翻太多"都管用。
3. **按实际扣费记账。** 每次返回都带 `meta.billing.amount`，是这次调用的准确扣费，十进制字符串。累加起来，预算用完就停。
4. **只重试有意义的错误。** 错误里会写明能不能重试（`retry` 为 `"yes"`、`"after_fix"`、`"no"` 或 `"same_key"`）。失败调用本来就不扣费，但无意义的重试照样浪费时间、占用限流额度。

## 预算能买到什么

| 预算 | 小红书搜索 | 抖音搜索 |
|---|---|---|
| $1.00 | 50 页 | — |
| $1.00 | — | 50 页 |
| 失控循环 500 次 | $10.00 | $10.00 |

## 一个预算包装器

```python
import os, time, uuid
from decimal import Decimal
import requests

API = "https://api.okdata.online"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}

class Budget:
    def __init__(self, usd: str, max_calls: int):
        self.left = Decimal(usd)
        self.calls_left = max_calls

    def get(self, path: str, **params):
        if self.left <= 0 or self.calls_left <= 0:
            raise RuntimeError("预算用完，停止调用")
        key = str(uuid.uuid4())  # 一次逻辑调用一个 key，重试时沿用
        for _ in range(3):
            body = requests.get(API + path, params=params, timeout=60,
                                headers={**H, "Idempotency-Key": key}).json()
            if body["code"] == "ok":
                self.calls_left -= 1
                self.left -= Decimal(body["meta"]["billing"]["amount"])
                return body
            if body.get("retry") not in ("yes", "same_key"):
                raise RuntimeError(f"{body['code']}: {body['message']}")
            time.sleep(body.get("retry_after_seconds") or 2)
        raise RuntimeError("重试 3 次仍失败，放弃")

budget = Budget("0.50", max_calls=40)
page = budget.get("/v1/xiaohongshu/notes/search", query="防晒霜", sort="latest")
```

把 `budget.get` 作为智能体拿数据的唯一入口。因为检查在调用之前，最多只会超出一次调用的钱。

## 你已经有的最后一道闸

okdata 是预付费的。余额归零后，调用会返回 `insufficient_balance`，不会扣费，所以再怎么循环也花不出你充进去的钱。余额保持在一周正常用量左右就好，随时可以用 `GET /v1/account` 查。新 key 自带 $0.10 试用额度。

## 还可以再加几层

智能体框架自带刹车：LangChain 的 `max_iterations`、LangGraph 的 `recursion_limit`，其他框架大多有步数上限。这些也要开，它们能拦住失控的推理，那部分同样在烧模型 token。几个团队共用一个 key 时，带消费规则的 API 网关会有帮助。账单面板和邮件提醒也有用，只是它们总在钱花出去之后才报。各接口价格见[价格页](/zh/pricing/)，每种错误码和重试建议见[错误码页](/zh/docs/errors/)。

## 用到的接口

- [小红书笔记搜索](https://okdata.online/zh/apis/xiaohongshu/notes/search/) `xiaohongshu.notes.search`：$0.02/次 · 每页约 20 篇笔记
- [抖音视频搜索](https://okdata.online/zh/apis/douyin/videos/search/) `douyin.videos.search`：$0.02/次 · 每页约 20 条视频

更新于 2026-11-12
