[音乐]

欢迎大家,感谢参加我的演讲。在接下来的二十分钟里,我想向大家介绍如何使用 Spin 构建超智能代理(Agents)和 MCPs,并在全球范围内分布式运行它们。我叫 Thorsten Hans,在 Ecomi 担任高级开发者倡导者。我想大家都已经构建过 MCPs 或代理,它们与其他类型的应用程序并无不同。

显然,这些应用要求极快的响应时间,以提供最佳的用户体验。然而,传统的区域绑定架构或基础设施在面向全球受众时显得力不从心,并带来了一些摩擦,从而催生了边缘原生架构。显然,延迟是最大的担忧之一,这取决于你在哪里部署 MCPs 或代理。对于全球受众的一部分人来说可能很快,但其他人可能会经历更低的延迟(即更高的时延),从而导致糟糕的用户体验。

这取决于你的分发单元,对吧?即使你选择容器或虚拟机作为部署方式,你也可能会遇到冷启动延迟。当你需要迅速扩展以应对意外的用户需求时,这种延迟可能从几秒到几分钟不等。然而,我们可以通过过度配置基础设施来克服这个问题。但是,保留许多容器或服务器而实际上未利用它们会导致更高的云支出,从环境足迹来看也是不可持续的。

因此,有一些更高级的解决方案可用于运行 MCPs 或代理,但它们通常带有专有 SDK、可分发单元,或者有其特定的方式来处理它们以使其在生产环境中工作。一旦你了解了这些限制,将你的工作负载或代理迁移到另一个超大规模云平台或其他类型的基础设施往往非常复杂且成本极高。

但有一个解决方案,那就是采用一种新的方式来构建后端或服务器端应用程序,即通过在服务端采用 WebAssembly。你可以将 WebAssembly 视为容器与虚拟机的关系:它们是二进制文件,体积超小,易于分发,运行速度极快且可移植。我所指的“边缘原生 AI 技术栈”是 CNCF 项目 Spin 与 Ecomi Functions(一种运行这些 WebAssembly 应用程序的运行时)的组合。

让我们深入了解一下 Spin。正如我所说的,Spin 是一个 CNCF 项目,它是厂商中立的,允许你构建旨在服务器或云端执行的 WebAssembly 应用程序。Spin 本身由三大支柱组成:首先是一个 CLI(命令行界面),我们开发人员用它来处理日常事务,即内环开发中的所有事项。

其次是运行时(Runtime)。它基于 Wasmtime,允许我们在本地、微控制器或受限环境中运行这类应用程序。最后但同样重要的是,Spin 提供了特定语言的 SDK,以提高开发人员在日常工作中的生产力,例如与 HTTP 服务交互、集成数据库等。尽管我们有特定语言的 SDK,但 Spin 本身是语言无关的,你可以选择所有能编译为 WebAssembly 的语言,包括 Wasm System Interface(简称 WASI)。

你可以在 spinframework.dev 上了解更多关于 Spin 的信息。扫描这个二维码,你将进入 Spin 的文档页面。Spin 是我们用于构建这类应用程序的开发工具。Ecomi Functions(原文为 echocomi/Echami,根据语境修正)是全球分布式且真正零冷启动的第一个无服务器计算平台。

因此,你部署到 Ecomi Functions 的每个应用程序都是按请求冷启动的。平均而言,我们可以在不到半毫秒的时间内完成冷启动。它是完全托管且以开发人员为中心的。你的开发人员部署工作负载,无需调整参数,无需编写 Terraform 代码,只需一行简单的命令,你的应用即可在全球范围内分发且无额外费用。

安全性由 WebAssembly 的沙箱机制保障。因此,除非开发人员明确授予权限,否则工作负载无法与外部资源交互。为了成为边缘的全功能无服务器计算平台,我们需要某种持久化层。因此,Ecomi Functions 内置了一个多租户键值存储库。你无需滚动凭据(原文为 roll credentials,意指手动管理),如果你的意图是使用它,它会与应用自动关联。

