网站正在迎来一种新的访问者:AI Agent。它们通常不渲染 CSS、不点击广告,却可能代表一个有明确需求、也愿意付费的人类用户。粗暴封禁所有自动化流量,挡住的不只是爬虫,也可能是正在替客户检索资料、比较服务或执行采购的 Agent。
真正需要解决的问题,不是简单地“允许还是禁止机器人”,而是建立一套让发布者与 Agent 能够合作的接口:内容可读、能力可发现、操作可调用、交易可付费,同时保留身份验证、授权、限流和审计边界。
网页能打开,不等于 Agent 能使用
传统网站围绕浏览器构建。导航藏在 JavaScript 状态里,正文与推荐模块混在 DOM 中,价格可能只有视觉样式,没有稳定的数据字段。人类能通过布局理解页面,Agent 却需要可预测的结构。
面向 Agent 的“可读”不意味着删除 HTML,而是补充机器友好的表达,例如:
- 为文章、产品和服务提供稳定的 URL 与结构化字段。
- 明确区分正文、作者、更新时间、价格、许可证和使用限制。
- 对动态页面提供 JSON 表达,避免要求 Agent 执行完整前端应用。
- 返回准确的 HTTP 状态码,不用
200 OK包装所有错误。 - 在响应中说明内容能否缓存、引用或用于后续处理。
HTML 仍然服务人类,结构化接口则减少 Agent 猜测页面含义的成本。两者可以共享同一个内容源,避免出现两套数据长期漂移。
四个接口层次
标题中的四个关键词可以对应四类工程能力。
可读:提供稳定的数据形状
Agent 应当能直接取得正文、摘要、元数据和约束条件。字段版本需要显式管理,删除或改名时也应有迁移周期。
可发现:公开能力清单
仅仅存在 API 还不够,Agent 必须知道入口在哪里、支持什么动作、需要何种认证。可以通过约定明确的清单地址描述能力。具体路径和格式仍需要生态形成共识,不应把某个自定义 JSON 当成已经确立的行业标准。
可调用:把动作设计成受控工具
搜索、预订、购买和提交任务应成为参数明确的操作。每个操作需要输入约束、幂等策略、超时语义和机器可解析的错误响应。高风险动作还应要求人类确认,不能因为调用方是 Agent 就跳过权限检查。
可付费:让价值交换进入协议
可付费不只是返回一个价格。完整流程还涉及报价有效期、币种、税费、支付授权、退款、收据和争议处理。Agent 可以替用户发起流程,但最终扣款必须受用户授权和支付系统规则约束。
一个可运行的最小服务
下面是一个概念性实践示例,并不代表来源已经规定了这些路径或字段。它使用 Python 标准库实现三个接口:能力发现、结构化内容读取和报价创建。报价只返回模拟结账地址,不会真实扣款。
将代码保存为 agent_service.py,使用 Python 3.10 或更高版本运行:
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import json
import time
import uuid
ARTICLE = {
"id": "agent-ready-web",
"title": "Designing services for agents",
"summary": "A structured article that agents can retrieve without rendering CSS.",
"updated_at": "2025-01-15T09:00:00Z",
"license": "read-only",
}
MANIFEST = {
"schema_version": "0.1-example",
"name": "Example Publisher",
"capabilities": {
"read_article": {
"method": "GET",
"path": "/agent/articles/{id}",
"authentication": "none",
},
"create_quote": {
"method": "POST",
"path": "/agent/quotes",
"authentication": "Bearer token",
},
},
}
class Handler(BaseHTTPRequestHandler):
def send_json(self, status, payload):
body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
self.send_response(status)
self.send_header("Content-Type", "application/json; charset=utf-8")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def do_GET(self):
if self.path == "/.well-known/agent.json":
return self.send_json(200, MANIFEST)
if self.path == "/agent/articles/agent-ready-web":
return self.send_json(200, ARTICLE)
self.send_json(404, {"error": "not_found"})
def do_POST(self):
if self.path != "/agent/quotes":
return self.send_json(404, {"error": "not_found"})
if self.headers.get("Authorization") != "Bearer demo-token":
return self.send_json(401, {"error": "invalid_token"})
length = int(self.headers.get("Content-Length", "0"))
try:
request = json.loads(self.rfile.read(length) or b"{}")
except json.JSONDecodeError:
return self.send_json(400, {"error": "invalid_json"})
if request.get("product_id") != "research-report":
return self.send_json(400, {"error": "unknown_product"})
quote_id = str(uuid.uuid4())
self.send_json(201, {
"quote_id": quote_id,
"amount": 1900,
"currency": "USD",
"expires_at_unix": int(time.time()) + 600,
"requires_human_confirmation": True,
"checkout_url": f"https://pay.example.test/checkout/{quote_id}",
})
if __name__ == "__main__":
server = ThreadingHTTPServer(("127.0.0.1", 8080), Handler)
print("Listening on http://127.0.0.1:8080")
server.serve_forever()
启动服务并依次测试发现、读取和报价接口:
python3 agent_service.py
curl -s http://127.0.0.1:8080/.well-known/agent.json
curl -s http://127.0.0.1:8080/agent/articles/agent-ready-web
curl -s -X POST http://127.0.0.1:8080/agent/quotes \
-H 'Authorization: Bearer demo-token' \
-H 'Content-Type: application/json' \
-d '{"product_id":"research-report","quantity":1}'
这个示例刻意把“报价”和“扣款”分开。生产系统应将 checkout_url 接入真实支付服务,通过签名 webhook 确认付款,并使用幂等键防止 Agent 重试时创建重复订单。
开放接口不等于放弃控制
Agent 流量仍然可能滥用资源,调用者背后有付费用户也不等于每次请求都可信。发布者至少需要处理以下边界:
- 使用 API Key、OAuth 或短期令牌标识调用方,并按主体授权。
- 对读取和写入操作设置不同的速率限制与配额。
- 对购买、删除、发布等动作要求二次确认或人类批准。
- 记录调用主体、参数摘要、结果和关联交易,避免日志泄露敏感数据。
- 对外部文本和工具返回值做校验,防止提示注入影响后续动作。
- 给清单与接口定义版本,保留旧版本的下线窗口。
- 明确内容许可。可读取不自动意味着可训练、可转载或可永久存储。
识别 Agent 时也不能只依赖 User-Agent 请求头,因为它很容易伪造。更可靠的方案需要令牌、签名请求、调用方注册以及异常行为检测共同参与。
从低风险入口开始
接入 Agent 不必一开始就开放支付和写操作。更稳妥的采用顺序是:先发布结构化只读内容,再增加能力清单和搜索接口;当认证、限流与审计稳定后,再开放报价、预订等可逆操作;真实扣款、内容发布和账号变更则应放在明确的人类授权之后。
上线前可以检查四件事:Agent 是否能在不渲染前端的情况下理解内容,是否能发现接口及其约束,是否能以幂等方式调用动作,以及支付是否保留清晰的用户授权、收据和退款路径。做到这些,网站面对的就不再是一团难以区分的自动化流量,而是一类可以被识别、约束并服务的新客户入口。