HTTP 与 API
请求、响应、GET / POST 与状态码:软件之间如何对话。
一句话理解:API 是软件之间约定好的“点单窗口”,HTTP 是点单的格式;Agent 调用的绝大多数工具,本质上都是一次 HTTP 请求。
当 Agent “查询订单”“拉取天气数据”“创建工单”时,背后几乎都是同一件事:程序按约定格式向某个系统发出请求,拿回一份响应。看不懂请求和响应,你就只能听工程师说“接口报错了”,而无法判断是参数填错了、权限不够、对方系统挂了,还是 Agent 调用得太频繁被限流了。
这一课不要求你会写代码,但要求你看到一个请求时,能读懂它在做什么。
用餐厅点单理解 API
| 餐厅 | 软件世界 | 说明 |
|---|---|---|
| 菜单 | API 文档 | 列出能点什么、需要提供什么信息 |
| 点单窗口 | 接口地址(Endpoint) | 例如 https://api.example.com/v1/orders |
| 点单动作 | 请求方法(GET、POST 等) | 是查询菜品,还是下单 |
| 点单内容 | 参数与请求体 | 要几份、什么口味 |
| 会员卡 | 认证信息(API Key、Token) | 证明你是谁、能点什么 |
| 出餐结果 | 响应(状态码 + 数据) | 成功出餐,还是“这道菜卖完了” |
API(Application Programming Interface)就是一个系统对外公开的、约定好格式的操作入口。HTTP 是互联网上最常用的请求—响应协议,大多数 Web API 都跑在它上面。
一次请求长什么样
以“查询订单详情”为例,一次完整的 HTTP 交互如下:
GET /v1/orders/A1234?include=items HTTP/1.1
Host: api.shop.example.com
Authorization: Bearer eyJhbGciOi...
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"order_no": "A1234",
"status": "processing",
"last_event": {
"time": "2026-09-14T08:12:00+08:00",
"type": "payment_received",
"description": "支付完成,等待商家确认"
},
"payment_status": "paid"
}
把这次往返画出来,就是下面这张图:
拆开来看:
| 组成部分 | 本例中的值 | 作用 |
|---|---|---|
| 方法 | GET |
要做什么动作(这里是读取) |
| 路径 | /v1/orders/A1234 |
操作哪个资源(订单 A1234) |
| 查询参数 | ?include=items |
附加条件(顺便返回商品明细) |
| 请求头 Headers | Authorization、Accept |
元信息:我是谁、我想要什么格式 |
| 请求体 Body | 无(GET 通常没有) | 要提交的数据 |
| 状态码 | 200 OK |
结果如何 |
| 响应体 | JSON 数据 | 返回的实际内容 |
再看一个写操作——“创建售后工单”:
POST /v1/tickets HTTP/1.1
Host: api.ticket.example.com
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
Idempotency-Key: 7f3c9a2e-order-A1234-payment
{
"order_no": "A1234",
"type": "payment_status_mismatch",
"priority": "high",
"summary": "支付平台显示扣款成功超过 24 小时,订单仍为未支付状态"
}
HTTP/1.1 201 Created
Content-Type: application/json
{ "ticket_id": "TK-88213", "status": "open", "assignee": "cs-team-1" }
常用方法:读与写的分界
| 方法 | 语义 | 是否修改数据 | 重复执行是否安全 | Agent 场景例子 |
|---|---|---|---|---|
| GET | 读取资源 | 否 | 安全 | 查订单、查汇率、查天气 |
| POST | 创建资源或触发动作 | 是 | 不一定,可能重复创建 | 创建工单、发送邮件、发起退款 |
| PUT | 整体替换资源 | 是 | 通常可重复 | 更新整个配置 |
| PATCH | 局部修改资源 | 是 | 视实现而定 | 修改订单状态 |
| DELETE | 删除资源 | 是 | 通常可重复,但后果严重 | 删除草稿 |
对 Agent 设计来说,这张表最重要的一列是“是否修改数据”。GET 类工具可以相对放心地自动调用;POST、PATCH、DELETE 类工具要进入权限与审批设计。 这正是安全的工具设计中“读写分离”的基础。
上面 POST 请求里的 Idempotency-Key(幂等键)值得注意:Agent 可能因为超时而重试,如果没有幂等设计,同一个工单可能被创建两次。一些 API(例如 Stripe)支持通过这类请求头让服务端识别重复请求。并非所有 API 都支持,需要看对方文档。
状态码:一眼判断问题出在哪
状态码是三位数字,第一位代表大类:
| 范围 | 含义 | 谁的问题 |
|---|---|---|
| 2xx | 成功 | 没问题 |
| 3xx | 重定向 | 资源换了位置 |
| 4xx | 客户端错误 | 调用方(也就是 Agent 或工具)的问题 |
| 5xx | 服务端错误 | 被调用的系统出了问题 |
最常遇到的几个,以及 Agent 应该如何应对:
| 状态码 | 含义 | 常见原因 | Agent 应该怎么做 |
|---|---|---|---|
| 200 OK | 成功 | — | 读取数据继续 |
| 201 Created | 创建成功 | — | 记录新资源 ID,用于后续验证 |
| 202 Accepted | 已接收,稍后处理 | 异步任务 | 记录任务 ID,稍后查询结果 |
| 400 Bad Request | 请求格式错误 | 参数缺失、类型错误 | 根据错误信息修正参数,不要原样重试 |
| 401 Unauthorized | 未认证 | Token 缺失或过期 | 停止,交给程序刷新凭据或请用户重新授权 |
| 403 Forbidden | 无权限 | 身份正确但权限不够 | 停止,告知用户缺少什么权限 |
| 404 Not Found | 资源不存在 | 订单号写错、资源已删除 | 核对输入,必要时询问用户 |
| 409 Conflict | 状态冲突 | 工单已被他人关闭 | 重新读取最新状态再决定 |
| 422 Unprocessable Content | 格式对但语义不对 | 日期范围非法、状态流转不允许 | 按错误信息修正 |
| 429 Too Many Requests | 请求过于频繁 | 触发限流 | 等待后重试,降低频率 |
| 500 Internal Server Error | 服务端内部错误 | 对方系统 bug | 有限次数重试,仍失败则报告 |
| 502 / 503 / 504 | 网关错误、服务不可用、超时 | 对方系统过载或维护 | 退避重试,超过上限后升级 |
按状态码的大类,Agent 的应对可以归成四条路径:
这张表可以直接变成工具的错误处理策略。一个好的工具不应该只把“请求失败”丢给模型,而应该返回 可行动的错误信息,例如“订单号不存在,请确认格式为字母 A 加 4 位数字”。详见工具设计原则。
API 调用与 Tool Calling 是什么关系
模型本身不会发 HTTP 请求。Tool Calling 的真实过程是:
两个关键点:
- 模型只决定“调什么、传什么”,真正发请求的是程序。 所以认证信息应该由程序注入,而不是让模型看到或填写。
- 工具不等于 API。 一个工具可以封装多个 API 调用(查订单 + 查支付状态),也可以只暴露 API 的一部分字段。工具是为模型设计的,API 是为程序设计的。
原理细节见Function Calling 原理,本模块最后的实操:调通第一个 API 会让你亲手走一遍这个过程。
常见误区
- “接口报错就是对方系统有问题。” 先看状态码:4xx 大多是调用方的问题(参数、权限、频率),5xx 才是对方的问题。
- “失败了就重试。” 400、401、403、404 原样重试没有意义,只会浪费调用次数;对 POST 类请求盲目重试还可能造成重复写入。
- “有 API 文档就能直接给 Agent 用。” API 往往字段繁多、命名面向程序员,直接暴露给模型容易用错。通常需要再包装成面向任务的工具。
产品经理检查清单
评审一个需要调用外部系统的 Agent 功能时:
- 需要调用哪些接口?分别是读还是写?
- 每个接口的认证方式是什么?凭据由谁保管、如何注入?
- 接口有没有限流?Agent 一次任务大约会调用多少次?
- 写操作是否支持幂等?超时重试会不会造成重复?
- 各类错误码对应的处理策略是什么?哪些重试、哪些停止、哪些找人?
- 接口返回的数据量有多大?是否需要裁剪后再给模型?
- 接口的响应时间大约多久?会不会拖慢整个任务?
练习
用 30–45 分钟完成:
- 在浏览器中直接打开下面这个地址(这是一个 GET 请求,无需注册):
https://api.open-meteo.com/v1/forecast?latitude=30.27&longitude=120.15¤t=temperature_2m,weather_code - 对照本课的表格,指出:方法、域名、路径、查询参数分别是什么,返回的 JSON 中哪个字段是当前温度。
- 把
latitude改成999再打开,观察返回的错误信息,想一想它对应哪一类状态码、Agent 应该如何处理。 - 为订单售后诊断 Agent 设计 3 个接口(1 个读、2 个写),写出方法、路径、请求体示例和可能的错误码。
延伸阅读
- MDN:HTTP response status codes,状态码的权威参考。
- Open-Meteo:Weather Forecast API 文档,本模块实操使用的免费天气 API。
下一步
API 返回的数据几乎都是 JSON,而模型调用工具时填写的参数也是 JSON。下一课「JSON 与 JSON Schema」讲清这门 Agent 世界的通用语言。