<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Sse | The .NET Blog</title><link>https://thedotnetblog.com/zh/tags/sse/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>zh</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Fri, 10 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/zh/tags/sse/index.xml" rel="self" type="application/rss+xml"/><item><title>构建不像黑盒的实时多智能体UI</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/</guid><description>AG-UI和Microsoft Agent Framework联手为多智能体工作流提供真正的前端——实时流式传输、人工审批，以及对智能体行为的完整可视化。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;多智能体系统的问题在于：它们在演示中看起来令人难以置信。三个智能体互相传递工作、解决问题、做出决策。然后你试图把它展示给真实用户，得到的却是……沉默。一个旋转的加载指示器。完全不知道哪个智能体在做什么，或者系统为什么暂停了。这不是产品——这是信任问题。&lt;/p&gt;
&lt;p&gt;Microsoft Agent Framework团队刚刚发布了一篇&lt;a href="https://devblogs.microsoft.com/agent-framework/ag-ui-multi-agent-workflow-demo/"&gt;精彩的教程&lt;/a&gt;，介绍如何将MAF工作流与&lt;a href="https://github.com/ag-ui-protocol/ag-ui"&gt;AG-UI&lt;/a&gt;配合使用。AG-UI是一个开放协议，通过Server-Sent Events将智能体执行事件流式传输到前端。说实话，这正是我们一直缺少的桥梁。&lt;/p&gt;
&lt;h2 id="为什么这对net开发者很重要"&gt;为什么这对.NET开发者很重要&lt;/h2&gt;
&lt;p&gt;如果你在构建AI驱动的应用，可能已经遇到过这堵墙。你的后端编排工作得很好——智能体之间传递任务、工具触发、决策做出。但前端完全不知道幕后发生了什么。AG-UI通过定义一个标准协议来解决这个问题，将智能体事件（想想&lt;code&gt;RUN_STARTED&lt;/code&gt;、&lt;code&gt;STEP_STARTED&lt;/code&gt;、&lt;code&gt;TOOL_CALL_*&lt;/code&gt;、&lt;code&gt;TEXT_MESSAGE_*&lt;/code&gt;）通过SSE直接传输到你的UI层。&lt;/p&gt;
&lt;p&gt;他们构建的演示是一个包含三个智能体的客户支持工作流：一个路由请求的分诊智能体、一个处理退款事务的退款智能体，以及一个管理换货的订单智能体。每个智能体都有自己的工具，交接拓扑是明确定义的——没有&amp;quot;从提示词中猜测&amp;quot;的感觉。&lt;/p&gt;
&lt;h2 id="交接拓扑才是真正的主角"&gt;交接拓扑才是真正的主角&lt;/h2&gt;
&lt;p&gt;让我眼前一亮的是&lt;code&gt;HandoffBuilder&lt;/code&gt;如何让你声明智能体之间的有向路由图：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HandoffBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ag_ui_handoff_workflow_demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;participants&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;termination_condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;termination_condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Refunds, damaged-item claims...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Replacement, exchange...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Replacement logistics needed after refund.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;After replacement/shipping tasks complete.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每个&lt;code&gt;add_handoff&lt;/code&gt;创建一条带有自然语言描述的有向边。框架基于这个拓扑为每个智能体生成交接工具。因此路由决策是基于你的编排结构，而不是LLM随意决定的。这对生产环境的可靠性意义重大。&lt;/p&gt;
&lt;h2 id="真正有效的人机协作"&gt;真正有效的人机协作&lt;/h2&gt;
&lt;p&gt;演示展示了任何真实世界智能体应用都需要的两种中断模式：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;工具审批中断&lt;/strong&gt; ——当智能体调用标记为&lt;code&gt;approval_mode=&amp;quot;always_require&amp;quot;&lt;/code&gt;的工具时，工作流暂停并发出事件。前端渲染一个包含工具名称和参数的审批模态框。没有烧掉token的重试循环——只是一个干净的暂停-审批-恢复流程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信息请求中断&lt;/strong&gt; ——当智能体需要用户提供更多上下文（比如订单ID）时，它会暂停并询问。前端显示问题，用户回答，执行从停止的地方精确恢复。&lt;/p&gt;
&lt;p&gt;两种模式都作为标准AG-UI事件进行流式传输，所以你的前端不需要针对每个智能体的自定义逻辑——只需渲染通过SSE连接传来的任何事件。&lt;/p&gt;
&lt;h2 id="接入出奇地简单"&gt;接入出奇地简单&lt;/h2&gt;
&lt;p&gt;MAF和AG-UI之间的集成就是一个函数调用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;agent_framework.ag_ui&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AgentFrameworkWorkflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;add_agent_framework_fastapi_endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;demo_workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AgentFrameworkWorkflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;workflow_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;_thread_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;create_handoff_workflow&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ag_ui_handoff_workflow_demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;add_agent_framework_fastapi_endpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;demo_workflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/handoff_demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;workflow_factory&lt;/code&gt;为每个线程创建一个新的工作流，这样每个对话都有隔离的状态。端点自动处理所有SSE管道。如果你已经在使用FastAPI（或者可以把它作为轻量层添加），这几乎是零摩擦的。&lt;/p&gt;
&lt;h2 id="我的看法"&gt;我的看法&lt;/h2&gt;
&lt;p&gt;对于我们.NET开发者来说，第一个问题是：&amp;ldquo;我能用C#做这个吗？&amp;ldquo;Agent Framework同时支持.NET和Python，AG-UI协议是语言无关的（只是SSE）。所以虽然这个特定演示使用Python和FastAPI，但模式可以直接移植。你可以用ASP.NET Core最小API配合SSE端点，遵循相同的AG-UI事件模式来实现。&lt;/p&gt;
&lt;p&gt;更重要的启示是，多智能体UI正在成为一等公民的关注点，而不是事后才想到的事情。如果你在构建任何需要智能体与人类交互的东西——客户支持、审批工作流、文档处理——MAF编排加AG-UI透明度的组合就是应该遵循的模式。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;AG-UI + Microsoft Agent Framework给你两全其美：后端强大的多智能体编排和前端的实时可视化。不再有黑盒式的智能体交互。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/agent-framework/ag-ui-multi-agent-workflow-demo/"&gt;完整教程&lt;/a&gt;和&lt;a href="https://github.com/ag-ui-protocol/ag-ui"&gt;AG-UI协议仓库&lt;/a&gt;以深入了解。&lt;/p&gt;</content:encoded></item></channel></rss>