雄鹰二 發表於 2026-2-13 22:27:00

MAF快速入门(16)用户智能体交互协议AG-UI(上)

<p>大家好,我是Edison。</p>
<p>最近我一直在跟着圣杰的《.NET+AI智能体开发进阶》课程学习MAF开发多智能体工作流,我强烈推荐你也上车跟我一起出发!</p>
<p>上一篇,<span><span>我们学习了MAF中<span>快速调试的利器DevUI<span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span>。本篇,我们来了解一个用户智能体交互协议:AG-UI。</span></span></span></span></span></p>
<h1><strong>1 什么是AG-UI</strong></h1>
<p><span><span><span><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span><span data-pm-slice="0 0 []"><span><span>AG-UI 全称&nbsp;<strong data-pm-slice="0 0 []"><span><span>Agent–User Interaction Protocol&nbsp;<span><span>即&nbsp;<span>智能体-用户 交互协议<span>,</span></span></span></span></span></span></strong>这是一个开放的、基于事件的协议,由 CopilotKit 团队发起,用于标准化 AI Agent 与 用户界面 的实时交互。</span></span></span></span></span></span></span></span></p>
<h3><span><span><span><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span>为什么出现AG-UI协议?</span></span></span></span></span></h3>
<p><span><span><span><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span>这是因为在构建AI Agent应用的界面时,传统API模式面临很多问题和挑战:</span></span></span></span></span></p>
<p><img src="https://img2024.cnblogs.com/blog/381412/202602/381412-20260213222047426-1470758576.png" alt="image" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<p><span><span><span><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span><span><span>而AG-UI则是专门为AI Agent与用户界面的交互而设计的协议,其核心价值体现在:</span></span></span></span></span></span></span></p>
<ul class="list-paddingleft-1">
<li>
<p><span>📡&nbsp;<strong>实时流式响应</strong><span>:即时展示 Agent 输出,无需等待</span></span></p>
</li>
<li>
<p><span>🎯&nbsp;<strong>事件驱动架构</strong><span>:细粒度的交互事件,精确控制 UI</span></span></p>
</li>
<li>
<p><span>🔄&nbsp;<strong>状态同步机制</strong><span>:Snapshot/Delta 模式,保持 UI 与 Agent 状态一致</span></span></p>
</li>
<li>
<p><span>🔧&nbsp;<strong>工具调用可视化</strong><span>:透明展示 Agent 的思考和行动过程</span></span></p>
</li>
</ul>
<h3><span><span><span><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span><span><span>三大Agent协议对比</span></span></span></span></span></span></span></h3>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">我们之前已经学习了MCP 和 A2A两个重要的协议了,加上AG-UI,它们共同组成了Agent的三大通信协议体系。</span></p>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">不过,它们的定位各有侧重,并非非此即彼,而是协同使用,用形象的比喻来讲:</span></p>
<p data-pm-slice="0 0 []"><strong><span><span>AG-UI 像是"客服窗口":</span></span></strong></p>
<ul class="list-paddingleft-1">
<li>
<p><span><span>用户与 Agent 之间的交互界面</span></span></p>
</li>
<li>
<p><span><span>实时展示 Agent 的工作状态</span></span></p>
</li>
<li>
<p><span><span>支持用户输入和反馈</span></span></p>
</li>
</ul>
<p><strong><span><span>MCP 像是"工具箱":</span></span></strong></p>
<ul class="list-paddingleft-1">
<li>
<p><span><span>Agent 调用外部工具完成任务</span></span></p>
</li>
<li>
<p><span><span>工具是被动的,等待调用</span></span></p>
</li>
<li>
<p><span><span>扩展 Agent 的能力边界</span></span></p>
</li>
</ul>
<p><strong><span><span>A2A 像是"同事协作":</span></span></strong></p>
<ul class="list-paddingleft-1">
<li>
<p><span><span>多个 Agent 之间的任务分发</span></span></p>
</li>
<li>
<p><span><span>每个 Agent 都是自主的</span></span></p>
</li>
<li>
<p><span><span>可以互相委托和协作</span></span></p>
</li>
</ul>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span data-lark-record-format="docx/record"><span data-lark-record-format="docx/record">在实际企业场景中,<strong data-pm-slice="0 0 []"><strong data-pm-slice="0 0 []"><span><span>三大协议通常协同使用:</span></span></strong></strong></span></span></span></p>
<ul class="list-paddingleft-1">
<li>
<p><strong>AG-UI</strong><span>:用户通过界面与主 Agent 交互</span></p>
</li>
<li>
<p><strong>MCP</strong><span>:Agent 内部使用 MCP 调用工具</span></p>
</li>
<li>
<p><strong>A2A</strong><span>:复杂任务委托给专家 Agent 处理</span></p>
</li>
</ul>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span data-lark-record-format="docx/record"><span data-lark-record-format="docx/record">下图展示了三大协议的详细对比:</span></span></span></p>
<p><img src="https://img2024.cnblogs.com/blog/381412/202602/381412-20260213222138115-952680249.png" alt="image" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<h1><strong><span>2 快速开始:AG-UI对话应用<strong><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;section&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;letter-spacing: 0.578px;text-align: left;margin: 8px;&quot;,&quot;data-pm-slice&quot;:&quot;6 3 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;outline: 0px;visibility: visible;line-height: 1.75em;margin-top: 16px;margin-bottom: 16px;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;color: rgb(0, 179, 139);font-family: \&quot;PingFang SC\&quot;, \&quot;Lantinghei SC\&quot;, \&quot;Microsoft Yahei\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft Sans Serif\&quot;, \&quot;WenQuanYi Micro Hei\&quot;, Helvetica, sans-serif;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;letter-spacing: 0.544px;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><br></span></strong></span></strong></h1>
<p data-pm-slice="0 0 []">AG-UI协议定义了清晰的架构组件,包括 Server、Client 和 Agent。</p>
<p data-pm-slice="0 0 []">在MAF中提供了一个内置的AG-UI组件,我们可以非常方便地创建集成AG-UI的Agent应用。</p>
<p data-pm-slice="0 0 []">接下来,我们就一步一步完成一个AG-UI对话应用涉及到的Server 和 Client。</p>
<h3 data-pm-slice="0 0 []">AG-UI Server</h3>
<p data-pm-slice="0 0 []">首先,我们创建一个ASP.NET Web应用,安装以下NuGet包:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Microsoft.Agents.AI.Hosting.AGUI.AspNetCore
Microsoft.Agents.AI.OpenAI
Microsoft.Extensions.AI.OpenAI</span></pre>
</div>
<p data-pm-slice="0 0 []">然后,就是整个示例的核心部分,我们一块一块来说:</p>
<p>(1)创建应用并注册AG-UI服务</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step0. Create WebApplication builder</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> builder =<span style="color: rgba(0, 0, 0, 1)"> WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient().AddLogging();

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step1. Register AG-UI services</span>
builder.Services.AddAGUI();</pre>
</div>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;margin: 8px;padding: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system-font, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;min-height: 1em;text-align: justify;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;span&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;font-family: system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;PingFang SC\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-align: left;caret-color: var(--weui-BRAND);&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">(2)创建一个AI Agent:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> builder.Build();

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step2. Load Configuration</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> config = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ConfigurationBuilder()
    .AddJsonFile($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">appsettings.json</span><span style="color: rgba(128, 0, 0, 1)">"</span>, optional: <span style="color: rgba(0, 0, 255, 1)">false</span>, reloadOnChange: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
    .AddJsonFile($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">appsettings.{Environment.GetEnvironmentVariable(</span><span style="color: rgba(128, 0, 0, 1)">"</span>ASPNETCORE_ENVIRONMENT<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">)}.json</span><span style="color: rgba(128, 0, 0, 1)">"</span>, optional: <span style="color: rgba(0, 0, 255, 1)">true</span>, reloadOnChange: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
    .Build();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> openAIProvider = config.GetSection(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">OpenAI</span><span style="color: rgba(128, 0, 0, 1)">"</span>).Get&lt;OpenAIProvider&gt;<span style="color: rgba(0, 0, 0, 1)">();

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step3. Create one ChatClient</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> chatClient = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> OpenAIClient(
      </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ApiKeyCredential(openAIProvider.ApiKey),
      </span><span style="color: rgba(0, 0, 255, 1)">new</span> OpenAIClientOptions { Endpoint = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Uri(openAIProvider.Endpoint) })
    .GetChatClient(openAIProvider.ModelId)
    .AsIChatClient();

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step4. Create one AI Agent</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> agent =<span style="color: rgba(0, 0, 0, 1)"> chatClient.AsAIAgent(
    name: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AGUI-Assistant</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    instructions: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">你是一个友好的AI助手,请使用中文回答用户的问题。</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">✅ AI Agent 创建成功</span><span style="color: rgba(128, 0, 0, 1)">"</span>);</pre>
</div>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px 0px;padding: 0px;outline: 0px;max-width: 100%;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);padding: 0px;outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">(3)映射AGUI端点并启动应用:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step5. Mapping AG-UI Endpoints</span>
app.MapAGUI(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, agent);

Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">🚀 AG-UI Server 已启动</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">📍 端点地址: https://localhost:8443/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">💡 使用 Ctrl+C 停止服务</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);

app.Run();</span></pre>
</div>
<p>可以看到,我们仅用一行代码 app.MapAGUI() 就启用了AG-UI协议,So Easy!</p>
<p><span><span>启动起来的效果如下图所示:</span></span></p>
<p><img src="https://img2024.cnblogs.com/blog/381412/202602/381412-20260213222325381-1327622437.png" alt="image" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<h3><strong><span><span>AG-UI Client</span></span></strong></h3>
<p>首先,我们创建一个控制台应用,安装以下NuGet包:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Microsoft.Agents.AI.AGUI
Microsoft.Agents.AI</span></pre>
</div>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px 0px;padding: 0px;outline: 0px;max-width: 100%;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);padding: 0px;outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;&quot;,&quot;data-pm-slice&quot;:&quot;0 0 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">然后,我们创建AG-UI Client 和 AI Agent:</span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Load Configuration</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> config = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ConfigurationBuilder()
    .AddJsonFile($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">appsettings.json</span><span style="color: rgba(128, 0, 0, 1)">"</span>, optional: <span style="color: rgba(0, 0, 255, 1)">false</span>, reloadOnChange: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
    .Build();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> openAIProvider = config.GetSection(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">OpenAI</span><span style="color: rgba(128, 0, 0, 1)">"</span>).Get&lt;OpenAIProvider&gt;<span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> serverEndpoint = config.GetValue&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt;(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AGUI_SERVER_URL</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
    </span>?? <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://localhost:8443</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">🚀 AG-UI 客户端已启动</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">📍 服务端地址: {serverEndpoint}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step1. Create HTTP Client</span>
<span style="color: rgba(0, 0, 255, 1)">using</span> HttpClient httpClient = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">()
{
    Timeout </span>= TimeSpan.FromSeconds(<span style="color: rgba(128, 0, 128, 1)">60</span><span style="color: rgba(0, 0, 0, 1)">)
};
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step2. Create AG-UI Client</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> chatClient = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> AGUIChatClient(httpClient, serverEndpoint);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step3. Create AI Agent</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> agent =<span style="color: rgba(0, 0, 0, 1)"> chatClient.AsAIAgent(
    name: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">agui-client</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    description: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AG-UI Client Agent</span><span style="color: rgba(128, 0, 0, 1)">"</span>);</pre>
</div>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;&quot;,&quot;data-pm-slice&quot;:&quot;0 0 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">然后,准备开始对话:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Step4. Prepare for Conversation</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> session = <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> agent.GetNewSessionAsync();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> messages = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;ChatMessage&gt;<span style="color: rgba(0, 0, 0, 1)">()
{
    </span><span style="color: rgba(0, 0, 255, 1)">new</span> ChatMessage(ChatRole.System, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">你是一个友好的AI助手,使用中文回答用户的问题。</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
};
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">💬 开始对话(输入 :q 或 quit 退出)\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
    Console.Write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">👤 用户: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">string</span>? message =<span style="color: rgba(0, 0, 0, 1)"> Console.ReadLine();
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">.IsNullOrWhiteSpace(message))
      </span><span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (message <span style="color: rgba(0, 0, 255, 1)">is</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">:q</span><span style="color: rgba(128, 0, 0, 1)">"</span> or <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">quit</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 添加用户消息</span>
    messages.Add(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ChatMessage(ChatRole.User, message));
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 流式接收响应</span>
    Console.Write(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">🤖 助手: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">await</span> <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> update <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> agent.RunStreamingAsync(messages, session))
    {
      </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (AIContent content <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> update.Contents)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (content)
            {
                </span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> TextContent textContent:
                  Console.Write(textContent.Text);
                  </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
                </span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> UsageContent usageContent:
                  Console.WriteLine($</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\n[📊 Tokens: {usageContent.Details.TotalTokenCount}]</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
                  </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
                </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
                  Console.Write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Unknown content!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
                  </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
            }
      }
    }
    Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
}
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">👋 再见!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Console.ReadKey();</span></pre>
</div>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;&quot;,&quot;data-pm-slice&quot;:&quot;0 0 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">最终的调试效果如下图所示:</span></p>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;&quot;,&quot;data-pm-slice&quot;:&quot;0 0 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><img src="https://img2024.cnblogs.com/blog/381412/202602/381412-20260213222507160-684244773.gif" alt="agui-gif-demo-001" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></span></p>
<p data-pm-slice="0 0 []"><span><span>可以看到,我们很容易就创建了一个用户友好的对话客户端,实时的流式响应也不需要我们写过多代码实现。</span></span></p>
<h1><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;&quot;,&quot;data-pm-slice&quot;:&quot;0 0 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]"><strong><span>3 小结</span></strong></span></h1>
<p><span data-pm-slice="1 1 [&quot;para&quot;,{&quot;tagName&quot;:&quot;p&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 8px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;color: rgba(0, 0, 0, 0.9);font-family: \&quot;PingFang SC\&quot;, system-ui, -apple-system, BlinkMacSystemFont, \&quot;Helvetica Neue\&quot;, \&quot;Hiragino Sans GB\&quot;, \&quot;Microsoft YaHei UI\&quot;, \&quot;Microsoft YaHei\&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.578px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.75em;visibility: visible;&quot;,&quot;data-pm-slice&quot;:&quot;0 0 []&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;},&quot;node&quot;,{&quot;tagName&quot;:&quot;strong&quot;,&quot;attributes&quot;:{&quot;style&quot;:&quot;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;&quot;},&quot;namespaceURI&quot;:&quot;http://www.w3.org/1999/xhtml&quot;}]">本文介绍了AG-UI协议的基本概念,为什么会出现AG-UI协议,AG-UI和MCP,A2A的对比,随后介绍了如何在MAF中快速开发一个基于AG-UI的对话应用。</span></p>
<h1>示例源码</h1>
<p>GitHub:&nbsp;https://github.com/EdisonTalk/MAFD</p>
<h1>参考资料</h1>
<p><span data-pm-slice="0 0 []"><span>圣杰,《.NET + AI 智能体开发进阶》(推荐指数:★★★★★)</span></span></p>
<p><span data-pm-slice="0 0 []"><span>Microsoft Learn,<span>《Agent Framework Tutorials》</span></span></span></p>
<div><span data-pm-slice="0 0 []"><span>&nbsp;</span></span></div>
<p style="text-align: center"><img src="https://images.cnblogs.com/cnblogs_com/edisonchou/1647700/o_200902144330EdisonTalk-Footer.jpg" alt="" style="width: 65%; border: 1px solid rgba(221, 221, 221, 1); border-radius: 3px; box-shadow: 0 4px 8px rgba(3, 27, 78, 0.12)"></p>
<div id="Copyright">
<p>作者:<span style="text-decoration: underline">爱迪生</span></p>
<p>出处:https://edisontalk.cnblogs.com</p>
<p>本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。</p>
</div>

</div>
<div id="MySignature" role="contentinfo">
    <div align="center"><img border="0" src="http://service.t.sina.com.cn/widget/qmd/2068032061/d643d182/10.png"></div><br><br>
来源:https://www.cnblogs.com/edisontalk/p/-/quick-start-on-maf-chatper16
頁: [1]
查看完整版本: MAF快速入门(16)用户智能体交互协议AG-UI(上)