这里还有一个二维码。扫描它以了解更多关于 Ecomi Functions 的信息,注册试用或免费账户并探索它。这些是我打算用来构建首个 MCP 服务器的技术基础。与其手工编写新的 MCP 服务器,即通过实现 HTTP 协议或基于 HTTP 的指定 API 来构建 MCP,还有更聪明的方法。

这种更聪明的方法是 WMCP(WebAssembly MCP)。WMCP 同样是一个 CLI,它与 Spin 无缝集成。这使得我们能够专注于业务逻辑。在 MCP 的语境下,业务逻辑基本上意味着我们实现工具、资源或提示词(prompts),然后就可以大功告成。

其余所有非功能性需求,例如使用 OAuth 2.0 和 OIDC 对用户进行身份验证,都由 WMCP 处理。然后我们从现成的组件中选取即用型部分,组合成一个最终的 MCP 服务器组件,并在 Spin 或 Ecomi Functions 上运行它。这就是我们即将要做的事情。

我已经在我的机器上安装了 WMCP,地址是 github.com/wasmcp。它提供了一个不错的 CLI 界面。我们可以执行 womcp new,选择语言(Rust、TypeScript、Python),并从模板中选择。默认模板目前只关注工具。让我们将这个新的 MCP 服务器命名为“hello”。

我们会收到指示:进入 hello 目录,然后在此侧打开一个新终端。也 CD 到这里的 hello 目录中。让我们运行 npm install,因为这需要几秒钟时间。让我们在编辑器中打开它并全屏显示。

那么我们会得到什么?我们得到了一个即用的样板代码,一旦 npm install 完成,那些松鼠线(squirrel lines,指占位符或提示文本)就会消失。我们要做的就是表达我们期望输入的架构(scheme),显然我们必须提供我们的工具列表。

必须在这里做一个好公民,并提供精确的描述,以便人类和大型语言模型知道如何处理这类工具。因此,我们将它们列在一个简单的数组中,然后有一个名为“调用工具”的摄入函数。根据我们接收到的有效载荷,我们必须决定执行哪个工具。如果我们跳转到这里的“处理示例工具”,我们可以看到所有传入的参数都经过验证,如果一切正常,我们基本上将接收到的输入与前缀连接起来并返回给用户。没什么花哨的。

让我们关闭这里的编辑器并按照说明操作。列表上的下一个是 make。make 继续执行,将 JavaScript 代码编译为 WebAssembly。因此,我们最终得到了一个工具 WebAssembly 组件,它还不是一个功能齐全的 MCP 服务器。接下来是 MCP Compose。让我们通过获取我们的工具并说“嘿,请给我一个用于演示的 MCP”来组合一个功能齐全的 MCP。我不关心身份验证。

它拉取所有必要的其他组件并将它们组合成一个 MCP 服务器,并给我如何运行它的说明。我可以执行 spin up -f server.wazm,我们应该看到它在 localhost 3000 上运行。好的,让我们把另一个终端带回来,在这里运行 npx mcp inspector。这应该在浏览器中启动。好了。它已经指向这里的 localhost 3000。所以让我们连接,列出工具。那里有我们的示例工具。我们提供“foo”作为输入参数。

运行该工具,我们应该得到返回的 foo。太棒了。没什么花哨的,很酷且有效。但这是本地体验。那么如何将其转变为全球分布式的 MCP 服务器呢?嗯,与其全局分发那个“你好世界”的 MCP 服务器,我有一个决策锁定(decision lock)MCP 服务器。让我先打开这个。所以这个是使用 Rust 实现的,为了用 Rust 实现它而这样做。

