很多人第一次接 ChatGPT 的 API,卡住的地方往往不是写代码:充了值发现账单对不上、密钥泄露被跑量、错误重试把额度烧光、以为订阅能当 API 用。这篇按接入顺序把每个容易踩的坑列出来,给出该看哪一页数字、什么情况下这套做法不适用,以及一个能照着走完的上线前自查顺序。
第一步不是写代码,是把账号和密钥管住
很多人第一次接 API,第一反应是打开编辑器写请求代码。先停一下:代码跑通只是最后一公里,前面账号和密钥没管住,后面出的问题基本都不是技术问题,而是账对不上、key 泄露、出了事没法单独吊销。所以第一步先把两层东西分清楚:谁在花钱,谁能用这把钥匙。
先说最常见的一个误解:网页订阅和 API 账户是两套独立的账。你在网页端付的钱,不会自动变成 API 的调用额度;反过来,API 充值也不会让你的网页订阅升级。判断标准很简单,看你的账单是从哪产生的:如果是在订阅管理页看到的那笔,属于网页订阅;如果是在 API 用量页按调用量结算的,才是 API 账户。两个页面的数据不互通,别拿一边的余额去推另一边还能不能跑。
| 你看到的现象 | 实际归属 | 该去哪里核对 |
|---|---|---|
| 在订阅页续费后,API 调用仍然报额度不足 | 网页订阅,与 API 无关 | 到 价格与套餐页(/pricing) 对比两类账户的区别 |
| API 用量页有消耗,但网页端会员权益没变化 | API 账户,独立计费 | 到 API 用量与账单页(/api-usage) 看当期消耗 |
| 两个页面都有数字,但加不到一起 | 两套账,本来就分开 | 分别记录,不要合并估算 |
第二件事是密钥。底线只有两条:key 不进前端,key 不进 Git。前端代码最终会被浏览器拿到,任何写进 JS 里的 key 等于公开;Git 历史一旦提交,删掉文件也没用。正确做法是服务端做一层代理,key 放环境变量,前端只调你自己的接口。本地调试也别图省事把 key 贴进聊天记录、截图或者临时文本里,这类东西传播得比你想象得快。
- 建代理层在服务端写一个薄封装接口,前端只请求它,由它带 key 去调上游。验证方法:在浏览器开发者工具的网络面板里搜一遍,确认请求头和响应里都不出现 key。
- key 进环境变量本地用 .env 且确保在 .gitignore 里,线上用平台的密钥管理。验证方法:git log 里搜不到 key 片段,仓库文件列表里没有 .env。
- 按项目和环境拆分一个项目一把 key,开发、预发、线上各一把。验证方法:随便挑一把禁用,只有对应环境报错,其他环境正常,说明隔离做到了。
- 上线前确认归属打开这把 key 的详情,看清它挂在哪个组织、哪个项目下,账单就归到那一层。多人小团队最容易在这里对不上账,最好把归属写进项目文档。
- 什么情况下可以省掉这套隔离:单人本地、一次性验证接口能不能通,跑完就删 key,可以不建代理不拆环境;但别把同一把 key 顺手拿去跑线上。
- 多人协作、有前端页面、要把服务暴露给外部访问,这三条占任意一条,隔离就不能省。
- 判断是否做过头:如果为了一个临时脚本建了三层网关,那是浪费;如果线上 key 和本地调试共用一把,那是隐患。
- 定期做一次吊销演练:随便禁用一把旧 key,看监控有没有告警、哪个服务挂掉,这比看文档更能验证你的隔离是否真实有效。
先把计费口径对齐,再谈花多少
刚上手的人最容易犯的错,是拿「调用次数」去估费用:一次调用看着便宜,实际账单翻几倍。原因是输入和输出分开计价,输出那段通常更贵,你让模型多写几句,成本就全压在后半段了。所以先把计费口径对齐,再谈花多少,否则后面所有预估都是白算。
| 计费项 | 怎么算 | 容易漏的点 |
|---|---|---|
| 输入 token | 你发过去的提示词、上下文、历史消息都算 | 多轮对话会把历史反复计入 |
| 输出 token | 模型生成的正文、结构化字段都算 | 输出单价通常高于输入,写长最烧钱 |
| 缓存命中 | 命中的部分按另一档单价计 | 长提示词场景差异被放大 |
| 倍率/折扣 | 不同渠道、不同档位有各自系数 | 账单和预估对不上时优先查这项 |
- 先按「输入 token × 输入单价 + 输出 token × 输出单价」两段算,别用次数乘一个平均值
- 长系统提示词、固定知识库这类重复内容,先确认能不能命中缓存,命中与否单价不同
- 把每次调用的输出长度上限压住,输出是最贵的那一段
- 多轮对话场景单独估一遍,历史消息会让输入 token 越滚越大
- 小调用量别过度设计,口径差异的绝对额有限,流程简单更重要
- 对齐当期单价到 /official-api 找到你实际用的那档,记下输入、输出、缓存三档单价,别用记忆里的旧数字
- 抓一次真实调用拿一条典型请求,分别记录输入和输出 token 数,按两段算成本,而不是只数调用次数
- 确认能否命中缓存看你的提示词是不是有稳定重复的前缀;没有就别按缓存价估,会低得离谱
- 账单对不上时按序排查先查缓存有没有漏算,再查倍率折扣,最后确认计费口径是否一致;变动记录到 /price-watch 看
第一次调通的五个检查点
第一次调通别贪心。先用一条短提示、少量输出把链路走通,确认鉴权、模型名、返回结构三件事都对,再去放大体量。很多人一上来就贴长文,报错时根本分不清是 key 的问题、模型名写错,还是请求体格式不对。
- 发一条最小请求提示词控制在几个字,输出上限调小,只验证能不能拿到正常返回。看返回里有没有预期的字段结构,别急着看内容好不好。
- 确认鉴权与模型名鉴权失败和模型不存在是两类错,报错信息不一样。把 key 的权限范围、模型名拼写逐一核对,别混着排查。
- 显式写上输出上限max tokens 这类参数一定要自己写死,不要留空。留空时模型可能一路写下去,费用跟着顶高,尤其提示词里带了「详细展开」的时候。
- 给足但别给过长的超时超时太短会误杀正常请求,太长会让卡住的请求占住重试预算。先按测出来的延迟基线留出余量,再决定具体数值。
- 记下这次的 token 数把输入输出 token 数抄下来当样本,后面估算成本就靠它。凭感觉估最容易偏,尤其是中文和代码混排的场景。
| 检查点 | 看什么 | 不通过时先查 |
|---|---|---|
| 鉴权 | 返回是否提示 key 无效或无权限 | key 是否复制完整、权限范围是否够 |
| 模型名 | 是否报模型不存在 | 拼写、大小写、账户是否开通该模型 |
| 返回结构 | 字段是否齐全、能否解析 | 请求体格式、是否漏了必填参数 |
| 输出上限 | 是否有明确的 max tokens | 参数名写错、被默认值覆盖 |
| 延迟 | 单次请求耗时多少 | 网络、超时设置、是否走了代理 |
延迟基线要单独量一次,别凭一次调用就下结论。到 /tools/speed-test 跑一遍,把当时的数字记下来。以后觉得「变慢了」,拿这个基线对照才有意义,否则只是主观感受。注意这个基线跟你的网络位置、时段都有关,换个环境要重量。
这套检查点适合刚接 API、还在调通的阶段。如果你的场景是批量任务或者对延迟极敏感,光靠一次最小请求不够,还得按实际请求形态压一轮。价格和模型参数这类会变的东西,别记在笔记里,到 /pricing 核对当时的数字。
重试、限速和「重复扣费」这层坑
限速被拒之后,最容易犯的错是立刻原地重发。很多人看到 429 就条件反射地再来一次,结果请求被拒、额度照烧,几分钟就把当天的量打空。正确姿势是先停下来看清楚:是短时突发被拦,还是当前并发本来就超了。前者可以退避重试,后者越重试越糟。
- 先确认上一次到底成没成别急着发第二次。看返回体里有没有正常的内容,再看响应头里的请求 ID 和状态。拿到了结果就是成了,没拿到且状态是限流或超时,才算失败。判断不清就别重发,按幂等思路先把这次请求标记为「结果未知」。
- 给重试加退避和次数上限失败后等一小段时间再试,间隔逐次拉长,并设一个硬性次数封顶,比如三次就放弃转人工或进失败队列。无上限重试等于给额度开了个漏斗。
- 把上限写进配置而不是记在脑子里每分钟请求数、并发数这类参数放进配置文件或环境变量,别靠印象。换机器、换网络、换账号时重新核对一遍,环境和限额是绑定的。
- 批量任务优先降并发整批跑的任务里,单条失败重试的收益远小于把整批并发调小。先砍并发,观察稳定了再谈重试策略。
| 现象 | 大概率原因 | 先做什么 |
|---|---|---|
| 频繁被限速拒绝 | 并发或每分钟请求数超了 | 降并发,别加重试 |
| 偶发超时、无返回 | 网络抖动或服务端短时忙 | 退避重试,设次数上限 |
| 重试后疑似重复计费 | 上一次其实已成功,结果没拿到 | 查请求 ID,按幂等处理 |
| 换环境后突然大量失败 | 新环境的限额没重新核对 | 对照配置逐项核对上限 |
- 重试前先看返回体和请求 ID,确认上一单成没成
- 退避间隔逐次拉长,次数设硬上限
- 限额参数写进配置,换环境重新核对
- 批量任务先降并发,再考虑单条重试
- 对「结果未知」的请求单独标记,别当成功也别当失败
成本追踪:让每一笔钱能对上号
很多人对账时只看月底账单总额,结果发现钱花了却说不清花在哪。想让每一笔钱能对上号,从第一次调用起就得记账。最少记四样:调用时间、这笔调用是干什么的(用途或任务名)、输入 token 数、输出 token 数。四样缺一不可。
最容易偷懒省掉的是「用途」这一列,但它恰恰最关键。只记时间和 token 数,你只知道花了多少,不知道钱花在哪个功能上。等到要砍成本或优化提示词时,没有用途就没法归因,只能对着总数干瞪眼。用途写到能一眼分辨的程度,比如「商品标题生成」「客服自动回复」「文档摘要」,别写「测试」这种回头自己也看不懂的词。
| 字段 | 记什么 | 为什么要有 |
|---|---|---|
| 时间 | 调用发生的日期与时段 | 按天/按周聚合,看用量曲线 |
| 用途 | 任务名或功能模块 | 优化和砍预算时的归因依据 |
| 输入 token | 本次请求消耗的输入量 | 换算成钱的主要部分之一 |
| 输出 token | 本次请求消耗的输出量 | 输出单价通常不同,必须单独记 |
token 数换成钱这一步,别手工翻单价表。单价会变,模型也分输入输出两套价,手算容易漏。直接用站内工具换算更稳:token 与价格换算走 /tools/token-price-calculator,整段调用的费用估算走 /tools/model-cost-calculator。把记录里的 token 数丢进去,得到当期口径下的金额,再汇总成周成本。
- 先定记录格式用表格或日志文件固定四个字段,团队共用一份,字段名别各写各的。验证方式:随便挑三条历史调用,看能否填满四列。
- 调用时顺手写用途在代码或调用脚本里给每次请求带一个任务标签,别事后回忆补。验证方式:抽查一天的记录,用途列是否都具体可辨。
- 用站内工具换算金额把 token 数代入 /tools/token-price-calculator 或 /tools/model-cost-calculator,得到金额后按任务名汇总。验证方式:汇总总额与账单量级是否接近。
- 按周复盘预估与实际每周比对「自己预估的花费」和「实际账单」,差异大就回到计费口径那一步重查,看是单价口径不对还是 token 统计漏了。验证方式:连续两周差异是否在可接受范围内收敛。
预算告警要设,但阈值别拍脑袋。先老老实实跑一周,拿到真实基线用量和花费,再按基线的倍数去设告警线,比如日常的两三倍就提醒。这样既不天天误报,也真出异常时能拦住。注意这套做法不适用于刚上线、用量还在剧烈爬坡的新功能,那种情况基线本身不稳,得先观察够再设。
密钥泄露和异常跑量的排查顺序
密钥泄露最怕的不是被发现,是被发现后还在继续烧。所以排查顺序要反过来想:先用最快的动作把出血点堵上,再回头找原因。按「用量曲线 → 来源 IP → 代码逻辑」这个顺序看,绝大多数情况在前两步就能定性,不用一上来就翻代码。
- 先看用量曲线的时间分布到站内的用量与成本记录页拉出最近一段时间的调用曲线,重点看非工作时段有没有突然抬升,或者日常平稳的曲线里冒出一段完全不符合业务节奏的尖峰。判断标准很简单:这段流量对应的时间点,团队里有没有人在干活。对不上就先把这段当异常处理。
- 再看请求来源 IP同一页面上通常能看到请求来源或调用方标记,对照一下你自己的服务器出口 IP、办公网出口 IP。出现陌生 IP、异地 IP、或者来自你根本没部署过的环境,基本可以确定 key 已经外流。这一步不需要精确到每一条,看有没有明显不属于你的来源就够。
- 最后才怀疑代码逻辑只有在时间分布正常、来源 IP 也都是自己的情况下,才回头查是不是死循环、重试策略写崩了、或者某个定时任务把量放大了。代码问题通常表现为持续均匀的跑量,而不是突发的陌生来源,这个特征可以用来反向印证前面的判断。
| 排查环节 | 看什么 | 什么情况算异常 |
|---|---|---|
| 用量曲线 | 非工作时段是否抬升、有无突发尖峰 | 曲线节奏和团队实际工作时间对不上 |
| 来源 IP | 请求来源是否都是自己的出口 | 出现陌生、异地或未部署环境的 IP |
| 代码逻辑 | 是否有死循环、重试放大、定时任务失控 | 时间和来源都正常,但量就是降不下来 |
- 旧 key 吊销后不要只是注释掉,确认控制台里已经失效,避免本地还留着副本被复用。
- 新 key 不要图省事塞进浏览器插件、第三方客户端或来路不明的聚合工具做「服务端直连」,那种环境你控制不了 key 的去向。
- 给每个环境、每个用途单独发 key,出问题时能一眼定位是哪一把泄露的。
- 如果本来就是多人共用一把 key,先别急着换 key,第一步是把 key 拆开、按人按服务分开并加上用量计量,否则换完还是查不清是谁在跑量。
什么时候该考虑别的接入路径
很多人一上来就纠结「官方直连还是走别的路子」,其实这问题没有统一答案,得看你现在处在哪个阶段。先问自己三件事:这次接入是验证想法还是扛真实业务、用量大概什么量级、有没有开票和合规要求。三个答案不同,选择就完全不同。
| 你的处境 | 优先考虑 | 先别急着做的事 |
|---|---|---|
| 只想跑通效果、量很小 | 先看官方有没有可用额度,跑通再谈别的 | 一上来就签长期协议或预付大额 |
| 需要正规票据、对稳定性有要求 | 把官方直连当基线,再对比其他方案的条款 | 只看单价不看结算方式和责任划分 |
| 要跨多家模型来回切 | 先明确切换成本和接口兼容性 | 默认某一家能一直满足所有场景 |
| 用量大到可以谈条件 | 把 SLA 和账期摆上桌再比价 | 图省事长期挂在不透明的中间层 |
如果只是小流量验证,最省事的路径往往是先把官方能用的额度摸清楚。规则和额度口径别靠记忆,直接去 /ai-nav/category/ai-api 看分类说明,再到 /providers 逐家对照,确认当前对你这边的开通条件和限制。这一步花十分钟,能省掉后面一堆返工。
当你开始需要合规票据、稳定带宽,或者要在多个厂商之间切换模型时,官方直连之外的方案就进入视野了。但这类方案各有取舍,别听人一句话就定。先去 /sites/all 看收录口径,再去 /rankings 看排序依据是什么、统计的是哪类指标,搞清楚「排名靠前」到底意味着什么,再决定要不要试。
有一条判断线值得记住:如果你的用量已经大到能支撑议价,或者业务明确需要 SLA,那就别为了省事长期走不透明的中间层——出了问题你连责任方都找不准。反过来,一次性小项目、做完就散的,先把流程跑通再说,过度设计反而是浪费。这个标准不适用于「量小但绝对不能中断」的场景,那种情况稳定性优先于省事。
- 先定性质写一句话说明这次接入是验证还是生产、预计持续多久。定性不清就别选路径。
- 核对口径到 /ai-nav/category/ai-api 与 /providers 看官方可用额度和开通条件,记下你实际能用的范围。
- 对比替代方案去 /sites/all 与 /rankings 看清收录与排序口径,只把符合你合规和带宽要求的列入候选。
- 做一次真假与计费核对任何替代路径上线前,先用 /tools/verify 做一次核对,确认响应真实、计费对得上。
- 小流量试水用非生产流量跑一轮,观察计费和稳定性,确认无误再切生产。
常见问题
API 充了值为什么网页版还是提示额度不够?
这是两套独立的账。网页/App 的订阅额度只作用于对话入口,API 是按 token 单独计费、单独充值的。先去 API 用量页确认你充的是哪一边,再回去看订阅侧的状态,别在错误的页面里反复充值。
账单比我自己估算的高很多,先查什么?
按这个顺序:一看是不是漏算了输出 token(输出通常更贵);二看缓存有没有命中;三看计费口径和倍率有没有对齐。三项都排除后,再去看是不是有重试或异常调用。当期单价以 /official-api 页面为准,不要去背数字。
密钥不小心传到 GitHub 了怎么办?
立刻吊销并新建一把,不要只删仓库。公开仓库的爬虫抓取速度比你想的快得多,通常在你删除前就已经被扫走。换完之后检查该 key 对应的用量记录,确认有没有陌生来源的调用。
调不通到底是额度问题还是代码问题?
用一个最小请求单独测:短提示、固定模型名、只输出几个字。能通就是你的代码或参数问题,报鉴权/额度错误就是账户侧问题。这一步能省掉大量瞎猜时间。
要不要一开始就给 API 设预算上限?
建议设,但阈值别拍脑袋。先正常跑一周拿到日均用量基线,再按基线设一个能容忍波动、又能拦住跑飞的值。完全不放闸的风险在于半夜的重试循环,那种消耗通常发生在没人盯着的时候。