第2章:API基础概念——RESTful API、认证机制与请求响应结构
好,咱们直接进入正题。API这东西,说白了就是程序之间沟通的“翻译官”。你想想看,你的应用要跟大模型对话,总得有个双方都懂的规矩吧?这个规矩,就是API。
我个人习惯把API理解成一个“外卖窗口”。你点餐(发请求),厨房做菜(大模型处理),然后窗口把菜递给你(返回响应)。今天咱们就把这个窗口的规矩聊透。
2.1 RESTful API:最流行的“窗口规矩”
RESTful API是目前企业级应用里最常见的API设计风格。我刚开始接触时也觉得概念挺多,什么资源、状态转移、无状态...其实没那么玄乎。
核心就一句话:用HTTP协议的方法,去操作服务器上的资源。
举个例子,你想查某个用户的订单信息。在RESTful风格里,你会这样设计:
GET /api/v1/users/12345/orders
看到没?GET是HTTP方法,/users/12345/orders是资源路径。意思就是“帮我查一下用户12345的订单”。
常用的HTTP方法就这几个:
| HTTP方法 | 操作 | 类比数据库 |
|---|---|---|
| GET | 获取资源 | SELECT |
| POST | 创建资源 | INSERT |
| PUT | 更新资源(全量) | UPDATE |
| PATCH | 更新资源(部分) | UPDATE |
| DELETE | 删除资源 | DELETE |
还有一点,RESTful API强调“无状态”。什么意思?就是每次请求都是独立的,服务器不记得你之前干过什么。嗯,这跟大模型API特别搭——你每次发一段话,它独立处理,不依赖上下文(除非你手动传历史记录)。
2.2 认证机制:你怎么证明你是你?
API接口不能谁都能调,对吧?你得证明你有权限。企业级API最常用的认证方式有两种:API Key和Token。
2.2.1 API Key:最简单的“门禁卡”
API Key就是一个字符串,相当于你的门禁卡。每次请求时带上它,服务器就知道你是谁了。
一般放在请求头里:
Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
或者直接放在URL参数里(不推荐,容易泄露):
https://api.openai.com/v1/completions?api_key=sk-xxxx
2.2.2 Token:更灵活的“临时通行证”
Token比API Key更高级。它通常有有效期,过期了就得重新获取。大模型API里,Token一般通过OAuth 2.0流程获取。
流程大概是:
- 你用API Key去换一个Token
- 拿着Token去调大模型API
- Token过期了,再换一个新的
代码示例(Python):
import requests
# 第一步:用API Key换Token
auth_url = "https://auth.example.com/token"
auth_data = {
"grant_type": "client_credentials",
"client_id": "your_client_id",
"client_secret": "your_client_secret"
}
auth_resp = requests.post(auth_url, data=auth_data)
token = auth_resp.json()["access_token"]
# 第二步:用Token调大模型
api_url = "https://api.example.com/v1/chat/completions"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-4",
"messages": [{"role": "user", "content": "你好"}]
}
resp = requests.post(api_url, headers=headers, json=payload)
print(resp.json())
2.3 请求与响应结构:你发什么,它回什么
搞清楚了怎么认证,接下来就是具体的“对话”格式了。大模型API的请求和响应,基本都是JSON格式。
2.3.1 请求结构:你说了算
一个典型的请求长这样:
{
"model": "gpt-4",
"messages": [
{"role": "system", "content": "你是一个AI助手"},
{"role": "user", "content": "今天天气怎么样?"}
],
"temperature": 0.7,
"max_tokens": 500
}
几个关键字段:
- model:选哪个模型,比如gpt-4、gpt-3.5-turbo
- messages:对话历史,role可以是system(系统指令)、user(用户)、assistant(模型回复)
- temperature:控制随机性,0到2之间。0最确定,2最放飞
- max_tokens:最多生成多少个token(不是字数,是词元数)
2.3.2 响应结构:模型说了算
模型返回的响应也很有规律:
{
"id": "chatcmpl-12345",
"object": "chat.completion",
"created": 1677652288,
"model": "gpt-4",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "今天天气不错,适合出门散步。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 30,
"completion_tokens": 10,
"total_tokens": 40
}
}
重点关注:
- choices:模型生成的回复,可能有多个(如果你设置了n>1)
- finish_reason:为什么停止生成。stop是正常结束,length是达到max_tokens,content_filter是被内容过滤拦截了
- usage:用了多少token,这可是真金白银啊
2.4 实战:写一个完整的API调用
好了,理论说完了,咱们动手写一个完整的调用。假设你要调一个企业级大模型API:
import requests
import json
import os
# 从环境变量读取API Key,千万别硬编码
api_key = os.environ.get("LLM_API_KEY")
if not api_key:
raise ValueError("请设置LLM_API_KEY环境变量")
url = "https://api.llm-service.com/v1/chat/completions"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"model": "enterprise-llm-v2",
"messages": [
{"role": "system", "content": "你是一个企业级AI助手,回答要简洁专业。"},
{"role": "user", "content": "帮我写一封英文商务邮件,邀请客户参加产品发布会。"}
],
"temperature": 0.8,
"max_tokens": 300
}
try:
resp = requests.post(url, headers=headers, json=payload, timeout=30)
resp.raise_for_status() # 检查HTTP状态码
result = resp.json()
reply = result["choices"][0]["message"]["content"]
tokens_used = result["usage"]["total_tokens"]
print(f"模型回复:\n{reply}")
print(f"\n本次调用消耗:{tokens_used} tokens")
except requests.exceptions.Timeout:
print("请求超时,建议检查网络或增加timeout值")
except requests.exceptions.HTTPError as e:
print(f"HTTP错误:{e.response.status_code}")
print(f"错误详情:{e.response.text}")
except Exception as e:
print(f"未知错误:{str(e)}")
这段代码里,我加了异常处理。为什么?因为我在生产环境吃过亏——网络抖动、API限流、Token过期...各种意外都可能发生。不加异常处理,程序崩了都不知道怎么回事。