GraphQL 是 AI agent 一直在等的语言
GraphQL 在 2015 年被设计出来,是为了让前端开发更快。结果它成了「会提聪明问题的机器」的完美接口。
在上一篇文章里,论点是每个应用都需要 API-first,因为 AI agent 正在成为软件的主要消费者。API 就是产品。界面只是其中一个客户端。
那个论点留下了一个几乎还没人问、但所有人都该问的后续问题:该建哪一种 API?
答案,在你真正观察 agent 如何试图使用软件之后,会强烈地指向一个方向。GraphQL。不是因为它时髦——它到现在已经十年了。而是因为让 GraphQL 区别于 REST 的那些具体特性,几乎完美对上了 agent 在没有人类介入时运作所需要的东西。
就好像 Facebook 在 2015 年意外造出了 agent 时代的查询语言,然后整个行业花了十年,主要用它让 React 应用稍微方便一点。这大大低估了它。低估得很戏剧化。
发现问题
这是一个 API 为人类而非机器建造的最明显迹象:文档页。端点以名词罗列。示例是为已经知道自己在找什么的人写的。版本历史自上次组织架构调整后就没人更新。当开发者到来时,他读文档、在脑子里建起资源图的心智模型,然后写代码去做一组具体的、预先规划好的调用序列来拿到需要的数据。文档是一次性的上手成本。
Agent 不是这样工作的。Agent 带着一个目标来到你的 API——找出分派给工程团队的、优先级最高的三个未关闭工单,并总结它们最近的动态——然后必须动态地弄清楚如何把这个目标分解成一系列操作。没有预先建好的集成。没有资深工程师去读文档。Agent 是在实时地、在初次相遇中推理你的 API。
称它为发现问题:agent 在不知道里面有什么的情况下来到你的应用,而这份无知的代价,会在它试图运行的每一条工作流中被支付。用 REST,agent 必须猜哪些端点存在、发起一次调用、检查响应以理解数据形状、意识到它需要来自别处的关联数据、再发起一次调用、把结果关联起来、处理分页、然后重复——而这一切都在把上下文窗口烧在它并不需要的数据上。
GraphQL 把发现问题折叠掉了。Agent 可以跑一次内省查询,拿回完整的 schema:每一个类型、每一个字段、每一个关系、每一个参数、每一段描述。这份 schema 不是一个可能与现实脱节的独立产物。它就是现实。它由解析这些查询的同一份代码生成。
对 agent 来说,这就是「在没有地图的城市里导航」和「一开始就有 GPS」之间的差别。
内省就是自文档化
每一个 GraphQL API 都是自文档化的。不是那种松散、志愿性的「有人记得把 OpenAPI 规范保持更新时,REST API 也算自文档化」的意思。GraphQL API 是字面意义上自文档化的,是设计使然,是协议的核心能力。
这对 agent 有一种具体的重要性。在发起任何一次数据请求之前,agent 就可以问这个 API:你能做什么?你有哪些数据?它们之间如何连接?而 API 会回答——完整地、准确地、以一种解析起来毫不费力的格式。
想象一个被要求找出近期关于账单的客户投诉的 agent。它内省 schema,发现有一个带 tickets 字段的 Customer 类型,发现工单有一个包含 BILLING 的 category 枚举,发现工单有 createdAt 时间戳和 status 字段,发现每个工单上有一个 comments 连接。几秒之内,它就拿到了数据模型的完整地图——不是从可能过期也可能没过期的文档里,而是从活着的系统本身。
这正是 Model Context Protocol——Anthropic 让 AI 助手能发现并调用外部工具的标准——本质上试图给每一种 API 后加上的那种特性。一份 GraphQL schema 已经是 MCP 形状的清单。当两者说同一种语言时,协议与数据模型在中途相遇。
精确请求你需要的东西
REST API 返回固定的数据结构。你调用 /api/users/123,拿回服务器决定放进用户响应里的一切:姓名、邮箱、地址、偏好、头像 URL、账户创建日期、上次登录时间戳、订阅等级,以及另外四十个字段。如果你还需要这个用户最近的订单,那是另一次调用。如果你需要那些订单里的商品,那是每个订单再一次调用。
当每一个 API 消费方都是能写定制代码去处理过度获取并编排来回请求的前端工程师时,这是合理的。当消费方是在真实约束下运作的 agent 时,这就深度低效了。
Agent 有上下文窗口。响应里每一个不必要数据的 token,都是本可以用于推理、规划或保存其他相关上下文的 token。当一个 REST API 返回 4KB 的用户数据而 agent 只需要姓名和邮箱时,那不只是浪费带宽。那是浪费认知容量。把它乘以一条多步工作流中的每一次调用,agent 的上下文就被噪声填满了。
GraphQL 消除了这个问题。Agent 指定它需要的确切字段:
query {
user(id: "123") {
name
email
recentOrders(first: 3) {
status
total
items {
productName
quantity
}
}
}
}
一次请求。恰好需要的数据。没有过度获取。没有获取不足。没有浪费的 token。Agent 拿回一份精确对应其信息需求的响应。这不是一次优化——这是一种根本不同的数据获取模式,消费方描述形状,服务器负责搞清楚如何把它组装出来。
那正是智能 agent 应当能用来与数据源交互的模式。那也正是 GraphQL 已经安静运行了十年的模式。
一次请求,而不是十二次
REST 里获取不足的问题比过度获取更痛,而这也正是 GraphQL 的优势变得最明显的地方。
想象一个被派去生成每周团队状态报告的 agent。它需要团队成员、每个人被分派的任务、这些任务的状态和优先级、本周有更新的任务上的评论,以及这些任务所属的项目。在一个典型的 REST API 里,这是一场瀑布:先拿团队名册,然后为每个成员取他的任务,然后为每个任务取评论和项目。几十次请求,每一次都依赖前一次。Agent 必须编排这一切、在每个端点上处理分页、应对限流、把不同响应形状里的数据缝在一起。为了一个概念上只有一个问题的东西,写了一大堆顺序逻辑。
在 GraphQL 里,这是一次查询。一次往返。所有数据,正确嵌套,恰好是 agent 要求的形状。Agent 不必理解编排模式,不必管理中间状态,不必维护「端点如何串联」的心智模型。每一次被消除的往返,都是一个被移除的失败模式、一份被省下的延迟成本,以及一段 agent 永远不必写的编排代码。
对一个从根本上说是在努力最小化不必要复杂度的推理引擎来说,这是巨大的优势。
自带校验的变更
GraphQL 的优势不限于读数据。当 agent 需要做事情时——创建记录、更新状态、触发工作流——GraphQL 的 mutation 提供了一个结构化、可预测、自校验的接口。
当 agent 通过 REST API 创建一张支持工单时,它必须构造一个带 JSON 体的 POST 请求,但那个体的确切形状——哪些字段必填、哪些可选、期待什么类型、什么值有效——只定义在外部文档里。搞错了,agent 会在运行时才发现,通过一条可能有帮助也可能没帮助的错误响应。
GraphQL 的 mutation 有带类型的输入对象。Schema 明确声明每一个参数、它的类型、是否必填以及它的描述。Agent 可以在发起调用之前内省这个 mutation、确定无疑地构造出合法载荷,并要求恰好它需要的确认数据返回。不用猜。不用试错。没有靠希望缝起来的脆弱集成。
机器就该以这种方式与应用交互。
Schema 就是契约
一份 GraphQL schema 实际上就是一份机器可读的能力清单。它宣告:这个应用能做的一切在此、涉及的数据类型在此、它们如何彼此关联在此、可用的操作在此。它是你的应用与任何想使用它的智能系统之间的契约。
当 agent 遇到一个 GraphQL API 时,它不需要定制集成。它不需要有人手写一个适配器。它读 schema,然后开始工作。Schema 就是集成层。
这正是 Archie Core 围绕其设计的特性。每一个建在 Archie Core 上的应用——前端、后端或两者——都免费获得一份 GraphQL schema。不是事后想法,不是挂在旁边的附件,而是作为主要接口。含义并不微妙:任何在 Archie 上交付的应用,在第一天就是 agent 就绪的,因为 agent 已经在说这门语言。
在一个 agent 越来越多地代表用户决定调用哪些工具的经济里,「容易协作」不是技术细节。它是一项进入市场的战略。
诚实的取舍
GraphQL 有真实的代价,装作没有会是偷懒。搭一个 GraphQL 服务器比立起 REST 端点更费事。朴素的实现可能产生过量的数据库查询——N+1 问题——需要 DataLoader 模式和查询规划来缓解。缓存比 REST 基于 URL 的资源更难;你需要持久化查询这类应用层策略,而不能依赖 CDN 层缓存。而如果你的应用有一个关系极少的扁平资源模型,REST 可能完全够用——即便是对 agent。
这些是有已知解法的工程挑战,不是根本性限制。问题在于这份代价相对于 agent 时代的收益是否值得,而对任何认真对待那个未来的应用来说,答案越来越是「值得」。
建一个机器能用来思考的 API
API-first 的论点是:应用需要通过程序化接口完全可达,因为 agent 正在成为主要消费者。GraphQL 的论点是它的自然延伸:API 应当以智能机器能以最小摩擦发现、理解和使用的方式来设计。
GraphQL 给你一份充当活能力清单的自描述 schema。给你尊重 agent 上下文限制的精确数据获取。给你消除猜测的带类型 mutation。给你让主动行为成为可能的实时订阅。而这一切都通过单一端点、用统一的查询语言提供。
REST 是为一个开发者一次一个端点手写集成的世界建造的。那个世界依然存在,REST 也依然很好地服务着它。但正在浮现的世界——agent 动态发现并即时组装应用能力——要求某种更有表达力、更结构化、更可内省的东西。
GraphQL 不再只是一项开发者便利。它是智能 agent 能用来推理的接口语言。而说这门语言的应用,将是它们最先伸手去找的那些。
延伸阅读
这底下架构的论证在界面是个谎言中,它的商业版本在 API-first 的商业论证中。
常见问题
对 AI agent 来说,为什么 GraphQL 比 REST 更好? GraphQL 通过内省实现自文档化,让 agent 在一次往返里请求恰好需要的字段,并对 mutation 强制带类型的输入。REST 要求 agent 猜测端点形状、为关联数据编排多次调用,并通过试错发现必填字段。
什么是发现问题? 发现问题是 AI agent 在不知道有哪些数据和操作可用的情况下来到一个应用时所支付的代价。REST API 强迫 agent 去猜;GraphQL API 通过一次返回完整 schema 的内省查询来回答。
GraphQL 与 Model Context Protocol(MCP)有什么关系? MCP 是 Anthropic 让 AI 助手能发现并调用外部工具的标准。一份 GraphQL schema 已经是 MCP 形状的——它提供了 MCP 本就旨在暴露的那份机器可读能力清单。GraphQL 应用与 agent 生态在中途相遇。
GraphQL 难道没有真实的代价和复杂度吗? 有。GraphQL 服务器比 REST 端点更复杂。缓存更难。朴素实现有 N+1 查询问题。这些是有已知解法的工程挑战——DataLoader、持久化查询、schema 规划——不是根本性限制。
Archie Core 为什么选 GraphQL 作为它的主要 API? Archie Core 的设计让每一个建在其上的应用都免费获得一份 GraphQL schema,这使得该应用从第一天起就可被 AI agent 发现和操作。Agent 就绪是架构的属性,不是之后添加的功能。