01
1 / 50

LLM API 入门

⏱️ 30分钟

调用成功不等于接入完成。AI Engineer 要能证明:请求发给了哪个模型、返回是否符合 schema、失败是否被正确分类、敏感数据是否进入日志,以及换供应商时哪些行为会改变。

1. 先分清产品订阅与 API 权限

ChatGPT、Claude 等产品订阅和开发者 API 是两套权限与计费体系。开始前记录以下信息,不把网页端能聊天当作 API 已开通:

字段必须记录的证据
Provider实际供应商与接入区域
Model ID控制台或官方模型目录中的精确 ID
API endpoint / SDK实际使用的端点与 SDK 版本
Access账号、组织、项目是否有权限
Budget配额、限流和允许的最大测试成本
Checked at核验日期;模型目录会变化

当期课堂可以用 gpt-6-astraclaude-fable-5-1 或账号内其他已验证模型。无法访问就标记 unavailable,不要伪造成功,也不要静默切换供应商。

2. 最小请求:先验证连接,不先堆 Prompt

OpenAI 的新工程示例使用 Responses API。模型 ID 从环境配置读取,不写死在业务逻辑里:

import os
import time
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
model_id = os.environ["OPENAI_MODEL_ID"]

started = time.perf_counter()
response = client.responses.create(
    model=model_id,
    input="Return exactly: connection-ok",
)

print(response.output_text)
print({
    "provider": "openai",
    "model": model_id,
    "request_id": getattr(response, "_request_id", None),
    "latency_ms": round((time.perf_counter() - started) * 1000),
})

第一次只检查四件事:凭证有效、模型可访问、响应可解析、请求 ID 与延迟可记录。不要同时加入 streaming、tools、长上下文和复杂 schema,否则失败时无法定位变量。

3. Structured Output:JSON 能解析还不够

生产系统需要业务 schema,而不是“请返回 JSON”这句话。以护理记录草稿为例:

{
	"resident_id": "R-1024",
	"summary": "Resident reported mild dizziness after standing.",
	"risk_level": "review",
	"requires_human_confirmation": true
}

应用侧仍需验证:必填字段和枚举、资源权限、refusal 与 validation failure,以及原始输入到结构化草稿的 lineage。Structured Outputs 约束形状,不保证事实正确;risk_level 仍需业务规则和人工确认。

4. Tool Calling:模型提出调用,应用执行动作

  1. 应用发送 tool name、input schema、用途与副作用说明。
  2. 模型返回 tool call 与 arguments。
  3. 应用校验身份、权限、参数和资源范围。
  4. 应用执行工具,并把结果绑定原 call ID 返回。
  5. 模型基于工具结果生成输出;应用保存 trace。

模型不能直接获得数据库权限。写入、发送、删除等有副作用的工具还要定义 idempotency、human approval 与失败补偿。

5. 错误分类:不是所有失败都应该重试

类型典型原因处理
Authentication / PermissionKey 错误、无权访问模型停止;修复配置,不重试
Validation参数或 schema 不受支持停止;按该模型契约修请求
Rate limitRPM/TPM/并发超限读取限流信息,带抖动退避
Timeout / Network网络中断、连接超时仅在操作可安全重试时有限重试
Provider 5xx服务暂时不可用有上限重试;超过阈值降级或人工处理
Output validation业务字段不合格保存失败证据;修复或人工复核

自动 fallback 会改变模型行为、数据去向、费用和合规边界。只有 routing policy 明确允许,且目标 provider、地区和数据处理条件通过检查时才能切换。

6. Provider Adapter:统一业务契约,不是假装 API 一样

type GenerateRequest = {
	taskType: 'draft-note' | 'policy-answer';
	input: unknown;
	traceId: string;
};

type GenerateResult<T> = {
	provider: string;
	modelId: string;
	output: T;
	usage?: { inputTokens?: number; outputTokens?: number };
	latencyMs: number;
	requestId?: string;
};

