<?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>AI Agents | The .NET Blog</title><link>https://thedotnetblog.com/zh/tags/ai-agents/</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>Tue, 05 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/zh/tags/ai-agents/index.xml" rel="self" type="application/rss+xml"/><item><title>Microsoft Agent Framework 第3部分：从工具到工作流 — 构建块完美契合</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-building-blocks-part-3-agents-tools-workflows/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-building-blocks-part-3-agents-tools-workflows/</guid><description>.NET AI 构建块系列第3部分涵盖 Microsoft Agent Framework — 从带工具的单一代理到带内存的多代理工作流。这是真正重要的内容。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。要查看原始版本，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-building-blocks-part-3-agents-tools-workflows/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;如果你一直在关注 .NET AI 构建块系列，你知道第1部分给了我们 &lt;code&gt;IChatClient&lt;/code&gt;（通用模型接口），第2部分给了我们 &lt;code&gt;Microsoft.Extensions.VectorData&lt;/code&gt;（语义搜索和 RAG）。两者都是基础性的，单独使用都很有用。但这里是一切开始连接的地方。&lt;/p&gt;
&lt;p&gt;第3部分关于 &lt;a href="https://github.com/microsoft/agent-framework"&gt;Microsoft Agent Framework&lt;/a&gt; — 说实话，这是我一直期待看到在 .NET 中落地的部分。1.0 在4月发布。API 稳定了。是时候真正构建代理了。&lt;/p&gt;
&lt;h2 id="代理到底是什么vs-聊天机器人"&gt;代理到底是什么（vs. 聊天机器人）&lt;/h2&gt;
&lt;p&gt;在深入代码之前，让我们厘清这个区别。聊天机器人接收输入，调用模型，返回输出。简单循环。&lt;/p&gt;
&lt;p&gt;代理有&lt;em&gt;自主性&lt;/em&gt;。它可以对任务进行推理，决定使用哪些工具，调用这些工具，评估结果，然后决定下一步做什么 — 所有这些都不需要你为每个场景编写明确的步骤逻辑。你给它工具和指令，它自己处理编排。&lt;/p&gt;
&lt;p&gt;这样理解：&lt;code&gt;IChatClient&lt;/code&gt; 就像进行对话。代理就像把任务清单委托给某人。&lt;/p&gt;
&lt;h2 id="10行代码写出你的第一个代理"&gt;10行代码写出你的第一个代理&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Microsoft.Agents.AI
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AzureOpenAIClient&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="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;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="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&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 class="n"&gt;GetChatClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deploymentName&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 class="n"&gt;AsAIAgent&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;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are good at telling jokes.&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Joker&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tell me a joke about a pirate.&amp;#34;&lt;/span&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;.AsAIAgent()&lt;/code&gt; 扩展方法是桥梁。与 MEAI 的 &lt;code&gt;.AsIChatClient()&lt;/code&gt; 相同的模式 — 它将提供商的 SDK 包装在一个稳定的抽象中。适用于 Azure OpenAI、OpenAI、GitHub Models、Microsoft Foundry 或本地模型。&lt;/p&gt;
&lt;p&gt;流式处理也可以：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunStreamingAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tell me a joke about a pirate.&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 class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update&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;h2 id="给代理提供工具"&gt;给代理提供工具&lt;/h2&gt;
&lt;p&gt;这里是代理不再只是高级聊天机器人的地方。工具是模型可以根据用户请求决定调用的函数。你不需要路由逻辑 — 模型自己搞清楚。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;[Description(&amp;#34;Get the weather for a given location.&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetWeather&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="na"&gt; [Description(&amp;#34;The location to get the weather for.&amp;#34;)]&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;location&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;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;The weather in {location} is cloudy with a high of 15°C.&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&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;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are a helpful assistant&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;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AIFunctionFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetWeather&lt;/span&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;AIFunctionFactory&lt;/code&gt; 来自 MEAI — 与普通 &lt;code&gt;IChatClient&lt;/code&gt; 使用的工具工厂相同。如果你已经为聊天场景定义了工具，它们在这里也能用。&lt;/p&gt;
&lt;p&gt;其次，&lt;code&gt;Description&lt;/code&gt; 属性非常重要。这是模型理解工具用途以及何时使用它的方式。把它们当作给 AI 的文档，而不是给人类的。&lt;/p&gt;
&lt;h2 id="会话真正有记忆的对话"&gt;会话：真正有记忆的对话&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentSession&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateSessionAsync&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;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Tell me a joke about a pirate.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&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;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&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="s"&gt;&amp;#34;Now add some emojis and tell it in the voice of a pirate&amp;#39;s parrot.&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;session&lt;/span&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;RunAsync&lt;/code&gt; 调用都是无状态的。有了会话，代理知道你指的是哪个笑话。&lt;code&gt;AgentSession&lt;/code&gt; 在轮次之间保留对话历史。&lt;/p&gt;
&lt;p&gt;对于生产中的无状态服务，会话可以干净地序列化：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;JsonElement&lt;/span&gt; &lt;span class="n"&gt;sessionState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SerializeSessionAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&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="c1"&gt;// ... 存储在某处 ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;restoredSession&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeserializeSessionAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionState&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;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;What were we just talking about?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;restoredSession&lt;/span&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;/p&gt;
&lt;h2 id="aicontextprovider跨会话的持久记忆"&gt;AIContextProvider：跨会话的持久记忆&lt;/h2&gt;
&lt;p&gt;会话在&lt;em&gt;会话内&lt;/em&gt;保留对话历史。但是，跨会话了解用户的信息呢？&lt;code&gt;AIContextProvider&lt;/code&gt; 处理这个问题。&lt;/p&gt;
&lt;p&gt;它有两个钩子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ProvideAIContextAsync&lt;/code&gt;&lt;/strong&gt; — 在每次交互&lt;em&gt;之前&lt;/em&gt;运行，向代理注入上下文&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;StoreAIContextAsync&lt;/code&gt;&lt;/strong&gt; — 在每次交互&lt;em&gt;之后&lt;/em&gt;运行，允许学习和持久化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个模式很优雅：你可以堆叠多个提供者 — 一个用于用户偏好，一个用于最近的交互，一个查询 VectorData 存储以获取相关文档。最后一个正是第2部分的 RAG 模式，现在作为每次代理调用的一部分自动运行。&lt;/p&gt;
&lt;h2 id="多代理工作流"&gt;多代理工作流&lt;/h2&gt;
&lt;p&gt;这里是框架名副其实的地方。它包括一个基于图的工作流系统，其中执行器（代理、函数、任何东西）通过边连接。&lt;/p&gt;
&lt;p&gt;一些原生支持的模式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;顺序&lt;/strong&gt;：代理A的输出流入代理B&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发（扇出/扇入）&lt;/strong&gt;：并行分发到多个代理，收集结果&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;条件路由&lt;/strong&gt;：根据输出将工作路由到不同代理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写作-批评循环&lt;/strong&gt;：一个代理写作，另一个评估，循环直到批准&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;子工作流&lt;/strong&gt;：层次化地组合工作流&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;写作-批评示例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;WorkflowBuilder&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;writerAgent&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;builder&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 class="n"&gt;AddEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;writerAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;criticAgent&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 class="n"&gt;AddEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;criticAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;writerAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsApproved&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 class="n"&gt;WithOutputFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;criticAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsApproved&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&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;/p&gt;
&lt;h2 id="人在回路中"&gt;人在回路中&lt;/h2&gt;
&lt;p&gt;并非所有事情都应该完全自主运行。对于敏感操作 — 数据库写入、金融交易、发送通信 — 你希望在代理执行之前有人类批准。&lt;/p&gt;
&lt;p&gt;框架通过 &lt;code&gt;FunctionApprovalRequestContent&lt;/code&gt; 和 &lt;code&gt;FunctionApprovalResponseContent&lt;/code&gt; 内置支持此功能。代理提出工具调用，你的应用代码将其呈现给用户，响应决定是否继续执行。&lt;/p&gt;
&lt;p&gt;这是在企业环境中思考代理的正确方式：不是完全自主，而是&lt;em&gt;带护栏的自主性&lt;/em&gt;。&lt;/p&gt;
&lt;h2 id="全貌"&gt;全貌&lt;/h2&gt;
&lt;p&gt;退一步看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MEAI&lt;/strong&gt; 为你提供任何模型的通用接口&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VectorData&lt;/strong&gt; 通过语义搜索让你的代理访问组织的知识&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Framework&lt;/strong&gt; 编排一切 — 内部使用 &lt;code&gt;IChatClient&lt;/code&gt;，与上下文提供者组合，通过工作流协调&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个部分都被设计为与其他部分组合。查看 &lt;a href="https://devblogs.microsoft.com/dotnet/microsoft-agent-framework-building-blocks-for-ai-part-3/"&gt;Jeremy Likness 的原始帖子&lt;/a&gt;和 &lt;a href="https://github.com/microsoft/agent-framework/tree/main/dotnet"&gt;Agent Framework GitHub 仓库&lt;/a&gt;获取完整示例。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Microsoft Agent Framework 第3部分的帖子完成了构建块系列的闭环。对于想要构建 AI 代理的 .NET 开发者 — 不只是聊天机器人，而是真正使用工具、记忆事物、协调行动的代理 — 这是你的前进之路。&lt;/p&gt;
&lt;p&gt;稳定的 1.0 版本意味着你可以在生产环境中构建这个。如果你一直在等待深入 .NET 代理开发，现在是时候了。&lt;/p&gt;</content:encoded></item><item><title>SQL MCP Server 在 Azure App Service 上运行 — 无需容器</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/sql-mcp-server-azure-app-service-no-containers/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/sql-mcp-server-azure-app-service-no-containers/</guid><description>SQL MCP Server 现在可以在 Azure App Service 上运行，无需 Docker 或 Kubernetes。这对于构建与 SQL 数据库通信的 AI 代理的 .NET 开发者意味着什么。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。要查看原始版本，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/sql-mcp-server-azure-app-service-no-containers/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;老实说：每次在教程中看到&amp;quot;需要容器&amp;quot;，我内心都会叹一口气。容器很棒——直到你的团队没有容器策略，一个看似简单的功能突然被意料之外的编排复杂性阻挡。&lt;/p&gt;
&lt;p&gt;这就是为什么这个让我眼前一亮。SQL MCP Server 现在可以在 Azure App Service 上运行——无需 Docker，无需 Kubernetes，只需相同的 Data API Builder（DAB）配置文件，通过 MCP、REST 和 GraphQL 公开你的 SQL 数据库。&lt;/p&gt;
&lt;h2 id="什么是-sql-mcp-server"&gt;什么是 SQL MCP Server？&lt;/h2&gt;
&lt;p&gt;如果你还不了解，简单介绍一下。SQL MCP Server 位于你的 AI 代理和 SQL 数据库之间。它不是让代理直接访问数据库（这是个糟糕的想法），而是将你的表和视图作为带有定义权限的实体抽象层公开。&lt;/p&gt;
&lt;p&gt;它构建在 &lt;a href="https://learn.microsoft.com/zh-cn/azure/data-api-builder/"&gt;Data API Builder&lt;/a&gt; 之上，这意味着单个配置文件同时管理 MCP、REST 和 GraphQL。你的代理与 MCP 端点通信，传统应用与 REST 或 GraphQL 通信。相同的配置，相同的运行时，不同的接口。&lt;/p&gt;
&lt;p&gt;这真的很有用——你不需要维护两个独立的 API 层。&lt;/p&gt;
&lt;h2 id="容器问题及解决方案"&gt;容器问题（及解决方案）&lt;/h2&gt;
&lt;p&gt;SQL MCP Server 最初的部署模型是容器。这在很多团队中运行良好，但并非所有团队都适用。许多 .NET 团队标准化使用 Azure App Service 或虚拟机。仅仅为了公开 SQL 端点而需要容器运行时，增加了没有人要求的摩擦。&lt;/p&gt;
&lt;p&gt;新的教程展示了如何完全跳过容器。一切都通过 &lt;code&gt;dab start&lt;/code&gt; 命令运行，作为标准的 .NET 8 Web 进程托管在 App Service 上。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装 Data API Builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet tool install microsoft.dataapibuilder --prerelease -g
&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="c1"&gt;# 初始化配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab init --database-type mssql --host-mode Development --connection-string &lt;span class="s2"&gt;&amp;#34;@env(&amp;#39;SQL_CONNECTION_STRING&amp;#39;)&amp;#34;&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="c1"&gt;# 添加实体&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab add products --source dbo.products --permissions &lt;span class="s2"&gt;&amp;#34;authenticated:*&amp;#34;&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="c1"&gt;# 配置 App Service 认证提供程序&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab configure --runtime.host.authentication.provider AppService
&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="c1"&gt;# 启动服务器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此时，你在 &lt;code&gt;/mcp&lt;/code&gt; 有 MCP，同一进程提供 REST 和 GraphQL，没有任何东西运行在容器中。&lt;/p&gt;
&lt;h2 id="无需共享-api-密钥的身份验证"&gt;无需共享 API 密钥的身份验证&lt;/h2&gt;
&lt;p&gt;这是我最欣赏的部分。部署到 App Service 时，你将 Microsoft Entra ID 配置为身份验证提供程序。配置文件中没有共享密钥，不需要轮换 API 密钥。&lt;/p&gt;
&lt;p&gt;连接字符串保留在 App Service 环境变量中（不在 &lt;code&gt;dab-config.json&lt;/code&gt; 中），MCP 端点通过平台身份验证保护。如果你的 Azure 工作负载已经与 Entra ID 对齐，这将自然融入。&lt;/p&gt;
&lt;p&gt;本地开发时，切换到 &lt;code&gt;Simulator&lt;/code&gt; 模式和 STDIO 传输。部署前切换回 &lt;code&gt;AppService&lt;/code&gt; 模式。干净且明确。&lt;/p&gt;
&lt;h2 id="部署到-app-service"&gt;部署到 App Service&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;az appservice plan create &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name &amp;lt;plan-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --resource-group &amp;lt;resource-group&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --sku B1 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --is-linux
&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;az webapp create &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name &amp;lt;app-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --resource-group &amp;lt;resource-group&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --plan &amp;lt;plan-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --runtime &lt;span class="s2"&gt;&amp;#34;DOTNETCORE:8.0&amp;#34;&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;az webapp config &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --name &amp;lt;app-name&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --resource-group &amp;lt;resource-group&amp;gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --startup-file &lt;span class="s2"&gt;&amp;#34;dab start&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后使用你的团队已经使用的代码部署方法部署你的 DAB 项目。关键细节：这是&lt;strong&gt;代码&lt;/strong&gt;部署，不是容器部署。&lt;/p&gt;
&lt;h2 id="为什么这对-net-开发者很重要"&gt;为什么这对 .NET 开发者很重要&lt;/h2&gt;
&lt;p&gt;如果你在 .NET 中构建 AI 代理，你的代理最终需要与数据库通信。SQL MCP Server 提供了一种结构化的方式来实现这一点，无需暴露原始连接字符串。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/azure-sql/sql-mcp-server-app-service/"&gt;原始博客文章&lt;/a&gt;和 &lt;a href="https://github.com/Azure-Samples/SQL-MCP-NoContainer"&gt;GitHub 示例仓库&lt;/a&gt;的完整教程。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;App Service 上的 SQL MCP Server 是 .NET 团队的实用选择，无需容器策略即可为代理提供结构化的 SQL 数据访问。试试看——你的代理会很感激清晰的 API 接口。&lt;/p&gt;</content:encoded></item><item><title>shiyong Agent Governance Toolkit zhili .NET zhong de MCP gongju diaoyong</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/governing-mcp-tool-calls-dotnet/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/governing-mcp-tool-calls-dotnet/</guid><description>Weirao "shiyong Agent Governance Toolkit zhili .NET zhong de MCP gongju diaoyong" de .NET tuandui shiyong jiedu baohan ke luodi de shengchan pinggu buzhou.</description><content:encoded>&lt;p&gt;&lt;em&gt;Benwen wei zidong fanyi banben. Yuanshi yingwen ban qing &lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/governing-mcp-tool-calls-dotnet/"&gt;dianji zheli&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/governing-mcp-tool-calls-in-dotnet-with-the-agent-governance-toolkit/"&gt;shiyong Agent Governance Toolkit zhili .NET zhong de MCP gongju diaoyong&lt;/a&gt; duiyu zhengzai goujian he yunying .NET shengchan xitong de tuandui hen zhide guanzhu.&lt;/p&gt;
&lt;p&gt;Zai wo kanlai guanjian bu zhishi gongneng benshen er shi nengfou kuaisu chendian wei ke fuyong ke zhili de gongcheng shijian.&lt;/p&gt;
&lt;h2 id="weishenme-zhe-dui-net-tuandui-zhongyao"&gt;Weishenme zhe dui .NET tuandui zhongyao&lt;/h2&gt;
&lt;p&gt;Zhe lei gengxin tongchang neng zai jiaofu sudu pingtai yizhixing he zhili zhijian tigong geng hao pingheng.&lt;/p&gt;
&lt;h2 id="shicao-jianyi"&gt;Shicao jianyi&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Xian zai xiaoguimo .NET shidian zhong yanzheng shiyong jiejin shengchan de shuju.&lt;/li&gt;
&lt;li&gt;Kuozhan qian xian dingyi keguancexing yu huigun jianchadian.&lt;/li&gt;
&lt;li&gt;Ba luodi zuofa xieru neibu muban fangbian qita tuandui fuyong.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="source"&gt;Source&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Original article: &lt;a href="https://devblogs.microsoft.com/dotnet/governing-mcp-tool-calls-in-dotnet-with-the-agent-governance-toolkit/"&gt;https://devblogs.microsoft.com/dotnet/governing-mcp-tool-calls-in-dotnet-with-the-agent-governance-toolkit/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Visual Studio si yue gengxin mianxiang .NET gongzuoliu de Cloud Agent jicheng</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/visual-studio-april-update-cloud-agent-integration/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/visual-studio-april-update-cloud-agent-integration/</guid><description>Weirao "Visual Studio si yue gengxin mianxiang .NET gongzuoliu de Cloud Agent jicheng" de .NET tuandui shiyong jiedu baohan ke luodi de shengchan pinggu buzhou.</description><content:encoded>&lt;p&gt;&lt;em&gt;Benwen wei zidong fanyi banben. Yuanshi yingwen ban qing &lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/visual-studio-april-update-cloud-agent-integration/"&gt;dianji zheli&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/visualstudio/visual-studio-april-update-cloud-agent-integration/"&gt;Visual Studio si yue gengxin mianxiang .NET gongzuoliu de Cloud Agent jicheng&lt;/a&gt; duiyu zhengzai goujian he yunying .NET shengchan xitong de tuandui hen zhide guanzhu.&lt;/p&gt;
&lt;p&gt;Zai wo kanlai guanjian bu zhishi gongneng benshen er shi nengfou kuaisu chendian wei ke fuyong ke zhili de gongcheng shijian.&lt;/p&gt;
&lt;h2 id="weishenme-zhe-dui-net-tuandui-zhongyao"&gt;Weishenme zhe dui .NET tuandui zhongyao&lt;/h2&gt;
&lt;p&gt;Zhe lei gengxin tongchang neng zai jiaofu sudu pingtai yizhixing he zhili zhijian tigong geng hao pingheng.&lt;/p&gt;
&lt;h2 id="shicao-jianyi"&gt;Shicao jianyi&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Xian zai xiaoguimo .NET shidian zhong yanzheng shiyong jiejin shengchan de shuju.&lt;/li&gt;
&lt;li&gt;Kuozhan qian xian dingyi keguancexing yu huigun jianchadian.&lt;/li&gt;
&lt;li&gt;Ba luodi zuofa xieru neibu muban fangbian qita tuandui fuyong.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="source"&gt;Source&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Original article: &lt;a href="https://devblogs.microsoft.com/visualstudio/visual-studio-april-update-cloud-agent-integration/"&gt;https://devblogs.microsoft.com/visualstudio/visual-studio-april-update-cloud-agent-integration/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>