嗯,让我们进入这里的 lib.rs。在 Rust 中有一个等效的类或结构体。正如你所见,我们正在查看“调用工具”函数,我们从中分支出来,要么使用 CRUD API 之一,要么使用我的 MCP 服务器提供的工具。如果我们深入研究实际实现……嗯,让我纠正一下,我想这个,然后我想要做那个决定。decision.rs 如果我们转到文件的底部,你可以看到这语法略有不同但含义相同:我必须定义我的工具。

如果我们在第 15 行左右,是的,“列出决策”,你可以看到这里我使用了一个存储。在我的本地机器上,Spin 认识到“托恩”想要使用键值存储,所以它自动在本地机器上使用 SQLite 创建一个用于开发目的的键值存储。而在 Akamai Functions(原文误读为 ecom myi 等,结合上下文及标题应为 Akamai)上,它利用全球分布的键值存储,无需我进行任何配置。从这里开始情况其实是一样的:我必须使用那个 make 文件并组合服务器,但我认为更明智的是更新应用程序清单并将这些任务连接起来。

这样我可以保持在 Spin 开发者体验中,基本上执行 spin build 来组合并编译我的 MCP 服务器。然而,我也可以将这个与 spin deploy(原文误读为 spin ecomi)结合使用。所以现在它组合服务器,问我“你希望如何在 Akamai Functions 上调用这个 MCP 服务器?”我称它为 ADR MCP。我允许我的终端与服务注册表交互。现在它获取了我的 Wasm 文件和应用程序清单,从这些文件生成 OCI 层并将它们上传到服务器端或服务端的 Akamai Functions。

我们收到这两个文件,并通过所有服务区域将它们分发到全球。每个区域必须确认它接收到了能够运行该工作负载的工作负载。然后我们实例化一次工作负载并进行内部健康检查。一旦所有服务区域都返回 HTTP 200,我们就代表你滚动一个通用子域名,以便你的 MCP 服务器将在公共互联网上。显然,你可以使用其他产品和服务(如属性管理器)来屏蔽它,在转发用户之前强制执行你想要的任何操作。

所以我们得到了那个 URL。我们在大约 60 秒内实现了全球分布。让我们移动到一个客户端。我在这里使用 Zed,但这适用于任何基本支持 MCP 的客户端。我添加一个服务器。我去这里的远程选项,并用我们收到的 URL 替换这个部分。添加服务器。我们可以看到我已经有五个工具了。我可以去这里说“查看工具”。这些是我的 MCP 定义的 CRUD 工具。

所以我可以回去与我的 IDE 在我的项目上下文中聊天,以便它可以利用我的 MCP 服务器。跟踪一个决定使用 Rust 2.0 Hello...(原文乱码,意为具体指令)。好的,所以它现在应该识别我的意图并请求运行插入决策工具的权限。我们可以看到原始输入。看起来不错。我们允许它。现在它调用 Akamai Functions,已经跟踪了我的决定,我可以说“请给我所有决策”。

现在的意图是使用列出决策工具。再次强调,是的,它可能想要读取详细信息以给我它所跟踪的一切内容。有了这个,我们就有了一个全球分布的 MCP 服务器,无论用户在哪里,它都将所有请求路由到最近的服务区域。再次强调,你可以使用 TypeScript、Python 或 Rust 模板编写这些工具、提示或资源。很酷。让我们继续讨论智能体(Agents)。

嗯,所以... 哎呀,不是这个。对于 AI 智能体来说,故事并无不同。然而,与其使用另一个 CLI,我们可以简单地选择任何流行且可用的 SDK。我认为 Vercel AI SDK 使用起来相当不错。这基本上允许我们使用 TypeScript 创建一个新的 Spin 应用程序。只需引入 Vercel AI 依赖项并构建自定义智能体。

再次,让我们回到终端看看它看起来是什么样子的。嗯,让我们向上移动一级,进入这里的简单游戏智能体目录。这里发生了什么?显然,我使用模板创建了一个新的 Spin 应用程序,以便快速开始。我利用部署在带有专用 GPU 的 Lenode(应为 Node)实例上的大型语言模型。而我的 Spin 应用程序所做的就是定义工具。