Adapter 可以统一业务输入、输出和观测字段,但供应商参数、tool result 格式、缓存规则、错误码与流式事件仍按各自官方契约实现。不要把一个 SDK 的参数或 tool schema 原样复制给另一个模型。

7. 日志、安全与成本证据

推荐记录 trace_id、provider、model ID、request ID、状态、延迟、token/cache usage、重试次数与 schema 结果。不要默认记录完整 Prompt、API Key、居民姓名、医疗信息、工具凭证或未经脱敏的输出。

成本不能用过期价格表硬算。保存真实 usage,再按调用当天官方价格或组织账单计算,并注明核验日期。

8. 三个渐进验证

A. Connection smoke test

发送固定短输入,保存 model ID、request ID、状态和 latency。无权限时明确显示 unavailable

B. Schema contract test

用正常输入、缺字段输入和含未知事实的输入测试结构化输出。应用须区分 success、refusal、validation failure 和 human review。

C. Failure drill

模拟 invalid model、短 timeout、429 和 tool permission denied。只有可重试错误进入有限重试;日志不能含凭证与 PII。

9. 常见错误

  • 把网页产品订阅当成 API 额度;
  • 使用博客里的旧 model ID 或旧 endpoint;
  • JSON 能解析就当作业务正确;
  • 对 401、参数错误和写入操作盲目重试;
  • 主模型失败后无策略地跨供应商切换;
  • 为排错打印完整 Prompt、工具结果和密钥;
  • 只展示最终回答,没有 request、schema、usage 和 failure evidence。

10. 完成自检

  • 我能展示精确 provider、model ID、SDK/endpoint 与核验日期。
  • 最小请求、Structured Output 和错误场景都有真实运行证据。
  • 我能解释 tool call 为什么必须经过应用权限校验。
  • 重试只覆盖明确的瞬时、可安全重试失败。
  • 日志包含可观测字段,但不泄露 Key、PII 或完整敏感内容。
  • 切换模型或供应商前会重新跑 contract tests,而不是假设兼容。

官方参考

📚 相关资源

常见问题

点击问题,查看本章对应的实践答案。

调 LLM API 第一步该选 OpenAI、Claude 还是 Gemini?

通用聊天/代码/产品内嵌选 OpenAI(GPT-5/4.1/4o,生态最全);长文档处理和代码审阅选 Claude 3(长上下文 + 安全性强);图片/视频/文档混合输入选 Gemini 3 Pro/Flash(多模态原生)。预算敏感先用每家的「小」模型,需要质量再换高配。

API Key 应该放在哪里?前端能不能直接调?

永远不要在前端暴露 Key。把 OPENAI_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEY 写进 `.env`,由后端代理网关统一鉴权、限流、审计。按环境分 Key(dev/uat/prod)、最小权限、定期轮换;前端调用走自家后端,后端再转发到模型厂商。

遇到 429 限流要怎么处理?重试策略怎么写?

用指数退避:0.5s → 1s → 2s → 4s,最多 3-5 次。区分错误类型——401/403 是 Key 配置问题不要重试;429 是限流退避后重试;5xx 是服务端,重试同时降级到备选模型。客户端超时设 30 秒以上,每次请求记录 request ID、模型、延迟、tokens 用量。

max_tokens 和 temperature 应该设多少?

max_tokens 必须设——不设会爆量扣费,建议按场景设 200-2000。temperature 通用任务 0-0.7(确定性回答用 0,创意用 0.7);top_p 一般默认即可,别和 temperature 同时大改。用 system 设角色风格保稳定,用 stop 定义停止符控制输出格式。

怎么开启流式输出(streaming)?前端体验有什么注意点?

OpenAI Python 设 `stream=True` 然后 `for chunk in resp` 迭代;Node 遍历 AsyncIterable 实时拼接。前端要做三件事:逐字追加显示、保留光标动画、支持用户取消(cancel)。失败时自动降级回非流式,避免死等;HTTP/2 + 较小 chunk 体验最稳。