MCP Tasks (async): Why Aren't Any Agents Supporting Them? — Cornelia Davis, Temporal
频道: AI Engineer
视频: https://www.youtube.com/watch?v=s4r6nk5WsZw
原文语言: en
统计: 共 18 轮 · Cornelia Davis 16
[0:01]
[music]
[music]
[0:12] Cornelia Davis
I know it's 1 minute ahead, but these 20-minute sessions are really short, so I'm going to get started. So, title of my talk you all have seen cuz you're all here, which is why the heck aren't any agents supporting MCP tasks. If you don't know what tasks are, don't worry, you will know in just a moment. But, the first answer to that question is, well, cuz they're smart. The people who are building those clients are smart. What I mean by that is that the MCP tasks specification that came out in November was marked as experimental. And so, well, you might shrug and say, well, gosh, those clients and servers, they're all supporting a whole bunch of experimental things. Why not MCP tasks? Well, again, you'll see the answer to that as we move forward. Um the next answer to that question is, well, they're pretty involved. Um there's a lot of complexity in here, and that's what I want to do over the next 20 minutes is teach you some of that complexity. Quick intro, my name is Cornelia Davis. I'm a technologist at uh Temporal. Uh we're distributed systems stuff. I have a long history in distributed systems, did a whole bunch of stuff in the microservices era, um including Cloud Foundry, Kubernetes, GitOps, Weave Works, all of that stuff, and I even wrote a book about that. That's who I am.
我知道现在还提前了一分钟,但这种 20 分钟的场次实在太短,所以我直接开始。我这场的标题大家都看到了——不然你们也不会坐在这儿——就是:到底为什么没有哪个 agent 支持 MCP tasks?如果你还不知道 task 是什么,别急,待会儿你就明白了。这个问题的第一个答案是:因为他们聪明。做那些 client 的人很聪明。我这话的意思是,11 月份发布的那份 MCP tasks 规范,当时被标成了 experimental。你可能会耸耸肩说,得了吧,那些 client 和 server 支持的 experimental 东西多了去了,凭什么 MCP tasks 就不行?好,这个问题的答案我们往下讲你就看到了。第二个答案是:这东西挺麻烦的。里面有相当多的复杂度,而接下来这 20 分钟我要做的,就是把其中一部分复杂度讲给你听。简单自我介绍一下,我叫 Cornelia Davis,在 Temporal 做技术,我们做的是分布式系统。我在分布式系统这块儿干了很久,微服务那个年代做过一大堆东西,包括 Cloud Foundry、Kubernetes、GitOps、Weaveworks,这些全都做过,我还就此写了一本书。这就是我。
[1:32] Cornelia Davis
Today's agenda in the next 19 minutes is that rather than just talking about things in the abstract, I'm going to ground us in a very concrete example. So, I'm going to give you the lay of the land of that concrete example. Then, I'm going to give you an overview of MCP tasks. Quick question, who here is wants to do things with tasks? Async MCP tools. Okay. So, I'm going to give you a little bit of an overview. Um then we're going to talk about it MCP tasks V1. That's the spec that came out in November and spoiler alert, there's a new one coming out in July. So, that comment that I made about them being smart about not implementing it yet. Well, there's some pretty radical changes. So, I'm going to show you um what's happening with V2 and I actually have some live demos to show all this working and then we'll have some takeaways at the end. So, the use case that we're going to talk about here is a simple purchase order use case. So, the use case is you're going to get in a purchase order and then it's going to go through a number of steps. It's going to record the fact that the goods were received and then it's going to do in parallel, it's going to do some back office stuff updating inventory, sending out notifications and then in parallel to that it's going to pay some invoices.
接下来这 19 分钟的议程是这样:与其空谈抽象概念,我想用一个非常具体的例子把话题落地。所以我先把这个例子的全貌给大家铺开,然后讲一遍 MCP tasks 的概览。快速问一下,在座有多少人想用 task 做点什么?也就是异步的 MCP tool。好。那我先做个概览。然后我们讲 MCP tasks V1,也就是 11 月出的那版规范;剧透一下,7 月还会出新的一版。所以我刚才说他们“聪明、先不急着实现”,就是因为里面有一些相当激进的改动。我会给大家看 V2 那边正在发生什么,而且我准备了几个 live demo 把这些都跑给你们看,最后再讲几点收获。我们要讲的场景是一个很简单的采购订单(purchase order)场景:进来一张采购订单,然后走一串步骤。先记录收货这件事,然后并行地做一些后台的事——更新库存、发通知;同时并行地去支付发票。
[2:51] Cornelia Davis
Now, the invoicing is going to happen via an MCP tool. Now, that MCP tool is has itself a number of steps. So, it's going to validate against an ERP, then it's going to have a little human in the loop to request approval, maybe. Um then it's going to reconcile against the ERP again, do a little bit more human in the loop and so on. So, you can see that on the right hand side that MCP server that's going to be it's a tool that's going to be doing the invoice processing for us. It is long running. It's not going to work in a request response style and that's what MCP tasks are all about. And what we're going to do and I'm today's talk is not about temporal, but really what I did here was just showed you a couple of snippets of the code and yes, I will be sharing all the code for what I'm showing today. Couple of snippets here and the real point that I want you to look at is that reject or approve. That is showing you that there is a mechanism for signaling into a long-running process. And that's really the point. And that's what we need is that this is all about asynchronous. So, you understand what MCP tasks are now? MCP tasks are allowing you to have an MCP tool that you can invoke and then it is long-running in the background, and then eventually you can get back some response.
开票这一段是通过一个 MCP tool 来完成的。而这个 MCP tool 本身又包含好几步:先去 ERP 里做校验,然后可能要走一次 human in the loop 请求审批,接着再跟 ERP 对一次账,再来一点 human in the loop,以此类推。所以你在右边能看到,那个 MCP server 就是替我们处理发票的那个 tool。它是长跑的,它不可能按 request/response 那种方式工作——而这正是 MCP tasks 要解决的问题。今天这场不是讲 Temporal 的,我在这儿只是给你们看几段代码片段——是的,我今天展示的所有代码后面都会分享出来。这里有几段代码,我真正想让你们看的重点是 reject 和 approve 这两个动作。它说明我们有一套机制,可以往一个长跑的流程里发信号。这才是关键。这就是我们需要的东西——一切都是围绕异步展开的。那么现在你明白 MCP tasks 是什么了吗?MCP tasks 让你可以调用一个 MCP tool,它在后台长时间运行,最后你再把结果拿回来。
[4:17] Cornelia Davis
So, let's talk about that MCP tasks overview. This is a very simple sequence diagram. It's exactly what you all would expect when I tell you that MCP tasks are long-running tasks. You're going to invoke a tool, and instead of getting back a response, you're going to get a handle. And you can interact with that handle, right? Obvious, right? This is This isn't rocket science. Looks easy enough, right? Well, it turns out that if you actually want this to work over long horizons, it gets a little bit more complicated than that. So, what are some of those complications? Well, you can have all sorts of the longer something runs, the more likely there's going to be some kind of infrastructure blip that's going to cause a problem in that long-running task. So, you could have network blips, you could have network challenges, you could have humans that you're waiting for their in-a-loop part, and they go away on vacation like I'm about to, yay, um day after tomorrow. Um or processes can crash. So, your agent can go down. The agent that's processing the purchase order can go down, or your MCP server can go down as well. So, all of those problems you need to deal with, and those are the things that makes it a little bit more difficult.
那我们来看 MCP tasks 的概览。这是一张非常简单的时序图,当我告诉你 MCP tasks 就是长跑任务时,它跟你脑子里想的一模一样:你调用一个 tool,拿回来的不是结果,而是一个 handle,然后你可以跟这个 handle 交互。显而易见吧?这又不是什么高深的火箭科学,看着挺简单。可事实是,你真要让它在很长的时间跨度上跑得住,事情就比这复杂多了。都有哪些麻烦?一件事跑得越久,中间出现某种基础设施抖动、把这个长跑任务搞出问题的概率就越大。可能是网络抖动,可能是网络本身的各种状况;也可能你正等着某个人完成 in-the-loop 那一步,结果人家休假去了——就像我后天也要去休假一样,耶。再或者进程直接崩了:你的 agent 可能挂掉,那个处理采购订单的 agent 挂掉;你的 MCP server 也可能挂掉。所有这些问题你都得处理,正是它们让这件事变得有点难。
[5:39] Cornelia Davis
Now, in addition to what I've told you about MCP tasks so far that you're going to get back a handle that you can interact with by the specification those MCP tasks can't disappear. This is verbage from the spec itself that says once you've locked launched a task it has to be durable. What that means is all of these things that I just showed you on the previous screen clients humans going away on vacation servers going down clients going down connections disconnecting the task needs to survive that and you need to be able to interact with that task when the infrastructure comes back. And I'm going to show you how all of that is done. Now on there's elements there's server side elements that talk about how you make the server side durable and I did a talk at the MCP Dev Summit in March and this is the QR code that it will take you to that YouTube video and that's where I go into a lot of detail about the server side and what you need to do with the server side. Today as you saw is an extension of that work where I'm talking about the client side. So without further ado let me go into a demo. I for those of you who know me I'm always doing demos. So what we have here is we have a dashboard. Um I am not doing this through a chat interface because it frankly it's more efficient for me to click a couple of buttons here to show you this rather than trying to type things in. So I have a user interface here that's showing you the number of purchase orders that have been submitted. I'm going to submit a simple purchase order so that's just a button that is kicking things off and in a moment if the dam demo gods are with me it says submitted we should see the purchase order pop up here and it should show some Ah here's why it's not working because I haven't started my servers. So remember I said it has to work even when the servers aren't running. I forgot to show you here that what I'm doing in this
另外,除了我刚才说的“你会拿回一个可以交互的 handle”之外,按照规范的要求,这些 MCP task 是不能凭空消失的。这是规范原文里的措辞:一旦你启动了一个 task,它就必须是 durable 的。意思是我上一页给你们看的那些情况——client 挂了、人休假去了、server 宕了、client 宕了、连接断了——task 都得活下来;等基础设施恢复之后,你还得能继续跟这个 task 交互。我待会儿会演示这一切是怎么做到的。这里面有 server 端的部分,讲的是怎么把 server 端做成 durable 的。我 3 月份在 MCP Dev Summit 上讲过一场,这个二维码会带你到那个 YouTube 视频,里面我把 server 端要做哪些事讲得非常细。而今天这场,你们也看到了,是那次工作的延伸,我讲的是 client 端。那么闲话少说,我直接进 demo——认识我的人都知道,我这人永远在做 demo。这里我们有一个 dashboard。我没有用聊天界面,说白了在这儿点两下按钮给你们看,比我现场敲字要高效得多。所以我这儿有个界面,显示已经提交的采购订单数量。我提交一张简单的采购订单——就是按一下按钮把流程启动起来——稍等一下,如果 demo 之神保佑我的话,它会显示已提交,我们应该能看到这张采购订单冒出来,而且应该显示……啊,我知道为什么没反应了,因为我压根没启动我的 server。你看,我刚才不是说了嘛,即使 server 没在跑,这套东西也得能工作。我忘了先给你们看,我在这
[7:47] Cornelia Davis
these two windows is in the upper window, I'm starting the back end. This is the MCP server. And in the um lower window, I am starting the MCP client. And you'll see what that client is in a moment. You can see in the splash screen there that I am using fast MCP on the client side. So, let's go back here and notice that even though I submitted that, even though my servers weren't running, that submission did go through. So, it's captured that. So, what you can see here, and you didn't see it cycle through, but on the far right-hand side, the invoice task is it initially showed you that it was work submitted, then it showed you that it was working, and now it's asking for input required. I can come over here. Let me show you what's going on at the back end and at the front end. What I have here are some dashboards that are showing those running processes. On the right-hand side, you have the back end. That's where the invoice processing is, and you can see the name here. Let me increase the font size there a little bit. So, you can see that this is running the invoice, and on the left-hand side, you can see that it's running the PO. I'll explain that task tracker thing in just a moment.
两个窗口里做的是:上面那个窗口我启动的是后端,也就是 MCP server;下面那个窗口我启动的是 MCP client,这个 client 是什么待会儿你们就知道了。从启动画面上能看到,我 client 端用的是 FastMCP。那我们切回这边,注意:虽然我提交的时候 server 还没起来,那次提交依然生效了,系统把它记下来了。所以你现在看到的是——中间那些状态切换你们没看到——最右边那个 invoice task,一开始显示 submitted,然后变成 working,现在它显示 input required,在等输入。我切过来给你们看看后端和前端各自在干什么。我这儿有几个 dashboard,显示的是那些正在跑的流程。右边是后端,也就是发票处理的地方,你能看到它的名字。我把字号调大一点。你能看到这边跑的是 invoice,左边跑的是 PO。那个 task tracker 是什么,我马上解释。
[9:03] Cornelia Davis
So, if we go into the invoice, we can see that it has the process that we talked about earlier. It validated against the ERP, and now it's waiting for human input. It's waiting for that approval. Over on the PO side, we can also see the process that I showed you earlier, which is to say, let's go back here. It is So, ah, yes. So, it did that record recorded that the goods were received. Then, in parallel, it's invoking the invoice processor MCP task. And notice that there's this line item here that says task tracker workflow. Yes, indeed. That is my MCP client implementation. Remember I said nobody's implemented this on the client side? Well, I created my own implementation here. But in parallel with doing the invoice processing, we also had this back office stuff that was happening. So if I come back over here and I click on input required, I can approve this. And I'll hit submit. And we come over here and you'll see in just a moment that the signal is going to come into the back end. Uh need to refresh. Oh, there it goes. So the approval came into the back end and now the back end is going ahead with its additional process paying the invoice. And you'll see a number of line items there. There's some um some uh re- uh retries that are have been programmed in here, but you can see here that it took a few tries before the the ERP went through. We paid the line item and now you can see that the task completed. So everything's completed. If I go back to the dashboard that you saw at the top, you can see that all of those processes completed. Okay? So that's the basic stuff. And I can run that again, but in the in I already gave you inadvertently gave you the example of the infrastructure was down. I could have killed that server halfway through and it would have continued exactly exactly as you saw here. Okay? So you saw it at the very beginning.
我们点进 invoice,可以看到它就是我们前面讲的那个流程:它跟 ERP 做了校验,现在正在等人工输入,等那个审批。PO 这边呢,我们同样能看到我前面展示过的流程,也就是……我们切回这边。它——啊,对,它已经记录了收货这件事。然后并行地去调用发票处理的那个 MCP task。注意这里有一条叫 task tracker workflow 的条目。没错,那就是我自己实现的 MCP client。记得我说过没人在 client 端实现这个吗?所以我就自己写了一个。而在做发票处理的同时,那些后台的活儿也在并行跑着。那我切回这边,点开 input required,我可以批准,然后点提交。再切过来,你马上就能看到这个信号进到后端。呃,得刷新一下。哦,来了。审批信号进到后端了,后端现在继续往下走它剩下的流程——付款。你会看到好几条记录,这里我特意编排了几次 retry,你可以看到 ERP 那边试了好几次才通。发票行项目付掉了,现在你能看到 task 完成了。所以全都完成了。回到最上面那个 dashboard,你能看到所有这些流程都跑完了。对吧?这就是最基础的部分。我可以再跑一遍,不过刚才我已经无意中给你们演示了“基础设施挂掉”的例子。我完全可以中途把 server 杀掉,它照样会跟你们刚才看到的一模一样地继续跑完。对吧?开头你们就已经看到了。
[11:09] Cornelia Davis
All right, let's go back to slides. So that's the first demo. So let's talk about um tasks version one. So in tasks version one, there were a number of tool semantics. And again, I go over these tool semantics in a lot more detail in that MCP Dev Summit talk. But there's one really interesting thing that I want to draw your attention to, which is that tasks come with it One of the things that the specification defines is a life cycle for tasks. And that's what you see here on the screen. It has working. It can go into an input required. From input required, it can go back to working, and then eventually it'll complete or be canceled or fail. So, that's one of the things that's super interesting about the task specification is that it's about the life cycle of the task. There's a whole bunch of other semantics there as well around obtaining inputs and delivering results. And I'm going to go through this fairly quickly because I already mentioned some of this is going away. So, this is what the tool semantics were before the task semantics. Notice that tools/call is exactly the same. There's some metadata that you pass in when you want it to be async. And then there's task get cancel list, as well as task result.
好,我们回到幻灯片。这是第一个 demo。接下来讲 tasks 的 version one。在 V1 里有一批 tool 语义,同样,这些语义我在 MCP Dev Summit 那场里讲得细得多。但这里有一件特别有意思的事,我想让你们注意:task 是自带生命周期的。规范定义的东西之一就是 task 的 life cycle,也就是屏幕上这张图。它有 working 状态,可以进入 input required;从 input required 又可以回到 working,最后要么 complete,要么被 cancel,要么 fail。所以 task 规范里特别有意思的一点,就是它讲的是 task 的生命周期。除此之外还有一大堆别的语义,围绕怎么获取输入、怎么交付结果。这部分我讲快一点,因为我前面提过,其中一些东西马上就要没了。这就是有 task 语义之前的 tool 语义。注意 tools/call 是完全一样的,只是当你想让它走异步时,多传一些 metadata 进去。然后还有 tasks/get、tasks/cancel、tasks/list,以及 tasks/result。
[12:35] Cornelia Davis
And so, the top four are request-response in style. The bottom one keeps a connection open. It keeps a connection alive. And the sequence diagram that you can see here is kind of the basic stuff. Now, there's two hiccups with this um uh two major challenges with this particular version of the protocol. The first one is right here. Task list. This is a stateful protocol. So, what that means is that the Remember I said that the server was responsible for durability? Well, this particular endpoint allows me to go to the server and say, "Hey, what tasks do you have?" So, if I have had if the client has gone away, if the user took too long to respond, if my network dropped out and I had to reconnect, I can use this task list to go back to the server and say, "What have you got?" And then you can continue on with that. That works fine if you have one task or two tasks, or maybe it it even works if you have 10 tasks, but what happens if you've got a whole slew of agents out there and you've got a million tasks at the back end. Spoiler alert, there is no filter on that endpoint. So, you would have to go through a million tasks to find the one that you're looking for that you want to interact with. This is going away.
前四个是 request-response 风格的,最后那个则会保持一条连接开着,让连接一直活着。你们看到的这张时序图是最基本的情况。不过这版协议有两个坎儿——两个比较大的挑战。第一个就在这儿:tasks/list。这是个有状态的协议。什么意思呢?记得我说过 server 要负责 durability 吧?这个 endpoint 允许我去问 server:嘿,你手上都有哪些 task?所以如果 client 掉线了、用户拖太久没回、或者我网络断了不得不重连,我就可以用 tasks/list 回过头问 server:你都有啥?然后接着往下走。如果你只有一个 task、两个 task,这套办法没问题;哪怕有 10 个 task 可能也还行。但如果外面跑着一大堆 agent,后端攒了一百万个 task 呢?剧透一下:这个 endpoint 上没有任何过滤条件。所以你得把一百万个 task 全翻一遍,才能找到你想交互的那一个。这个设计要被砍掉了。
[14:03] Cornelia Davis
You'll see in just a moment, but that's one of the challenges. Just because you can doesn't mean you should. The other one is the task result because that is where we were tunneling the input required. So, in the case of task result, this sequence diagram is really simple. It doesn't have the the interactivity. What we have as soon as you do task as soon as you have input required is the top and bottom are just fine, but this middle section has this weird protocol where you open a long-running connection and then the server elicits a response from the client. That gets super tricky. And I'm running short on time, so I'm not actually going to show you this demo. Happy to show it to you. I'll be around all day tomorrow, too. So, I can happy to show it to you, but I want to show you instead Here's basically the architecture of what you need to build on the server side. This is Notice that this is using fast MCP. So, fast MCP already has support for server side and some client side stuff as well. But, the interesting thing is notice that little box in the on the left-hand side that on the on the lower part where it says MCP client protocol handler? That protocol handler with the ugliness that I just showed you or results actually looks like this.
待会儿你们就会看到,这是其中一个挑战。能做,不代表就该这么做。另一个问题是 tasks/result,因为 input required 就是从这儿隧穿过去的。单看 tasks/result 的话,这张时序图很简单,它没有那种交互性。真实情况是,一旦你进入 input required 状态——上半段和下半段都没问题——但中间这一段用了一种很别扭的协议:你要开一条长连接,然后由 server 反过来向 client 发起 elicitation 索取响应。这就变得极其麻烦了。我时间不太够了,所以这个 demo 我就不现场跑了。很乐意单独演示给你看,我明天也会在场一整天,随时可以给你演示。我想给你们看的是另一个东西——这基本上就是你在 server 端需要搭出来的架构。注意这里用的是 FastMCP。FastMCP 已经支持 server 端,也有一部分 client 端的能力。但有意思的地方在于,注意左边偏下方那个小方块,写着 MCP client protocol handler。那个 protocol handler,配上我刚才给你们看的那一坨难看的东西——就是 result 那套——实际长成了这个样子。
[15:25] Cornelia Davis
And I can show this to you running and it has all sorts of complexity in it. I got to have the long-running connection. Well, what happens if my connection dies in the middle of that? How do I pick up where I left off when I come back? You'll see that a big part of what the task specification does is it talks about durability. So, back to the question of why the heck aren't there any clients that are supporting this protocol? Yeah. That's why. Super involved. It's still involved with V2, but it gets better. So, let me tell you about that. So, in May, Angie Jones, who's responsible for developer experience at the Agoric AI Foundation, which is where MCP now lives, posted this blog. And one of the things that made me jump up and celebrate a little bit is that the protocol is going stateless. So, as somebody who's been working in the microservices world for a long time, stateful protocols are the absolute worst thing in large-scale distributed systems. So, the protocol is going stateless. It's also doing a number of other things. So, the first bullet is a stateless core. The second bullet is interesting cuz it's they also have structured MCP so that there's a core and there's extensions. If some of you were in the room for the previous two talks, they talked about MCPUI two talks ago, they mentioned extension.
这套东西我可以现场跑给大家看,但它里面的复杂度是方方面面的。我必须维持一条长连接。那问题来了——万一连接中途断了怎么办?我回来之后怎么从断掉的地方接着往下走?你会发现,task 规范里有很大一块篇幅讲的就是 durable(持久性)这件事。所以回到最开始那个问题:为什么到现在都没有哪个 client 支持这套协议?喏,这就是原因。太麻烦了。到了 V2 还是有点麻烦,但确实好多了。我来讲讲 V2。今年 5 月,Angie Jones 发了一篇博客——她在 Agentic AI Foundation 负责开发者体验,MCP 现在就归在这个基金会底下。这篇博客里有一条让我当场想跳起来庆祝:协议要走向 stateless(无状态)了。我在微服务这块摸爬滚打了很多年,在大规模分布式系统里,有状态的协议绝对是最要命的东西。所以协议要无状态化了。同时它还做了其他几件事。第一条是 stateless core(无状态内核)。第二条也挺有意思:他们把 MCP 做了结构化拆分,分成一个 core 加上若干 extension(扩展)。如果你听了前面那两场——两场之前那位讲 MCP UI 的,就提到过 extension。
[16:54] Cornelia Davis
Well, that's what's happening here in the V2 MCP protocol is that they have extensions and tasks have become an extension. So, let me tell you a little bit about how tasks changed from V1 to V2 and I do want to give you one more demo. So, on the left-hand side, you can see what the protocol was before. These are the RPC requests that you were doing over the wire. On the right-hand side, you can see a couple of things. Task list has gone away. Good. Wasn't particularly useful anyway, especially at large scale. And instead of having this input required going over a long-running session, you now have an endpoint that allows you from the client side to say, "Here's an update." So, if you remember a while ago, I showed you that screenshot that said Temporal has this notion of a signal. That's effectively what this is. It's a way of signaling into this long-running task. The task result stays, but it changes because it no longer has this long session-based protocol. But, I put the picture on the right-hand side here to emphasize the fact that the life cycle management of these tasks is unchanged. That's actually sound. Now, I go into this a lot into more detail in the talk that I keep referring to. Um on the server side, in invoice processing, I have my own state machine that the invoice is going through. And so, part of what you're doing when you implement these server-side these tasks is you're mapping from the life cycle states of the task over to the domain state machine that's running the the application that the the MCP server in the back end or the tool.
对,V2 的 MCP 协议里就是这么干的:有了 extension 机制,而 task 本身就变成了一个 extension。所以我讲讲 task 从 V1 到 V2 具体变了什么,另外我还想再给大家演示一个 demo。左边这一列是原来的协议长什么样,就是你在网络上实际发的那些 RPC 请求。右边你能看出几个变化。第一,task list 没了。挺好——它本来也没多大用,尤其在大规模场景下。第二,原来那种在一条长会话上传 input required 的做法,现在换成了一个 endpoint,让你从 client 这边直接说一句:「这是我给你的更新。」还记得我前面给你们看的那张截图吗,Temporal 里有个概念叫 signal,这东西本质上就是那个——它是一种往长期运行的 task 里发信号的方式。task result 还在,但形态变了,因为它不再依赖那套基于长会话的协议。我之所以把右边这张图放上来,是想强调一点:这些 task 的生命周期管理是没变的。这个设计本身是靠谱的。这块我在我一直提的那场演讲里讲得更细。在 server 端,比如发票处理这个场景,我自己维护了一台状态机,发票会在里面流转。所以你在 server 端实现这些 task 的时候,很大一部分工作就是把 task 的生命周期状态,映射到后端 MCP server(或者说那个 tool)里真正在跑的业务状态机上。
[18:48] Cornelia Davis
So, list again goes away. Now, remember I said that the MCP tasks specification has durability all over it? With this change, given that lists are gone, you now are required on the client side, well, kind of required. There's a little an a little uh parenthetical remark here. The The spec right now says that clients should persist task IDs, but it also points out that if you don't persist task IDs, there is no way to get it back. So, I'm not quite sure why this doesn't have a an all caps must. The other thing that I want to point out is that I already mentioned it is that you're going to have potentially a lot of agents that are processing POs or a lot of agents that are doing a lot of things. And so, having multiple things running, I think is really um crucial as well. So, with that um I'm going to go to the the second demo. And I'm going to go back to my purchase order here. So, what I'm going to do now is I'm going to submit a number of things. And I'm actually still demoing here because I have 13 seconds left. I'm not going to switch over to my V2. You'll see that from the high level, it actually looks exactly the same. I am going to show you what the client proto- client server protocol looks like in the V1 case. It's really quite ugly. But, you'll notice here that we have um I've submitted a bunch of different ones. I can tell you with the V1 protocol, the reference implementation, if you had input required on multiple even though you can see that there's many of them in flight, on the client side they were FIFO.
所以 list 又一次没了。还记得我说过 MCP tasks 规范里到处都是 durable 吗?有了这个改动,list 既然没了,你在 client 端就必须——嗯,算是必须吧,这里得加个小小的旁注。规范目前的措辞是 client「应该(should)」持久化 task ID,但它同时又指出:如果你不持久化 task ID,你就再也拿不回来了。所以我不太理解为什么这里不是一个全大写的 MUST。另一件我想强调的、前面也提过的事:你很可能会有很多个 agent 在同时处理采购单,或者很多个 agent 在同时干各种事。所以能同时跑多个任务,我觉得也是非常关键的。好,那我们进入第二个 demo。我切回到我这个采购单页面。我现在要一口气提交一批单子。我这边还在接着演示,因为时间还剩一点点,我现在切到 V2 这边。你会看到,从上层视角看,它跟刚才长得一模一样。我先给大家看看 V1 情况下 client 和 server 之间的协议长什么样——那是真的挺难看。你注意看这里,我已经提交了一批不同的单子。我可以告诉你,在 V1 协议的参考实现里,如果你有多个任务同时处于 input required 状态,虽然你能看到有很多个在同时跑,但在 client 这边它们是 FIFO(先进先出)的。
[20:40] Cornelia Davis
So, you could only respond to the first one. And part of the protocol that I implemented was to get around that gap. So, let's come over here. We can refresh both of these and you can see that there's going to be a bunch of POs in flight. And now I want to show you the task tracker. So, if we go into the task tracker, that's the MCP client. And now let me just expand this so we can see it in a little bit more detail. What you can see here is that remember that that protocol, I showed you that big long sequence diagram? There's a lot of steps involved in that. And what I've done here is I've implemented it as a workflow. And you can see here that there's some elicitation handling that's going from the server side back to the client. So, I won't go into any more details cuz I'm literally out of time now, but I want to share two more things. And that is Um so, going from V1, remember this ugly picture, to V2 in the client server protocol, much much cleaner. Much easier to implement. So, speaking of implementing, here's a summary of all the things that you need to do if you want to implement tasks. Still relatively involved. Here's a picture. I'm going to make these slides available in the Git repo that I'm about to show you.
也就是说,你只能先回复排在第一个的那个。我做的那版实现里,有一部分工作就是为了绕开这个缺陷。我们切过来看。这两边都刷新一下,你能看到有一批采购单正在跑。现在我想给你们看看 task tracker。进到 task tracker 里,这就是那个 MCP client。我把它展开一下,方便看得清楚一点。你看这里——还记得那张巨长的时序图吗?那里面涉及一大堆步骤。而我这里是把它整个实现成了一个 workflow。你能看到这里有 elicitation 的处理逻辑,是从 server 端往回传给 client 的。我不再往下细讲了,因为我时间是真的到了,但我还想再说两件事。第一,从 V1——记得那张丑图吧——到 V2,client 和 server 之间的协议干净太多了,实现起来也容易得多。说到实现,这一页是个汇总:如果你想自己实现 tasks,需要做的所有事情都在这儿了。还是相对麻烦。这里有张图,这些幻灯片我会放到马上要给你们看的那个 Git repo 里。
[22:01] Cornelia Davis
And here's the Git repo that I'm going about to show you. And while you're getting that screenshot, I'm going to tell you about two pieces of work that I'm continuing with. Number one, even though this is better, it still doesn't scale to the millions. Why? Because if I've got a million tasks running, I've got a million clients that are doing gets against each and every one of those tasks. That does not scale. There is a part of the MCPC task specification that is a notifications protocol, which I haven't gotten far enough yet, but it's showing promise, which is going to allow you to, instead of having a million clients uh uh to uh pulling their tasks, it's going to have a single endpoint where they can say, "Has something changed?" And if it has, tell me which one, and now I'll go pull that task. So, it's definitely from a scale perspective. The other thing that we're doing is in the very near future in the next month or so or two, we're going to have a an implementation of all of this where it's going to be much simpler for you. My goal is to actually implement it in in fast MCP so [snorts] that you can use the same protocol the same framework that you're using probably for your MCP servers today.
这就是我说的那个 Git repo。趁大家拍照的工夫,我讲讲我正在继续做的两件事。第一件:虽然现在这样已经好多了,但它还是撑不到百万级。为什么?因为如果我有一百万个 task 在跑,就意味着有一百万个 client 在对着这一百万个 task 一个个做 get。这是扛不住的。MCP tasks 规范里其实有一部分是 notifications 协议,我还没研究得特别深,但看着很有希望——它的思路是,与其让一百万个 client 各自去 polling 自己的 task,不如给一个统一的 endpoint,client 只要问一句「有东西变了吗?」如果有,告诉我是哪几个,然后我再去拉那几个 task。所以从可扩展性的角度看,这个方向是对的。我们在做的另一件事是:在很近的将来,大概一两个月内,我们会拿出一版实现,让你用起来简单得多。我的目标是把它做进 FastMCP,这样你就可以沿用你今天做 MCP server 大概率已经在用的那套框架和协议了。
[23:24] Cornelia Davis
So without further ado, that is it. Thank you to the next speaker for letting me go a few minutes long and I'll be around. I'll step out if you have any questions find me in the hallway.
好,废话不多说,就到这儿。谢谢下一位讲者让我超时了几分钟。我人就在附近,我先撤出去,大家有问题的话到走廊上找我。
[23:34]
[applause]
[applause]