所以,这是一个简单的游戏智能体用于演示目的,它可以翻转硬币(原文误读为 flip co),可以掷骰子,你可以指定骰子应该有多少面。在这里的实际 HTTP 处理程序中,我们加载配置并定义我们的智能体,你知道的,指向在节点上运行的 llama 实例。我们给智能体一个身份和关于什么的指令...

其实际意图是,我们注册工具并设定步骤数量的约束。生成响应后将其返回给客户端。好的,让我们在这里退出所有操作,然后执行另一个 spin deploy 命令并确认构建,系统会询问名称,即游戏代理。在上传过程中,让我解释一下编译解释型语言时发生的情况:编译时会加载解释器、自定义 JavaScript 代码并评估全局作用域。这有一个优势,不仅运行时是热启动的,所有依赖项也已加载,随后我们获取内存快照并写入 Wasm 存储区保存到磁盘。这意味着用 JavaScript 编写的 WebAssembly 应用在冷启动和运行时性能方面比原生 JavaScript 应用更快。唯一的权衡是我们必须随用户代码一起分发 JavaScript 运行时,但我们使用了一个名为 SpiderMonkey(注:原文 stalling monkey 为误听)的优化 JavaScript 运行时,大小约为 10MB。

我们得到一个 URL,让我替换这里的链接并模拟抛硬币操作。我们看到响应返回了。查看这些标头,我们可以看到进入 Akamai 网络的边缘节点位于圣克拉拉,而离我们的 AI 代理最近的服务区域是洛杉矶(LAX)。另一个有趣的标头是 X-Envoy-Upstream-Service-Time,它告诉我们从接收请求、执行业务逻辑、联系大语言模型生成响应到返回用户,整个过程耗时 33-34 毫秒。哦,出现了内部服务器错误,太棒了(讽刺)。让我们再试一次。是的,那是用户端错误,抱歉。之前屏幕前停留了 30 多毫秒的错误提示,现在看是 866 毫秒。这更现实了,因为我们需要通过大语言模型来确认抛硬币的结果是反面。

让我们再试一次:反面、反面……哦,有个帽子(注:原文 hat 可能为误听或特定语境),不错。因此,通过将代理部署到 Functions 并完整循环经过大语言模型,我们大约能实现 820 毫秒的响应时间。开发工作流程始终相同:无论构建何种业务应用、MCP(模型上下文协议)还是代理,你都使用可编译为 WebAssembly 的语言来实现应用。目前最主流的是 Rust、TypeScript、Python 和 Go。你可以使用 Spin CLI 在本地测试,通过单个 spin deploy 命令进行部署,最后将客户端指向你的 MCP 或代理。

从我角度来看的关键要点是便携性:你可以将这些 Spin 应用运行在任何符合 Wasm 标准的运行时上。Akamai Functions 是一种全局分布式的运行时环境。这一切都基于开放标准,Spin、CNCF、WASI 和 WebAssembly 均由 Bytecode Alliance 治理。最终你获得了速度,拥有快速的响应时间。开发者构建 MCP 和代理的时间到市场(Time to Market)也缩短了,因为你无需搭建基础设施或实现非功能性需求,这些都已由平台处理。在基础设施方面实现了零运维(NoOps),spin deploy 是你唯一需要的命令。

工具箱中还有其他命令,你可以收集指标、检索日志和进行升级等。但开发者体验是我们启动 Spin 时的最高优先级,且我们继续朝这个方向发展。我们有一个新网站叫 Akamai Developer Hub(注:原文 Ecomi/Akcomi 均为误听,应为 Akamai),在这里分享故事、实验和经验。请访问 developers.akamai.com 查看。如果有更多问题,请在 Akamai 展位找我。非常感谢大家。