第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
我的小经验: 调用大模型API时,绝大多数情况只用POST。因为你要“创建”一次对话或“提交”一段文本让模型处理。GET一般只用来查账户余额或模型列表。

还有一点,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
注意: 我曾经见过有人把API Key硬编码在GitHub仓库里,结果几分钟就被爬虫扫到,账户被盗刷了几千块。API Key一定要放在环境变量或密钥管理服务里。

2.2.2 Token:更灵活的“临时通行证”

Token比API Key更高级。它通常有有效期,过期了就得重新获取。大模型API里,Token一般通过OAuth 2.0流程获取。

流程大概是:

  1. 你用API Key去换一个Token
  2. 拿着Token去调大模型API
  3. 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())
核心区别: API Key是“永久的钥匙”,Token是“有时效的通行证”。企业级场景里,Token更安全,因为泄露了也能很快失效。

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(不是字数,是词元数)
避坑指南: 我曾经把temperature设成0,以为这样最稳定。结果模型回答变得特别机械,像机器人。后来我调到0.7,效果好了很多。记住,完全确定 = 完全无聊。

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,这可是真金白银啊
注意: 响应里的token数就是计费依据。我见过有人写了个死循环,一直调API,一晚上烧掉几千块。记得在代码里加个计数器,控制调用次数。

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过期...各种意外都可能发生。不加异常处理,程序崩了都不知道怎么回事。

总结一下: RESTful API是规矩,API Key/Token是钥匙,请求响应是对话内容。这三样搞明白了,大模型API调用就算入门了。下一章咱们聊聊更高级的——流式响应和并发控制。