免费大模型API调用方法

接入与开发

用 Python 和 C# 两种写法把免费大模型 API 接进项目,讲清请求结构、超时重试、并发控制和日志排查这些落地环节。

你可能已经拿到一个免费额度的 Key,也知道了接口地址,但真正写起来就卡住:Python 用哪个库、C# 用 HttpClient 还是 SDK、报错了不知道是网络还是鉴权。这篇不重复协议和客户端配置,只给两种语言的调用骨架和工程细节,让你半小时内跑通第一行、之后少踩坑。

你可能已经拿到一个免费额度的 Key,也知道了接口地址,但真正写起来就卡住:Python 用哪个库、C# 用 HttpClient 还是 SDK、报错了不知道是网络还是鉴权。这篇不重复协议和客户端配置,只给两种语言的调用骨架和工程细节,让你半小时内跑通第一行、之后少踩坑。

先说清楚适用范围:下面的写法针对「OpenAI 兼容协议」的免费接口。如果对方用的是私有签名、私有鉴权头或者非标准返回体,这套骨架只能当参考,具体字段要去对应中转站或官方的接入说明里核对。哪些站是兼容协议、哪些不是,可以去 /sites 看站点档案里标注的协议类型。

最小可跑通骨架:Python 与 C# 各一份

Python 侧不要手写 HTTP,直接用 OpenAI 兼容 SDK,只改三个值:base_url、api_key、model。C# 侧分两种情况:临时验证用 HttpClient 手写一次请求最快,长期维护的正式项目建议用官方 SDK,省掉自己处理重试和序列化。两种语言都要先做一次非流式调用,确认能拿到完整响应再改流式,否则一开始就被 SSE 解析问题带偏。

  1. 装依赖并读 KeyPython 装 OpenAI 兼容 SDK;C# 建一个控制台项目,用 dotnet user-secrets 存 Key。两边都从环境变量或用户机密读取,绝不写进代码和仓库。
  2. 非流式调一次把 base_url、api_key、model 填进去,发一条最简 prompt。成功标准是拿到完整响应文本,且能读到 usage 字段。
  3. 打印三个诊断值每次调用都打印 status code、总耗时、usage。这三个值决定后面排查有没有抓手,缺了就只能靠猜。
  4. 再改流式确认非流式通了之后,再开 stream 参数按块读。一旦流式解析失败,退回上一步验证是协议问题还是解析问题。
import os, time\nfrom openai import OpenAI\n\nclient = OpenAI(\n    base_url=os.environ["API_BASE_URL"],\n    api_key=os.environ["API_KEY"],\n    timeout=30.0,\n)\n\nt0 = time.time()\nresp = client.chat.completions.create(\n    model=os.environ["MODEL_NAME"],\n    messages=[{"role": "user", "content": "用一句话介绍你自己"}],\n)\nprint("status=ok", "cost_ms=", int((time.time()-t0)*1000))\nprint(resp.choices[0].message.content)\nprint("usage=", resp.usage)
using System.Net.Http.Headers;\nusing System.Text;\nusing System.Text.Json;\n\nvar http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };\nhttp.DefaultRequestHeaders.Authorization =\n    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("API_KEY"));\n\nvar body = JsonSerializer.Serialize(new {\n    model = Environment.GetEnvironmentVariable("MODEL_NAME"),\n    messages = new[] { new { role = "user", content = "用一句话介绍你自己" } }\n});\n\nvar sw = System.Diagnostics.Stopwatch.StartNew();\nvar req = new HttpRequestMessage(HttpMethod.Post,\n    Environment.GetEnvironmentVariable("API_BASE_URL") + "/chat/completions")\n{ Content = new StringContent(body, Encoding.UTF8, "application/json") };\n\nvar res = await http.SendAsync(req);\nsw.Stop();\nConsole.WriteLine($"code={(int)res.StatusCode} cost_ms={sw.ElapsedMilliseconds}");\nConsole.WriteLine(await res.Content.ReadAsStringAsync());
什么时候用 SDK
需要自动重试、流式解析、类型化返回时;团队多人维护时优先 SDK,减少手写歧义。
什么时候手写 HttpClient
只想快速验证连通性,或目标接口返回体不标准、SDK 罩不住时;手写要自己管超时和重试。
三个必改值
base_url、api_key、model。换站点或换模型时,只有这三个值该动,其他代码不应该跟着改。

超时与重试:把连接、读取、整体三层分开设

很多人只设一个 timeout,结果分不清是「连不上」还是「连上了不返回」。连接超时管握手阶段,读取超时管响应返回阶段,整体超时兜底防止请求挂在半路。三者设成同一个值,排查时就没有信息量了。建议连接层给短一点,读取层按业务可接受延迟给,整体超时略大于两者之和。

