大模型 API 开发实战:从第一个请求到批量任务
大模型 API 这件事,理解起来比很多人想象中简单:你不用买显卡,不用自己部署模型,不用管推理框架,只要把文本请求发到一个 HTTP 接口,就能拿到模型生成的内容。对新手开发者来说,最容易上手、最能快速看见成果的路线,不是本地部署,也不是微调,而是先学会调 API。这篇内容适合刚接触大模型开发、想快速做出一个能用的 AI 小工具的人。我会按真实落地顺序写:接入前要准备什么,第一段调用代码怎么写,怎么从单次调用扩成命令行工具,再扩成批量任务,最后把 400、401、429、超时这些常见报错的排查思路说清楚。按这个节奏,第一个请求一般 5 分钟内能跑通,后面扩展只是结构问题。
1. 大模型 API 解决什么问题,适合什么人
1.1 本质是“把模型能力变成接口”
以前想在自己项目里用上大模型,传统路径是先准备一台带 GPU 的机器,然后装驱动、装推理框架、下载模型权重,再写服务把模型包起来。这套流程对个人开发者来说太重了,光是显存和依赖版本问题就能劝退很多人。
大模型 API 改变了这个局面。模型仍然跑在服务商的服务器上,你的程序只负责三件事:收集输入、调用接口、处理输出。至于模型内部是怎么推理的,完全不需要关心。这种“文本进、文本出”的服务模式,让很多原本需要专门算法团队的场景,变成了普通开发者也能完成的普通功能开发。
很多人一上来就研究本地部署和微调,但先把手上的大模型 API 用熟,才是成本最低的第一站。你不需要理解注意力机制,不需要知道量化是什么,只要能正确构造请求、解析返回、处理异常,就已经具备做出一堆实用小工具的能力。
1.2 适合的场景和人群
大模型 API 适合的任务有很明显的特征:输入和输出都可以用文本表达。常见的有问答机器人、文档摘要、翻译、改写、文本分类、信息抽取、客服话术生成、代码解释、JSON 结构化输出等等。
判断一个需求是否适合用 API,可以问自己三个问题:
- 输入是不是文本,或者能不能转成文本。
- 输出是不是文本,或者能不能从文本里解析。
- 对延迟和数据隐私的要求是不是极端。
如果前两条满足,且第三条不极端,就适合用 API 来做。
适用人群也很广。前端、后端、测试、运维,都可以在现有业务里接入大模型能力;产品、运营、学生,则可以快速做出原型工具。你不需要懂算法细节,需要的是:会发 HTTP 请求、会处理 JSON、会写基本 Python,再加上一点耐心看文档。
1.3 和本地部署大模型相比
本地部署并不是没有优势,尤其数据敏感、长期高频、需要深度定制的时候。但对新手和绝大多数个人工具来说,API 的性价比明显更高。
| 对比项 | 大模型 API | 本地部署大模型 |
|---|---|---|
| 硬件门槛 | 无,有网络就行 | 需要 GPU 和足够的显存 |
| 上手速度 | 几分钟到几小时 | 半天到几天 |
| 前期成本 | 按 token 计费,通常有免费额度 | 硬件成本、电费、运维成本 |
| 数据位置 | 请求文本会发送到平台 | 数据留在本地 |
| 模型更新 | 平台维护,你不需要管 | 需要自己下载新版本 |
| 适合场景 | 个人工具、原型、业务集成、中小规模调用 | 数据敏感、私有化部署、超高频调用 |
如果以后真的需要本地部署,Ollama、vLLM 这些工具也能帮上忙,但那是另一条技术路线,建议等 API 用熟之后再考虑。
2. 接入前的四样东西:账号、Key、环境、接口地址
2.1 选一个开放平台
现在可选的大模型开放平台很多,国内常用的有 DeepSeek、智谱、通义、讯飞星火等,不同平台的模型能力、价格、免费额度都不一样。选平台时重点看三点:文档是否清楚、接口是否兼容常见格式、免费额度够不够你做第一次测试。
不要因为某家宣传多就选哪家,先确定自己需要什么能力再决定。第一次选一个文档示例多、社区讨论多的平台,后面遇到问题会更容易搜到答案。
一个常见误区是同时注册五六个平台,结果每个都只试了一下,反而什么都没学会。我建议先固定用一个平台,把完整流程跑通,再去看其他平台的区别。
2.2 获取 API Key 的基本流程
各平台流程略有差异,但大致是几步:
- 注册账号,完成平台要求的实名认证。
- 进入控制台,找到 API Key 或 Token 管理页面。
- 创建一个新的 Key,复制保存好。
- 查看账户是否有免费额度,或者是否需要先充值。
这里最关键的一点是:API Key 相当于你的账号密码,一旦泄露,别人可以拿它调用接口产生费用。不要把 Key 写进代码后截图发到群里,也不要提交到公开代码仓库。第 7 部分我会专门展开 Key 安全。
2.3 本地环境准备
环境准备其实很少,一个能联网的电脑、一个文本编辑器就够了。
建议安装 Python 3.8 或更高版本。如果本机已经装过 Python,打开终端执行 python --version 看一眼版本。然后安装 requests 库:
pip install requests
如果你选的平台接口兼容 OpenAI SDK 格式,也可以顺手装 openai 库:
pip install openai
为什么先准备这些?因为大模型 API 本质上就是 HTTP 请求,requests 足够完成所有基础调用。openai SDK 只是把请求封装得更简洁,不是必须。编辑器用 VS Code、PyCharm、IDLE 都可以,没有硬性要求。
2.4 为什么要先确认接口地址和模型名
每个开放平台的文档里都会给出 base_url、模型名和请求参数。常见的 Chat 接口路径通常是 {base_url}/chat/completions 或者 {base_url}/v1/chat/completions ,具体以你的平台文档为准。
一个看着不起眼但最常见的问题是模型名写错。你在代码里写的模型名,必须和你在这个平台开通的模型完全一致。很多平台的报错信息会把支持的模型名直接列出来,比如提示“支持的模型名是 A 或 B”,看到这种提示照抄进代码就行,不用怀疑是平台出了问题。
所以在写第一段代码之前,先做一件事:打开控制台,确认你调用的模型确切叫什么名字。这是最便宜的排查,能省掉后面一大半 400 报错。
3. 第一个请求:把“你好”发给大模型
3.1 最小可运行的 Python 调用
下面这段代码是完整的最小示例,可以把 API_URL、API_KEY、模型名换成你自己的:
import requests
API_URL = "https://api.example.com/v1/chat/completions"
API_KEY = "sk-你的密钥"
MODEL_NAME = "your-model-name"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": MODEL_NAME,
"messages": [
{"role": "user", "content": "你好,用一句话介绍一下你自己"}
],
"temperature": 0.7,
"max_tokens": 512
}
resp = requests.post(API_URL, headers=headers, json=payload, timeout=30)
print("HTTP 状态码:", resp.status_code)
print("返回内容:", resp.text)
注意:这里的接口地址和模型名都是占位符,实际以你选择的平台文档为准。第一次测试不用追求一次性写对,重点是看清返回结构和错误信息。
3.2 兼容 OpenAI SDK 格式的写法
如果你选的平台接口兼容 OpenAI 格式,可以用更简洁的写法:
from openai import OpenAI
client = OpenAI(
api_key="sk-你的密钥",
base_url="https://api.example.com/v1"
)
resp = client.chat.completions.create(
model="your-model-name",
messages=[
{"role": "user", "content": "你好"}
],
temperature=0.7,
max_tokens=512
)
print(resp.choices[0].message.content)
这种写法好处是代码更短,SDK 已经帮你处理了请求头、超时和返回解析。缺点是多了一层封装,报错时可能不如直接看 requests 返回直观。新手第一次测试,我更推荐先用 requests 版,把状态码和返回文本打印出来看一遍。
3.3 请求体里的几个关键参数
| 参数 | 含义 | 新手建议 |
|---|---|---|
| model | 指定用哪个模型 | 用文档默认模型,不要自己猜 |
| messages | 对话消息数组 | 至少包含一条 user 消息 |
| temperature | 输出随机性 | 先设 0.7,不要随意调高 |
| max_tokens | 最大输出 token 数 | 第一次先设 512 |
| stream | 是否流式返回 | 第一次设 false,方便看完整结果 |
messages 里的 role 有三种:system 用来设定系统人设和约束,user 是用户输入,assistant 是模型历史回复。第一次调用只需要 user 一条就行。
temperature 这个参数值得多说一句。它控制的是输出的确定性,值越高越随机,越低越稳定。做创意写作可以调高一点,做翻译、分类、信息抽取这种要求格式稳定的任务,建议调低,比如 0.2 到 0.4。
3.4 如何判断调用成功
判断标准很简单:
- HTTP 状态码是 200。
- 返回的 JSON 里
choices[0].message.content有文本内容。 - 打印出来的内容没有乱码或截断。
调用失败时,先不要盯着代码猜,先看 resp.text 。绝大多数平台的错误信息都会直接告诉你原因,比如模型名不存在、Key 无效、上下文超长。这些提示比任何调试工具都管用。
3.5 第一次测试要控制成本
第一次调用建议就用一句话,输出限制小一点。跑通之后,看一眼返回里的 usage 字段。它通常包含 prompt_tokens 和 completion_tokens ,也就是这次请求用了多少输入和输出 token。这是你后面估算成本的唯一依据。
不要一上来就写一个循环连续调用几百次,先确认单次请求稳定,再谈批量。
4. 做一个能对话的命令行 AI 小工具
4.1 需求拆解
第一个小工具不需要界面,做一个命令行聊天工具就够。需求拆解下来只有三步:
- 用一个 messages 列表保存对话历史。
- 每次用户输入后,把消息追加进列表,再把整个列表发给接口。
- 拿到回复后追加进列表,打印给用户,然后继续下一轮。
为什么用列表保存历史?因为大模型 API 本身没有记忆,每次请求都要把需要它“看到”的全部对话传过去。工具能不能记住上下文,全靠你客户端有没有把历史消息完整带上。
4.2 完整代码
import requests
API_URL = "https://api.example.com/v1/chat/completions"
API_KEY = "sk-你的密钥"
MODEL_NAME = "your-model-name"
def chat(messages):
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": MODEL_NAME,
"messages": messages,
"temperature": 0.7,
"max_tokens": 1024
}
resp = requests.post(API_URL, headers=headers, json=payload, timeout=60)
resp.raise_for_status()
return resp.json()["choices"][0]["message"]["content"]
def main():
messages = [
{"role": "system", "content": "你是一个乐于助人的 AI 助手,回答尽量简洁。"}
]
print("输入 exit 退出")
while True:
user_input = input("你:")
if user_input.strip().lower() == "exit":
break
messages.append({"role": "user", "content": user_input})
try:
reply = chat(messages)
print("AI:" + reply)
messages.append({"role": "assistant", "content": reply})
except Exception as e:
print("调用失败:", e)
if __name__ == "__main__":
main()
这段代码已经是一个能用的 AI 小工具。跑通之后,你可以往 system 消息里塞不同的人设,比如“你是翻译助手”“你是代码审查员”,同一个程序就变成了不同工具。
4.3 上下文为什么需要管理
很多人写到这一步就开始忘乎所以,不停聊天,直到某次请求突然报错。原因通常是 messages 越来越长,超过了模型的上下文窗口,或者费用涨得飞快。
大模型 API 会把 messages 完整发送到服务端,所以对话越长,请求的 token 就越多,延迟和费用都会上升。做一个正经工具,必须考虑上下文管理。
| 方案 | 适合场景 |
|---|---|
| 只保留最近 10 轮对话 | 简单问答、日常聊天 |
| 限制总 token 数,超出丢弃最早的消息 | 长对话、角色扮演 |
| 把旧对话总结成摘要再继续 | 客服、长期任务、多轮复杂场景 |
最简单实用的做法是:设置一个最大轮数,超过就删掉最早的用户和助手消息。比如只保留最近 10 轮,消息数量可控,费用也稳定。
4.4 stream 和 timeout 先不要急着搞
流式输出就是让模型边生成边返回,视觉效果像打字机。很多演示看起来很酷,但对新手来说,流式响应需要解析 SSE 格式,代码复杂度会上升不少。我建议第一次做工具时先不碰 stream,等普通请求跑通、功能稳定了再优化。
timeout 则一定要设置。如果不设置,网络异常时脚本可能一直挂在那里,看起来像死机。上面代码里统一设了 60 秒,日常使用基本够。如果输入特别长,再往上调。
5. 从单次调用到批量任务,怎么改更稳
5.1 批量任务的正确姿势
命令行工具跑通之后,很多人会想做批量处理,比如批量翻译、批量总结文章、批量生成标题。这时候最容易犯的错误是:直接就写一个大循环,把几百条数据塞进去,然后人离开屏幕,回来发现一半失败,还不知道错在哪。
批量任务的核心不是“能跑”,而是“跑完之后,你清楚每一条是成功还是失败,失败原因是什么”。所以正确姿势是:
- 先用 3 到 5 条样例把流程跑通。
- 输入输出都用文件,不要靠控制台复制粘贴。
- 每条请求尽量独立,单条失败不影响整批。
- 给每条记录保留一个原始 id,方便失败后回查。
5.2 失败重试和限速
批量任务最容易遇到两类问题:网络抖动和接口限流。解决办法不是不失败,而是让失败可控。
我一般会给调用函数加一个重试层,第一次失败等 2 秒,第二次失败等 4 秒,最多重试 3 次:
import time
import requests
def call_once(messages):
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": MODEL_NAME,
"messages": messages,
"temperature": 0.3,
"max_tokens": 1024
}
resp = requests.post(API_URL, headers=headers, json=payload, timeout=60)
resp.raise_for_status()
return resp.json()["choices"][0]["message"]["content"]
def call_with_retry(messages, max_retry=3):
for i in range(max_retry):
try:
return call_once(messages)
except Exception as e:
print(f"第 {i + 1} 次调用失败:{e}")
if i < max_retry - 1:
time.sleep(2 * (i + 1))
raise RuntimeError("重试多次仍然失败")
重试等待为什么要递增?因为 429 限流通常是短时间请求太多,立刻重试只会继续触发限流,间隔拉长反而更容易成功。连续失败超过 3 次就不要硬跑了,先看日志和输入,再决定是修数据还是降并发。
5.3 输出落盘与断点续跑
批量处理的输出一定要写文件,而且建议每完成一条就 flush 一次。这样即使程序中途崩溃,已经完成的不会丢。
import json
from pathlib import Path
input_path = Path("input.jsonl")
output_path = Path("output.jsonl")
with input_path.open("r", encoding="utf-8") as fin, \
output_path.open("a", encoding="utf-8") as fout:
for idx, line in enumerate(fin):
item = json.loads(line)
messages = [{"role": "user", "content": item["text"]}]
try:
reply = call_with_retry(messages)
except Exception as e:
print(f"第 {idx} 条失败:{e}")
continue
result = {"id": item["id"], "output": reply}
fout.write(json.dumps(result, ensure_ascii=False) + "\n")
fout.flush()
这里用追加模式打开输出文件,每条结果单独一行。失败的任务可以先跳过,跑完后再补跑失败清单。这就是最简单的断点续跑,不用引入任务队列。
5.4 异步和并发,新手边界
新手先用串行。确定单条稳定之后,再考虑开 2 到 4 个并发。并发数过高会触发平台限流,反而比串行更慢。不要一上来就开 50 个线程,你还没看清日志,就已经被限流了。
异步能提升吞吐,但也会让日志和错误排查变复杂。我的建议是:先能跑,再跑快。串行跑 100 条如果能接受,就先不折腾并发;等数据量真的大到必须优化,再按“并发数、重试、限流”这个顺序逐步调整。
6. 常见报错的判断顺序:现象→输入→环境→参数→工具
报错不可怕,可怕的是不知道从哪里看起。我的排查顺序永远是:先看现象,再看输入,再看环境,再看参数,最后才怀疑工具本身。
6.1 401 和 403:先查 Key 和权限
401 通常表示鉴权失败。优先检查:
- API Key 是否复制完整,有没有多出空格或换行。
- Authorization 请求头是否带了
Bearer前缀。 - Key 是否还能用,去控制台重新生成一个对比。
403 通常表示权限不足。比如账号没有开通某个模型的访问权限,或者账户状态异常。这类问题改代码没用,要去控制台确认账号权限和套餐状态。
6.2 400:先查模型名和 messages 格式
400 是新手遇到最多的错误,但也是最好解决的。常见原因有:
- 模型名写错。报错信息经常会直接列出支持的模型名,照着改就行。
- messages 缺少 role 或 content 字段,或者 messages 是空数组。
- 参数类型或范围不对。比如报错提示某个参数必须是正整数,说明你传入了负数、小数或字符串。
- 输入内容超过模型上下文长度。报错信息里通常会写明最大 token 数,需要截断或压缩输入。
看到 400,先做一件事:把 resp.text 完整打印出来。平台返回的错误信息几乎已经告诉了你正确答案。
6.3 429:限流和额度问题
429 表示请求被限流。可能原因:
- 并发请求太高。
- 免费额度用完。
- 账户欠费。
处理方式是降低并发、增加重试等待,然后去控制台看余额和使用量。如果确认账户还有额度,那就是并发太猛,把并发降到 1 再试一次,正常了再慢慢往上加。
6.4 连接中断和超时
连接中断、响应超时、返回内容不完整,
更多推荐

所有评论(0)