标题去空格=22字符
原文:https://dev.to/nikolas_dimitroulakis_d23/we-described-our-api-twice-once-for-humans-once-for-agents-4e4g(作者 @nikolas_dimitroulakis_d23)
最后一次是谁调用你的API?
对我们来说,诚实的答案是:越来越多的是AI代理。Claude Code正在调试一个流程。一个助手正在查询订单。某人的自定义GPT。
而我们的工具仍然假设是一个人类在点击“发送”。
这篇文章就是关于这个差距。我们自己是如何遇到它的,目前大多数团队是如何处理的,以及我们做了什么改变。
我们是如何遇到的
我们运营着ApyHub,一个实用API目录。今年,我们希望像Claude、ChatGPT和Le Chat这样的助手能直接调用这些API。于是我们构建了一个MCP服务器并将其发布到了官方的MCP注册中心。
它成功了。人们开始使用。
然后我们注意到了一些令人不安的事情。我们现在有了同一API的两套描述。
一套是我们已经信任的请求和测试。另一套是手工编写的MCP服务器,它们并排放在那里。
修改一个端点?需要更新两处。忘记一处?等代理出问题时才发现。
测试MCP这部分是另一项繁琐的工作。连接检查器,点击工具,读取JSON,关闭标签页。下次发布,再凭记忆重复一遍。
这些都不是什么大问题。只是这类摩擦在无声地累积,直到你意识到,你为自己已有的东西,构建了一个第二份、更差的副本。
我们不断遇到的三种情况
当我们仔细观察时,发现这其实是三个不同的问题。它们都与MCP有关,所以很容易被混为一谈。区别在于是谁在调用谁。
1. 你自己的编码代理,在盲目调试
结账流程返回了400错误。你请求Claude Code帮忙。
今天,你粘贴错误信息。可能还有一个curl命令。代理会推理哪里可能出了错。当它想测试什么时,它会自己写一个curl,猜测请求头,并询问令牌在哪里。
最终你成了代理的“手”。
我们想要的更简单一些。项目里已经存在这些请求。让代理运行它们。
所以我们就这样做了。我们为此使用Voiden,这是我们正在开发的开源API工具,其中的请求以纯Markdown文件的形式存储在代码库中。点击一个按钮(或在终端运行voiden agent),你的编码代理就可以列出、运行和检查这些请求。它调用的是真实的端点,读取的是真实的响应。在我们的结账示例中,它会自己发现缺失的请求头。
这默认对整个项目开启。我们的推理是:这是你、你的编辑器和你自己的代理。信任边界很小。
我对此相当有信心。但我知道有些团队会不同意,特别是当环境里有生产环境凭证时。如果你们是这种情况,我很想听听你们的底线在哪里。
2. 别人的代理,调用一个端点
你的客服助手需要发放退款。只能是退款。
今天,有人编写一个MCP服务器。选择一个SDK。将输入重新定义为一个模式。连接好认证。搞清楚密钥。部署它。
现在就有了一个新的代码库,描述着一个你已经拥有的API。它会漂移。直到某个代理发送了一个在两个迭代周期前就已更名的字段时,才有人发现。
这正是我们在ApyHub的故事。
我们现在的做法是:拿出已经编写和测试好的退款请求。将其标记为一个工具。选择哪些值可以由代理设置,在这个例子中只是订单ID。密钥保留在你的环境里。这就是整个服务器。
除非你将其标记,否则什么都不会暴露。一旦涉及其他人的代理,选择加入似乎是唯一诚实的默认方式。
有一条规则更具倾向性:一个工具只有在其测试通过时才可用。测试变红,工具就下线。
这很严格。如果测试不稳定,它会让你烦恼。我们还是选择了这样做,因为让代理失去访问权限,感觉比让代理调用一个近期无人验证的东西要好。
这是正确的权衡吗?我真的在反复权衡。很好奇其他人的看法。
3. 测试一个MCP服务器,无论是你自己的还是供应商的
这有两个版本。你运行自己的MCP服务器,想知道它在发布前是否还能正常工作。或者你即将基于一个供应商的服务器构建,想看看它实际返回什么。
今天:打开检查器标签页。点击,阅读,关闭。结束。或者是一个放在某人主目录里的一次性脚本。
我们想要的是和我们为REST API已经拥有的东西一样。保存调用。添加断言。在CI中运行。
所以现在一个MCP调用只是文件中的另一个代码块。将其指向一个服务器,选择一个工具,用你将在任何地方使用的相同认证和断言来检查响应。在发布前,它确认search_orders仍然返回你期望的结构。对于像Notion这样的供应商服务器,这个文件就成了团队可以重跑的工作参考。
我最在乎的部分
所有这三件事都存在于一个文件中。
你用来测试的请求,就是你的代理运行的那个。也是你作为工具发布的那个。而且它就直接放在你的MCP测试旁边。
对API只有一份描述,而不是三份逐渐产生分歧的描述。
因为它是仓库中的一个纯文件,变更会通过拉取请求进行。如果有人扩展了退款工具可接受的范围,审查者会在差异中看到。
这对我来说才是真正的重点。让一个代理访问API是一个权限决策。权限决策值得有一个审查轨迹。
为什么我们持续构建这个
Voiden不是我们的核心业务。ApyHub为它提供资金。我们构建它是因为我们每天都在使用它,当某件事足够困扰我们时,它最终会出现在下一个版本中。
这件事困扰了我们数月。
它在2.3版本中发布了,还包括一些其他内容。如果你感兴趣,完整的列表请查看更新日志。
一个开放的问题,因为我认为还没有人完全弄明白:
今天,你如何决定你的API中哪些部分允许代理接触?配置文件?网关?手写的MCP服务器?还是凭直觉?
我很想听听什么方法有效,什么方法无效。
原文:https://dev.to/nikolas_dimitroulakis_d23/we-described-our-api-twice-once-for-humans-once-for-agents-4e4g(作者 @nikolas_dimitroulakis_d23)