层级管什么判断信号
连接超时握手、DNS、TCP 建连立刻失败,多半是网络或地址写错
读取超时连上后等首个响应或分块连得上但一直没数据,可能是网关或模型排队
整体超时单次调用总耗时上限重试和流式场景下防止任务永久挂住

重试只对幂等且可恢复的错误做。网络抖动、网关类 5xx 可以带退避重试;鉴权失败、参数错误重试多少次结果都一样,直接抛出来。退避一定要带随机抖动,否则多个实例同时重试会把限流打成雪崩。重试次数和每次耗时都要进日志,不然一次调用慢了几秒,你会以为是模型慢。

  • 鉴权类错误:不重试,检查 Key 是否过期、环境变量是否读对。
  • 参数类错误:不重试,检查 model 名和 messages 结构。
  • 连接类错误:重试,考虑换网络或换接入点。
  • 网关类 5xx:有限次退避重试,带随机抖动。
  • 限流类错误:退避后重投,并把失败任务单独收集做二次处理。

并发控制:免费额度下更要排队和分批

免费档位的并发通常很低,本地先用信号量或队列把并发压到可控范围,跑批量任务时按批提交、批间留间隔。遇到限流类错误不要硬刚,退避后重投,并把失败任务单独收集做二次处理。异步写法里尤其注意别在一个循环里无限 fire-and-forget,请求数会瞬间打满并发上限。并发和分批的取舍按任务性质定:离线批处理可以慢,用户实时请求要优先保延迟。

  1. 先量后调从并发 1 开始跑,记录成功率和平均耗时,再逐步加。加到哪里开始出限流错误,那个值就是你的实际上限。
  2. 加信号量Python 用 asyncio.Semaphore,C# 用 SemaphoreSlim,包住每一次请求。同一进程内不要有绕过信号量的调用路径。
  3. 失败隔离单条任务失败不影响整批,用结果收集器把失败项挑出来,最后统一重投一次。
  4. 批间留间隔每批之间 sleep 一段固定时间,比批量内部挤在一起重试更稳。

免费额度和价格档位会变,不要拿旧文档里的并发数字当准绳。当前各家的免费档限制和实测并发表现,到 /price-watch 核对当时的数字,再决定你自己的分批参数。

日志该记什么:一次调用能复盘才有意义

每条日志至少带请求 id、模型名、耗时、状态码、token 用量和是否重试过。这几项能覆盖大部分「慢」和「贵」的归因。不要把完整 prompt 和 Key 原样打进日志,脱敏后再落盘,尤其是团队共用环境。日志格式建议结构化,方便之后按请求 id 串起多行。

字段用途脱敏要求
请求 id串联一次调用的所有日志行无需脱敏
模型名与耗时归因慢请求无需脱敏
状态码与重试次数判断是否网络或限流问题无需脱敏
token 用量估算成本与上下文长度无需脱敏
prompt 摘要复现问题截断并去掉敏感字段

排查顺序固定下来,别每次从头猜:先看连通性和鉴权,再看超时和网关,最后才怀疑模型侧。把每一步的判定条件写进脚本或清单里,新人照着走也能定位。同一个脚本换接口或换模型后,先跑一遍最小用例确认基础链路没坏,再跑全量,这能挡掉大部分「换完就崩」的情况。

  • 第一步:连通性与鉴权,看状态码和错误体。
  • 第二步:超时分层,看是连接断还是读取断。
  • 第三步:网关与限流,看重试后是否恢复。
  • 第四步:模型侧,看是否只有某些 prompt 失败。
  • 第五步:换最小用例复跑,确认基础链路本身没问题。
下一步把你要用的站点的协议类型和当前免费档限制核对清楚,再照着上面的骨架写第一行;站点是否 OpenAI 兼容、有没有已知的调用坑,档案里通常有标注。

常见问题

免费额度的 Key 拿去跑生产任务靠谱吗?

不靠谱。免费额度一般有并发和总量限制,还可能随时调整规则。适合用来验证代码链路、做小规模测试,生产任务要有付费兜底或备用通道,具体额度和限制去站内官方 API 价格页核对当时的数字。

Python 和 C# 的写法差别大吗,能不能一份代码两用?

请求结构和字段是一样的,都是构造 JSON 发 HTTP。差别在库和类型处理:Python 用 SDK 省事,C# 手写 HttpClient 更可控。逻辑分层可以照着抄,代码不用强求共用。

调用一直超时,应该先改哪一项?

先确认是否为连接层问题:把超时调大仍然连不上,基本是网络或地址问题。能连上但读取超时,多半是模型侧响应慢或流式没处理完。先定位到哪一层,再决定加重试还是换通道。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。