<?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 | The .NET Blog</title><link>https://thedotnetblog.com/zh/tags/ai/</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>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/zh/tags/ai/index.xml" rel="self" type="application/rss+xml"/><item><title>NL2SQL 是智能体时代的 SQL 注入</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/nl2sql-agentic-sql-injection-mcp-server/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/nl2sql-agentic-sql-injection-mcp-server/</guid><description>在让智能体用自然语言查询你的数据库之前，请先读这篇文章。NL2SQL 看起来简单，直到你思考模式完整性、非确定性，以及 SQL MCP Server 究竟解决了什么。</description><content:encoded>&lt;p&gt;NL2SQL 有一个听起来很完美的推介版本：用户用自然语言提问，智能体生成 SQL，数据返回。更少的界面，更少的查询，更少的代码。简单。&lt;/p&gt;
&lt;p&gt;然后你再多想五分钟。&lt;/p&gt;
&lt;h2 id="演示中没人提的问题"&gt;演示中没人提的问题&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;模式（Schema）不是为了解释事物而设计的。&lt;/strong&gt; 晦涩的表名、不一致的列名、在没有额外谓词的情况下语义上无效的技术有效关系——这在企业数据库中很常见。这些不是 bug，只是业务变更积累的历史。但当你要求模型从一个并非为传达意图而设计的模式中推断意图时，模型还是会尝试。它不会放弃。它会生成最佳查询并自信地返回结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;模型是非确定性的。&lt;/strong&gt; 对同一个数据库问同一个问题两次，你可能会得到不同的 SQL。模型在计算概率，上下文中的细微变化会产生不同的输出。你无法通过测试获得智能体总是生成正确查询的保证。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用户审查无法扩展。&lt;/strong&gt; &amp;ldquo;执行前只需审查每个查询&amp;quot;听起来很安全。但这假设用户既是数据模型又是 SQL 的专家——恰恰是那些不需要自然语言界面的人。它还引入了认知过载和新型确认偏差，被查询复杂性压倒的用户会批准无效查询而不是去调查它们。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;然后还有注入。&lt;/strong&gt; 在传统 SQL 开发中，参数化解决了注入问题，因为用户输入填充的是参数，而不是 SQL 结构。在 NL2SQL 中，模型本身生成 SQL。提示词、模式上下文、对话历史和检索的数据都会影响执行的内容。如果有人精心设计一个改变模型生成内容的提示，那就是注入——不是在参数级别，而是在查询生成级别。与 DROP TABLE（明显、可恢复）不同，NL2SQL 注入会产生在没有可见错误的情况下返回错误结果的查询。业务决策基于错误数据做出。&lt;/p&gt;
&lt;h2 id="sql-mcp-server-究竟解决了什么"&gt;SQL MCP Server 究竟解决了什么&lt;/h2&gt;
&lt;p&gt;这里文章提出了最有用的实用观点。SQL MPC Server 不是给智能体任意的模式访问权限并期待最好的结果，而是暴露了一个建立在 &lt;a href="https://learn.microsoft.com/en-us/azure/data-api-builder/overview"&gt;Data API builder&lt;/a&gt; 之上的&lt;strong&gt;精心策划的 API 表面&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;差异很重要：智能体不生成 SQL。它调用返回预定义结果形状的命名端点。SQL 由开发人员编写一次，是确定性的。智能体的非确定性被限制在选择&lt;em&gt;调用哪个&lt;/em&gt;端点，而不是组合任意查询。&lt;/p&gt;
&lt;p&gt;这类似于参数化在传统应用模型中对 SQL 注入所做的——消除了从不受信任的输入构建任意查询的能力。&lt;/p&gt;
&lt;h2 id="正确的问题"&gt;正确的问题&lt;/h2&gt;
&lt;p&gt;这篇文章不是说&amp;quot;永远不要使用 NL2SQL&amp;rdquo;。它说：对&lt;em&gt;在哪里&lt;/em&gt;应用它以及&lt;em&gt;暴露什么&lt;/em&gt;要有意识。对于在受控环境中、具有有限范围模式和只读访问权限的探索性分析，NL2SQL 可能没问题。对于业务决策依赖于结果的生产系统，经过精心策划的 API 层要安全得多。&lt;/p&gt;
&lt;p&gt;说实话：有些问题确实更适合用命名端点后面的结构化查询来解决，而不是自然语言到 SQL。SQL MCP Server 为你提供了这个选项，而不必完全放弃智能体界面。&lt;/p&gt;
&lt;p&gt;原文链接：&lt;a href="https://devblogs.microsoft.com/azure-sql/sql-mcp-server-nl2sql/"&gt;Considering NL2SQL? Should your database really be the prompt? How can SQL MCP Server help?&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Microsoft Foundry 2026年4月：Foundry Local GA、GPT-5.5、Hyperlight上的CodeAct</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/microsoft-foundry-april-2026-whats-new/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/microsoft-foundry-april-2026-whats-new/</guid><description>4月的Foundry回顾内容丰富：Foundry Local达到GA，GPT-5.5到来，Agent Framework获得OpenTelemetry追踪，CodeAct在Hyperlight微型虚拟机中运行Python，以及代理监控仪表板上线。</description><content:encoded>&lt;p&gt;微软Foundry迎来了繁忙的一个月。以下是最重要的公告。&lt;/p&gt;
&lt;h2 id="foundry-local正式发布"&gt;Foundry Local正式发布&lt;/h2&gt;
&lt;p&gt;Foundry Local — 微软的跨平台本地AI运行时 — 在Windows、macOS（Apple Silicon）和Linux x64上从预览版升级为GA版本。具备开发者友好SDK的生产就绪本地模型推理。1.1版本增加了转录、embeddings和Responses API支持。&lt;/p&gt;
&lt;h2 id="gpt-55"&gt;GPT-5.5&lt;/h2&gt;
&lt;p&gt;GPT-5系列的最新模型现已在Foundry中提供。Tier 5和Tier 6订阅的默认配额。如果您一直在使用早期的GPT-5变体，值得针对您的用例进行评估。&lt;/p&gt;
&lt;h2 id="foundry中的agent-framework追踪"&gt;Foundry中的Agent Framework追踪&lt;/h2&gt;
&lt;p&gt;本月有两项追踪功能以预览形式发布：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Agent Framework追踪&lt;/strong&gt; — MAF代理现在可以向Foundry发送OpenTelemetry追踪。调试代理行为，追踪多步骤执行，显示工具调用中的延迟和错误。这填补了一个真实的空白：知道&lt;em&gt;代理在生产中实际做了什么&lt;/em&gt;，而不仅仅是它返回了什么。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;托管代理追踪&lt;/strong&gt; — 托管代理的会话、工具调用和运行步骤也出现在Foundry追踪中。相同的可观测性能力延伸到托管层。&lt;/p&gt;
&lt;h2 id="hyperlight上的codeactalpha"&gt;Hyperlight上的CodeAct（Alpha）&lt;/h2&gt;
&lt;p&gt;这是技术上最有趣的新增功能：Agent Framework现在可以在&lt;a href="https://github.com/hyperlight-dev/hyperlight"&gt;Hyperlight&lt;/a&gt;微型虚拟机中执行Python代码。&lt;/p&gt;
&lt;p&gt;CodeAct是代理将Python代码作为工具生成并执行的模式。显而易见的担忧是安全性 — 您正在运行模型生成的代码。Hyperlight的微型VM以接近原生的启动时间提供进程级隔离，使沙盒代码执行变得实用，而无需完整容器或VM的开销。&lt;/p&gt;
&lt;p&gt;对于需要代码执行的代理工作流，这是相比在宿主进程中运行代码的重大安全改进。&lt;/p&gt;
&lt;h2 id="代理监控仪表板预览"&gt;代理监控仪表板（预览）&lt;/h2&gt;
&lt;p&gt;统一的操作仪表板，在一个视图中结合了令牌使用情况、延迟、运行成功率和评估器分数。与常规可观测性仪表板的区别：它在操作指标旁边包含评估结果，因此您可以将&amp;quot;代理变慢了&amp;quot;与&amp;quot;评估器分数下降了&amp;quot;关联起来 — 或确认它们无关。&lt;/p&gt;
&lt;h2 id="持续评估自定义评估器预览"&gt;持续评估自定义评估器（预览）&lt;/h2&gt;
&lt;p&gt;您现在可以将自己的基于代码或提示的评估器带入持续评估管道。以前，持续评估仅限于内置评估器。自定义评估器让您在生产监控循环中执行团队特定的质量标准。&lt;/p&gt;
&lt;h2 id="控制平面中的代理清单"&gt;控制平面中的代理清单&lt;/h2&gt;
&lt;p&gt;Foundry控制平面的Operate视图现在显示订阅中所有受支持的代理：Foundry代理、Azure SRE Agent、Logic Apps代理循环和已注册的自定义代理。一个视图来了解部署了什么以及在哪里。&lt;/p&gt;
&lt;p&gt;原始帖子：&lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-apr-2026/"&gt;What&amp;rsquo;s new in Microsoft Foundry | April 2026&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Handoff 模式：当一个智能体不够用时</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-handoff-orchestration-pattern-tour/</link><pubDate>Mon, 01 Jun 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-handoff-orchestration-pattern-tour/</guid><description>Microsoft Agent Framework 的 Handoff 编排模式让智能体能够决定由谁处理下一轮对话——而不会丢失对话上下文或违反拓扑规则。</description><content:encoded>&lt;p&gt;在某个时刻，每个多智能体系统都会超越一个简单的路由器。第一个信号通常是当一个专业智能体需要提出后续问题时，或者在轮次中途意识到另一个智能体应该继续时。固定管道在那里失败。单次路由器在那里失败。&lt;/p&gt;
&lt;p&gt;这正是 Microsoft Agent Framework 中 Handoff 编排模式设计解决的问题。&lt;/p&gt;
&lt;h2 id="handoff-如何工作"&gt;Handoff 如何工作&lt;/h2&gt;
&lt;p&gt;开发者声明一个图：这些是智能体，这些是它们之间的边。框架完成其余工作——为每条出边合成一个 handoff 工具并将其注入每个智能体。当智能体决定交出控制权时，它调用该工具。框架强制执行拓扑结构。&lt;/p&gt;
&lt;p&gt;三件事使这与简单地让智能体互相调用不同：&lt;/p&gt;
&lt;ol&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; — 当活跃智能体在没有调用 handoff 工具的情况下结束其轮次时，工作流让位给用户。无需轮询，无需显式退出条件。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="最小示例"&gt;最小示例&lt;/h2&gt;
&lt;p&gt;在 .NET 中，构建 handoff 工作流看起来像这样：&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;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI&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;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI.Workflows&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;triage&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;Route to the right specialist.&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;Triage&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;billing&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;Handle billing questions.&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;Billing&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;tech&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;Handle technical support.&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;Tech&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="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;HandoffWorkflow&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&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;Add&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;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tech&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;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&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&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;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tech&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&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;billing&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;Triage 可以发送给任一专家。两个专家都可以发送回 triage。图支持无环，但在需要时支持后向边（&amp;ldquo;我需要更多信息&amp;rdquo; → 返回研究）。&lt;/p&gt;
&lt;h2 id="何时使用-handoff何时不使用"&gt;何时使用 Handoff（何时不使用）&lt;/h2&gt;
&lt;p&gt;Handoff 是好的选择，当：&lt;/p&gt;
&lt;ul&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; — handoff 的决定是上下文相关的，最好由模型而不是类型化谓词来做出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;不是&lt;/em&gt;正确选择，当：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;管道是固定且顺序的 — 为此使用 &lt;code&gt;Sequential&lt;/code&gt; 工作流&lt;/li&gt;
&lt;li&gt;每个步骤都是独立的 — 智能体共享一个只有一个需要的转录只是噪音&lt;/li&gt;
&lt;li&gt;需要严格的处理保证 — 模型驱动路由的不确定性不是你想要的&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="后向边和-human-in-the-loop"&gt;后向边和 Human-in-the-Loop&lt;/h2&gt;
&lt;p&gt;Handoff 允许的最有趣的形式之一是真正的后向边。智能体可以决定&amp;quot;我没有足够的信息&amp;quot;并路由回研究步骤——不是使用硬编码循环，而是因为模型决定这是正确的决定。&lt;/p&gt;
&lt;p&gt;Human-in-the-loop 交互也自然地组合。当专家需要用户输入时，工作流通过默认的轮次循环让位给用户，收集响应，并以完整上下文恢复。智能体从未丢失对话。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Handoff 是那些看起来简单但一旦内化就能实现很多功能的模式之一：分散路由、共享上下文、强制拓扑、自然终止。当你的智能体开始说&amp;quot;实际上，应该由其他人来处理这个&amp;quot;时，这是正确的下一步。&lt;/p&gt;
&lt;p&gt;在原始帖子中阅读完整演练：&lt;a href="https://devblogs.microsoft.com/agent-framework/a-tour-of-handoff-orchestration-pattern/"&gt;A Tour of the Handoff Orchestration Pattern&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Microsoft Agent Framework中的持久工作流：从内存到Azure Functions</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-durable-workflows-azure-functions-durable-task/</link><pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-durable-workflows-azure-functions-durable-task/</guid><description>MAF的工作流编程模型现在支持由Durable Task支持的持久执行——以下是如何构建可组合的代理工作流，这些工作流能够在进程重启后继续运行并在Azure Functions上扩展。</description><content:encoded>&lt;p&gt;早期AI代理工作流的痛点之一：它们很脆弱。绑定到单个进程的长时间运行多步骤工作流意味着进程重启 = 状态丢失。对于简单的演示这没问题。对于生产工作负载则不然。&lt;/p&gt;
&lt;p&gt;Microsoft Agent Framework的工作流编程模型现在支持&lt;strong&gt;持久执行&lt;/strong&gt;，由Durable Task框架支持，通过Azure Functions托管。以下是编程模型的工作原理以及持久性为何重要。&lt;/p&gt;
&lt;h2 id="核心构建块"&gt;核心构建块&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Executor&lt;/strong&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;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI.Workflows&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="kd"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderLookup&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;Executor&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderCancelRequest&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;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;OrderLookup&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="n"&gt;ValueTask&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HandleAsync&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;OrderCancelRequest&lt;/span&gt; &lt;span class="n"&gt;message&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;IWorkflowContext&lt;/span&gt; &lt;span class="n"&gt;context&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;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;default&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="c1"&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;return&lt;/span&gt; &lt;span class="k"&gt;new&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;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrderId&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;工作流&lt;/strong&gt;使用流畅构建器将执行器连接成有向图。框架处理执行、步骤之间的数据流和错误传播。&lt;/p&gt;
&lt;p&gt;您可以建模：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;顺序链（步骤A → 步骤B → 步骤C）&lt;/li&gt;
&lt;li&gt;并行fan-out/fan-in（并行运行代理A、B、C，聚合结果）&lt;/li&gt;
&lt;li&gt;条件分支&lt;/li&gt;
&lt;li&gt;人在回路审批（暂停工作流，等待外部信号）&lt;/li&gt;
&lt;/ul&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="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Agents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Agents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Workflows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;核心包包含轻量级进程内运行器。无外部依赖，无数据库，无Azure资源。非常适合本地开发和单元测试。&lt;/p&gt;
&lt;h2 id="使用durable-task添加持久性"&gt;使用Durable Task添加持久性&lt;/h2&gt;
&lt;p&gt;当工作流需要在进程重启后继续运行时——因为它运行时间长，因为它有人在回路步骤，因为它分散在许多并行代理调用中——内存运行器不够用。&lt;/p&gt;
&lt;p&gt;MAF的Durable Task集成将工作流状态存储在Azure Storage中。如果进程重启，工作流从中断处继续。编程模型保持不变；只需替换运行器。&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;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Agents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Workflows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DurableTask&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="azure-functions托管"&gt;Azure Functions托管&lt;/h2&gt;
&lt;p&gt;第三层是Azure Functions托管。您的工作流成为Function应用：通过HTTP端点触发工作流，持久运行时处理扩展、状态和可靠性。&lt;/p&gt;
&lt;p&gt;这意味着具有并行调用、条件分支和人工审批的多代理工作流可以在无服务器Functions环境中扩展，无需自定义状态管理。&lt;/p&gt;
&lt;h2 id="为什么这很重要"&gt;为什么这很重要&lt;/h2&gt;
&lt;p&gt;这种组合对真实AI系统很重要：&lt;/p&gt;
&lt;ul&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;——Azure Functions水平扩展执行；Durable Task框架管理并行状态协调&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果您正在构建超越简单本地演示的MAF工作流，这就是走向生产质量执行的道路。&lt;/p&gt;
&lt;p&gt;原始文章：&lt;a href="https://devblogs.microsoft.com/dotnet/durable-workflows-in-microsoft-agent-framework/"&gt;Durable Workflows in the Microsoft Agent Framework&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>您的本地 MAF 代理刚刚在生产环境中找到了家</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-agent-local-to-production-foundry-hosted-agents/</link><pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-agent-local-to-production-foundry-hosted-agents/</guid><description>Foundry Hosted Agents 为您的 Microsoft Agent Framework 代理提供身份、扩展、会话持久性和无需额外配置的可观测性。以下是实际效果。</description><content:encoded>&lt;p&gt;让代理在本地运行是有趣的部分。棘手的部分是之后的一切：不用抓狂地部署它、管理会话、设置身份、连接可观测性。通常这意味着大量自定义基础设施粘合代码。&lt;/p&gt;
&lt;p&gt;Foundry Hosted Agents 刚刚为 Microsoft Agent Framework (MAF) 用户消除了大部分粘合代码。&lt;/p&gt;
&lt;h2 id="foundry-hosted-agents-实际做什么"&gt;Foundry Hosted Agents 实际做什么&lt;/h2&gt;
&lt;p&gt;当您将 MAF 代理部署到 Foundry Hosted Agents 时，平台会处理一个令人惊讶的长列表，这些都是您否则需要自己构建的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;缩放到零&lt;/strong&gt; — 代理空闲时不花费任何费用，并自动重新启动&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;每个会话的 VM 隔离沙箱&lt;/strong&gt; — 每个用户会话都有自己的沙箱，具有在缩减事件中存活的文件系统持久性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内置 Entra ID&lt;/strong&gt; — 每个代理都获得自己的身份，可以调用 Foundry 模型、Toolbox 和 Azure 服务，而无需将密钥嵌入镜像&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;code&gt;APPLICATIONINSIGHTS_CONNECTION_STRING&lt;/code&gt; 在运行时注入，使 MAF 的 OpenTelemetry 跟踪自动流入 App Insights&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后一点确实很好。无需额外配置，无需额外设置。跟踪就这样出现了。&lt;/p&gt;
&lt;h2 id="代码差异很小"&gt;代码差异很小&lt;/h2&gt;
&lt;p&gt;这是我最欣赏这个集成的地方。您无需重写代理。只需包装它：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.NET 中：&lt;/strong&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;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI.Foundry.Hosting&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="kt"&gt;var&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;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&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 class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddFoundryResponses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&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="kt"&gt;var&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;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;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MapFoundryResponses&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&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;strong&gt;Python 中：&lt;/strong&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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ResponsesHostServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&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;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&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;Hosted Agents 支持两种端点样式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Responses&lt;/strong&gt; (&lt;code&gt;/responses&lt;/code&gt;) — 兼容 OpenAI，管理会话历史和流式传输。聊天形式代理的良好默认选择。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invocations&lt;/strong&gt; (&lt;code&gt;/invocations&lt;/code&gt;) — 您定义请求/响应模式。适合非对话工作流。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果您构建的东西看起来像对话，从 Responses 开始。如果您构建的是接受结构化输入并返回结构化输出的 API 形式代理，Invocations 给您灵活性。&lt;/p&gt;
&lt;h2 id="使用-azd-的部署流程"&gt;使用 &lt;code&gt;azd&lt;/code&gt; 的部署流程&lt;/h2&gt;
&lt;p&gt;当您使用 MAF 代理运行 &lt;code&gt;azd up&lt;/code&gt; 时：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;可选地创建 Foundry 项目并部署模型&lt;/li&gt;
&lt;li&gt;打包代码并将镜像推送到 Azure Container Registry&lt;/li&gt;
&lt;li&gt;从 ACR 镜像供应计算&lt;/li&gt;
&lt;li&gt;为代理分配专用 Entra ID&lt;/li&gt;
&lt;li&gt;公开稳定端点 (&lt;code&gt;https://{project_endpoint}/agents/{agent_name}&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;从此处理其他一切&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;会话持续最多 30 天。空闲计算在 15 分钟后取消供应，并在下一个请求时透明地恢复。从代理的角度来看，没有任何变化。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;在本地运行&amp;quot;和&amp;quot;在生产中运行&amp;quot;之间的距离历来对 AI 代理来说既漫长又痛苦。Foundry Hosted Agents + MAF 显著缩小了这一差距。如果您已经有了用 Agent Framework 构建的本地代理，今天就值得一试。&lt;/p&gt;
&lt;p&gt;团队说 GA 即将到来 — 目前处于预览阶段。查看 &lt;a href="https://learn.microsoft.com/en-us/agent-framework/hosting/foundry-hosted-agent"&gt;MAF Hosted Agent 集成文档&lt;/a&gt; 和 &lt;a href="https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/04-hosting/FoundryHostedAgents"&gt;.NET 示例&lt;/a&gt; 开始使用。&lt;/p&gt;
&lt;p&gt;原始文章: &lt;a href="https://devblogs.microsoft.com/agent-framework/from-local-to-production-deploy-your-microsoft-agent-framework-agent-with-foundry-hosted-agents/"&gt;From Local to Production: Deploy Your Microsoft Agent Framework Agent with Foundry Hosted Agents&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>构建智能体是容易的部分——安全运行它们才是难的部分</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-agent-governance-toolkit-runtime-policy/</link><pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/maf-agent-governance-toolkit-runtime-policy/</guid><description>Microsoft Agent Framework 与 Agent Governance Toolkit 协同工作，在运行时执行策略、管理工具调用并提供 Merkle 链式审计日志——无需修改智能体提示词。</description><content:encoded>&lt;p&gt;在 AI 智能体开发中，有一个我开始称为&amp;quot;演示后悔&amp;quot;的模式。智能体在演示中运行良好。然后有人问：如果它调用了错误的工具会怎样？如果它访问了不该访问的数据？谁审计了这个？&lt;/p&gt;
&lt;p&gt;Microsoft Agent Framework 为构建和编排提供支持。Agent Governance Toolkit（AGT）覆盖之后的部分——治理、策略执行以及运行时可审计性。&lt;/p&gt;
&lt;h2 id="每个项目的实际用途"&gt;每个项目的实际用途&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Agent Framework (MAF)&lt;/strong&gt; 提供编程模型：多智能体工作流、A2A 协议互操作性、中间件钩子、内存以及通过 Foundry Agent Service 进行托管。它在模型输入/输出层面处理内容安全。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agent Governance Toolkit (AGT)&lt;/strong&gt; 插入相同的中间件管道以管理&lt;em&gt;操作&lt;/em&gt;。每次工具调用、资源访问和智能体间消息在执行前都会根据策略进行评估。亚毫秒级开销。无 sidecar，无代理，无修改的提示词。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;智能体操作 --&amp;gt; 策略检查 --&amp;gt; 允许 / 拒绝 --&amp;gt; 审计日志 (&amp;lt; 0.1 ms)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;不同层次，完整覆盖，一个管道。&lt;/p&gt;
&lt;h2 id="接入只需添加中间件"&gt;接入只需添加中间件&lt;/h2&gt;
&lt;p&gt;在 Python 中，AGT 添加到与日志记录或内容过滤器相同的 &lt;code&gt;middleware&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&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;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;OpenAIChatClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-5.3&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="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Contoso Loan Officer&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;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a governed loan 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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;check_credit_score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_loan_rates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;approve_small_loan&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;middleware&lt;/span&gt;&lt;span class="o"&gt;=&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;AuditTrailMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audit_log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;audit_log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_did&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;loan-agent&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;GovernancePolicyMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evaluator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;evaluator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;audit_log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;audit_log&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;CapabilityGuardMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allowed_tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;check_credit_score&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;get_loan_rates&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;RogueDetectionMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;loan-agent&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="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 .NET 中，通过 &lt;code&gt;.Use()&lt;/code&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="kt"&gt;var&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;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BuildAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;gpt-5.3&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 class="n"&gt;Use&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;GovernancePolicyMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evaluator&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;Use&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;CapabilityGuardMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allowedTools&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;Use&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;AuditTrailMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auditLog&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;相同的智能体，相同的编排，相同的工具。AGT 在不修改智能体逻辑的情况下添加治理能力。&lt;/p&gt;
&lt;h2 id="你能获得什么"&gt;你能获得什么&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GovernancePolicyMiddleware&lt;/strong&gt; — 根据声明式策略规则评估每个操作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CapabilityGuardMiddleware&lt;/strong&gt; — 白名单规定智能体允许调用哪些工具（上面 &lt;code&gt;approve_small_loan&lt;/code&gt; 工具故意不在允许列表中）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RogueDetectionMiddleware&lt;/strong&gt; — 在运行时检测异常行为模式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AuditTrailMiddleware&lt;/strong&gt; — Merkle 链式审计日志，使每个操作在密码学上防篡改&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后一点对合规性很重要。Merkle 链意味着如果有人修改日志，链就会断裂。审计即证据。&lt;/p&gt;
&lt;h2 id="五个行业场景"&gt;五个行业场景&lt;/h2&gt;
&lt;p&gt;AGT 代码库包含五个完整的端到端场景：金融服务（贷款专员）、医疗（患者数据）、法律（合同审查）、政府（公民服务）和制造（质量控制）。每个场景都将真实的 MAF 智能体与真实的 AGT 治理中间件配对。&lt;/p&gt;
&lt;p&gt;这些不是玩具演示。它们是您在生产中实际需要治理的那类场景。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;如果您正在构建涉及真实数据、做出有后果决策或在生产中无人监管运行的智能体——治理不是可选的。MAF + AGT 的组合提供完整的技术栈：用 Agent Framework 构建，用 AGT 治理。&lt;/p&gt;
&lt;p&gt;两个项目都是开源的。原文包含完整代码示例的链接。&lt;/p&gt;
&lt;p&gt;原文链接：&lt;a href="https://devblogs.microsoft.com/agent-framework/governance-at-the-speed-of-agents-microsoft-agent-framework-and-agent-governance-toolkit-better-together/"&gt;Governance at the Speed of Agents: Microsoft Agent Framework and Agent Governance Toolkit, Better Together&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Foundry Local 1.1：实时转录、Embeddings 和 Responses API</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-local-11-transcription-embeddings-responses-api/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-local-11-transcription-embeddings-responses-api/</guid><description>Foundry Local 1.1 新增实时麦克风转录、文本 embeddings 和 Responses API 支持——全部在本地运行，无云依赖、无网络延迟、无每令牌费用。</description><content:encoded>&lt;p&gt;Foundry Local 1.0 已证明了这一概念：通过开发者友好的 SDK 在 Windows、macOS（Apple Silicon）和 Linux x64 上本地运行 AI 模型。1.1 版本新增三项功能，涵盖了许多真实的生产用例。&lt;/p&gt;
&lt;h2 id="实时音频转录"&gt;实时音频转录&lt;/h2&gt;
&lt;p&gt;最重要的新功能：直接从麦克风进行实时语音转文字流式处理。字幕、语音 UI、会议转录、无障碍工具——全部在本地运行，无任何云依赖。&lt;/p&gt;
&lt;p&gt;API 基于会话，结果一到达即流式传输，使用 &lt;code&gt;is_final&lt;/code&gt; 标记区分中间文本和最终文本。适用于所有语言绑定：JavaScript、C#、Python 和 Rust。&lt;/p&gt;
&lt;p&gt;从目录加载流式语音模型，使用音频设置（采样率、声道、语言）创建会话，启动它，推送原始 PCM 音频块，并消费结果的异步流。文章中有完整的 Python 和 C# 示例。&lt;/p&gt;
&lt;h2 id="文本-embeddings"&gt;文本 Embeddings&lt;/h2&gt;
&lt;p&gt;语义搜索、RAG 管道、聚类、相似性匹配——这些都需要 embeddings。Foundry Local 1.1 新增 embedding 模型支持，让你可以直接从同一 SDK 本地生成向量，无需将数据发送到云端。&lt;/p&gt;
&lt;p&gt;对于数据驻留地很重要或需要处理敏感内容的应用程序，本地 embedding 生成是一项有意义的功能。&lt;/p&gt;
&lt;h2 id="responses-api"&gt;Responses API&lt;/h2&gt;
&lt;p&gt;Foundry Local 现已支持 &lt;a href="https://platform.openai.com/docs/api-reference/responses"&gt;Responses API&lt;/a&gt;——专为代理式交互设计的结构化接口。这新增了：&lt;/p&gt;
&lt;ul&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;与标准 API 格式兼容，因此针对 OpenAI Responses API 的现有 agent 可以直接对接本地模型&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="包大小改进"&gt;包大小改进&lt;/h2&gt;
&lt;p&gt;两项更改减少了 JavaScript 包大小：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;koffi&lt;/code&gt; FFI 层已替换为自定义 Node-API C 插件&lt;/li&gt;
&lt;li&gt;WebGPU 执行提供程序作为单独插件提供，不需要 GPU 加速的应用无需承担额外的大小开销&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C# SDK 现在针对更低的框架版本，以获得更广泛的 .NET 兼容性。&lt;/p&gt;
&lt;h2 id="为什么重要"&gt;为什么重要&lt;/h2&gt;
&lt;p&gt;三项功能组合——转录、embeddings、工具调用——涵盖了许多 AI 应用程序的核心构建块。在本地运行它们意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无需互联网&lt;/li&gt;
&lt;li&gt;无每令牌费用&lt;/li&gt;
&lt;li&gt;数据不离开设备&lt;/li&gt;
&lt;li&gt;无论网络状况如何，延迟保持一致&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Foundry Local 是边缘场景、隐私敏感工作负载、离线应用程序或任何希望在开发过程中避免云依赖的场景的正确选择。&lt;/p&gt;
&lt;p&gt;原文：&lt;a href="https://devblogs.microsoft.com/foundry/foundry-local-v1-1/"&gt;Foundry Local 1.1: Live Transcription, Embeddings, and Responses API&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Cosmos DB Shell 现已推出公共预览版 — 并且内置了 MCP 服务器</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/cosmosdb-shell-public-preview-mcp-server-cli/</link><pubDate>Sun, 24 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/cosmosdb-shell-public-preview-mcp-server-cli/</guid><description>Azure Cosmos DB Shell 是一款新的开源 CLI，将数据库命令作为 MCP 工具公开。您的 AI 代理可以使用与您相同的界面导航容器、运行查询和管理数据。</description><content:encoded>&lt;p&gt;如果您曾经为了回答一个关于 Cosmos DB 的问题，不得不在门户标签页、SDK 示例和半成品脚本之间来回切换，那么您已经了解这个项目旨在消除的摩擦。&lt;/p&gt;
&lt;p&gt;Azure Cosmos DB Shell 刚刚进入公共预览版。这是一个具有类 bash 语法的开源 CLI，还有——让它变得有趣的部分——一个内置的 MCP 服务器。&lt;/p&gt;
&lt;h2 id="与其他数据库-cli-的不同之处"&gt;与其他数据库 CLI 的不同之处&lt;/h2&gt;
&lt;p&gt;CLI 本身很有用：熟悉的命令、脚本支持、CI/CD 集成。这部分是面向开发者的数据库工具的最低要求。&lt;/p&gt;
&lt;p&gt;有趣的部分是 MCP 服务器集成。CLI 公开的每个命令都可以作为 AI 代理可以调用的 MCP 工具。没有自定义 API 层，没有需要编写的集成代码。您的代理可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;cd&lt;/code&gt;、&lt;code&gt;ls&lt;/code&gt;、&lt;code&gt;pwd&lt;/code&gt; 导航数据库层次结构&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;query&lt;/code&gt; 执行 SQL 查询并获取结构化结果&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;create item&lt;/code&gt;、&lt;code&gt;update&lt;/code&gt;、&lt;code&gt;rm&lt;/code&gt; 创建和修改项目&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;mkdb&lt;/code&gt;、&lt;code&gt;mkcon&lt;/code&gt;、&lt;code&gt;rmdb&lt;/code&gt;、&lt;code&gt;rmcon&lt;/code&gt; 管理数据库和容器&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;endpoint&lt;/code&gt;、&lt;code&gt;pwd&lt;/code&gt; 检查当前上下文&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关键变化：您的代理不是在与 Cosmos DB API 交互——而是在与您使用的相同 shell 界面交互。命令是确定性的、可审计的，并且是开源的，因此您可以检查确切发生了什么。&lt;/p&gt;
&lt;h2 id="开源基础很重要"&gt;开源基础很重要&lt;/h2&gt;
&lt;p&gt;这不是一个黑箱托管服务。Shell 是开源的，这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安全团队可以审计实现&lt;/li&gt;
&lt;li&gt;平台团队可以 fork 并根据其特定标准进行扩展&lt;/li&gt;
&lt;li&gt;开发者可以贡献对所有人有益的改进&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于采用 AI 工具的企业团队来说，&amp;ldquo;我们能确切看到它是如何工作的吗&amp;quot;越来越不是可选要求。这里的开源是一个重要的差异化因素。&lt;/p&gt;
&lt;h2 id="三个变得更容易的场景"&gt;三个变得更容易的场景&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;智能数据分析&lt;/strong&gt; — 将代理连接到 shell，用自然语言提问，获取结构化查询结果。代理处理查询构建；shell 处理执行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自主数据管理&lt;/strong&gt; — 需要在 Cosmos DB 中创建、更新或删除数据的工作流可以通过 MCP 工具完成，无需自定义集成。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实时监控和警报&lt;/strong&gt; — 代理可以定期查询容器，比较结果，并通过任何有意义的通知渠道报告异常。&lt;/p&gt;
&lt;p&gt;MCP 接口使这些场景可以与任何支持 MCP 的 AI 平台组合——不仅仅是微软的工具。&lt;/p&gt;
&lt;h2 id="入门"&gt;入门&lt;/h2&gt;
&lt;p&gt;Shell 处于公共预览阶段。安装它，配置您的 Cosmos DB 连接，并启用 MCP 服务器。从那里，任何 MCP 兼容的代理宿主都可以发现并使用这些工具。&lt;/p&gt;
&lt;p&gt;原始文章：&lt;a href="https://devblogs.microsoft.com/cosmosdb/azure-cosmos-db-shell-public-preview-ai-mcp-cli/"&gt;Announcing the Public Preview of Azure Cosmos DB Shell: Open-Source Power Meets AI-Driven Database Automation&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Azure SQL 现在可以生成嵌入向量了 — 纯 T-SQL，无需应用层</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-sql-ai-generate-embeddings-ga-rag-tsql/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-sql-ai-generate-embeddings-ga-rag-tsql/</guid><description>AI_GENERATE_EMBEDDINGS 和 CREATE EXTERNAL MODEL 现已在 Azure SQL Database 和 Managed Instance 中正式发布。完全用 T-SQL 构建的 RAG 管道，无需数据移动。</description><content:encoded>&lt;p&gt;如果你曾经构建过 RAG 管道，你就知道管道税：你的数据存在于 SQL 中，但要生成嵌入向量，你需要提取数据、调用嵌入 API、处理批处理和速率限制，并将结果存储到支持向量搜索的地方。通常是在完全不同的数据库中。&lt;/p&gt;
&lt;p&gt;Azure SQL 刚刚通过两个现已正式发布的功能消除了大部分这些问题：&lt;code&gt;CREATE EXTERNAL MODEL&lt;/code&gt; 和 &lt;code&gt;AI_GENERATE_EMBEDDINGS&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="它们的作用"&gt;它们的作用&lt;/h2&gt;
&lt;p&gt;这两个 T-SQL 功能作为集成管道工作：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;CREATE EXTERNAL MODEL&lt;/code&gt;&lt;/strong&gt; — 将外部 AI 模型端点注册为命名数据库对象。你只需设置一次位置、API 格式、模型类型和凭据。随处可重用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;AI_GENERATE_EMBEDDINGS&lt;/code&gt;&lt;/strong&gt; — 一个标量 T-SQL 函数，调用注册的模型并返回向量值的 JSON 数组。可在 SELECT、INSERT、UPDATE 和 MERGE 语句中使用。&lt;/p&gt;
&lt;p&gt;它们共同形成端到端的嵌入管道，无需离开 SQL 引擎。&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-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 步骤 1：一次性注册嵌入提供程序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;EXTERNAL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyEmbeddingModel&lt;/span&gt;&lt;span class="w"&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;WITH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;LOCATION&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://your-aoai-resource.openai.azure.com/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;API_FORMAT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Azure OpenAI&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MODEL_TYPE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EMBEDDINGS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;text-embedding-ada-002&amp;#39;&lt;/span&gt;&lt;span class="w"&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="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&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;-- 步骤 2：在 T-SQL 中内联生成嵌入
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="w"&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;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AI_GENERATE_EMBEDDINGS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyEmbeddingModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&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;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&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;-- 步骤 3：用向量距离搜索
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TOP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="w"&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;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="w"&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;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VECTOR_DISTANCE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cosine&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AI_GENERATE_EMBEDDINGS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;USE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyEmbeddingModel&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这就是整个管道：SQL 中的数据、SQL 中生成的嵌入、SQL 中的相似性搜索。没有编排层，没有 ETL，没有单独的向量数据库。&lt;/p&gt;
&lt;h2 id="支持的-api-格式和选项"&gt;支持的 API 格式和选项&lt;/h2&gt;
&lt;p&gt;正式发布时，&lt;code&gt;API_FORMAT&lt;/code&gt; 支持 &lt;strong&gt;Azure OpenAI&lt;/strong&gt; 和 &lt;strong&gt;OpenAI&lt;/strong&gt;。&lt;code&gt;MODEL_TYPE&lt;/code&gt; 目前固定为 &lt;code&gt;EMBEDDINGS&lt;/code&gt;。&lt;code&gt;PARAMETERS&lt;/code&gt; JSON 允许设置模型级别的默认值，包括重试次数：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;PARAMETERS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{&amp;#34;sql_rest_options&amp;#34;:{&amp;#34;retry_count&amp;#34;:3}}&amp;#39;&lt;/span&gt;&lt;span class="w"&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="这为-net-应用程序带来了什么"&gt;这为 .NET 应用程序带来了什么&lt;/h2&gt;
&lt;p&gt;对于在现有 SQL 数据上构建 AI 功能的 .NET 开发者来说，这意义重大。你不需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为嵌入将数据提取到中间存储&lt;/li&gt;
&lt;li&gt;管理外部嵌入管道&lt;/li&gt;
&lt;li&gt;设置单独的向量数据库（如果你想要全功能的向量存储，可以使用 Azure AI Search）&lt;/li&gt;
&lt;li&gt;更改应用程序的数据访问层&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以使用已有的相同 T-SQL 工具，逐步向现有 SQL 应用程序添加语义搜索。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;SQL 数据上的 RAG 模式变得简单多了。&lt;code&gt;AI_GENERATE_EMBEDDINGS&lt;/code&gt; + &lt;code&gt;CREATE EXTERNAL MODEL&lt;/code&gt; 意味着你现有的 SQL 应用程序可以在不添加新基础设施的情况下获得向量搜索功能。&lt;/p&gt;
&lt;p&gt;这两个功能今天在 Azure SQL Database 和 Azure SQL Managed Instance 中已正式发布。&lt;/p&gt;
&lt;p&gt;原始帖子：&lt;a href="https://devblogs.microsoft.com/azure-sql/generate-embeddings-function-and-external-model-object-support-are-now-generally-available-in-azure-sql/"&gt;Generate Embeddings Function and External Model Object Support Are Now Generally Available in Azure SQL&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>您的 AI 代理有一个身份问题（这是解决它的模板）</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azd-least-privilege-ai-agents-oauth-token-pattern/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azd-least-privilege-ai-agents-oauth-token-pattern/</guid><description>Curity 和 Microsoft 的新 azd 模板展示了如何构建使用具有精细作用域的短期 OAuth 令牌的 AI 代理——这样代理永远无法看到它们不应该看到的数据。</description><content:encoded>&lt;p&gt;在每个 AI 代理项目中都有这样一个时刻：演示完美运行，代理解释自然语言，调用正确的 API，返回正确的数据。然后你开始思考真实用户。&lt;/p&gt;
&lt;p&gt;什么能阻止一个用户的代理会话看到另一个用户的数据？如果代理通过提示注入被欺骗会怎样？如果它以意外的方式调用工具会怎样？&lt;/p&gt;
&lt;p&gt;这些不是边缘情况。这些是你需要在发布之前做出的设计决策。&lt;/p&gt;
&lt;p&gt;Curity 和 Microsoft 的新 &lt;code&gt;azd&lt;/code&gt; 模板为您提供了针对这个问题的可工作参考。&lt;/p&gt;
&lt;h2 id="核心问题身份验证--授权"&gt;核心问题：身份验证 ≠ 授权&lt;/h2&gt;
&lt;p&gt;大多数代理示例都很好地处理了用户身份验证。它们对授权处理得很差。知道用户是&lt;em&gt;谁&lt;/em&gt;并不能告诉你他们应该看到&lt;em&gt;什么数据&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;传统客户端应用程序进行可预测的 API 调用。AI 代理是不确定性的——它解释自然语言并决定调用什么。它可以很有创意。它也可能出错。如果通过提示注入被操纵，你需要不依赖于 AI 良好行为的规则。&lt;/p&gt;
&lt;p&gt;这个模板演示的解决方案：&lt;strong&gt;为每一跳携带正确信息的短期令牌&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="令牌链如何工作"&gt;令牌链如何工作&lt;/h2&gt;
&lt;p&gt;该模板使用带有令牌交换的 OAuth 2.0 访问令牌，在每个步骤缩小权限。用户令牌在到达 MCP 服务器之前会被交换两次：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;第一次交换&lt;/strong&gt; — 缩小作用域并将不透明令牌转换为 JWT&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第二次交换&lt;/strong&gt; — 添加代理身份和 MCP 服务器跳的新受众&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;MCP 服务器令牌的样子：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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="nt"&gt;&amp;#34;scope&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;stocks/read&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="nt"&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;62c839b8...&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="nt"&gt;&amp;#34;aud&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://mcp.demo.example&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="nt"&gt;&amp;#34;customer_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;178&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="nt"&gt;&amp;#34;region&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;USA&amp;#34;&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;customer_id&lt;/code&gt; 由授权服务器嵌入令牌中，而不是作为代理控制的参数传递。API 检查令牌，而不是代理的指令。&lt;/p&gt;
&lt;p&gt;这意味着：即使有人欺骗代理尝试获取另一个客户的数据，令牌也不会授权它。&lt;/p&gt;
&lt;h2 id="模板部署什么"&gt;模板部署什么&lt;/h2&gt;
&lt;p&gt;用几个 &lt;code&gt;azd&lt;/code&gt; 命令，您将获得：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft Foundry 上的后端代理（C#、Microsoft A2A 和 MCP SDK）&lt;/li&gt;
&lt;li&gt;公开示例投资组合 API 的 MCP 服务器&lt;/li&gt;
&lt;li&gt;Curity Identity Server 作为授权服务器，以及用于身份验证的 Entra ID&lt;/li&gt;
&lt;li&gt;处理令牌交换和审计日志的外部和内部 API 网关&lt;/li&gt;
&lt;li&gt;所有 Azure 基础设施的 Bicep：Container Apps、VNet、ACR、Azure AI Foundry、Key Vault、Azure SQL Database、存储&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整个模式是可检查和可定制的。&lt;/p&gt;
&lt;h2 id="值得借鉴的设计原则"&gt;值得借鉴的设计原则&lt;/h2&gt;
&lt;p&gt;即使您不使用 Curity，该模式也是可转移的：&lt;strong&gt;代理永远不应该拥有永久 API 访问权限&lt;/strong&gt;。每个操作都应使用仅具有该特定调用所需最小作用域的短期令牌，为特定代理身份颁发，携带 API 进行授权决策所需的声明。&lt;/p&gt;
&lt;p&gt;这能抵御创意代理、错误和提示注入，而&amp;quot;只要确保代理不做坏事&amp;quot;永远做不到这一点。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;AI 代理的安全模式在整个行业中仍在研究中。这个模板是我见过的最完整的参考实现之一——它涵盖了实际的授权流程，而不仅仅是身份验证。&lt;/p&gt;
&lt;p&gt;原始文章：&lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-curity-least-privilege-ai-agents/"&gt;Least privilege AI agents: A new azd template from Curity and Microsoft&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.3：Kubernetes 支持、浏览器日志和 Aspireify 技能</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-133-kubernetes-browser-logs-aspireify/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-133-kubernetes-browser-logs-aspireify/</guid><description>13.2 发布五周后，Aspire 13.3 带来 45 项新功能，包括一流的 AKS 部署、AI 辅助的入门技能、浏览器日志捕获和结构化命令结果。</description><content:encoded>&lt;p&gt;五周对于一个版本来说并不长，但 Aspire 13.3 让人感觉不是这样。主要内容非常重要：使用 Helm 进行 Kubernetes 和 AKS 一流部署、名为 Aspireify 的代理辅助入门技能、直接在仪表板中捕获浏览器日志，以及结构化命令结果。还包括 45 项新功能、134 项改进和 93 个错误修复。&lt;/p&gt;
&lt;p&gt;让我们来看看亮点。&lt;/p&gt;
&lt;h2 id="aspireify代理辅助入门"&gt;Aspireify：代理辅助入门&lt;/h2&gt;
&lt;p&gt;将 Aspire 添加到现有项目听起来很简单——添加 AppHost，完成。实际上需要大量研究：哪些端口重要、哪些环境变量是真正的依赖项、哪些 Docker Compose 服务应该映射到 Aspire 集成。&lt;/p&gt;
&lt;p&gt;新的 &lt;strong&gt;Aspireify 技能&lt;/strong&gt; 正是为此为您的编码代理提供了引导工作流程。当 &lt;code&gt;aspire init&lt;/code&gt; 创建骨架 AppHost 时，Aspireify 技能会帮助代理检查存储库、了解其已有的工作方式，并连接 AppHost 以适应应用程序——而不是反过来。&lt;/p&gt;
&lt;p&gt;默认立场是&amp;quot;最小化对代码的更改&amp;quot;。如果您的应用程序已经读取 &lt;code&gt;DATABASE_URL&lt;/code&gt;，代理会使用 &lt;code&gt;WithEnvironment()&lt;/code&gt; 进行映射，而不是要求您重写配置。如果端口是硬编码的，该技能会告诉代理何时保留它。&lt;/p&gt;
&lt;p&gt;这正是那种能真正节省时间而不是生成更多审查工作的 AI 工具。&lt;/p&gt;
&lt;h2 id="一流的-kubernetes-和-aks-部署"&gt;一流的 Kubernetes 和 AKS 部署&lt;/h2&gt;
&lt;p&gt;这在愿望清单上已经有一段时间了。Aspire 13.3 提供了&lt;strong&gt;使用 Helm 的 Kubernetes 和 AKS 一流部署支持&lt;/strong&gt;。您现在可以直接从 Aspire 工具中将 AKS 指定为部署目标。&lt;/p&gt;
&lt;p&gt;对于已经在 AKS 上运行生产工作负载的团队，这弥补了一个重要缺口。您的 Aspire 应用模型现在有了从本地开发到 Kubernetes 的清晰路径，无需手动编写 Helm 图表。&lt;/p&gt;
&lt;h2 id="仪表板中的浏览器日志"&gt;仪表板中的浏览器日志&lt;/h2&gt;
&lt;p&gt;这是那些在调试前端问题之前看起来很小的功能之一。&lt;/p&gt;
&lt;p&gt;新的 &lt;code&gt;WithBrowserLogs()&lt;/code&gt; API 将跟踪的浏览器资源附加到任何支持端点的资源。Aspire 使用私有 CDP 管道启动 Chromium，并将控制台日志、网络请求和错误直接流式传输到资源的日志流中：&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;frontend&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;AddViteApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;../frontend&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 class="n"&gt;WithHttpEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&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;WithBrowserLogs&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;TypeScript AppHost 同样支持：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frontend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addViteApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;../frontend&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 class="nx"&gt;withHttpEndpoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;: &lt;span class="kt"&gt;3000&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="nx"&gt;withBrowserLogs&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;控制台错误、失败的网络请求、客户端异常——所有这些都在您已经观察追踪和指标的同一仪表板中可见。不再需要为了基础内容切换到浏览器 DevTools。&lt;/p&gt;
&lt;h2 id="结构化命令结果"&gt;结构化命令结果&lt;/h2&gt;
&lt;p&gt;资源命令获得了重大升级。到目前为止，命令返回成功/失败。现在它们返回结构化结果：流经模型、仪表板 UI、CLI 和 MCP 工具的文本、JSON 或 Markdown。&lt;/p&gt;
&lt;p&gt;仪表板通过标题中的新通知中心将这一切联系在一起。命令结果以带时间戳的通知形式出现，带有 Markdown 渲染和&amp;quot;查看响应&amp;quot;操作。&lt;/p&gt;
&lt;p&gt;这使资源命令真正可组合。集成现在可以公开一个返回有意义输出的命令——比如隧道 URL——而不仅仅是在某处更改状态。&lt;/p&gt;
&lt;h2 id="结论"&gt;结论&lt;/h2&gt;
&lt;p&gt;Aspire 13.3 仅凭 Kubernetes 支持就值得升级。浏览器日志和结构化命令结果感觉像是那种在日常开发工作流程中快速积累的生活质量改进。&lt;/p&gt;
&lt;p&gt;完整发布说明：&lt;a href="https://devblogs.microsoft.com/aspire/whats-new-aspire-13-3/"&gt;What&amp;rsquo;s New in Aspire 13.3&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>SDD Conference 2026</title><link>https://thedotnetblog.com/zh/events/sdd-conference-2026/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/zh/events/sdd-conference-2026/</guid><description>在伦敦 Barbican Centre 举办的5天软件开发大会，78场演讲和14场工作坊，涵盖架构、.NET、AI、Azure、DevOps 等主题。</description><content:encoded>&lt;p&gt;&lt;strong&gt;SDD 2026&lt;/strong&gt; 于 &lt;strong&gt;2026年5月11日至15日&lt;/strong&gt; 在 &lt;strong&gt;伦敦 Barbican Centre&lt;/strong&gt; 举办。为期3天的核心大会从周二到周四，周一和周五有可选的全天工作坊。&lt;/p&gt;
&lt;p&gt;拥有 &lt;strong&gt;78场演讲&lt;/strong&gt; 和 &lt;strong&gt;14场工作坊&lt;/strong&gt;，是欧洲内容最丰富的开发者大会之一。&lt;/p&gt;
&lt;h2 id="主题"&gt;主题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;架构思维&lt;/li&gt;
&lt;li&gt;C# 13 中的函数式代码&lt;/li&gt;
&lt;li&gt;无服务器设计&lt;/li&gt;
&lt;li&gt;语义 AI&lt;/li&gt;
&lt;li&gt;Azure Kubernetes Services&lt;/li&gt;
&lt;li&gt;精益 DevOps 策略&lt;/li&gt;
&lt;li&gt;模型上下文协议 (MCP)&lt;/li&gt;
&lt;li&gt;.NET 中的智能代理 AI&lt;/li&gt;
&lt;li&gt;重构单体应用&lt;/li&gt;
&lt;li&gt;使用 LLM 更快编程&lt;/li&gt;
&lt;li&gt;后量子世界中的密码学&lt;/li&gt;
&lt;li&gt;本地优先开发&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="演讲者"&gt;演讲者&lt;/h2&gt;
&lt;p&gt;世界级阵容包括 &lt;strong&gt;Kevlin Henney&lt;/strong&gt;、&lt;strong&gt;Neal Ford&lt;/strong&gt;、&lt;strong&gt;Sander Hoogendoorn&lt;/strong&gt;、&lt;strong&gt;Andrew Clymer&lt;/strong&gt;、&lt;strong&gt;Jacqui Read&lt;/strong&gt;、&lt;strong&gt;Christian Weyer&lt;/strong&gt;、&lt;strong&gt;Jeff Prosise&lt;/strong&gt;、&lt;strong&gt;Jules May&lt;/strong&gt;、&lt;strong&gt;Oliver Sturm&lt;/strong&gt; 和 &lt;strong&gt;Raju Gandhi&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="门票和信息"&gt;门票和信息&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sddconf.com/"&gt;活动网站&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sddvault.s3.amazonaws.com/assets/SDD_2026_schedule.pdf"&gt;完整议程 PDF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sddconf.com/register"&gt;注册选项&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;98%的 SDD 2025 参会者将整体体验评为&amp;quot;好&amp;quot;、&amp;ldquo;非常好&amp;quot;或&amp;quot;优秀&amp;rdquo;。&lt;/p&gt;</content:encoded></item><item><title>使用.NET可组合技术栈构建AI驱动的会议应用</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/ai-conference-app-dotnet-composable-stack/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/ai-conference-app-dotnet-composable-stack/</guid><description>Microsoft构建了ConferencePulse——一个通过组合Microsoft.Extensions.AI、DataIngestion、VectorData、MCP和Agent Framework打造的实时会议Blazor应用。以下是各部分如何组合在一起的说明。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。要查看原始版本，&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/ai-conference-app-dotnet-composable-stack/"&gt;请点击此处&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/building-ai-conference-app-dotnet-composable-stack/"&gt;使用.NET可组合技术栈构建AI驱动的会议应用&lt;/a&gt; — Microsoft通过组合五个.NET扩展库，构建了ConferencePulse——一个用于实时会议演讲的Blazor Server应用。该应用在MVP Summit上投入使用。&lt;/p&gt;
&lt;h2 id="conferencepulse的功能"&gt;ConferencePulse的功能&lt;/h2&gt;
&lt;p&gt;ConferencePulse在实时演讲期间运行，提供以下功能：根据演讲内容AI生成的投票、通过RAG管道从实时知识库提取信息的观众问答、自动生成的洞察，以及由多个并发AI代理生成的演讲摘要。技术栈为.NET 10、Blazor Server、Aspire，分为五个项目：Web、Core、Ingestion、Agents、Mcp和AppHost。&lt;/p&gt;
&lt;h2 id="microsoftextensionsai万物的统一抽象"&gt;Microsoft.Extensions.AI：万物的统一抽象&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;IChatClient&lt;/code&gt;是统一的抽象层——配置一次，同一接口可用于Azure OpenAI、OpenAI、Anthropic或任何其他提供商。六行代码即可获得具备函数调用、OpenTelemetry追踪和日志中间件的完整配置客户端：&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;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddChatClient&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 class="n"&gt;GetChatClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gpt-4o&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 class="n"&gt;UseFunctionInvocation&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;UseOpenTelemetry&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;UseLogging&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;IChatClient&lt;/code&gt;在后续数据摄取的增强步骤中被复用——无需为此创建单独的客户端。&lt;/p&gt;
&lt;h2 id="dataingestion管道"&gt;DataIngestion管道&lt;/h2&gt;
&lt;p&gt;演讲内容通过管道流转：&lt;code&gt;MarkdownReader&lt;/code&gt; → &lt;code&gt;HeaderChunker&lt;/code&gt;（500个token，50个token重叠）→ &lt;code&gt;SummaryEnricher&lt;/code&gt; + &lt;code&gt;KeywordEnricher&lt;/code&gt; → &lt;code&gt;VectorStoreWriter&lt;/code&gt;（Qdrant）。增强器使用同一个&lt;code&gt;IChatClient&lt;/code&gt;在索引前生成摘要并提取关键词。观众问题、问答对和投票结果在演讲进行期间实时摄取——知识库在演讲过程中持续增长。&lt;/p&gt;
&lt;h2 id="vectordata与提供商无关的搜索"&gt;VectorData：与提供商无关的搜索&lt;/h2&gt;
&lt;p&gt;无论底层存储是Qdrant还是Azure AI Search，&lt;code&gt;VectorStoreCollection.SearchAsync()&lt;/code&gt;的工作方式相同。支持混合搜索（向量+全文检索）。观众问答的RAG管道查询该集合，获取相关文本块作为上下文传递给聊天客户端。&lt;/p&gt;
&lt;h2 id="mcp作为工具的演讲内容"&gt;MCP：作为工具的演讲内容&lt;/h2&gt;
&lt;p&gt;演讲内容通过MCP公开，任何兼容MCP的客户端都可以访问。服务器和客户端均已实现——服务器将演讲知识作为MCP工具公开，客户端允许在代理管道中调用这些工具。&lt;/p&gt;
&lt;h2 id="agent-framework并行多代理摘要"&gt;Agent Framework：并行多代理摘要&lt;/h2&gt;
&lt;p&gt;演讲摘要由三个并发运行的代理生成——&lt;code&gt;PollSummaryAgent&lt;/code&gt;、&lt;code&gt;QuestionSummaryAgent&lt;/code&gt;和&lt;code&gt;InsightSummaryAgent&lt;/code&gt;——然后合并。这使用了Microsoft Agent Framework的群聊或并行执行模式。每个代理处理一个关注点，编排器合并各代理的输出。&lt;/p&gt;
&lt;h2 id="设计原则"&gt;设计原则&lt;/h2&gt;
&lt;p&gt;文章提出了一个值得铭记的观点：使用最简单的适用工具。简单生成任务使用直接的&lt;code&gt;IChatClient&lt;/code&gt;调用；结构化数据提取使用工具/函数调用；只有在需要自主多步骤推理时才使用完整的代理。库的分层设计强制执行这一原则——你可以使用&lt;code&gt;Microsoft.Extensions.AI&lt;/code&gt;而无需引入完整的Agent Framework。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/dotnet/building-ai-conference-app-dotnet-composable-stack/"&gt;完整文章&lt;/a&gt;以获取完整的项目结构和源代码链接。&lt;/p&gt;</content:encoded></item><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>Agent Framework中的CodeAct：如何将智能体延迟减半</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</guid><description>CodeAct将多步骤工具链压缩为单个沙盒代码块——延迟降低52%，令牌使用量减少64%。了解它对您的智能体意味着什么以及何时使用它。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。如需阅读原文，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;在每个智能体项目中，都会有这样一个时刻：你查看追踪信息，心想：&amp;ldquo;为什么这要花这么长时间？&amp;ldquo;模型没问题，工具也能运行，但为了获得一个本可一步计算出的结果，却需要七次往返请求。&lt;/p&gt;
&lt;p&gt;这正是CodeAct解决的问题——&lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;Agent Framework团队刚刚发布了Alpha支持&lt;/a&gt;，通过新的&lt;code&gt;agent-framework-hyperlight&lt;/code&gt;包实现。&lt;/p&gt;
&lt;h2 id="什么是codeact"&gt;什么是CodeAct？&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/abs/2402.01030"&gt;CodeAct模式&lt;/a&gt;优雅而简单：不再给模型一个工具列表让它逐一调用，而是给它一个单一的&lt;code&gt;execute_code&lt;/code&gt;工具，让它将&lt;em&gt;整个计划&lt;/em&gt;表达为一个简短的Python程序。智能体只需编写一次代码，沙盒执行它，你就能得到一个统一的结果。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方式&lt;/th&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;令牌&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;传统方式&lt;/td&gt;
&lt;td&gt;27.81秒&lt;/td&gt;
&lt;td&gt;6,890&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeAct&lt;/td&gt;
&lt;td&gt;13.23秒&lt;/td&gt;
&lt;td&gt;2,489&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;提升&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;52.4%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;63.9%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="安全机制hyperlight微型虚拟机"&gt;安全机制：Hyperlight微型虚拟机&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;agent-framework-hyperlight&lt;/code&gt;包使用&lt;a href="https://github.com/hyperlight-dev/hyperlight"&gt;Hyperlight&lt;/a&gt;微型虚拟机。每次&lt;code&gt;execute_code&lt;/code&gt;调用都在一个全新的微型VM中运行。启动时间以毫秒计算。隔离几乎是免费的。&lt;/p&gt;
&lt;p&gt;你的工具仍在主机上运行。模型生成的&lt;em&gt;粘合代码&lt;/em&gt;在沙盒中运行。这是正确的分工。&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-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&lt;/span&gt; &lt;span class="kn"&gt;import&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;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&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_hyperlight&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&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="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;str&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="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Return the current weather for a city.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temperature_c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;21.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;conditions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;partly cloudy&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;codeact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&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;approval_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;never_require&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&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;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&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;CodeActAgent&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;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&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;context_providers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;codeact&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="何时使用codeact何时不用"&gt;何时使用CodeAct（何时不用）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;使用CodeAct的情况：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;任务需要链接许多小型工具调用（查询、连接、计算）&lt;/li&gt;
&lt;li&gt;延迟和令牌成本很重要&lt;/li&gt;
&lt;li&gt;需要对模型生成的代码进行强隔离&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;继续使用传统工具调用的情况：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;智能体每轮只进行一两次工具调用&lt;/li&gt;
&lt;li&gt;每次调用都有需要单独审批的副作用&lt;/li&gt;
&lt;li&gt;工具描述稀少或模糊&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="立即尝试"&gt;立即尝试&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;pip install agent-framework-hyperlight --pre
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;请查阅&lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;Agent Framework博客的完整文章&lt;/a&gt;获取更深入的介绍。&lt;/p&gt;</content:encoded></item><item><title>Azure MCP Server 现在是 .mcpb — 无需任何运行时即可安装</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/</guid><description>Azure MCP Server 现已作为 MCP Bundle (.mcpb) 提供 — 下载、拖入 Claude Desktop，完成。无需 Node.js、Python 或 .NET 运行时。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。如需查看原文，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;你知道配置 MCP 服务器有什么烦人的地方吗？需要运行时。npm 版需要 Node.js，pip/uvx 需要 Python，dotnet 版需要 .NET SDK。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-mcp-server-mcpb-support/"&gt;Azure MCP Server 刚刚改变了这一切&lt;/a&gt;。它现在作为 &lt;code&gt;.mcpb&lt;/code&gt; — MCP Bundle — 提供，配置方式是拖放。&lt;/p&gt;
&lt;h2 id="什么是-mcp-bundle"&gt;什么是 MCP Bundle？&lt;/h2&gt;
&lt;p&gt;把它想象成 VS Code 扩展（&lt;code&gt;.vsix&lt;/code&gt;）或浏览器扩展（&lt;code&gt;.crx&lt;/code&gt;），但用于 MCP 服务器。&lt;code&gt;.mcpb&lt;/code&gt; 文件是一个独立的 ZIP 存档，包含服务器二进制文件及其所有依赖项。&lt;/p&gt;
&lt;h2 id="如何安装"&gt;如何安装&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. 为你的平台下载 Bundle&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;前往 &lt;a href="https://github.com/microsoft/mcp/releases?q=Azure.Mcp.Server"&gt;GitHub Releases 页面&lt;/a&gt;，下载适合你 OS 和架构的 &lt;code&gt;.mcpb&lt;/code&gt; 文件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 在 Claude Desktop 中安装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最简单的方式：在扩展设置页面（&lt;code&gt;☰ → 文件 → 设置 → 扩展&lt;/code&gt;）打开时，将 &lt;code&gt;.mcpb&lt;/code&gt; 文件拖放到 Claude Desktop 窗口中。查看服务器详情，点击安装，确认。完成。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 向 Azure 进行身份验证&lt;/strong&gt;&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;az login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;就这样。Azure MCP Server 使用你现有的 Azure 凭据。&lt;/p&gt;
&lt;h2 id="能做什么"&gt;能做什么&lt;/h2&gt;
&lt;p&gt;直接从 AI 客户端访问 100 多个 Azure 服务工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查询和管理 Cosmos DB、Storage、Key Vault、App Service、Foundry&lt;/li&gt;
&lt;li&gt;为任何任务生成 &lt;code&gt;az&lt;/code&gt; CLI 命令&lt;/li&gt;
&lt;li&gt;创建 Bicep 和 Terraform 模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="开始使用"&gt;开始使用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;下载&lt;/strong&gt;: &lt;a href="https://github.com/microsoft/mcp/releases?q=Azure.Mcp.Server-"&gt;GitHub Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;仓库&lt;/strong&gt;: &lt;a href="https://aka.ms/azmcp"&gt;aka.ms/azmcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文档&lt;/strong&gt;: &lt;a href="https://aka.ms/azmcp/docs"&gt;aka.ms/azmcp/docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-mcp-server-mcpb-support/"&gt;完整文章&lt;/a&gt;。&lt;/p&gt;</content:encoded></item><item><title>GPT-5.5 已来到 Azure Foundry — .NET 开发者需要了解的一切</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/</guid><description>GPT-5.5 在 Microsoft Foundry 正式发布。从 GPT-5 到 5.5 的演进、真正改进了什么，以及今天如何在你的 Agent 中开始使用它。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。如需查看原文，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;微软刚刚宣布 &lt;a href="https://azure.microsoft.com/en-us/blog/openais-gpt-5-5-in-microsoft-foundry-frontier-intelligence-on-an-enterprise-ready-platform/"&gt;GPT-5.5 在 Microsoft Foundry 正式发布&lt;/a&gt;。如果你一直在 Azure 上构建 Agent，这就是你一直等待的更新。&lt;/p&gt;
&lt;h2 id="gpt-5-的演进"&gt;GPT-5 的演进&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPT-5&lt;/strong&gt;：将推理与速度统一到单一系统中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-5.4&lt;/strong&gt;：更强的多步推理，面向企业的早期 Agent 能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-5.5&lt;/strong&gt;：更深入的长上下文推理，更可靠的 Agent 执行，更好的 Token 效率&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="真正发生了什么变化"&gt;真正发生了什么变化&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Agent 编码改进&lt;/strong&gt;：GPT-5.5 在大型代码库中保持上下文，诊断架构级故障，并预测测试需求。模型在行动前推理&lt;em&gt;修复还会影响什么&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Token 效率&lt;/strong&gt;：更少的 Token 和更少的重试产生更高质量的输出。生产部署的成本和延迟直接降低。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;长上下文分析&lt;/strong&gt;：处理大量文档和多会话历史记录而不失去线索。&lt;/p&gt;
&lt;h2 id="定价"&gt;定价&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模型&lt;/th&gt;
&lt;th&gt;输入 ($/M tokens)&lt;/th&gt;
&lt;th&gt;缓存输入&lt;/th&gt;
&lt;th&gt;输出 ($/M tokens)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.5&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;$30.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.5 Pro&lt;/td&gt;
&lt;td&gt;$30.00&lt;/td&gt;
&lt;td&gt;$3.00&lt;/td&gt;
&lt;td&gt;$180.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="为什么-foundry-很重要"&gt;为什么 Foundry 很重要&lt;/h2&gt;
&lt;p&gt;Foundry Agent Service 允许你在 YAML 中定义 Agent，或与 Microsoft Agent Framework、GitHub Copilot SDK、LangGraph 或 OpenAI Agents SDK 连接——并将它们作为具有持久文件系统、独立 Microsoft Entra 身份和零扩展定价的隔离托管 Agent 运行。&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;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;aiProjectClient&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 class="s"&gt;&amp;#34;gpt-5.5&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&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;你是一个有用的助手。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&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;我的Agent&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;a href="https://azure.microsoft.com/en-us/blog/openais-gpt-5-5-in-microsoft-foundry-frontier-intelligence-on-an-enterprise-ready-platform/"&gt;完整公告&lt;/a&gt;了解所有详情。&lt;/p&gt;</content:encoded></item><item><title>你的 Agent 在哪里记住事情？聊天历史存储实践指南</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</guid><description>服务管理还是客户端管理？线性还是分叉？这个架构决策决定了你的 AI Agent 能做什么——附 C# 和 Python 代码示例。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。如需查看原文，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;在构建 AI Agent 时，你把大部分精力花在模型、工具和提示词上。&lt;em&gt;对话历史存储在哪里&lt;/em&gt;这个问题看起来像是实现细节——但实际上是你将做出的最重要的架构决策之一。&lt;/p&gt;
&lt;p&gt;它决定了用户能否分叉对话、撤销回答、重启后恢复会话，以及数据是否会离开你的基础设施。&lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;Agent Framework 团队发布了一篇深度分析&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="两种基本模式"&gt;两种基本模式&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;服务管理型&lt;/strong&gt;：AI 服务存储对话状态。你的应用保持一个引用，服务自动在每次请求中包含相关历史记录。更简单，控制更少。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;客户端管理型&lt;/strong&gt;：你的应用维护完整历史记录，并在每次请求时发送相关消息。服务无状态。你控制一切。&lt;/p&gt;
&lt;h2 id="agent-framework-如何抽象这一切"&gt;Agent Framework 如何抽象这一切&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 class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;first&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;我叫 Alice。&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 class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;second&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;我叫什么名字？&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;/code&gt;&lt;/pre&gt;&lt;/div&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;session&lt;/span&gt; &lt;span class="o"&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;create_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="n"&gt;first&lt;/span&gt; &lt;span class="o"&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;我叫 Alice。&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="o"&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="n"&gt;second&lt;/span&gt; &lt;span class="o"&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;我叫什么名字？&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="o"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Session 处理底层差异。无论切换什么提供商，应用代码不变。&lt;/p&gt;
&lt;h2 id="提供商快速参考"&gt;提供商快速参考&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;提供商&lt;/th&gt;
&lt;th&gt;存储位置&lt;/th&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;压缩&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI/Azure Chat Completions&lt;/td&gt;
&lt;td&gt;客户端&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;你&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foundry Agent Service&lt;/td&gt;
&lt;td&gt;服务端&lt;/td&gt;
&lt;td&gt;线性&lt;/td&gt;
&lt;td&gt;服务端&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responses API（默认）&lt;/td&gt;
&lt;td&gt;服务端&lt;/td&gt;
&lt;td&gt;分叉型&lt;/td&gt;
&lt;td&gt;服务端&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic Claude, Ollama&lt;/td&gt;
&lt;td&gt;客户端&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;你&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="如何选择"&gt;如何选择&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;需要分叉对话或&amp;quot;撤销&amp;quot;？&lt;/strong&gt; → 服务管理型 Responses API&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;/ol&gt;
&lt;p&gt;阅读&lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;完整文章&lt;/a&gt;了解完整决策树。&lt;/p&gt;</content:encoded></item><item><title>Foundry Toolboxes：AI Agent工具的统一端点</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</guid><description>Microsoft Foundry已推出公开预览版Toolboxes——一种通过单一MCP兼容端点管理和公开AI Agent工具的方式，无需在每个Agent中重新配置所有内容。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。如需查看原始版本，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;有一个问题听起来无聊，直到你真正遇到它：你的组织在构建多个AI Agent，每个都需要工具，每个团队都从头开始配置。相同的Web搜索集成、相同的Azure AI Search配置、相同的GitHub MCP服务器连接——但在不同的仓库里，由不同的团队，使用不同的凭据，没有任何共享治理。&lt;/p&gt;
&lt;p&gt;Microsoft Foundry刚刚以公开预览版发布了&lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;Toolboxes&lt;/a&gt;，这是对该问题的直接回应。&lt;/p&gt;
&lt;h2 id="什么是toolbox"&gt;什么是Toolbox&lt;/h2&gt;
&lt;p&gt;Toolbox是一个有命名的、可复用的工具包，在Foundry中定义一次，通过单一MCP兼容端点公开。任何能够使用MCP的Agent运行时都可以消费它——不受限于Foundry Agents。&lt;/p&gt;
&lt;p&gt;承诺很简单：&lt;strong&gt;build once, consume anywhere&lt;/strong&gt;。定义工具，集中配置身份验证（OAuth直通、Entra托管标识），发布端点。需要这些工具的每个Agent连接到端点即可获取全部工具。&lt;/p&gt;
&lt;h2 id="四个支柱今天两个可用"&gt;四个支柱（今天两个可用）&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;支柱&lt;/th&gt;
&lt;th&gt;状态&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discover&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;即将推出&lt;/td&gt;
&lt;td&gt;无需手动搜索即可发现已批准的工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;现已可用&lt;/td&gt;
&lt;td&gt;将工具整合到可复用包中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consume&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;现已可用&lt;/td&gt;
&lt;td&gt;单一MCP端点公开所有工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Govern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;即将推出&lt;/td&gt;
&lt;td&gt;集中身份验证+所有工具调用的可观测性&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="实践示例"&gt;实践示例&lt;/h2&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;azure.identity&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;
&lt;/span&gt;&lt;/span&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;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&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;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FOUNDRY_PROJECT_ENDPOINT&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;credential&lt;/span&gt;&lt;span class="o"&gt;=&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&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;toolbox_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toolboxes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_toolbox_version&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;toolbox_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;customer-feedback-triaging-toolbox&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;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;搜索文档并回应GitHub issues&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="o"&gt;=&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="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;web_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;搜索公开文档&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 class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;azure_ai_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;index_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;internal-docs&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 class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mcp_server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;server_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://your-github-mcp-server.com&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="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;发布后，Foundry提供统一端点。一次连接，获取所有工具。&lt;/p&gt;
&lt;h2 id="不受限于foundry-agents"&gt;不受限于Foundry Agents&lt;/h2&gt;
&lt;p&gt;Toolboxes在Foundry中&lt;strong&gt;创建和管理&lt;/strong&gt;，但消费面是开放的MCP协议。可以从使用Microsoft Agent Framework或LangGraph的自定义Agent、GitHub Copilot和其他MCP兼容IDE以及任何支持MCP的运行时中使用它们。&lt;/p&gt;
&lt;h2 id="为什么现在重要"&gt;为什么现在重要&lt;/h2&gt;
&lt;p&gt;多Agent浪潮正在进入生产环境。每个新Agent都是重复配置、过期凭据和不一致行为的新风险面。Build + Consume基础足以开始集中化。当Govern支柱推出时，你将拥有对整个Agent群完全可观测、集中控制的工具层。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;还是早期阶段——公开预览，Python SDK优先，Discover和Govern仍在路上。但模型是稳固的，MCP原生设计意味着它可以与你已经在构建的工具配合使用。查阅&lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;官方公告&lt;/a&gt;了解详情。&lt;/p&gt;</content:encoded></item><item><title>Windows App Dev CLI v0.3：从终端实现F5调试和面向智能体的UI自动化</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/</guid><description>Windows App Development CLI v0.3带来了winapp run（从终端进行调试启动）、winapp ui（UI自动化）以及一个让dotnet run支持打包应用的NuGet包。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文已自动翻译。如需查看原文，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio的F5体验非常棒。但是，仅仅为了启动和调试一个打包的Windows应用而打开VS，在CI流水线、自动化工作流或AI智能体执行测试时就显得过于繁重了。&lt;/p&gt;
&lt;p&gt;Windows App Development CLI v0.3&lt;a href="https://devblogs.microsoft.com/ifdef-windows/windows-app-development-cli-v0-3-new-run-and-ui-commands-plus-dotnet-run-support-for-packaged-apps/"&gt;正式发布&lt;/a&gt;，通过两个核心功能直接解决了这个问题：&lt;code&gt;winapp run&lt;/code&gt;和&lt;code&gt;winapp ui&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="winapp-run随处可用的f5"&gt;winapp run：随处可用的F5&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;winapp run&lt;/code&gt;接受一个未打包的应用文件夹和清单，执行VS在调试启动时所做的一切：注册松散包、启动应用，并在重新部署之间保留&lt;code&gt;LocalState&lt;/code&gt;。&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;# 构建应用，然后作为打包应用运行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winapp run ./bin/Debug
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;支持WinUI、WPF、WinForms、Console、Avalonia等。各模式同时面向开发者和自动化工作流：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--detach&lt;/code&gt;&lt;/strong&gt;：启动后立即将控制权返回给终端。非常适合CI/自动化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--unregister-on-exit&lt;/code&gt;&lt;/strong&gt;：应用关闭时清理已注册的包。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--debug-output&lt;/code&gt;&lt;/strong&gt;：实时捕获&lt;code&gt;OutputDebugString&lt;/code&gt;消息和异常。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="新nuget包打包应用的dotnet-run支持"&gt;新NuGet包：打包应用的dotnet run支持&lt;/h2&gt;
&lt;p&gt;面向.NET开发者，新增了一个NuGet包：&lt;code&gt;Microsoft.Windows.SDK.BuildTools.WinApp&lt;/code&gt;。安装后，&lt;code&gt;dotnet run&lt;/code&gt;处理整个内循环：构建、准备松散布局包、在Windows中注册和启动——一步完成。&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;winapp init
&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;dotnet add package Microsoft.Windows.SDK.BuildTools.WinApp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="winapp-ui从命令行实现ui自动化"&gt;winapp ui：从命令行实现UI自动化&lt;/h2&gt;
&lt;p&gt;这是开启智能体场景的功能。&lt;code&gt;winapp ui&lt;/code&gt;从终端提供对任何正在运行的Windows应用（WPF、WinForms、Win32、Electron、WinUI3）的完整UI自动化访问。&lt;/p&gt;
&lt;p&gt;可以实现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;列出所有顶层窗口&lt;/li&gt;
&lt;li&gt;遍历窗口的完整UI自动化树&lt;/li&gt;
&lt;li&gt;按名称、类型或自动化ID搜索元素&lt;/li&gt;
&lt;li&gt;单击、调用和设置值&lt;/li&gt;
&lt;li&gt;截图&lt;/li&gt;
&lt;li&gt;等待元素出现——非常适合测试同步&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;将&lt;code&gt;winapp ui&lt;/code&gt;与&lt;code&gt;winapp run&lt;/code&gt;结合使用，即可从终端实现完整的构建→启动→验证工作流。智能体可以运行应用、检查UI状态、以编程方式交互并验证结果。&lt;/p&gt;
&lt;h2 id="其他新功能"&gt;其他新功能&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;winapp unregister&lt;/code&gt;&lt;/strong&gt;：测试完成后删除旁加载的包。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;winapp manifest add-alias&lt;/code&gt;&lt;/strong&gt;：添加别名，从终端按名称启动应用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tab补全&lt;/strong&gt;：一条命令配置PowerShell补全。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="安装方式"&gt;安装方式&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;winget install Microsoft.WinAppCli
&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;npm install -g @microsoft/winappcli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;CLI处于公开预览阶段。完整文档请查看&lt;a href="https://github.com/microsoft/WinAppCli"&gt;GitHub仓库&lt;/a&gt;，所有详细信息请查看&lt;a href="https://devblogs.microsoft.com/ifdef-windows/windows-app-development-cli-v0-3-new-run-and-ui-commands-plus-dotnet-run-support-for-packaged-apps/"&gt;原始公告&lt;/a&gt;。&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.117：Agent 拥有了自己的 Git 分支，我举双手赞成</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</link><pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</guid><description>VS Code 1.117 为 Agent 会话带来了 worktree 隔离、持久化 Autopilot 模式和子 Agent 支持。Agent 编码工作流变得更加真实了。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;ldquo;AI 助手&amp;quot;和&amp;quot;AI 队友&amp;quot;之间的界限越来越模糊。VS Code 1.117 刚刚发布，&lt;a href="https://code.visualstudio.com/updates/v1_117"&gt;完整的发行说明&lt;/a&gt;内容丰富，但核心很明确：Agent 正在成为你开发工作流中的一等公民。&lt;/p&gt;
&lt;p&gt;以下是真正重要的内容。&lt;/p&gt;
&lt;h2 id="autopilot-模式终于能记住你的偏好了"&gt;Autopilot 模式终于能记住你的偏好了&lt;/h2&gt;
&lt;p&gt;以前，你每次开始新会话都得重新启用 Autopilot。很烦。现在你的权限模式会在会话之间持久化，你还可以配置默认值。&lt;/p&gt;
&lt;p&gt;Agent Host 支持三种会话配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Default&lt;/strong&gt; — 工具在运行前会请求确认&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bypass&lt;/strong&gt; — 自动批准一切&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autopilot&lt;/strong&gt; — 完全自主，自己回答问题并继续执行&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你正在搭建一个带有迁移、Docker 和 CI 的新 .NET 项目——设置一次 Autopilot 就行了。这个偏好会一直保持。&lt;/p&gt;
&lt;h2 id="agent-会话的-worktree-和-git-隔离"&gt;Agent 会话的 worktree 和 git 隔离&lt;/h2&gt;
&lt;p&gt;这是重头戏。Agent 会话现在支持完整的 worktree 和 git 隔离。这意味着当一个 Agent 处理任务时，它会获得自己的分支和工作目录。你的主分支完全不受影响。&lt;/p&gt;
&lt;p&gt;更好的是——Copilot CLI 会为这些 worktree 会话生成有意义的分支名称。不再是 &lt;code&gt;agent-session-abc123&lt;/code&gt;。你会得到一个真正描述 Agent 正在做什么的名称。&lt;/p&gt;
&lt;p&gt;对于管理多个功能分支或在长时间脚手架任务运行期间修复 bug 的 .NET 开发者来说，这是一个游戏规则的改变。你可以让一个 Agent 在一个 worktree 中构建 API 控制器，同时你在另一个 worktree 中调试服务层问题。没有冲突。没有 stash。没有混乱。&lt;/p&gt;
&lt;h2 id="子-agent-和-agent-团队"&gt;子 Agent 和 Agent 团队&lt;/h2&gt;
&lt;p&gt;Agent Host Protocol 现在支持子 Agent。一个 Agent 可以启动其他 Agent 来处理任务的各个部分。把它想象成委派——你的主 Agent 负责协调，专门的 Agent 处理各个部分。&lt;/p&gt;
&lt;p&gt;这还处于早期阶段，但对 .NET 工作流的潜力显而易见。想象一下，一个 Agent 处理你的 EF Core 迁移，另一个设置你的集成测试。我们还没有完全到达那里，但协议支持现在落地意味着工具很快就会跟上。&lt;/p&gt;
&lt;h2 id="agent-发送输入时终端输出自动包含"&gt;Agent 发送输入时终端输出自动包含&lt;/h2&gt;
&lt;p&gt;虽小但有意义。当 Agent 向终端发送输入时，终端输出现在会自动包含在上下文中。以前，Agent 需要额外的一个回合才能读取发生了什么。&lt;/p&gt;
&lt;p&gt;如果你曾经看到一个 Agent 运行 &lt;code&gt;dotnet build&lt;/code&gt;，失败了，然后又需要一次往返才能看到错误——这种摩擦消失了。它立即看到输出并做出反应。&lt;/p&gt;
&lt;h2 id="macos-上的-agents-应用自动更新"&gt;macOS 上的 Agents 应用自动更新&lt;/h2&gt;
&lt;p&gt;macOS 上的独立 Agents 应用现在可以自动更新了。不再需要手动下载新版本。它会自动保持最新。&lt;/p&gt;
&lt;h2 id="值得了解的小改进"&gt;值得了解的小改进&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;package.json 悬停提示&lt;/strong&gt;现在同时显示已安装版本和最新可用版本。如果你在 .NET 项目旁边管理 npm 工具，这很有用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSDoc 注释中的图片&lt;/strong&gt;在悬停和补全中正确渲染。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot CLI 会话&lt;/strong&gt;现在会显示是由 VS Code 还是外部创建的——当你在终端之间切换时很方便。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot CLI、Claude Code 和 Gemini CLI&lt;/strong&gt; 被识别为 shell 类型。编辑器知道你在运行什么。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;VS Code 1.117 不是一个花哨的功能堆砌。它是基础设施。Worktree 隔离、持久化权限、子 Agent 协议——这些是构建一个工作流的基石，在这个工作流中，Agent 可以处理真实的并行任务而不会干扰你的代码。&lt;/p&gt;
&lt;p&gt;如果你正在用 .NET 开发，还没有尝试 Agent 工作流，说实话，现在就是开始的时候。&lt;/p&gt;</content:encoded></item><item><title>Foundry的RFT更便宜、更智能了 — 看看有什么变化</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/</guid><description>Microsoft Foundry本月发布了三项RFT更新：o4-mini的全球训练、新的GPT-4.1模型评分器，以及一份能为你节省数小时调试时间的最佳实践指南。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你正在开发依赖微调模型的.NET应用，这个月的Foundry更新值得关注。Reinforcement Fine-Tuning变得更易获取，价格也大幅降低。&lt;/p&gt;
&lt;p&gt;完整详情请参阅&lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-foundry-finetune-april-2026/"&gt;官方公告&lt;/a&gt;，这里是实用要点总结。&lt;/p&gt;
&lt;h2 id="o4-mini的全球训练"&gt;o4-mini的全球训练&lt;/h2&gt;
&lt;p&gt;o4-mini是推理密集型和智能体工作负载的首选模型。重大消息：你现在可以从13+个Azure区域启动微调任务，与Standard训练相比，每token的训练费率更低。相同的基础设施，相同的质量，更广的覆盖范围。&lt;/p&gt;
&lt;p&gt;如果你的团队分布在不同地区，这很重要。你不再局限于少数几个区域来进行训练。&lt;/p&gt;
&lt;p&gt;以下是启动全球训练任务的REST API调用：&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;curl -X POST &lt;span class="s2"&gt;&amp;#34;https://&amp;lt;your-resource&amp;gt;.openai.azure.com/openai/fine_tuning/jobs?api-version=2025-04-01-preview&amp;#34;&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; -H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&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; -H &lt;span class="s2"&gt;&amp;#34;api-key: &lt;/span&gt;&lt;span class="nv"&gt;$AZURE_OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&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; -d &lt;span class="s1"&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;model&amp;#34;: &amp;#34;o4-mini&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;training_file&amp;#34;: &amp;#34;&amp;lt;your-training-file-id&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;method&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;type&amp;#34;: &amp;#34;reinforcement&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;reinforcement&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;grader&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;type&amp;#34;: &amp;#34;string_check&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;answer-check&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;input&amp;#34;: &amp;#34;{{sample.output_text}}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;reference&amp;#34;: &amp;#34;{{item.reference_answer}}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;operation&amp;#34;: &amp;#34;eq&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;hyperparameters&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;n_epochs&amp;#34;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;compute_multiplier&amp;#34;: 1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;trainingType&amp;#34;: &amp;#34;globalstandard&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;那个&lt;code&gt;trainingType: globalstandard&lt;/code&gt;标志就是关键区别。&lt;/p&gt;
&lt;h2 id="新模型评分器gpt-41系列"&gt;新模型评分器：GPT-4.1系列&lt;/h2&gt;
&lt;p&gt;评分器定义了模型优化所针对的奖励信号。此前，基于模型的评分器仅限于较少的模型集合。现在你有三个新选项：GPT-4.1、GPT-4.1-mini和GPT-4.1-nano。&lt;/p&gt;
&lt;p&gt;什么时候应该使用模型评分器而不是确定性评分器？当你的任务输出是开放式的，当你需要在多个维度上进行部分评分，或者当你在构建智能体工作流且工具调用的正确性取决于语义上下文时。&lt;/p&gt;
&lt;p&gt;关键在于，分层策略很实用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1-nano&lt;/strong&gt; 用于初始迭代。低成本，快速反馈循环。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1-mini&lt;/strong&gt; 当你的评分标准稳定并需要更高保真度时使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1&lt;/strong&gt; 用于生产环境评分或每个评分决策都至关重要的复杂标准。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你甚至可以在单个RFT任务中混合使用评分器类型。用string-match来评判&amp;quot;正确答案&amp;quot;维度，用模型评分器来评估推理质量。说实话，这种灵活性才是它对实际工作负载真正有用的地方。&lt;/p&gt;
&lt;h2 id="rft数据格式的陷阱"&gt;RFT数据格式的陷阱&lt;/h2&gt;
&lt;p&gt;这是很多人会踩的坑。RFT的数据格式与SFT不同。每行的最后一条消息必须是User或Developer角色——不是Assistant。期望的答案放在顶层键中，如&lt;code&gt;reference_answer&lt;/code&gt;，评分器会直接引用它。&lt;/p&gt;
&lt;p&gt;如果你之前一直在做监督微调并想切换到RFT，你需要重新组织训练数据。不要跳过这一步，否则你的任务会静默失败。&lt;/p&gt;
&lt;h2 id="为什么这对net开发者很重要"&gt;为什么这对.NET开发者很重要&lt;/h2&gt;
&lt;p&gt;如果你通过Azure OpenAI SDK从.NET应用中调用微调模型，更便宜的训练意味着你可以更积极地迭代。模型评分器选项意味着你可以针对细微的任务进行微调——不仅仅是精确匹配场景。&lt;a href="https://github.com/microsoft-foundry/fine-tuning/blob/main/Demos/Agentic_RFT_PrivatePreview/RFT_Best_Practice.md"&gt;GitHub&lt;/a&gt;上的最佳实践指南将为你节省真正的调试时间。&lt;/p&gt;
&lt;p&gt;从小处开始。十到一百个样本。简单的评分器。验证循环。然后扩展。&lt;/p&gt;</content:encoded></item><item><title>Global Azure Spain 2026</title><link>https://thedotnetblog.com/zh/events/global-azure-spain-2026/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/zh/events/global-azure-spain-2026/</guid><description>西班牙最大的 Azure 社区活动 — 一整天的 Azure、AI、数据、安全和云原生开发主题演讲，38位演讲者，3个分场。</description><content:encoded>&lt;p&gt;Global Azure Spain 2026 于 &lt;strong&gt;2026年4月18日&lt;/strong&gt; 在马德里 Alcobendas 的 &lt;strong&gt;Kinépolis Diversia&lt;/strong&gt; 举办。这是西班牙最大的社区驱动 Azure 活动，38位演讲者在3个平行分场分享 AI 代理、Azure 网络、Cosmos DB、Fabric、IoT、安全等主题。&lt;/p&gt;
&lt;p&gt;活动时间为 &lt;strong&gt;08:30 至 18:30&lt;/strong&gt;，包括主题演讲、茶歇、午餐和闭幕问答环节。&lt;/p&gt;
&lt;h2 id="议程亮点"&gt;议程亮点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domando Agentes de IA&lt;/strong&gt;：使用 Azure AI Foundry 和 Azure API Management 的治理、工具和 API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Construyendo agentes con LibreChat en Azure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How Can I Steal Your Data with Azure Private Endpoints&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stop Building APIs. Forge Agents with Azure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agentic DevOps Meets IoT: Real-Time Systems with Fabric and GitHub Copilot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El regreso de los tamagotchis!&lt;/strong&gt;：多代理系统实战&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundry Control Plane como plataforma de Agentes global&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rompiendo el perímetro: Zero Trust aplicado en Azure&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="门票"&gt;门票&lt;/h2&gt;
&lt;p&gt;注册为象征性捐赠 — 门票全部收入直接捐赠给 &lt;strong&gt;Plan International&lt;/strong&gt;，支持全球儿童权利和平等。名额有限，请尽早报名。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eventbrite.es/e/entradas-global-azure-spain-2026-en-madrid-1981594189564"&gt;在 Eventbrite 获取门票&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://globalazure.es/"&gt;活动网站&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="azure-tour-2026"&gt;Azure Tour 2026&lt;/h2&gt;
&lt;p&gt;除马德里外，Global Azure Tour 2026 还将在 &lt;strong&gt;萨拉戈萨&lt;/strong&gt;、&lt;strong&gt;特内里费&lt;/strong&gt; 和 &lt;strong&gt;塞维利亚&lt;/strong&gt; 举办。&lt;/p&gt;</content:encoded></item><item><title>你在Azure上的AI实验正在烧钱——这样解决</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/</guid><description>Azure上的AI工作负载很容易变得昂贵。让我们聊聊在不拖慢开发进度的情况下，什么方法真正有效地控制成本。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你现在正在Azure上构建AI驱动的应用，你可能已经注意到一件事：你的云账单看起来和以前不一样了。不只是更高了——更奇怪了。波动很大，难以预测。&lt;/p&gt;
&lt;p&gt;Microsoft刚刚发布了一篇关于&lt;a href="https://azure.microsoft.com/en-us/blog/cloud-cost-optimization-principles-that-still-matter/"&gt;仍然重要的云成本优化原则&lt;/a&gt;的优秀文章，说实话，时机再好不过了。因为AI工作负载在成本方面已经改变了游戏规则。&lt;/p&gt;
&lt;h2 id="为什么ai工作负载不一样"&gt;为什么AI工作负载不一样&lt;/h2&gt;
&lt;p&gt;事情是这样的。传统的.NET工作负载相对可预测。你了解你的App Service层级，了解你的SQL DTU，可以相当准确地估算每月开支。AI工作负载呢？完全不是这么回事。&lt;/p&gt;
&lt;p&gt;你在测试多个模型看哪个合适。你在启动GPU支持的基础设施进行微调。你在调用Azure OpenAI的API，而token消耗量会因prompt长度和用户行为的不同而产生巨大差异。每个实验都要花真金白银，你可能需要运行几十次才能找到正确的方法。&lt;/p&gt;
&lt;p&gt;这种不可预测性正是成本优化至关重要的原因——不是事后才想到，而是从第一天开始。&lt;/p&gt;
&lt;h2 id="管理与优化了解区别"&gt;管理与优化——了解区别&lt;/h2&gt;
&lt;p&gt;文章中有一个我认为开发者容易忽视的区别：成本&lt;em&gt;管理&lt;/em&gt;和成本&lt;em&gt;优化&lt;/em&gt;是不同的。&lt;/p&gt;
&lt;p&gt;管理是跟踪和报告。你在Azure Cost Management中设置预算，收到警报，查看仪表板。这是基本功。&lt;/p&gt;
&lt;p&gt;优化是你真正做决策的地方。你真的需要S3层级，还是S1就能处理你的负载？那个始终运行的计算实例周末是不是闲着？你能否用竞价实例来跑训练任务？&lt;/p&gt;
&lt;p&gt;作为.NET开发者，我们往往专注于代码，把基础设施决策留给&amp;quot;运维团队&amp;quot;。但如果你在Azure上部署，这些决策也是你的决策。&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; 给你的资源打标签。我是认真的。如果你无法分辨哪个项目或实验在消耗你的预算，你就无法优化任何东西。配合适当标签的Azure Cost Management是你最好的朋友。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实验之前设好护栏。&lt;/strong&gt; 使用Azure Policy限制dev/test环境中昂贵的SKU。为你的Azure OpenAI部署设置消费上限。不要等到账单到了才发现有人让GPU集群在周末一直运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;持续进行合理配置。&lt;/strong&gt; 原型阶段选的那个VM？可能不适合生产环境。Azure Advisor会给你建议——真的去看看。每月审查，而不是每年。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;考虑生命周期。&lt;/strong&gt; 开发资源应该关闭。测试环境不需要7×24小时运行。使用自动关机策略。特别是对于AI工作负载，考虑使用按执行付费的无服务器选项，而不是让计算资源一直保持运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;衡量价值，而不仅仅是成本。&lt;/strong&gt; 这一点容易忘记。一个成本更高但能产出显著更好结果的模型可能才是正确的选择。目标不是花最少的钱——而是花得聪明。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;云成本优化不是一次性的清理工作。它是一个习惯。随着AI工作负载让开支比以往任何时候都更难预测，尽早养成这个习惯可以帮你避免日后的痛苦惊喜。&lt;/p&gt;
&lt;p&gt;如果你是一名在Azure上构建的.NET开发者，开始像对待代码一样对待你的云账单吧——定期审查，混乱时重构，永远不要在不了解成本的情况下部署。&lt;/p&gt;</content:encoded></item><item><title>Docker Sandbox 让 Copilot 代理重构你的代码而不危及你的机器</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/</guid><description>Docker Sandbox 为 GitHub Copilot 代理提供安全的微型虚拟机，让它们可以自由重构——无需权限提示，不会对主机造成风险。这就是它为什么会改变大规模 .NET 现代化的一切。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你用过 Copilot 的代理模式做一些超出小修改范围的事情，你一定知道那种痛苦。每次写文件，每个终端命令——又一个权限提示。现在想象一下在 50 个项目上这样操作。一点都不好玩。&lt;/p&gt;
&lt;p&gt;Azure 团队刚发布了一篇关于 &lt;a href="https://devblogs.microsoft.com/all-things-azure/best-of-both-worlds-for-agentic-refactoring-github-copilot-microvms-via-docker-sandbox/"&gt;GitHub Copilot 代理的 Docker Sandbox&lt;/a&gt; 的文章，说实话，这是我见过的最实用的代理工具改进之一。它使用微型虚拟机为 Copilot 提供一个完全隔离的环境，让它可以随意操作——安装包、运行构建、执行测试——而不会触及你的主机系统。&lt;/p&gt;
&lt;h2 id="docker-sandbox-实际给你带来什么"&gt;Docker Sandbox 实际给你带来什么&lt;/h2&gt;
&lt;p&gt;核心思路很简单：启动一个带有完整 Linux 环境的轻量级微型虚拟机，将你的工作区同步进去，然后让 Copilot 代理在里面自由操作。完成后，更改会同步回来。&lt;/p&gt;
&lt;p&gt;以下是让它不仅仅是&amp;quot;在容器里运行东西&amp;quot;的特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;双向工作区同步&lt;/strong&gt;，保留绝对路径。你的项目结构在沙箱内看起来完全一样。不会有路径相关的构建失败。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;私有 Docker 守护进程&lt;/strong&gt;在微型虚拟机内运行。代理可以构建和运行容器，而无需挂载你主机的 Docker socket。这对安全性来说意义重大。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP/HTTPS 过滤代理&lt;/strong&gt;控制代理在网络上可以访问什么。你来决定允许哪些注册表和端点。沙箱内恶意 &lt;code&gt;npm install&lt;/code&gt; 带来的供应链攻击？已封锁。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;YOLO 模式&lt;/strong&gt;——是的，他们就是这么叫的。代理运行时无需权限提示，因为它根本无法损坏你的主机。每一个破坏性操作都被隔离了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="为什么-net-开发者应该关注"&gt;为什么 .NET 开发者应该关注&lt;/h2&gt;
&lt;p&gt;想想现在有多少团队正在面对现代化工作。你有一个包含 30 个项目的 .NET Framework 解决方案，需要迁移到 .NET 9。那是数百个文件的更改——项目文件、命名空间更新、API 替换、NuGet 迁移。&lt;/p&gt;
&lt;p&gt;使用 Docker Sandbox，你可以将 Copilot 代理指向一个项目，让它在微型虚拟机内自由重构，运行 &lt;code&gt;dotnet build&lt;/code&gt; 和 &lt;code&gt;dotnet test&lt;/code&gt; 进行验证，然后只接受那些真正有效的更改。不用担心它在实验过程中意外破坏你的本地开发环境。&lt;/p&gt;
&lt;p&gt;文章还描述了运行&lt;strong&gt;并行代理舰队&lt;/strong&gt;的场景——每个代理在自己的沙箱中——同时处理不同的项目。对于大型 .NET 解决方案或微服务架构来说，这是一个巨大的时间节省。每个服务一个代理，全部隔离运行，全部独立验证。&lt;/p&gt;
&lt;h2 id="安全角度很重要"&gt;安全角度很重要&lt;/h2&gt;
&lt;p&gt;大多数人忽略的一点是：当你让 AI 代理执行任意命令时，你是在把整台机器都托付给它。Docker Sandbox 翻转了这个模型。代理在一次性环境中获得完全自主权。网络代理确保它只能从已批准的来源下载。你的主机文件系统、Docker 守护进程和凭据完好无损。&lt;/p&gt;
&lt;p&gt;对于有合规要求的团队——这是大多数企业级 .NET 公司的情况——这就是&amp;quot;我们不能使用代理式 AI&amp;quot;和&amp;quot;我们可以安全地采用它&amp;quot;之间的区别。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Docker Sandbox 解决了代理式编程的根本矛盾：代理需要自由才能发挥作用，但在你的主机上拥有自由是危险的。微型虚拟机两者兼得。如果你正在规划任何大规模的 .NET 重构或现代化，现在就值得设置起来。Copilot 的代码智能与安全执行环境的结合，正是生产团队一直在等待的。&lt;/p&gt;</content:encoded></item><item><title>Azure上のAIエージェントはどこにホストすべき？実践的な判断ガイド</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</guid><description>Azure提供六种托管AI代理的方式——从原始容器到完全托管的Foundry Hosted Agents。以下是如何为你的.NET工作负载选择合适方案。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你现在正在用.NET构建AI代理，你可能已经注意到一件事：在Azure上托管它们的方式&lt;em&gt;太多了&lt;/em&gt;。Container Apps、AKS、Functions、App Service、Foundry Agents、Foundry Hosted Agents——在你真正需要选择之前，每个都听起来合理。Microsoft刚刚发布了一份&lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;Azure AI代理托管综合指南&lt;/a&gt;来澄清这个问题，我想从.NET开发者的实践角度来拆解它。&lt;/p&gt;
&lt;h2 id="六种选项速览"&gt;六种选项速览&lt;/h2&gt;
&lt;p&gt;以下是我对这个版图的总结：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;选项&lt;/th&gt;
&lt;th&gt;最适合&lt;/th&gt;
&lt;th&gt;你需要管理&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Container Apps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无需K8s复杂性的完整容器控制&lt;/td&gt;
&lt;td&gt;可观测性、状态、生命周期&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AKS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;企业合规、多集群、自定义网络&lt;/td&gt;
&lt;td&gt;所有东西（这就是重点）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Azure Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;事件驱动的短时代理任务&lt;/td&gt;
&lt;td&gt;几乎不需要——真正的无服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;App Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;简单的HTTP代理、可预测的流量&lt;/td&gt;
&lt;td&gt;部署、扩展配置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;通过门户/SDK的无代码代理&lt;/td&gt;
&lt;td&gt;几乎不需要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Hosted Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;托管基础设施上的自定义框架代理&lt;/td&gt;
&lt;td&gt;仅你的代理代码&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;前四个是通用计算——你&lt;em&gt;可以&lt;/em&gt;在上面运行代理，但它们不是为此设计的。最后两个是代理原生的：它们将对话、工具调用和代理生命周期理解为一等概念。&lt;/p&gt;
&lt;h2 id="foundry-hosted-agentsnet代理开发者的最佳选择"&gt;Foundry Hosted Agents——.NET代理开发者的最佳选择&lt;/h2&gt;
&lt;p&gt;这是引起我注意的地方。Foundry Hosted Agents正好处于中间位置：你获得运行自己代码的灵活性（Semantic Kernel、Agent Framework、LangGraph——随便什么），但平台处理基础设施、可观测性和对话管理。&lt;/p&gt;
&lt;p&gt;关键部分是&lt;strong&gt;Hosting Adapter&lt;/strong&gt;——一个将你的代理框架连接到Foundry平台的薄抽象层。对于Microsoft Agent Framework，看起来是这样的：&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;azure.ai.agentserver.agentframework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;from_agent_framework&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatAgent&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;chat_client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AzureAIAgentClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&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="o"&gt;=&lt;/span&gt;&lt;span class="s2"&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="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_local_time&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="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&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;from_agent_framework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&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;这就是你的整个托管方案。适配器自动处理协议转换、通过server-sent events的流式传输、对话历史和OpenTelemetry追踪。不需要自定义中间件，不需要手动配置。&lt;/p&gt;
&lt;h2 id="部署真的很简单"&gt;部署真的很简单&lt;/h2&gt;
&lt;p&gt;我以前在Container Apps上部署过代理，虽然可以工作，但最后你会写很多胶水代码来处理状态管理和可观测性。使用Hosted Agents和&lt;code&gt;azd&lt;/code&gt;，部署是：&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;# 安装AI代理扩展&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ext install azure.ai.agents
&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;azd ai agent init
&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;azd up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个单独的&lt;code&gt;azd up&lt;/code&gt;会构建你的容器、推送到ACR、配置Foundry项目、部署模型端点并启动你的代理。五个步骤压缩成一个命令。&lt;/p&gt;
&lt;h2 id="内置对话管理"&gt;内置对话管理&lt;/h2&gt;
&lt;p&gt;这是在生产中节省最多时间的部分。不需要构建自己的对话状态存储，Hosted Agents原生处理：&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="c1"&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;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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="c1"&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;response1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&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;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&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="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Remember: my favorite number is 42.&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="c1"&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;response2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&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;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&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="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Multiply my favorite number by 10.&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;不需要Redis。不需要Cosmos DB会话存储。不需要自定义中间件来序列化消息。平台直接处理了。&lt;/p&gt;
&lt;h2 id="我的决策框架"&gt;我的决策框架&lt;/h2&gt;
&lt;p&gt;在审查了所有六个选项之后，这是我的快速心智模型：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;需要零基础设施？&lt;/strong&gt; → Foundry Agents（门户/SDK，无容器）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有自定义代理代码但想要托管主机？&lt;/strong&gt; → Foundry Hosted Agents&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需要事件驱动的短期代理任务？&lt;/strong&gt; → Azure Functions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需要不用K8s的最大容器控制？&lt;/strong&gt; → Container Apps&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需要严格合规和多集群？&lt;/strong&gt; → AKS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有流量可预测的简单HTTP代理？&lt;/strong&gt; → App Service&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于大多数使用Semantic Kernel或Microsoft Agent Framework构建的.NET开发者来说，Hosted Agents可能是正确的起点。你能获得scale-to-zero、内置OpenTelemetry、对话管理和框架灵活性——无需管理Kubernetes或搭建自己的可观测性栈。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Azure上的代理托管格局正在快速成熟。如果你今天要开始一个新的AI代理项目，我会在习惯性地使用Container Apps或AKS之前认真考虑Foundry Hosted Agents。托管基础设施节省实际时间，而hosting adapter模式让你保留框架选择。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;Microsoft的完整指南&lt;/a&gt;和&lt;a href="https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents"&gt;Foundry Samples仓库&lt;/a&gt;获取可运行的示例。&lt;/p&gt;</content:encoded></item><item><title>.NET的Agent Skills变得真正灵活了</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/</guid><description>Microsoft Agent Framework现在支持三种创建技能的方式——文件、类和内联代码——全部通过单一provider组合。这篇文章解释为什么这很重要以及如何使用每种方式。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你一直在用Microsoft Agent Framework构建代理，那你已经熟悉流程了：定义技能，连接到provider，让代理决定调用哪个。新的是你&lt;em&gt;如何&lt;/em&gt;创建这些技能——灵活性的提升非常显著。&lt;/p&gt;
&lt;p&gt;最新更新引入了三种agent skill编写模式：&lt;strong&gt;基于文件的&lt;/strong&gt;、&lt;strong&gt;基于类的&lt;/strong&gt;和&lt;strong&gt;内联代码定义的&lt;/strong&gt;。三种都连接到单一的 &lt;code&gt;AgentSkillsProviderBuilder&lt;/code&gt;，意味着你可以自由混搭，无需路由逻辑或特殊粘合代码。让我带你了解每种模式以及何时使用。&lt;/p&gt;
&lt;h2 id="基于文件的技能起点"&gt;基于文件的技能：起点&lt;/h2&gt;
&lt;p&gt;基于文件的技能顾名思义——磁盘上的一个目录，包含 &lt;code&gt;SKILL.md&lt;/code&gt; 文件、可选脚本和参考文档。给代理添加新能力最直接的方式：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;skills/
└── onboarding-guide/
├── SKILL.md
├── scripts/
│ └── check-provisioning.py
└── references/
└── onboarding-checklist.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;SKILL.md&lt;/code&gt; 的frontmatter声明技能名称和描述，指令部分告诉代理如何使用脚本和参考：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&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;name: onboarding-guide
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;description: &amp;gt;-
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Walk new hires through their first-week setup checklist.
&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Instructions
&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="k"&gt;1.&lt;/span&gt; Ask for the employee&amp;#39;s name and start date.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; Run &lt;span class="sb"&gt;`scripts/check-provisioning.py`&lt;/span&gt; to verify accounts.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; Walk through &lt;span class="sb"&gt;`references/onboarding-checklist.md`&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;4.&lt;/span&gt; Follow up on incomplete items.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后用 &lt;code&gt;SubprocessScriptRunner.RunAsync&lt;/code&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProvider&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;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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;SubprocessScriptRunner&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&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="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 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 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;GetResponsesClient&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 class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChatClientAgentOptions&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;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;HRAgent&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;ChatOptions&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="p"&gt;{&lt;/span&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 HR 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;AIContextProviders&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;skillsProvider&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;model&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;代理自动发现技能并在需要检查账户状态时调用配置脚本。干净简单。&lt;/p&gt;
&lt;h2 id="基于类的技能通过nuget分发"&gt;基于类的技能：通过NuGet分发&lt;/h2&gt;
&lt;p&gt;这里对团队来说变得有趣了。基于类的技能继承自 &lt;code&gt;AgentClassSkill&amp;lt;T&amp;gt;&lt;/code&gt; 并使用 &lt;code&gt;[AgentSkillResource]&lt;/code&gt; 和 &lt;code&gt;[AgentSkillScript]&lt;/code&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BenefitsEnrollmentSkill&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentClassSkill&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BenefitsEnrollmentSkill&lt;/span&gt;&lt;span class="p"&gt;&amp;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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="n"&gt;AgentSkillFrontmatter&lt;/span&gt; &lt;span class="n"&gt;Frontmatter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;benefits-enrollment&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="s"&gt;&amp;#34;Enroll an employee in health, dental, or vision plans.&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="kd"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Instructions&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plans&lt;/span&gt; &lt;span class="n"&gt;resource&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="m"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Confirm&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="n"&gt;wants&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="m"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;enroll&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;complete&lt;/span&gt; &lt;span class="n"&gt;enrollment&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;&amp;#34;&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&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; [AgentSkillResource(&amp;#34;available-plans&amp;#34;)]&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;Plan options with monthly pricing.&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;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;AvailablePlans&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="n"&gt;Plans&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2026&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;Health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt; &lt;span class="n"&gt;HMO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Premium&lt;/span&gt; &lt;span class="n"&gt;PPO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&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;Dental&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Standard&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Enhanced&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&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;Vision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&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;&amp;#34;&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&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; [AgentSkillScript(&amp;#34;enroll&amp;#34;)]&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;Enrolls employee in the specified benefit plan.&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;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Enroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;planCode&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="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnrollInPlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;planCode&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;return&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&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;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;planCode&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="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;妙处在于团队可以将其打包为NuGet包。你添加到项目中，放入builder，它就能和基于文件的技能一起工作，无需协调：&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProviderBuilder&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;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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 class="n"&gt;UseSkill&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;BenefitsEnrollmentSkill&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;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&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="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;你知道那个时刻吗，另一个团队正在构建你需要的技能，但要到下个sprint才能完成？&lt;code&gt;AgentInlineSkill&lt;/code&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;timeOffSkill&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;AgentInlineSkill&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;time-off-balance&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;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Calculate remaining vacation and sick days.&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;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Ask&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;provided&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="m"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="n"&gt;balance&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="m"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Present&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;clearly&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;&amp;#34;&amp;#34;)
&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;AddScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;calculate-balance&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;leaveType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAnnualAllowance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&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;int&lt;/span&gt; &lt;span class="n"&gt;daysUsed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDaysUsed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&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;int&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;daysUsed&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;return&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&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;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;daysUsed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remaining&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;和其他技能一样添加到builder：&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProviderBuilder&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;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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 class="n"&gt;UseSkill&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;BenefitsEnrollmentSkill&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;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeOffSkill&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;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&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="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;当NuGet包最终发布时，你只需将内联技能替换为基于类的版本。代理不会注意到区别。&lt;/p&gt;
&lt;p&gt;但内联技能不仅仅用于桥接。当你需要在运行时动态生成技能——想想从配置加载的每个业务单元一个技能——或者当脚本需要捕获不属于DI容器的本地状态时，它们也是正确的选择。&lt;/p&gt;
&lt;h2 id="脚本审批人在回路中"&gt;脚本审批：人在回路中&lt;/h2&gt;
&lt;p&gt;对我们构建生产代理的.NET开发者来说，这是真正打开部署讨论的部分。有些脚本有实际后果——给某人注册福利、查询生产基础设施。开启 &lt;code&gt;UseScriptApproval&lt;/code&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&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;AgentSkillsProviderBuilder&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;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&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 class="n"&gt;UseSkill&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;BenefitsEnrollmentSkill&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;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeOffSkill&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;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseScriptApproval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;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;当代理想执行脚本时，它会返回一个审批请求。你的应用收集决定——批准或拒绝——代理相应继续。在受监管的环境中，这就是&amp;quot;我们可以部署这个&amp;quot;和&amp;quot;法务说不行&amp;quot;之间的区别。&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;从小处开始&lt;/strong&gt;，迭代指令，不写C#就能发布&lt;/li&gt;
&lt;li&gt;将&lt;strong&gt;可复用的技能&lt;/strong&gt;作为NuGet包分发，其他团队一行代码就能添加&lt;/li&gt;
&lt;li&gt;当&lt;em&gt;现在&lt;/em&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;code&gt;AgentSkillsProviderBuilder&lt;/code&gt; 组合。没有特殊路由，没有条件逻辑，没有技能类型检查。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;.NET中的agent skills现在拥有了真正灵活的编写模型。无论你是用基于文件的技能做原型的独立开发者，还是通过NuGet分发打包能力的企业团队，这些模式都能适配。脚本审批机制使其在需要人工检查点的环境中也能投入生产。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/agent-framework/agent-skills-in-net-three-ways-to-author-one-provider-to-run-them/"&gt;原始公告&lt;/a&gt;、Microsoft Learn上的&lt;a href="https://learn.microsoft.com/en-us/agent-framework/agents/skills"&gt;Agent Skills文档&lt;/a&gt;和GitHub上的&lt;a href="https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/02-agents/AgentSkills"&gt;.NET示例&lt;/a&gt;开始动手吧。&lt;/p&gt;</content:encoded></item><item><title>Azure MCP Server 2.0 正式发布——自托管智能云自动化来了</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</guid><description>Azure MCP Server 2.0 稳定版发布，支持自托管远程部署、57 个 Azure 服务中的 276 个工具，以及企业级安全性——这是 .NET 开发者构建智能工作流需要了解的内容。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文为自动翻译。如需查看原文，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;如果你最近一直在用 MCP 和 Azure 构建东西，你可能已经知道本地体验非常好。接入一个 MCP 服务器，让你的 AI 智能体与 Azure 资源对话，然后继续工作。但一旦你需要在团队中共享这个设置？那就会变得复杂。&lt;/p&gt;
&lt;p&gt;不再是这样了。Azure MCP Server &lt;a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release/"&gt;刚刚发布 2.0 稳定版&lt;/a&gt;，而主打功能正是企业团队一直在要求的：&lt;strong&gt;自托管远程 MCP 服务器支持&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="什么是-azure-mcp-server"&gt;什么是 Azure MCP Server？&lt;/h2&gt;
&lt;p&gt;快速回顾一下。Azure MCP Server 实现了 &lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro"&gt;Model Context Protocol&lt;/a&gt; 规范，并将 Azure 功能暴露为结构化、可发现的工具，AI 智能体可以调用。把它看作是你的智能体和 Azure 之间的标准化桥梁——配置、部署、监控、诊断，都通过一个统一的接口。&lt;/p&gt;
&lt;p&gt;这些数字说明一切：&lt;strong&gt;跨越 57 个 Azure 服务的 276 个 MCP 工具&lt;/strong&gt;。这是真正的覆盖范围。&lt;/p&gt;
&lt;h2 id="重大突破自托管远程部署"&gt;重大突破：自托管远程部署&lt;/h2&gt;
&lt;p&gt;关键是这样的。在你的本地机器上运行 MCP 对于开发和实验来说没问题。但在真实的团队场景中，你需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开发者和内部智能体系统的共享访问&lt;/li&gt;
&lt;li&gt;集中化配置（租户上下文、订阅默认值、遥测）&lt;/li&gt;
&lt;li&gt;企业网络和策略边界&lt;/li&gt;
&lt;li&gt;与 CI/CD 流程的集成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Azure MCP Server 2.0 解决了所有这些问题。你可以将其部署为一个集中管理的内部服务，具有基于 HTTP 的传输、适当的身份验证和一致的治理。&lt;/p&gt;
&lt;p&gt;对于身份验证，你有两个不错的选择：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;托管标识&lt;/strong&gt;——在 &lt;a href="https://aka.ms/azmcp/self-host/foundry"&gt;Microsoft Foundry&lt;/a&gt; 旁边运行时&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代表流 (OBO 流)&lt;/strong&gt;——OpenID Connect 委托，使用已登录用户的上下文调用 Azure API&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于我们 .NET 开发者来说，OBO 流特别有趣。这意味着你的智能工作流可以使用用户的实际权限运行，而不是某个过度特权的服务账户。最小权限原则，内置其中。&lt;/p&gt;
&lt;h2 id="安全加固"&gt;安全加固&lt;/h2&gt;
&lt;p&gt;这不仅仅是一个功能发布——它也是一个安全发布。2.0 版本添加了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更强的端点验证&lt;/li&gt;
&lt;li&gt;针对面向查询工具中注入模式的保护&lt;/li&gt;
&lt;li&gt;更严格的开发环境隔离控制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你要将 MCP 暴露为共享服务，这些保障措施很重要。非常重要。&lt;/p&gt;
&lt;h2 id="你可以在哪里使用它"&gt;你可以在哪里使用它？&lt;/h2&gt;
&lt;p&gt;客户端兼容性范围很广。Azure MCP Server 2.0 可与以下配合使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IDE&lt;/strong&gt;：VS Code、Visual Studio、IntelliJ、Eclipse、Cursor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CLI 智能体&lt;/strong&gt;：GitHub Copilot CLI、Claude Code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;独立版&lt;/strong&gt;：用于简单设置的本地服务器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自托管远程&lt;/strong&gt;：2.0 的新星&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，还有针对 Azure 美国政府版和由 21Vianet 运营的 Azure 的主权云支持，这对于受管制的部署至关重要。&lt;/p&gt;
&lt;h2 id="为什么这对-net-开发者很重要"&gt;为什么这对 .NET 开发者很重要&lt;/h2&gt;
&lt;p&gt;如果你使用 .NET 构建智能应用——无论是使用 Semantic Kernel、Microsoft Agent Framework，还是你自己的编排——Azure MCP Server 2.0 让你能够以生产级的方式让你的智能体与 Azure 基础设施交互。没有自定义 REST 包装。没有服务特定的集成模式。只是 MCP。&lt;/p&gt;
&lt;p&gt;结合几天前发布的 &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;MCP 应用流畅 API&lt;/a&gt;，.NET MCP 生态系统正在快速成熟。&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;&lt;a href="https://aka.ms/azmcp"&gt;GitHub 仓库&lt;/a&gt;&lt;/strong&gt;——源代码、文档，一切&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/docker"&gt;Docker 镜像&lt;/a&gt;&lt;/strong&gt;——容器化部署&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/vscode"&gt;VS Code 扩展&lt;/a&gt;&lt;/strong&gt;——IDE 集成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/self-host"&gt;自托管指南&lt;/a&gt;&lt;/strong&gt;——2.0 的旗舰功能&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Azure MCP Server 2.0 正是那种在演示中看起来不起眼但在实践中改变一切的基础设施升级。具有适当身份验证、安全加固和主权云支持的自托管远程 MCP 意味着 MCP 已为在 Azure 上构建真实智能工作流的真实团队做好准备。如果你一直在等待&amp;quot;企业就绪&amp;quot;的信号——就是现在。&lt;/p&gt;</content:encoded></item><item><title>.NET Aspire 13.2想成为你AI智能体的好朋友</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/</guid><description>Aspire 13.2全力投入智能体开发 — 结构化CLI输出、隔离运行、自愈环境以及完整的OpenTelemetry数据，让你的AI智能体能够真正构建、运行和观察你的应用。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你知道那种感觉吗？你的AI编码智能体写出了不错的代码，你很兴奋，然后当它试图&lt;em&gt;运行&lt;/em&gt;这个东西时一切都崩溃了？端口冲突、幽灵进程、错误的环境变量 — 突然你的智能体在排查启动问题上烧掉了大量token，而不是构建功能。&lt;/p&gt;
&lt;p&gt;Aspire团队刚刚发布了一篇关于这个问题的&lt;a href="https://devblogs.microsoft.com/aspire/agentic-dev-aspirations/"&gt;深思熟虑的文章&lt;/a&gt;，他们的答案很有说服力：Aspire 13.2的设计不仅面向人类，更面向AI智能体。&lt;/p&gt;
&lt;h2 id="问题是真实存在的"&gt;问题是真实存在的&lt;/h2&gt;
&lt;p&gt;AI智能体在写代码方面令人难以置信。但交付一个可工作的全栈应用涉及的远不止生成文件。你需要按正确的顺序启动服务、管理端口、设置环境变量、连接数据库，以及在出问题时获得反馈。目前，大多数智能体通过试错来处理所有这些 — 运行命令、读取错误输出、再试一次。&lt;/p&gt;
&lt;p&gt;我们叠加Markdown指令、自定义技能和提示来引导它们，但这些是不可预测的，无法编译，而且仅仅解析就要消耗token。Aspire团队抓住了核心洞察：智能体需要&lt;strong&gt;编译器和结构化API&lt;/strong&gt;，而不是更多的Markdown。&lt;/p&gt;
&lt;h2 id="aspire作为智能体基础设施"&gt;Aspire作为智能体基础设施&lt;/h2&gt;
&lt;p&gt;以下是Aspire 13.2为智能体开发带来的内容：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;整个技术栈用类型化代码描述。&lt;/strong&gt; AppHost用可编译的TypeScript或C#定义你的完整拓扑 — API、前端、数据库、缓存：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createBuilder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;./.modules/aspire.js&amp;#39;&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="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;createBuilder&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="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postgres&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addPostgres&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;addDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;catalog&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="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addRedis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cache&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="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&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="nx"&gt;addNodeApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;api&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./api&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;src/index.ts&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 class="nx"&gt;withHttpEndpoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PORT&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 class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postgres&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="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&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="nx"&gt;addViteApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./frontend&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 class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&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="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;run&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;em&gt;通过构建来验证&lt;/em&gt;。编译器会立即告诉它哪里出了问题。不需要猜测，不需要在配置文件上反复试错。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一个命令统治所有。&lt;/strong&gt; 智能体不再需要在&lt;code&gt;docker compose up&lt;/code&gt;、&lt;code&gt;npm run dev&lt;/code&gt;和数据库启动脚本之间来回切换，一切只需&lt;code&gt;aspire start&lt;/code&gt;。所有资源按正确顺序、在正确的端口、用正确的配置启动。长时间运行的进程也不会挂起智能体 — Aspire负责管理它们。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;并行智能体的隔离模式。&lt;/strong&gt; 使用&lt;code&gt;--isolated&lt;/code&gt;，每次Aspire运行都会获得自己的随机端口和独立的用户密钥。多个智能体在git worktree中工作？它们不会冲突。这对于VS Code的后台智能体等创建并行环境的工具来说意义重大。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;通过遥测赋予智能体视野。&lt;/strong&gt; 这是真正强大的地方。Aspire CLI在开发期间暴露完整的OpenTelemetry数据 — 追踪、指标、结构化日志。你的智能体不是只读控制台输出然后祈祷一切顺利。它可以跨服务追踪失败的请求、分析慢端点，并精确定位问题所在。这是开发循环中的生产级可观察性。&lt;/p&gt;
&lt;h2 id="保龄球护栏类比"&gt;保龄球护栏类比&lt;/h2&gt;
&lt;p&gt;Aspire团队用了一个很棒的类比：把Aspire想象成AI智能体的保龄球道护栏。如果智能体不够完美（它确实不会完美），护栏会防止它打出沟球。技术栈定义防止配置错误，编译器捕获错误，CLI处理进程管理，遥测提供反馈循环。&lt;/p&gt;
&lt;p&gt;将此与Playwright CLI之类的工具结合，你的智能体就可以真正&lt;em&gt;使用&lt;/em&gt;你的应用 — 点击流程、检查DOM、在遥测中发现问题、修复代码、重启并重新测试。构建、运行、观察、修复。这就是我们一直追求的自主开发循环。&lt;/p&gt;
&lt;h2 id="入门"&gt;入门&lt;/h2&gt;
&lt;p&gt;Aspire新手？从&lt;a href="https://get.aspire.dev"&gt;get.aspire.dev&lt;/a&gt;安装CLI并遵循&lt;a href="https://aspire.dev/get-started/first-app"&gt;入门指南&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;已经在使用Aspire？运行&lt;code&gt;aspire update --self&lt;/code&gt;获取13.2，然后将你最喜欢的编码智能体指向你的仓库。有了Aspire的护栏，你可能会惊讶于它能走多远。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Aspire 13.2不再仅仅是一个分布式应用框架 — 它正在成为必不可少的智能体基础设施。结构化的技术栈定义、一键启动、隔离的并行运行和实时遥测，为AI智能体提供了从编写代码到交付应用所需的一切。&lt;/p&gt;
&lt;p&gt;阅读Aspire团队的&lt;a href="https://devblogs.microsoft.com/aspire/agentic-dev-aspirations/"&gt;完整文章&lt;/a&gt;获取所有细节和演示视频。&lt;/p&gt;</content:encoded></item><item><title>MCP Apps 迎来 Fluent API — 三步在 .NET 中构建丰富的 AI 工具界面</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/</guid><description>Azure Functions 上 MCP Apps 的全新 Fluent 配置 API 让你只需几行代码就能将任何 .NET MCP 工具转变为带有视图、权限和 CSP 策略的完整应用。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MCP 工具非常适合赋予 AI 代理各种能力。但如果你的工具需要向用户展示某些东西呢？比如仪表板、表单或交互式可视化？这就是 MCP Apps 的用武之地，而且现在构建它们变得简单多了。&lt;/p&gt;
&lt;p&gt;Azure SDK 团队的 Lilian Kasem &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;发布了全新的 Fluent 配置 API&lt;/a&gt;，用于 .NET Azure Functions 上的 MCP Apps。这种开发者体验的改进会让你想，为什么以前不一直这么简单呢。&lt;/p&gt;
&lt;h2 id="什么是-mcp-apps"&gt;什么是 MCP Apps？&lt;/h2&gt;
&lt;p&gt;MCP Apps 扩展了 Model Context Protocol，让工具可以携带自己的 UI 视图、静态资源和安全控制。你的 MCP 工具不再只是返回文本，而是可以渲染完整的 HTML 体验 — 交互式仪表板、数据可视化、配置表单 — 全部可由 AI 代理调用，并通过 MCP 客户端呈现给用户。&lt;/p&gt;
&lt;p&gt;问题在于，手动连接这一切需要深入了解 MCP 规范：&lt;code&gt;ui://&lt;/code&gt; URI、特殊 MIME 类型、工具和资源之间的元数据协调。不难，但很繁琐。&lt;/p&gt;
&lt;h2 id="fluent-api-三步走"&gt;Fluent API 三步走&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;第一步：定义你的函数。&lt;/strong&gt; 标准的 Azure Functions MCP 工具：&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;[Function(nameof(HelloApp))]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;HelloApp&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; [McpToolTrigger(&amp;#34;HelloApp&amp;#34;, &amp;#34;A simple MCP App that says hello.&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ToolInvocationContext&lt;/span&gt; &lt;span class="n"&gt;context&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="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Hello from app&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;strong&gt;第二步：将其提升为 MCP App。&lt;/strong&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;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureMcpTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;HelloApp&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 class="n"&gt;AsMcpApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;app&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;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;assets/hello-app.html&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 class="n"&gt;WithTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello App&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 class="n"&gt;WithPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpAppPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClipboardWrite&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;McpAppPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClipboardRead&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;WithCsp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csp&lt;/span&gt; &lt;span class="p"&gt;=&amp;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;csp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowBaseUri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://www.microsoft.com&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 class="n"&gt;ConnectTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://www.microsoft.com&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;strong&gt;第三步：添加你的 HTML 视图。&lt;/strong&gt; 创建 &lt;code&gt;assets/hello-app.html&lt;/code&gt;，放入你需要的界面。&lt;/p&gt;
&lt;p&gt;就这样。Fluent API 处理了所有 MCP 协议的管道工作 — 生成合成资源函数、设置正确的 MIME 类型、注入将工具与其视图连接起来的元数据。&lt;/p&gt;
&lt;h2 id="api-设计精良"&gt;API 设计精良&lt;/h2&gt;
&lt;p&gt;几个我特别喜欢的地方：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;视图源灵活。&lt;/strong&gt; 你可以从磁盘文件提供 HTML，也可以将资源直接嵌入程序集中以实现自包含部署：&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpViewSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;assets/my-view.html&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpViewSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromEmbeddedResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;MyApp.Resources.view.html&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;strong&gt;CSP 可组合。&lt;/strong&gt; 你明确允许应用所需的来源，遵循最小权限原则。多次调用 &lt;code&gt;WithCsp&lt;/code&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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithCsp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csp&lt;/span&gt; &lt;span class="p"&gt;=&amp;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;csp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://api.example.com&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 class="n"&gt;LoadResourcesFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://cdn.example.com&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 class="n"&gt;AllowFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://youtube.com&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;strong&gt;可见性控制。&lt;/strong&gt; 你可以让工具仅对 LLM 可见、仅对宿主 UI 可见，或两者兼具。想要一个只渲染 UI 而不应被模型调用的工具？简单：&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="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithVisibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// UI-only, hidden from the model&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Mcp --version 1.5.0-preview.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果你已经在用 Azure Functions 构建 MCP 工具，这只是一个包更新。如果你是新手，&lt;a href="https://learn.microsoft.com/azure/azure-functions/scenario-mcp-apps?tabs=bash%2Clinux&amp;amp;pivots=programming-language-csharp"&gt;MCP Apps 快速入门&lt;/a&gt;是最好的起点。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;MCP Apps 是 AI 工具领域最令人兴奋的发展之一 — 不仅能&lt;em&gt;做事&lt;/em&gt;，还能向用户&lt;em&gt;展示事物&lt;/em&gt;的工具。Fluent API 消除了协议复杂性，让你专注于真正重要的事：工具的逻辑和界面。&lt;/p&gt;
&lt;p&gt;阅读&lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;完整文章&lt;/a&gt;获取完整的 API 参考和示例。&lt;/p&gt;</content:encoded></item><item><title>Microsoft Foundry 2026年3月 — GPT-5.4、Agent Service GA，以及改变一切的SDK刷新</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</guid><description>Microsoft Foundry 2026年3月更新非常重大：Agent Service正式GA，GPT-5.4带来可靠推理，azure-ai-projects SDK在所有语言中稳定发布，Fireworks AI将开放模型引入Azure。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;每月的&amp;quot;Microsoft Foundry新动态&amp;quot;文章通常是增量改进和偶尔亮点功能的混合。&lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;2026年3月版&lt;/a&gt;呢？基本上全是亮点功能。Foundry Agent Service正式GA，GPT-5.4投入生产，SDK获得重要的稳定版本发布，Fireworks AI将开放模型推理引入Azure。让我来解析对.NET开发者来说什么最重要。&lt;/p&gt;
&lt;h2 id="foundry-agent-service已准备好投入生产"&gt;Foundry Agent Service已准备好投入生产&lt;/h2&gt;
&lt;p&gt;这是最大的新闻。新一代代理运行时已正式发布 — 构建在OpenAI Responses API之上，与OpenAI代理协议兼容，并向多个提供商的模型开放。如果您今天正在使用Responses API构建，迁移到Foundry将在您现有的代理逻辑之上添加企业级安全性、私有网络、Entra RBAC、完整追踪和评估功能。&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;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&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;azure.ai.projects.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptAgentDefinition&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;project_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&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;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_PROJECT_ENDPOINT&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;credential&lt;/span&gt;&lt;span class="o"&gt;=&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&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_version&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;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-enterprise-agent&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;definition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptAgentDefinition&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;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&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;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&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="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;关键新增功能：端到端私有网络、MCP认证扩展（包括OAuth透传）、语音对语音代理的Voice Live预览，以及在6个新区域托管代理。&lt;/p&gt;
&lt;h2 id="gpt-54--可靠性优于纯粹的智能"&gt;GPT-5.4 — 可靠性优于纯粹的智能&lt;/h2&gt;
&lt;p&gt;GPT-5.4不是为了变得更聪明，而是为了变得更可靠。在长时间交互中更强的推理能力、更好的指令遵循性、更少的工作流中途故障，以及集成的计算机使用功能。对于生产环境的代理来说，这种可靠性比基准测试分数重要得多。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模型&lt;/th&gt;
&lt;th&gt;价格（每百万token）&lt;/th&gt;
&lt;th&gt;最佳用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 (≤272K)&lt;/td&gt;
&lt;td&gt;$2.50 / $15 输出&lt;/td&gt;
&lt;td&gt;生产代理、编码、文档工作流&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Pro&lt;/td&gt;
&lt;td&gt;$30 / $180 输出&lt;/td&gt;
&lt;td&gt;深度分析、科学推理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Mini&lt;/td&gt;
&lt;td&gt;经济实惠&lt;/td&gt;
&lt;td&gt;分类、提取、轻量级工具调用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;聪明的策略是路由：GPT-5.4 Mini处理高吞吐量、低延迟的工作，而GPT-5.4负责推理密集型的请求。&lt;/p&gt;
&lt;h2 id="sdk终于稳定了"&gt;SDK终于稳定了&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azure-ai-projects&lt;/code&gt; SDK在所有语言中发布了稳定版 — Python 2.0.0、JS/TS 2.0.0、Java 2.0.0和.NET 2.0.0（4月1日）。&lt;code&gt;azure-ai-agents&lt;/code&gt;依赖已经消失 — 一切都在&lt;code&gt;AIProjectClient&lt;/code&gt;下。使用&lt;code&gt;pip install azure-ai-projects&lt;/code&gt;安装，包中直接捆绑了&lt;code&gt;openai&lt;/code&gt;和&lt;code&gt;azure-identity&lt;/code&gt;作为依赖项。&lt;/p&gt;
&lt;p&gt;对于.NET开发者来说，这意味着一个NuGet包就能覆盖Foundry的全部功能。不再需要在多个代理SDK之间来回切换。&lt;/p&gt;
&lt;h2 id="fireworks-ai将开放模型引入azure"&gt;Fireworks AI将开放模型引入Azure&lt;/h2&gt;
&lt;p&gt;也许是架构上最有趣的新增：Fireworks AI每天处理超过13万亿token，速度达到~180K请求/秒，现在可以通过Foundry使用。DeepSeek V3.2、gpt-oss-120b、Kimi K2.5和MiniMax M2.5在发布时可用。&lt;/p&gt;
&lt;p&gt;真正的故事是&lt;strong&gt;自带权重&lt;/strong&gt; — 从任何地方上传量化或微调的权重，无需更改服务栈。通过无服务器按token付费或预配置吞吐量进行部署。&lt;/p&gt;
&lt;h2 id="其他亮点"&gt;其他亮点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phi-4 Reasoning Vision 15B&lt;/strong&gt; — 针对图表、图形和文档布局的多模态推理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evaluations GA&lt;/strong&gt; — 开箱即用的评估器，配合持续生产监控，直接接入Azure Monitor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Priority Processing&lt;/strong&gt;（预览）— 面向延迟敏感型工作负载的专用计算通道&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice Live&lt;/strong&gt; — 直接连接到Foundry代理的语音对语音运行时&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tracing GA&lt;/strong&gt; — 具有排序和过滤功能的端到端代理追踪检查&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PromptFlow弃用&lt;/strong&gt; — 在2027年1月前迁移到Microsoft Framework Workflows&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;2026年3月是Foundry的转折点。Agent Service GA、所有语言的稳定SDK、用于可靠生产代理的GPT-5.4，以及通过Fireworks AI实现的开放模型推理 — 该平台已准备好应对严肃的工作负载。&lt;/p&gt;
&lt;p&gt;阅读&lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;完整汇总&lt;/a&gt;并&lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;构建您的第一个代理&lt;/a&gt;来开始吧。&lt;/p&gt;</content:encoded></item><item><title>SQL MCP Server — 给 AI 代理数据库访问的正确方式</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</guid><description>Data API builder 的 SQL MCP Server 为 AI 代理提供安全、确定性的数据库访问，无需暴露架构或依赖 NL2SQL。RBAC、缓存、多数据库支持 — 全部内置。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/sql-mcp-server-data-api-builder/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;说实话：今天市面上大多数数据库 MCP 服务器都很可怕。它们接受自然语言查询，即时生成 SQL，然后在你的生产数据上执行。有什么可能出错的？（一切。一切都可能出错。）&lt;/p&gt;
&lt;p&gt;Azure SQL 团队刚刚&lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;发布了 SQL MCP Server&lt;/a&gt;，它采用了一种根本不同的方法。作为 Data API builder（DAB）2.0 的功能构建，它为 AI 代理提供结构化、确定性的数据库操作访问 — 没有 NL2SQL，不暴露你的架构，每一步都有完整的 RBAC。&lt;/p&gt;
&lt;h2 id="为什么不用-nl2sql"&gt;为什么不用 NL2SQL？&lt;/h2&gt;
&lt;p&gt;这是最有趣的设计决策。模型不是确定性的，复杂查询最容易产生微妙的错误。用户希望 AI 能生成的那些查询，恰恰也是在非确定性生成时最需要审查的查询。&lt;/p&gt;
&lt;p&gt;相反，SQL MCP Server 使用 &lt;strong&gt;NL2DAB&lt;/strong&gt; 方法。代理使用 Data API builder 的实体抽象层和内置查询构建器来确定性地生成准确、格式良好的 T-SQL。对用户来说结果相同，但没有幻觉 JOIN 或意外数据泄露的风险。&lt;/p&gt;
&lt;h2 id="七个工具不是七百个"&gt;七个工具，不是七百个&lt;/h2&gt;
&lt;p&gt;SQL MCP Server 精确暴露七个 DML 工具，与数据库大小无关：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;describe_entities&lt;/code&gt; — 发现可用实体和操作&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_record&lt;/code&gt; — 插入行&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read_records&lt;/code&gt; — 查询表和视图&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update_record&lt;/code&gt; — 修改行&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delete_record&lt;/code&gt; — 删除行&lt;/li&gt;
&lt;li&gt;&lt;code&gt;execute_entity&lt;/code&gt; — 运行存储过程&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aggregate_records&lt;/code&gt; — 聚合查询&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这很聪明，因为上下文窗口是代理的思考空间。用数百个工具定义淹没它们会减少推理空间。七个固定工具让代理专注于&lt;em&gt;思考&lt;/em&gt;而不是&lt;em&gt;导航&lt;/em&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-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;runtime&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;:&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="nt"&gt;&amp;#34;mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&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="nt"&gt;&amp;#34;enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/mcp&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="nt"&gt;&amp;#34;dml-tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&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="nt"&gt;&amp;#34;describe-entities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;create-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;read-records&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;update-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;delete-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;execute-entity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;aggregate-records&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="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;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;dab init &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --database-type mssql &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --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;dab add Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --source dbo.Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --permissions &lt;span class="s2"&gt;&amp;#34;anonymous:*&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;dab start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这就是一个运行中的 SQL MCP Server，暴露你的 Customers 表。实体抽象层意味着你可以为名称和列创建别名、按角色限制字段，并精确控制代理看到的内容 — 而不暴露内部架构细节。&lt;/p&gt;
&lt;h2 id="安全故事很扎实"&gt;安全故事很扎实&lt;/h2&gt;
&lt;p&gt;这是 Data API builder 成熟度发挥价值的地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;每一层都有 RBAC&lt;/strong&gt; — 每个实体定义哪些角色可以读取、创建、更新或删除，以及哪些字段可见&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Key Vault 集成&lt;/strong&gt; — 安全管理连接字符串和密钥&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Entra + 自定义 OAuth&lt;/strong&gt; — 生产级认证&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容安全策略&lt;/strong&gt; — 代理通过受控契约交互，而不是原始 SQL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;架构抽象特别重要。你的内部表名和列名永远不会暴露给代理。你定义对 AI 交互有意义的实体、别名和描述 — 而不是你的数据库 ERD 图。&lt;/p&gt;
&lt;h2 id="多数据库和多协议"&gt;多数据库和多协议&lt;/h2&gt;
&lt;p&gt;SQL MCP Server 支持 Microsoft SQL、PostgreSQL、Azure Cosmos DB 和 MySQL。由于它是 DAB 的功能，你可以从同一配置同时获取 REST、GraphQL 和 MCP 端点。相同的实体定义、相同的 RBAC 规则、相同的安全性 — 跨所有三种协议。&lt;/p&gt;
&lt;p&gt;DAB 2.0 的自动配置甚至可以检查你的数据库并动态构建配置，如果你愿意为快速原型设计减少抽象的话。&lt;/p&gt;
&lt;h2 id="我的看法"&gt;我的看法&lt;/h2&gt;
&lt;p&gt;这就是 AI 代理的企业级数据库访问应该如何工作。不是&amp;quot;嘿 LLM，给我写点 SQL 然后对生产环境 YOLO&amp;quot;。而是：定义良好的实体层、确定性查询生成、每一步的 RBAC、缓存、监控和遥测。以最好的方式无聊着。&lt;/p&gt;
&lt;p&gt;对于 .NET 开发者，集成故事很清晰 — DAB 是 .NET 工具，MCP Server 作为容器运行，与大多数人已经在用的 Azure SQL 配合工作。如果你正在构建需要数据访问的 AI 代理，从这里开始。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;SQL MCP Server 是免费、开源的，可在任何地方运行。这是微软为给 AI 代理提供安全数据库访问的规范性方法。查看&lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;完整文章&lt;/a&gt;和&lt;a href="https://aka.ms/sql/mcp"&gt;文档&lt;/a&gt;开始使用。&lt;/p&gt;</content:encoded></item><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><item><title>将 Azure Functions 上的 MCP 服务器连接到 Foundry 代理 — 方法在这里</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/</guid><description>一次构建 MCP 服务器，部署到 Azure Functions，通过适当的身份验证连接到 Microsoft Foundry 代理。你的工具随处可用 — VS Code、Cursor，现在还有企业级 AI 代理。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是我喜欢 MCP 生态系统的一点：你只需构建一次服务器，它就能在任何地方运行。VS Code、Visual Studio、Cursor、ChatGPT — 每个 MCP 客户端都能发现并使用你的工具。现在，微软正在向这个列表中添加另一个消费者：Foundry 代理。&lt;/p&gt;
&lt;p&gt;Azure SDK 团队的 Lily Ma &lt;a href="https://devblogs.microsoft.com/azure-sdk/give-your-foundry-agent-custom-tools-with-mcp-servers-on-azure-functions/"&gt;发布了一份实用指南&lt;/a&gt;，介绍如何将部署在 Azure Functions 上的 MCP 服务器与 Microsoft Foundry 代理连接。如果你已经有了 MCP 服务器，这纯粹是增值 — 无需重新构建。&lt;/p&gt;
&lt;h2 id="为什么这种组合有意义"&gt;为什么这种组合有意义&lt;/h2&gt;
&lt;p&gt;Azure Functions 为托管 MCP 服务器提供了可扩展的基础设施、内置身份验证和无服务器计费。Microsoft Foundry 为你提供能够推理、规划和行动的 AI 代理。连接两者意味着你的自定义工具 — 查询数据库、调用业务 API、运行验证逻辑 — 成为企业 AI 代理可以自主发现和使用的能力。&lt;/p&gt;
&lt;p&gt;关键点：你的 MCP 服务器保持不变。你只是将 Foundry 添加为另一个消费者。在 VS Code 设置中运行的相同工具现在为你的团队或客户交互的 AI 代理提供动力。&lt;/p&gt;
&lt;h2 id="身份验证选项"&gt;身份验证选项&lt;/h2&gt;
&lt;p&gt;这是文章真正增值的地方。根据你的场景提供四种身份验证方法：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;使用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;基于密钥&lt;/strong&gt;（默认）&lt;/td&gt;
&lt;td&gt;开发或没有 Entra 身份验证的服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Microsoft Entra&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;使用托管标识的生产环境&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OAuth 身份透传&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每个用户单独认证的生产环境&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;无身份验证&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开发/测试或仅公开数据&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;对于生产环境，使用代理身份的 Microsoft Entra 是推荐路径。OAuth 身份透传适用于用户上下文重要的场景 — 代理提示用户登录，每个请求携带用户自己的令牌。&lt;/p&gt;
&lt;h2 id="设置方法"&gt;设置方法&lt;/h2&gt;
&lt;p&gt;大致流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;将 MCP 服务器部署到 Azure Functions&lt;/strong&gt; — &lt;a href="https://github.com/Azure-Samples/remote-mcp-functions-dotnet"&gt;.NET&lt;/a&gt;、Python、TypeScript 和 Java 的示例均可用&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在你的函数应用上启用内置 MCP 身份验证&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;获取你的端点 URL&lt;/strong&gt; — &lt;code&gt;https://&amp;lt;FUNCTION_APP_NAME&amp;gt;.azurewebsites.net/runtime/webhooks/mcp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在 Foundry 中添加 MCP 服务器作为工具&lt;/strong&gt; — 在门户中导航到你的代理，添加新的 MCP 工具，提供端点和凭据&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;然后在 Agent Builder 操场中发送一个会触发你某个工具的提示来测试它。&lt;/p&gt;
&lt;h2 id="我的看法"&gt;我的看法&lt;/h2&gt;
&lt;p&gt;这里的组合性故事变得非常强大。用 .NET（或 Python、TypeScript、Java）构建一次 MCP 服务器，部署到 Azure Functions，每个 MCP 兼容的客户端都能使用它 — 编码工具、聊天应用，现在还有企业 AI 代理。这是一个真正有效的&amp;quot;一次编写，到处使用&amp;quot;模式。&lt;/p&gt;
&lt;p&gt;特别是对于 .NET 开发者，&lt;a href="https://github.com/Azure-Samples/remote-mcp-functions-dotnet"&gt;Azure Functions MCP 扩展&lt;/a&gt;让这一切变得简单明了。你将工具定义为 Azure Functions，部署，就拥有了一个具备 Azure Functions 所提供的所有安全性和可扩展性的生产级 MCP 服务器。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;如果你有在 Azure Functions 上运行的 MCP 工具，将它们连接到 Foundry 代理是一个快速的胜利 — 你的自定义工具变成了企业 AI 能力，具有适当的身份验证，且服务器本身无需代码更改。&lt;/p&gt;
&lt;p&gt;阅读&lt;a href="https://devblogs.microsoft.com/azure-sdk/give-your-foundry-agent-custom-tools-with-mcp-servers-on-azure-functions/"&gt;完整指南&lt;/a&gt;了解每种身份验证方法的分步说明，查看&lt;a href="https://learn.microsoft.com/azure/azure-functions/functions-mcp-foundry-tools?tabs=entra%2Cmcp-extension%2Cfoundry"&gt;详细文档&lt;/a&gt;了解生产环境配置。&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.115 — 后台终端通知、SSH Agent 模式及更多</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-115-agent-improvements/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-115-agent-improvements/</guid><description>VS Code 1.115 带来了面向 Agent 的后台终端通知、SSH 远程 Agent 托管、终端文件粘贴以及会话感知的编辑追踪。以下是对 .NET 开发者重要的内容。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。如需查看原文，&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-115-agent-improvements/"&gt;请点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;VS Code 1.115 刚刚&lt;a href="https://code.visualstudio.com/updates/v1_115"&gt;发布&lt;/a&gt;了，虽然从主要功能来看这是一个较轻量的版本，但如果你每天都在使用 AI 编程助手，那么与 Agent 相关的改进确实非常实用。&lt;/p&gt;
&lt;p&gt;让我来重点介绍一下真正值得了解的内容。&lt;/p&gt;
&lt;h2 id="后台终端与-agent-通信"&gt;后台终端与 Agent 通信&lt;/h2&gt;
&lt;p&gt;这是本次最突出的功能。后台终端现在会在命令完成时自动通知 Agent，包括退出代码和终端输出。后台终端中的输入提示也会被检测并展示给用户。&lt;/p&gt;
&lt;p&gt;这为什么重要？如果你用过 Copilot 的 Agent 模式在后台运行构建命令或测试套件，你肯定知道&amp;quot;那个跑完了没？&amp;ldquo;的痛苦——后台终端基本上就是发射后不管。现在 Agent 会在你的 &lt;code&gt;dotnet build&lt;/code&gt; 或 &lt;code&gt;dotnet test&lt;/code&gt; 完成时收到通知，看到输出，并相应地做出反应。这是一个小改动，但让 Agent 驱动的工作流程变得更加可靠。&lt;/p&gt;
&lt;p&gt;还有一个新的 &lt;code&gt;send_to_terminal&lt;/code&gt; 工具，允许 Agent 在用户确认后向后台终端发送命令，解决了 &lt;code&gt;run_in_terminal&lt;/code&gt; 带超时参数时会将终端移到后台并使其变为只读的问题。&lt;/p&gt;
&lt;h2 id="ssh-远程-agent-托管"&gt;SSH 远程 Agent 托管&lt;/h2&gt;
&lt;p&gt;VS Code 现在支持通过 SSH 连接到远程机器，自动安装 CLI 并以 Agent 主机模式启动。这意味着你的 AI Agent 会话可以直接针对远程环境——对于在 Linux 服务器或云虚拟机上构建和测试的 .NET 开发者来说非常有用。&lt;/p&gt;
&lt;h2 id="agent-会话中的编辑追踪"&gt;Agent 会话中的编辑追踪&lt;/h2&gt;
&lt;p&gt;Agent 会话期间进行的文件编辑现在会被追踪和恢复，支持差异对比、撤销/重做和状态恢复。如果 Agent 修改了你的代码并且出了问题，你可以准确地看到哪些内容发生了变化并将其回滚。让 Agent 修改代码库时更加安心。&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;浏览器标签页追踪&lt;/strong&gt; — 聊天现在可以追踪和链接会话期间打开的浏览器标签页，这样 Agent 可以引用你正在查看的网页&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;终端文件粘贴&lt;/strong&gt; — 使用 Ctrl+V、拖放或右键点击将文件（包括图片）粘贴到终端&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;小地图中的测试覆盖率&lt;/strong&gt; — 测试覆盖率指示器现在显示在小地图中，提供快速的视觉概览&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mac 上的双指缩放&lt;/strong&gt; — 集成浏览器支持双指缩放手势&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会话中的 Copilot 使用权限&lt;/strong&gt; — 状态栏在会话视图中显示使用信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;转到文件中的网站图标&lt;/strong&gt; — 打开的网页在快速选择列表中显示网站图标&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;VS Code 1.115 是一个渐进式版本，但 Agent 改进——后台终端通知、SSH Agent 托管和编辑追踪——加在一起为 AI 辅助开发带来了明显更流畅的体验。如果你在 .NET 项目中使用 Copilot 的 Agent 模式，这些正是每天减少摩擦的生活质量改进。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://code.visualstudio.com/updates/v1_115"&gt;完整的发行说明&lt;/a&gt;了解所有细节。&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2 自带文档 CLI — 你的 AI 代理也能用</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-docs-cli-ai-skills/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-docs-cli-ai-skills/</guid><description>.NET Aspire 13.2 新增了 aspire docs — 一个无需离开终端即可搜索、浏览和阅读官方文档的 CLI。它也可以作为 AI 代理的工具。这就是为什么这很重要。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-docs-cli-ai-skills/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你知道那种时刻吗——你正深入一个 Aspire AppHost，接入各种集成，然后需要确认 Redis 集成到底需要哪些参数？你 Alt-Tab 切到浏览器，在 aspire.dev 上翻来翻去，眯着眼看 API 文档，然后切回编辑器。上下文没了，心流断了。&lt;/p&gt;
&lt;p&gt;Aspire 13.2 刚刚&lt;a href="https://devblogs.microsoft.com/aspire/aspire-docs-in-your-terminal/"&gt;发布了解决方案&lt;/a&gt;。&lt;code&gt;aspire docs&lt;/code&gt; CLI 让你直接从终端搜索、浏览和阅读 Aspire 官方文档。而且因为它由可复用的服务支撑，AI 代理和技能可以使用同样的命令来查找文档，而不是幻想出不存在的 API。&lt;/p&gt;
&lt;h2 id="这到底解决了什么问题"&gt;这到底解决了什么问题&lt;/h2&gt;
&lt;p&gt;David Pine 在原文中说得很到位：AI 代理在帮助开发者构建 Aspire 应用方面&lt;em&gt;糟糕透了&lt;/em&gt;。它们推荐 &lt;code&gt;dotnet run&lt;/code&gt; 而不是 &lt;code&gt;aspire run&lt;/code&gt;，引用 learn.microsoft.com 来查找实际在 aspire.dev 上的文档，建议过时的 NuGet 包，还有——我个人最喜欢的——幻想出根本不存在的 API。&lt;/p&gt;
&lt;p&gt;为什么？因为 Aspire 作为 .NET 专属工具的时间远比它成为多语言工具的时间长，而且 LLM 使用的训练数据早于最新功能。当你给 AI 代理真正查找当前文档的能力时，它就不再猜测，开始变得有用了。&lt;/p&gt;
&lt;h2 id="三个命令零个浏览器标签页"&gt;三个命令，零个浏览器标签页&lt;/h2&gt;
&lt;p&gt;CLI 简洁得令人耳目一新：&lt;/p&gt;
&lt;h3 id="列出所有文档"&gt;列出所有文档&lt;/h3&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;aspire docs list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;返回 aspire.dev 上所有可用的文档页面。需要机器可读的输出？加上 &lt;code&gt;--format Json&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id="搜索主题"&gt;搜索主题&lt;/h3&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;aspire docs search &lt;span class="s2"&gt;&amp;#34;redis&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同时搜索标题和内容，使用加权相关性评分。与内部驱动文档工具的搜索引擎完全一样。你会得到带有标题、slug 和相关性分数的排名结果。&lt;/p&gt;
&lt;h3 id="阅读完整页面或仅一个章节"&gt;阅读完整页面（或仅一个章节）&lt;/h3&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;aspire docs get redis-integration
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将完整页面以 markdown 格式流式传输到你的终端。只需要一个章节？&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;aspire docs get redis-integration --section &lt;span class="s2"&gt;&amp;#34;Add Redis resource&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;精准定位。不用滚动 500 行。只看你需要的部分。&lt;/p&gt;
&lt;h2 id="ai-代理的视角"&gt;AI 代理的视角&lt;/h2&gt;
&lt;p&gt;对于我们这些使用 AI 工具进行开发的人来说，这才是真正有趣的地方。同样的 &lt;code&gt;aspire docs&lt;/code&gt; 命令可以作为 AI 代理的工具——通过技能、MCP 服务器或简单的 CLI 封装。&lt;/p&gt;
&lt;p&gt;你的 AI 助手不再根据过时的训练数据编造 Aspire API，而是可以调用 &lt;code&gt;aspire docs search &amp;quot;postgres&amp;quot;&lt;/code&gt;，找到官方集成文档，阅读正确的页面，给你文档记录的方案。实时的、最新的文档——而不是模型六个月前记住的内容。&lt;/p&gt;
&lt;p&gt;背后的架构是有意为之的。Aspire 团队构建了可复用的服务（&lt;code&gt;IDocsIndexService&lt;/code&gt;、&lt;code&gt;IDocsSearchService&lt;/code&gt;、&lt;code&gt;IDocsFetcher&lt;/code&gt;、&lt;code&gt;IDocsCache&lt;/code&gt;），而不是一次性集成。这意味着同一个搜索引擎为终端中的人类、编辑器中的 AI 代理以及 CI 流水线中的自动化服务。&lt;/p&gt;
&lt;h2 id="真实场景"&gt;真实场景&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;终端快速查询：&lt;/strong&gt; 你已经深入到第三个文件，需要 Redis 配置参数。两个命令，九十秒，回去干活：&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;aspire docs search &lt;span class="s2"&gt;&amp;#34;redis&amp;#34;&lt;/span&gt; --limit &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs get redis-integration --section &lt;span class="s2"&gt;&amp;#34;Configuration&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;AI 辅助开发：&lt;/strong&gt; 你的 VS Code 技能封装了 CLI 命令。你问&amp;quot;给我的 AppHost 添加一个 PostgreSQL 数据库&amp;quot;，代理在回答之前先查阅真实文档。没有幻觉。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CI/CD 验证：&lt;/strong&gt; 你的流水线以编程方式根据官方文档验证 AppHost 配置。&lt;code&gt;--format Json&lt;/code&gt; 输出可以干净地通过管道传递给 &lt;code&gt;jq&lt;/code&gt; 和其他工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自定义知识库：&lt;/strong&gt; 在构建自己的 AI 工具？将结构化 JSON 输出直接导入你的知识库：&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;aspire docs search &lt;span class="s2"&gt;&amp;#34;monitoring&amp;#34;&lt;/span&gt; --format Json &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;[.[] | {slug, title, summary}]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不需要网页抓取。不需要 API 密钥。与文档工具内部使用的完全一样的结构化数据。&lt;/p&gt;
&lt;h2 id="文档始终是最新的"&gt;文档始终是最新的&lt;/h2&gt;
&lt;p&gt;这是我最欣赏的部分。CLI 不会下载快照——它通过基于 ETag 的缓存查询 aspire.dev。文档一旦更新，你的 CLI 和构建在其之上的所有技能都会反映出来。没有过时的副本，没有&amp;quot;但是 wiki 上说的是&amp;hellip;&amp;ldquo;的尴尬时刻。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;aspire docs&lt;/code&gt; 是那种以简洁方式解决真实问题的小功能之一。人类获得了终端原生的文档访问。AI 代理获得了停止猜测、开始引用真实文档的方式。而且一切都由同一个事实来源支撑。&lt;/p&gt;
&lt;p&gt;如果你正在使用 .NET Aspire 开发，还没试过这个 CLI，运行 &lt;code&gt;aspire docs search &amp;quot;你的主题&amp;quot;&lt;/code&gt; 看看感觉如何。然后考虑将这些命令封装到你正在使用的任何 AI 技能或自动化设置中——你的代理会感谢你的。&lt;/p&gt;
&lt;p&gt;查看 &lt;a href="https://davidpine.dev/posts/aspire-docs-mcp-tools/"&gt;David Pine 的深入分析&lt;/a&gt;了解文档工具是如何构建的，以及&lt;a href="https://aspire.dev/reference/cli/commands/aspire-docs/"&gt;官方 CLI 参考&lt;/a&gt;获取所有细节。&lt;/p&gt;</content:encoded></item><item><title>Microsoft Agent Framework 正式发布 1.0 — 这些才是 .NET 开发者真正需要关注的</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agent-framework-1-0-production-ready/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agent-framework-1-0-production-ready/</guid><description>Microsoft Agent Framework 1.0 已具备生产环境就绪能力，拥有稳定的 API、多代理编排以及所有主流 AI 提供商的连接器。以下是作为 .NET 开发者你需要了解的内容。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。如需查看原文，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agent-framework-1-0-production-ready/"&gt;点击此处&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你一直在关注 Agent Framework 从早期 Semantic Kernel 和 AutoGen 时代走来的历程，这次的消息意义重大。Microsoft Agent Framework 刚刚&lt;a href="https://devblogs.microsoft.com/agent-framework/microsoft-agent-framework-version-1-0/"&gt;发布了 1.0 版本&lt;/a&gt; — 生产就绪、API 稳定、长期支持承诺。它同时支持 .NET 和 Python，并且真正可以承载实际工作负载。&lt;/p&gt;
&lt;p&gt;让我跳过公告的噪音，专注于你用 .NET 构建 AI 驱动应用时真正重要的内容。&lt;/p&gt;
&lt;h2 id="简短版本"&gt;简短版本&lt;/h2&gt;
&lt;p&gt;Agent Framework 1.0 将之前的 Semantic Kernel 和 AutoGen 统一为一个开源 SDK。一个代理抽象。一个编排引擎。多个 AI 提供商。如果你之前一直在 Semantic Kernel（企业模式）和 AutoGen（研究级多代理工作流）之间来回切换，现在可以停了。这就是那个唯一的 SDK。&lt;/p&gt;
&lt;h2 id="入门简单得几乎不公平"&gt;入门简单得几乎不公平&lt;/h2&gt;
&lt;p&gt;这是一个在 .NET 中运行的代理：&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="c1"&gt;// dotnet add package Microsoft.Agents.AI.OpenAI --prerelease&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI&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;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI.Foundry&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;using&lt;/span&gt; &lt;span class="nn"&gt;Azure.Identity&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="kt"&gt;var&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;AIProjectClient&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 class="s"&gt;&amp;#34;https://your-project.services.ai.azure.com&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 class="n"&gt;GetResponsesClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gpt-5.3&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 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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;HaikuBot&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;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are an upbeat assistant that writes beautifully.&amp;#34;&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;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;Write a haiku about shipping 1.0.&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;就这些。几行代码，你就有了一个在 Azure Foundry 上运行的 AI 代理。Python 的等效代码同样简洁。随着需求增长，逐步添加函数工具、多轮对话和流式输出 — API 表面会平稳地扩展，不会变得奇怪。&lt;/p&gt;
&lt;h2 id="多代理编排--这才是真正的核心"&gt;多代理编排 — 这才是真正的核心&lt;/h2&gt;
&lt;p&gt;单个代理对演示来说够了，但生产场景通常需要协调。Agent Framework 1.0 附带了经过实战考验的编排模式，直接来自 Microsoft Research 和 AutoGen：&lt;/p&gt;
&lt;ul&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;li&gt;&lt;strong&gt;Magentic-One&lt;/strong&gt; — 来自 MSR 的研究级多代理模式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所有这些都支持流式处理、检查点、人机回路审批以及暂停/恢复。检查点部分至关重要 — 长时间运行的工作流在进程重启后依然可以恢复。对于我们这些用 Azure Functions 构建过持久工作流的 .NET 开发者来说，这感觉很熟悉。&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; 你知道 ASP.NET Core 有中间件管道吗？同样的概念，但用于代理执行。拦截每个阶段 — 添加内容安全、日志记录、合规策略 — 而无需触碰代理的提示词。这就是让代理达到企业级标准的方式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可插拔内存。&lt;/strong&gt; 对话历史、持久键值状态、基于向量的检索。选择你的后端：Foundry Agent Service、Mem0、Redis、Neo4j，或者自己实现。内存是将无状态的 LLM 调用变成真正能记住上下文的代理的关键。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;声明式 YAML 代理。&lt;/strong&gt; 在版本控制的 YAML 文件中定义代理的指令、工具、内存和编排拓扑。通过单个 API 调用加载和运行。这对于想要在不重新部署代码的情况下迭代代理行为的团队来说是颠覆性的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A2A 和 MCP 支持。&lt;/strong&gt; MCP（Model Context Protocol）让代理能够动态发现和调用外部工具。A2A（Agent-to-Agent 协议）实现跨运行时协作 — 你的 .NET 代理可以与其他框架中运行的代理进行协调。A2A 1.0 支持即将推出。&lt;/p&gt;
&lt;h2 id="值得关注的预览功能"&gt;值得关注的预览功能&lt;/h2&gt;
&lt;p&gt;1.0 中有些功能以预览形式发布 — 功能可用但 API 可能会演进：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DevUI&lt;/strong&gt; — 一个基于浏览器的本地调试器，用于实时可视化代理执行、消息流和工具调用。可以把它想象成 Application Insights，但用于代理推理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Copilot SDK 和 Claude Code SDK&lt;/strong&gt; — 直接从编排代码中使用 Copilot 或 Claude 作为代理工具。在同一工作流中将编程代理与其他代理组合在一起。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Harness&lt;/strong&gt; — 一个可定制的本地运行时，为代理提供对 shell、文件系统和消息循环的访问。可以理解为编码代理和自动化模式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt; — 可复用的领域能力包，为代理提供开箱即用的结构化能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="从-semantic-kernel-或-autogen-迁移"&gt;从 Semantic Kernel 或 AutoGen 迁移&lt;/h2&gt;
&lt;p&gt;如果你有现有的 Semantic Kernel 或 AutoGen 代码，有专门的迁移助手可以分析你的代码并生成逐步迁移计划。&lt;a href="https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-semantic-kernel"&gt;Semantic Kernel 迁移指南&lt;/a&gt;和 &lt;a href="https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-autogen"&gt;AutoGen 迁移指南&lt;/a&gt;会引导你完成所有步骤。&lt;/p&gt;
&lt;p&gt;如果你一直在使用 RC 包，升级到 1.0 只需更改版本号。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Agent Framework 1.0 是企业团队一直在等待的生产里程碑。稳定的 API、多提供商支持、真正能在大规模下运行的编排模式，以及从 Semantic Kernel 和 AutoGen 的迁移路径。&lt;/p&gt;
&lt;p&gt;该框架已&lt;a href="https://github.com/microsoft/agent-framework"&gt;在 GitHub 上完全开源&lt;/a&gt;，你今天就可以通过 &lt;code&gt;dotnet add package Microsoft.Agents.AI&lt;/code&gt; 开始使用。查看&lt;a href="https://learn.microsoft.com/en-us/agent-framework/get-started/"&gt;快速入门指南&lt;/a&gt;和&lt;a href="https://github.com/microsoft/agent-framework"&gt;示例&lt;/a&gt;来动手实践。&lt;/p&gt;
&lt;p&gt;如果你一直在等待&amp;quot;可以安全用于生产&amp;quot;的信号 — 就是现在。&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2的Dashboard现在有了遥测API — 这改变了一切</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/</guid><description>.NET Aspire 13.2带来了更智能的遥测导出、可编程的trace和日志API，以及GenAI可视化改进。了解为什么这对你的调试工作流很重要。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原始版本，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你一直在用 .NET Aspire 构建分布式应用，你已经知道dashboard是整个体验中最棒的部分。所有的trace、日志和指标都在一个地方 — 不需要外部的Jaeger，不需要Seq配置，不需要&amp;quot;让我看看另一个终端&amp;quot;的时刻。&lt;/p&gt;
&lt;p&gt;Aspire 13.2 刚刚做了重大改进。James Newton-King &lt;a href="https://devblogs.microsoft.com/aspire/aspire-dashboard-improvements-export-and-telemetry/"&gt;发布了更新公告&lt;/a&gt;，说实话，单是遥测导出和API功能就值得升级。&lt;/p&gt;
&lt;h2 id="像正常人一样导出遥测数据"&gt;像正常人一样导出遥测数据&lt;/h2&gt;
&lt;p&gt;这是我们都经历过的场景：你在调试一个分布式问题，花了二十分钟终于复现了，现在你需要和团队分享发生了什么。之前？截图。复制粘贴trace ID。一如既往的混乱。&lt;/p&gt;
&lt;p&gt;Aspire 13.2 添加了一个&lt;strong&gt;管理日志和遥测&lt;/strong&gt;对话框，你可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;清除所有遥测（在复现bug之前很有用）&lt;/li&gt;
&lt;li&gt;将选定的遥测数据导出为标准OTLP/JSON格式的ZIP文件&lt;/li&gt;
&lt;li&gt;稍后将该ZIP重新导入任何Aspire dashboard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后一点是杀手级功能。你复现一个bug，导出遥测数据，附加到工作项，你的队友可以导入到自己的dashboard中，看到你所看到的完全一样的内容。不再需要&amp;quot;你能在你的机器上复现吗？&amp;quot;&lt;/p&gt;
&lt;p&gt;单个trace、span和日志也在上下文菜单中有了&amp;quot;Export JSON&amp;quot;选项。需要分享一个特定的trace？右键点击，复制JSON，粘贴到PR描述中。搞定。&lt;/p&gt;
&lt;h2 id="遥测api才是真正的革命性变化"&gt;遥测API才是真正的革命性变化&lt;/h2&gt;
&lt;p&gt;这是最让我兴奋的。Dashboard现在在&lt;code&gt;/api/telemetry&lt;/code&gt;下暴露了HTTP API，用于编程式查询遥测数据。可用端点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/resources&lt;/code&gt; — 列出有遥测数据的资源&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/spans&lt;/code&gt; — 带过滤器查询span&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/logs&lt;/code&gt; — 带过滤器查询日志&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/traces&lt;/code&gt; — 列出trace&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/traces/{traceId}&lt;/code&gt; — 获取特定trace的所有span&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一切都以OTLP JSON格式返回。这驱动了新的CLI命令&lt;code&gt;aspire agent mcp&lt;/code&gt;和&lt;code&gt;aspire otel&lt;/code&gt;，但真正的意义更大：你现在可以构建工具、脚本和AI代理集成，直接查询你应用的遥测数据。&lt;/p&gt;
&lt;p&gt;想象一个AI编码代理在调试时能看到你实际的分布式trace。这不再是假设 — 这就是这个API所实现的。&lt;/p&gt;
&lt;h2 id="genai遥测变得实用"&gt;GenAI遥测变得实用&lt;/h2&gt;
&lt;p&gt;如果你正在用Semantic Kernel或Microsoft.Extensions.AI构建AI驱动的应用，你会喜欢改进的GenAI遥测可视化器。Aspire 13.2 新增了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI工具描述以Markdown渲染&lt;/li&gt;
&lt;li&gt;Trace页面上的专用GenAI按钮，方便快速访问&lt;/li&gt;
&lt;li&gt;对截断或非标准GenAI JSON更好的错误处理&lt;/li&gt;
&lt;li&gt;工具定义之间的点击高亮导航&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;文章提到VS Code Copilot chat、Copilot CLI和OpenCode都支持配置&lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt;。将它们指向Aspire dashboard，你可以通过遥测数据实时观看你的AI代理思考过程。这是你在其他任何地方都找不到的调试体验。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Aspire 13.2将dashboard从&amp;quot;不错的调试UI&amp;quot;转变为&amp;quot;可编程的可观测性平台&amp;quot;。单是导出/导入工作流就能在分布式调试中节省真实时间，而遥测API为AI辅助诊断打开了大门。&lt;/p&gt;
&lt;p&gt;如果你已经在用Aspire，升级吧。如果还没有 — 这是一个了解&lt;a href="https://aspire.dev"&gt;aspire.dev&lt;/a&gt;的好理由。&lt;/p&gt;</content:encoded></item><item><title>azd现在可以在本地运行和调试AI代理了 — 2026年3月都有哪些变化</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</guid><description>Azure Developer CLI在2026年3月发布了七个版本。亮点：AI代理的本地运行和调试循环、GitHub Copilot项目设置集成、Container App Jobs支持。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原始版本，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一个月七个版本。这是Azure Developer CLI (&lt;code&gt;azd&lt;/code&gt;) 团队在2026年3月发布的成果，而头条功能正是我一直在等的：&lt;strong&gt;AI代理的本地运行和调试循环&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;PC Chan &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;发布了完整摘要&lt;/a&gt;，虽然内容很多，但让我筛选出对构建AI驱动应用的.NET开发者真正重要的部分。&lt;/p&gt;
&lt;h2 id="不用部署就能运行和调试ai代理"&gt;不用部署就能运行和调试AI代理&lt;/h2&gt;
&lt;p&gt;这是最大的亮点。新的 &lt;code&gt;azure.ai.agents&lt;/code&gt; 扩展添加了一组命令，为AI代理提供了完整的内循环体验：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;azd ai agent run&lt;/code&gt; — 在本地启动你的代理&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent invoke&lt;/code&gt; — 向其发送消息（本地或已部署的）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent show&lt;/code&gt; — 显示容器状态和健康状况&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent monitor&lt;/code&gt; — 实时流式传输容器日志&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以前，测试AI代理意味着每次修改都要部署到Microsoft Foundry。现在你可以在本地迭代，测试代理行为，准备好了再部署。&lt;/p&gt;
&lt;h2 id="github-copilot为你配置azd项目"&gt;GitHub Copilot为你配置azd项目&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd init&lt;/code&gt; 现在提供了&amp;quot;Set up with GitHub Copilot (Preview)&amp;ldquo;选项。无需手动回答关于项目结构的提示，Copilot代理为你生成配置。当命令失败时，&lt;code&gt;azd&lt;/code&gt; 提供AI辅助的问题排查——全程不需要离开终端。&lt;/p&gt;
&lt;h2 id="container-app-jobs和部署改进"&gt;Container App Jobs和部署改进&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Container App Jobs&lt;/strong&gt;：&lt;code&gt;azd&lt;/code&gt;现在通过现有的&lt;code&gt;host: containerapp&lt;/code&gt;配置部署&lt;code&gt;Microsoft.App/jobs&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可配置的部署超时&lt;/strong&gt;：&lt;code&gt;azd deploy&lt;/code&gt;的新&lt;code&gt;--timeout&lt;/code&gt;标志和&lt;code&gt;azure.yaml&lt;/code&gt;中的&lt;code&gt;deployTimeout&lt;/code&gt;字段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;远程构建回退&lt;/strong&gt;：当ACR构建失败时，&lt;code&gt;azd&lt;/code&gt;自动回退到本地Docker/Podman构建。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本地预检验证&lt;/strong&gt;：部署前在本地验证Bicep参数。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="开发体验改进"&gt;开发体验改进&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自动检测pnpm/yarn&lt;/strong&gt; — JS/TS项目&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pyproject.toml支持&lt;/strong&gt; — Python打包&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本地模板目录&lt;/strong&gt; — &lt;code&gt;azd init --template&lt;/code&gt;接受文件系统路径&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更好的错误消息&lt;/strong&gt; — &lt;code&gt;--no-prompt&lt;/code&gt;模式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;构建环境变量&lt;/strong&gt; — 注入到所有框架构建子进程（.NET、Node.js、Java、Python）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;本地AI代理调试循环是这个版本的明星，但部署改进和DX优化的积累使&lt;code&gt;azd&lt;/code&gt;比以往更加成熟。如果你在Azure上部署.NET应用——特别是AI代理——这次更新值得关注。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;完整发行说明&lt;/a&gt;了解所有细节。&lt;/p&gt;</content:encoded></item><item><title>Visual Studio 3月更新允许构建自定义Copilot代理 — find_symbol是一大亮点</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/</guid><description>Visual Studio 2026年3月更新带来了自定义Copilot代理、可复用的代理技能、语言感知的find_symbol工具、以及从Test Explorer进行的Copilot性能分析。</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原始版本，请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Visual Studio刚刚获得了最重要的Copilot更新。Mark Downie &lt;a href="https://devblogs.microsoft.com/visualstudio/visual-studio-march-update-build-your-own-custom-agents/"&gt;发布了3月版本&lt;/a&gt;，标题是自定义代理——但说实话，&lt;code&gt;find_symbol&lt;/code&gt;工具可能才是最能改变你工作流的功能。&lt;/p&gt;
&lt;h2 id="仓库中的自定义copilot代理"&gt;仓库中的自定义Copilot代理&lt;/h2&gt;
&lt;p&gt;想让Copilot遵循你团队的编码标准？自定义代理定义为&lt;code&gt;.github/agents/&lt;/code&gt;中的&lt;code&gt;.agent.md&lt;/code&gt;文件。每个代理都有完整的工作区感知、代码理解、工具、首选模型和MCP连接访问权限。&lt;/p&gt;
&lt;h2 id="代理技能可复用的指令包"&gt;代理技能：可复用的指令包&lt;/h2&gt;
&lt;p&gt;技能从仓库的&lt;code&gt;.github/skills/&lt;/code&gt;或个人资料的&lt;code&gt;~/.copilot/skills/&lt;/code&gt;自动加载。&lt;/p&gt;
&lt;h2 id="find_symbol语言感知导航"&gt;find_symbol：语言感知导航&lt;/h2&gt;
&lt;p&gt;新的&lt;code&gt;find_symbol&lt;/code&gt;工具为Copilot的代理模式提供了基于语言服务的符号导航。代理不再搜索文本，而是可以找到符号的所有引用并访问类型信息和作用域。&lt;/p&gt;
&lt;p&gt;对于.NET开发者来说这是巨大改进——拥有深层类型层次结构的C#代码库受益匪浅。&lt;/p&gt;
&lt;h2 id="用copilot分析测试性能"&gt;用Copilot分析测试性能&lt;/h2&gt;
&lt;p&gt;Test Explorer上下文菜单中新增了&lt;strong&gt;Profile with Copilot&lt;/strong&gt;。Profiling Agent自动运行测试并分析性能。&lt;/p&gt;
&lt;h2 id="实时调试中的perf-tips"&gt;实时调试中的Perf Tips&lt;/h2&gt;
&lt;p&gt;性能优化现在在调试过程中进行。Visual Studio内联显示执行时间。看到慢的行？点击Perf Tip向Copilot请求优化建议。&lt;/p&gt;
&lt;h2 id="从solution-explorer修复nuget漏洞"&gt;从Solution Explorer修复NuGet漏洞&lt;/h2&gt;
&lt;p&gt;当检测到NuGet包漏洞时，Solution Explorer中直接显示&lt;strong&gt;Fix with GitHub Copilot&lt;/strong&gt;链接。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;自定义代理和技能是标题，但&lt;code&gt;find_symbol&lt;/code&gt;是隐藏的亮点——它从根本上改变了Copilot重构.NET代码时的准确性。下载&lt;a href="https://visualstudio.microsoft.com/downloads/"&gt;Visual Studio 2026 Insiders&lt;/a&gt;来体验所有新功能。&lt;/p&gt;</content:encoded></item><item><title>KubeCon Europe 2026：.NET 开发者真正需要关注的内容</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/</link><pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/</guid><description>微软在 KubeCon Europe 2026 上发布了大量 Kubernetes 公告。这是过滤后的版本——只有当你在交付 .NET 应用时真正重要的 AKS 和云原生更新。</description><content:encoded>&lt;p&gt;&lt;em&gt;本文为自动翻译。查看原文请&lt;a href="https://thedotnetblog.com/zh/news/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/"&gt;点击这里&lt;/a&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;你知道那种感觉吗？一个巨大的公告文章出来了，你一边滚动一边想&amp;quot;不错，但这对我到底有什么改变&amp;quot;？这就是我每个 KubeCon 季的状态。&lt;/p&gt;
&lt;p&gt;微软刚刚发布了他们的 &lt;a href="https://opensource.microsoft.com/blog/2026/03/24/whats-new-with-microsoft-in-open-source-and-kubernetes-at-kubecon-cloudnativecon-europe-2026/"&gt;KubeCon Europe 2026 完整总结&lt;/a&gt;——出自 Brendan Burns 本人之手——说实话？这次有真正的干货。不只是功能清单，而是真正改变你在生产环境中运维方式的运营改进。&lt;/p&gt;
&lt;p&gt;让我来梳理一下对我们 .NET 开发者真正重要的内容。&lt;/p&gt;
&lt;h2 id="不用付服务网格税的-mtls"&gt;不用付服务网格税的 mTLS&lt;/h2&gt;
&lt;p&gt;服务网格的问题在于：每个人都想要安全保障，没人想要运营负担。AKS 终于在弥补这个差距了。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aka.ms/aks/application-network"&gt;Azure Kubernetes Application Network&lt;/a&gt; 给你提供了双向 TLS、应用感知授权和流量遥测——不需要部署一个带 sidecar 的重型 mesh。结合 &lt;a href="https://aka.ms/acns/cilium-mtls"&gt;Advanced Container Networking Services 中的 Cilium mTLS&lt;/a&gt;，你可以获得使用 X.509 证书和 SPIRE 身份管理的加密 pod 间通信。&lt;/p&gt;
&lt;p&gt;这在实践中意味着什么：你的 ASP.NET Core API 与后台 worker 通信，你的 gRPC 服务互相调用——全部在网络层加密和身份验证，零应用代码更改。这意义重大。&lt;/p&gt;
&lt;p&gt;对于从 &lt;code&gt;ingress-nginx&lt;/code&gt; 迁移的团队，还有 &lt;a href="https://aka.ms/aks/app-routing/gateway-api"&gt;Meshless Istio 的 Application Routing&lt;/a&gt; 全面支持 Kubernetes Gateway API。无 sidecar。基于标准。并且发布了 &lt;code&gt;ingress2gateway&lt;/code&gt; 工具用于增量迁移。&lt;/p&gt;
&lt;h2 id="不再是事后想到的-gpu-可观测性"&gt;不再是事后想到的 GPU 可观测性&lt;/h2&gt;
&lt;p&gt;如果你在 .NET 服务旁运行 AI 推理（说实话，谁现在还没开始？），你可能遇到过 GPU 监控盲区。CPU/内存仪表板很棒，然后 GPU 部分…没有手动配置导出器就什么都没有。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aka.ms/aks/managed-gpu-metrics"&gt;AKS 现在原生暴露 GPU 指标&lt;/a&gt; 到托管的 Prometheus 和 Grafana。同样的技术栈，同样的仪表板，同样的告警管道。无需自定义导出器，无需第三方代理。&lt;/p&gt;
&lt;p&gt;在网络方面，增加了 HTTP、gRPC 和 Kafka 流量的逐流可见性，配合&lt;a href="https://learn.microsoft.com/en-us/azure/aks/container-network-observability-logs"&gt;一键 Azure Monitor 体验&lt;/a&gt;。IP、端口、工作负载、流方向、策略决策——全部在内置仪表板中。&lt;/p&gt;
&lt;p&gt;让我看了两遍的是：&lt;a href="https://learn.microsoft.com/en-us/azure/aks/advanced-container-networking-services-overview"&gt;agentic container networking&lt;/a&gt; 添加了一个 Web UI，你可以用自然语言询问集群的网络状态。&amp;ldquo;为什么 pod X 无法到达服务 Y？&amp;quot;→ 从实时遥测获取只读诊断。凌晨两点真的很有用。&lt;/p&gt;
&lt;h2 id="不需要博士学位的跨集群网络"&gt;不需要博士学位的跨集群网络&lt;/h2&gt;
&lt;p&gt;多集群 Kubernetes 历来是&amp;quot;自带网络胶水&amp;quot;的体验。Azure Kubernetes Fleet Manager 现在通过托管 Cilium 集群网格提供&lt;a href="https://aka.ms/kubernetes-fleet/networking/cross-cluster"&gt;跨集群网络&lt;/a&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AKS 集群间的统一连接&lt;/li&gt;
&lt;li&gt;用于跨集群发现的全局服务注册表&lt;/li&gt;
&lt;li&gt;集中管理配置，而不是每个集群重复&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你为了弹性或合规在多个区域运行 .NET 微服务，这替代了很多脆弱的自定义胶水。West Europe 的服务 A 可以通过网格发现和调用 East US 的服务 B，使用一致的路由和安全策略。&lt;/p&gt;
&lt;h2 id="不需要勇气的升级"&gt;不需要勇气的升级&lt;/h2&gt;
&lt;p&gt;说实话——生产环境中的 Kubernetes 升级是有压力的。&amp;ldquo;升级然后祈祷&amp;quot;一直是太多团队的实际策略，也是集群版本落后的主要原因。&lt;/p&gt;
&lt;p&gt;两个新功能改变了这一点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blue-green 代理池升级&lt;/strong&gt; 用新配置创建一个并行节点池。验证行为，逐步转移流量，保持干净的回滚路径。不再在生产节点上进行就地变更。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;代理池回滚&lt;/strong&gt; 允许你在升级出问题后将节点池恢复到之前的 Kubernetes 版本和节点镜像——无需重建集群。&lt;/p&gt;
&lt;p&gt;两者结合，终于给运维人员提供了对升级生命周期的真正控制。对于 .NET 团队来说很重要，因为平台速度直接控制你能多快采用新的运行时、安全补丁和网络能力。&lt;/p&gt;
&lt;h2 id="ai-工作负载成为-kubernetes-一等公民"&gt;AI 工作负载成为 Kubernetes 一等公民&lt;/h2&gt;
&lt;p&gt;上游开源工作同样重要。Dynamic Resource Allocation (DRA) 刚在 Kubernetes 1.36 中 GA，使 GPU 调度成为真正的一等功能而不是变通方案。&lt;/p&gt;
&lt;p&gt;值得关注的项目：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;项目&lt;/th&gt;
&lt;th&gt;作用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/kaito-project/kubeairunway"&gt;AI Runway&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;推理的通用 Kubernetes API——不懂 K8s 也能部署模型，带 HuggingFace 发现和成本估算&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.cncf.io/blog/2026/01/07/holmesgpt-agentic-troubleshooting-built-for-the-cloud-native-era/"&gt;HolmesGPT&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;云原生的智能体故障排除——现在是 CNCF Sandbox 项目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/project-dalec/dalec"&gt;Dalec&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;带 SBOM 生成的声明式容器镜像构建——构建阶段减少 CVE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;方向很明确：你的 .NET API、Semantic Kernel 编排层和推理工作负载应该都运行在一个一致的平台模型上。我们正在接近。&lt;/p&gt;
&lt;h2 id="这周我会从哪里开始"&gt;这周我会从哪里开始&lt;/h2&gt;
&lt;p&gt;如果你在为团队评估这些变化，这是我真诚的优先级列表：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;先搞可观测性&lt;/strong&gt;——在非生产集群中启用 GPU 指标和网络流日志。看看你一直错过了什么。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;测试 blue-green 升级&lt;/strong&gt;——在下次生产集群升级前测试回滚工作流。建立对流程的信心。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;试点身份感知网络&lt;/strong&gt;——选择一个内部服务路径并用 Cilium 启用 mTLS。测量开销（剧透：很小）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;评估 Fleet Manager&lt;/strong&gt;——如果你运行超过两个集群，跨集群网络光减少自定义胶水就能回本。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;小实验，快反馈。这永远是正确的做法。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;KubeCon 公告可能让人应接不暇，但这批更新确实为 AKS 上的 .NET 团队带来了实质性改变。更好的网络安全（无 mesh 开销）、真正的 GPU 可观测性、更安全的升级以及更强大的 AI 基础设施支撑。&lt;/p&gt;
&lt;p&gt;如果你已经在用 AKS，现在是加强运营基准的好时机。如果你计划将 .NET 工作负载迁移到 Kubernetes——平台刚刚变得更加适合生产环境了。&lt;/p&gt;</content:encoded></item><item><title>SQL MCP Server、SSMS 中的 Copilot 以及带 AI 代理的 Database Hub：SQLCon 2026 真正重要的内容</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agentic-ai-microsoft-databases-what-matters/</link><pubDate>Sat, 28 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/agentic-ai-microsoft-databases-what-matters/</guid><description>Microsoft 在 SQLCon 2026 上发布了一系列数据库公告。如果你在 Azure SQL 上构建 AI 应用，这些才是真正重要的内容。</description><content:encoded>&lt;p&gt;Microsoft 刚刚在&lt;a href="https://www.microsoft.com/en-us/sql-server/blog/2026/03/18/advancing-agentic-ai-with-microsoft-databases-across-a-unified-data-estate/"&gt;亚特兰大与 FabCon 同期举办了 SQLCon 2026&lt;/a&gt;，内容非常多。原始公告涵盖了从节省计划到企业合规功能的方方面面。我打算跳过企业定价的幻灯片，专注于对使用 Azure SQL 和 AI 进行开发的人来说真正重要的部分。&lt;/p&gt;
&lt;h2 id="sql-mcp-server"&gt;SQL MCP Server&lt;/h2&gt;
&lt;p&gt;这是我眼中的头条新闻。Azure SQL Database Hyperscale 现在有了一个 &lt;strong&gt;SQL MCP Server&lt;/strong&gt; 公共预览版，让你可以使用 &lt;a href="https://modelcontextprotocol.io/"&gt;Model Context Protocol&lt;/a&gt; 将 SQL 数据安全地连接到 AI 代理和 Copilot。&lt;/p&gt;
&lt;p&gt;如果你一直在关注 MCP 的浪潮——说实话，现在想不注意到都难——这是一个大事件。你不再需要构建自定义数据管道来为 AI 代理提供来自数据库的上下文，而是获得了一个标准化协议来直接公开 SQL 数据。你的代理可以查询、推理并基于实时数据库信息采取行动。&lt;/p&gt;
&lt;p&gt;对于我们这些用 Semantic Kernel 或 Microsoft Agent Framework 构建 AI 代理的人来说，这打开了一条干净的集成路径。你的代理需要检查库存？查找客户记录？验证订单？MCP 提供了一种结构化的方式来做这些事情，而不需要你为每个场景编写定制的数据获取代码。&lt;/p&gt;
&lt;h2 id="ssms-22-中的-github-copilot-现已正式发布"&gt;SSMS 22 中的 GitHub Copilot 现已正式发布&lt;/h2&gt;
&lt;p&gt;如果你在 SQL Server Management Studio 中花过任何时间——说实话，我们大多数人还在用——GitHub Copilot 现在已在 SSMS 22 中正式发布。和你在 VS Code 和 Visual Studio 中使用的 Copilot 体验一样，但用于 T-SQL。&lt;/p&gt;
&lt;p&gt;实际价值很直接：基于聊天的辅助来编写查询、重构存储过程、排查性能问题和处理管理任务。概念上没什么革命性的，但直接在 SSMS 中使用意味着你不需要为了获得数据库工作的 AI 帮助而切换到另一个编辑器。&lt;/p&gt;
&lt;h2 id="向量索引获得了重大升级"&gt;向量索引获得了重大升级&lt;/h2&gt;
&lt;p&gt;Azure SQL Database 现在拥有更快、更强大的向量索引，完全支持插入、更新和删除操作。这意味着你的向量数据可以实时保持最新——不需要批量重建索引。&lt;/p&gt;
&lt;p&gt;新功能如下：&lt;/p&gt;
&lt;ul&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;如果你正在使用 Azure SQL 作为向量存储进行 Retrieval-Augmented Generation (RAG)，这些改进直接有用。你可以将向量和关系数据放在同一个数据库中，相比运行单独的向量数据库，这大大简化了你的架构。&lt;/p&gt;
&lt;p&gt;同样的向量增强功能在 Fabric 中的 SQL Database 也可用，因为两者底层运行的是同一个 SQL 引擎。&lt;/p&gt;
&lt;h2 id="fabric-中的-database-hub代理式管理"&gt;Fabric 中的 Database Hub：代理式管理&lt;/h2&gt;
&lt;p&gt;这个更偏向未来，但很有意思。Microsoft 宣布了 &lt;strong&gt;Microsoft Fabric 中的 Database Hub&lt;/strong&gt;（抢先体验），为你提供跨 Azure SQL、Cosmos DB、PostgreSQL、MySQL 和 SQL Server via Arc 的统一视图。&lt;/p&gt;
&lt;p&gt;有意思的不仅仅是统一视图——而是代理式的管理方法。AI 代理持续监控你的数据库群，展示发生了什么变化，解释为什么重要，并建议下一步该做什么。这是一个人机协作（human-in-the-loop）模型，代理做前期工作，你来做决策。&lt;/p&gt;
&lt;p&gt;对于管理多个数据库的团队来说，这可能真正减少运维噪音。代理把信号带给你，而不是让你在各个门户之间跳来跳去手动检查指标。&lt;/p&gt;
&lt;h2 id="这对-net-开发者意味着什么"&gt;这对 .NET 开发者意味着什么&lt;/h2&gt;
&lt;p&gt;贯穿所有这些公告的主线很清晰：Microsoft 正在将 AI 代理嵌入数据库技术栈的每一层。不是作为噱头，而是作为实用的工具层。&lt;/p&gt;
&lt;p&gt;如果你正在构建基于 Azure SQL 的 .NET 应用，以下是我实际会做的事情：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;试试 SQL MCP Server&lt;/strong&gt;，如果你在构建 AI 代理的话。这是给代理提供数据库访问最干净的方式，不需要自定义的管道代码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在 SSMS 中启用 Copilot&lt;/strong&gt;，如果还没有的话——对日常 SQL 工作来说是免费的生产力提升。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;了解一下向量索引&lt;/strong&gt;，如果你在做 RAG 且目前运行着单独的向量存储。整合到 Azure SQL 意味着少管理一个服务。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;完整公告还有更多内容——节省计划、迁移助手、合规功能——但对开发者来说，重点在 MCP Server、向量改进和代理式管理层。这些才是改变你构建方式的东西，而不仅仅是改变你做预算的方式。&lt;/p&gt;
&lt;p&gt;查看 &lt;a href="https://www.microsoft.com/en-us/sql-server/blog/2026/03/18/advancing-agentic-ai-with-microsoft-databases-across-a-unified-data-estate/"&gt;Shireesh Thota 的完整公告&lt;/a&gt; 获取全貌，如果你想试试新的管理体验，可以&lt;a href="https://aka.ms/database-hub"&gt;注册 Database Hub 抢先体验&lt;/a&gt;。&lt;/p&gt;</content:encoded></item><item><title>Azure DevOps MCP Server 登陆 Microsoft Foundry：这对你的 AI 代理意味着什么</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-devops-mcp-server-microsoft-foundry/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/azure-devops-mcp-server-microsoft-foundry/</guid><description>Azure DevOps MCP Server 现已在 Microsoft Foundry 中可用。只需几次点击，即可将你的 AI 代理直接连接到 DevOps 工作流 — 工作项、仓库、管道。</description><content:encoded>&lt;p&gt;MCP（Model Context Protocol）正在迎来它的高光时刻。如果你一直在关注 AI 代理生态系统，你可能已经注意到 MCP 服务器到处涌现 — 通过标准化协议赋予代理与外部工具和服务交互的能力。&lt;/p&gt;
&lt;p&gt;现在 &lt;a href="https://devblogs.microsoft.com/devops/remote-mcp-server-preview-in-microsoft-foundry/"&gt;Azure DevOps MCP Server 已在 Microsoft Foundry 中可用&lt;/a&gt;，这是那种让你思考实际可能性的集成之一。&lt;/p&gt;
&lt;h2 id="这里到底发生了什么"&gt;这里到底发生了什么&lt;/h2&gt;
&lt;p&gt;Microsoft 已经发布了 Azure DevOps MCP Server 的&lt;a href="https://devblogs.microsoft.com/devops/azure-devops-remote-mcp-server-public-preview"&gt;公开预览版&lt;/a&gt; — 那是 MCP 服务器本身。新的是 Foundry 集成。你现在可以直接从工具目录将 Azure DevOps MCP Server 添加到 Foundry 代理中。&lt;/p&gt;
&lt;p&gt;对于还不熟悉 Foundry 的人：它是 Microsoft 用于大规模构建和管理 AI 驱动应用程序和代理的统一平台。模型访问、编排、评估、部署 — 全部在一个地方。&lt;/p&gt;
&lt;h2 id="配置"&gt;配置&lt;/h2&gt;
&lt;p&gt;配置出奇地简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在你的 Foundry 代理中，进入 &lt;strong&gt;Add Tools&lt;/strong&gt; &amp;gt; &lt;strong&gt;Catalog&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;搜索 &amp;ldquo;Azure DevOps&amp;rdquo;&lt;/li&gt;
&lt;li&gt;选择 Azure DevOps MCP Server（preview）并点击 &lt;strong&gt;Create&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;输入你的组织名称并连接&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就这样。你的代理现在可以访问 Azure DevOps 工具了。&lt;/p&gt;
&lt;h2 id="控制代理可以访问什么"&gt;控制代理可以访问什么&lt;/h2&gt;
&lt;p&gt;这是我欣赏的部分：你不会被困在全有或全无的方式中。你可以指定哪些工具对代理可用。如果你只想让它读取工作项但不碰管道，可以这样配置。最小权限原则，应用到你的 AI 代理上。&lt;/p&gt;
&lt;p&gt;这在企业场景中很重要，你不希望一个代理因为有人让它&amp;quot;帮忙发布&amp;quot;就意外触发部署管道。&lt;/p&gt;
&lt;h2 id="为什么这对-net-团队很有趣"&gt;为什么这对 .NET 团队很有趣&lt;/h2&gt;
&lt;p&gt;想想这在实践中能实现什么：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;冲刺规划助手&lt;/strong&gt; — 可以拉取工作项、分析速度数据并建议冲刺容量的代理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码审查机器人&lt;/strong&gt; — 因为能实际读取你的仓库和关联的工作项，所以理解你的 PR 上下文的代理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事件响应&lt;/strong&gt; — 可以创建工作项、查询最近的部署并将 bug 与最近的更改关联的代理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开发者入职&lt;/strong&gt; — &amp;ldquo;我应该做什么？&amp;ldquo;得到基于实际项目数据的真实回答&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于已经在 CI/CD 管道和项目管理中使用 Azure DevOps 的 .NET 团队来说，拥有一个能直接与这些系统交互的 AI 代理是迈向有用自动化的重要一步。&lt;/p&gt;
&lt;h2 id="更大的-mcp-图景"&gt;更大的 MCP 图景&lt;/h2&gt;
&lt;p&gt;这是更广泛趋势的一部分：MCP 服务器正在成为 AI 代理与外部世界交互的标准方式。我们在 GitHub、Azure DevOps、数据库、SaaS API 中都能看到它们 — 而 Foundry 正在成为所有这些连接汇聚的中心。&lt;/p&gt;
&lt;p&gt;如果你在 .NET 生态系统中构建代理，MCP 值得关注。协议是标准化的，工具正在成熟，Foundry 集成使其无需手动配置服务器连接即可访问。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Foundry 中的 Azure DevOps MCP Server 目前处于预览阶段，所以预计它会继续发展。但核心工作流是可靠的：连接、配置工具访问，让你的代理使用你的 DevOps 数据工作。如果你已经在 Foundry 生态系统中，只需几次点击就能开始。试试看你能构建什么工作流。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/devops/remote-mcp-server-preview-in-microsoft-foundry/"&gt;完整公告&lt;/a&gt;获取完整的配置步骤和更多详情。&lt;/p&gt;</content:encoded></item><item><title>Foundry Agent Service 正式发布：对 .NET 代理开发者真正重要的是什么</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</guid><description>微软的 Foundry Agent Service 刚刚正式发布，带来了私有网络、Voice Live、生产评估和开放的多模型运行时。这是你需要知道的。</description><content:encoded>&lt;p&gt;说实话 — 构建一个 AI 代理原型是简单的部分。困难的是之后的一切：用适当的网络隔离投入生产、运行真正有意义的评估、处理合规要求，以及不在凌晨 2 点搞崩东西。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;Foundry Agent Service 刚刚正式发布&lt;/a&gt;，这个版本像激光一样聚焦在&amp;quot;之后一切&amp;quot;的鸿沟上。&lt;/p&gt;
&lt;h2 id="构建在-responses-api-之上"&gt;构建在 Responses API 之上&lt;/h2&gt;
&lt;p&gt;标题新闻：新一代 Foundry Agent Service 构建在 OpenAI Responses API 之上。如果你已经在用这个 wire protocol 构建，迁移到 Foundry 只需最少的代码改动。你获得的：企业安全、私有网络、Entra RBAC、完整追踪和评估 — 在你现有的代理逻辑之上。&lt;/p&gt;
&lt;p&gt;架构是有意开放的。你不被锁定在一个模型提供商或一个编排框架上。用 DeepSeek 做规划、OpenAI 做生成、LangGraph 做编排 — 运行时处理一致性层。&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;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&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;azure.ai.projects.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptAgentDefinition&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="k"&gt;with&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;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;credential&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;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_PROJECT_ENDPOINT&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;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;project_client&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;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_openai_client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;openai_client&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_version&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;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-enterprise-agent&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;definition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptAgentDefinition&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;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&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;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&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="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;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&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="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;What are best practices for building AI agents?&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;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&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="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&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="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_text&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;blockquote&gt;
&lt;p&gt;如果你从 &lt;code&gt;azure-ai-agents&lt;/code&gt; 包迁移过来，代理现在是 &lt;code&gt;azure-ai-projects&lt;/code&gt; 中 &lt;code&gt;AIProjectClient&lt;/code&gt; 的一等操作。移除独立依赖，使用 &lt;code&gt;get_openai_client()&lt;/code&gt; 来驱动响应。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="私有网络企业阻碍已移除"&gt;私有网络：企业阻碍已移除&lt;/h2&gt;
&lt;p&gt;这是解锁企业采用的功能。Foundry 现在支持完整的端到端私有网络配合 BYO VNet：&lt;/p&gt;
&lt;ul&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; — MCP 服务器、Azure AI Search、Fabric 数据代理都通过私有路径运作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后一点至关重要。不只是推理调用保持私有 — 每个工具调用和检索调用也都留在你的网络边界内。对于在数据分类策略下禁止外部路由的团队来说，这就是缺失的那块。&lt;/p&gt;
&lt;h2 id="mcp-认证做对了"&gt;MCP 认证做对了&lt;/h2&gt;
&lt;p&gt;MCP 服务器连接现在支持完整的认证模式谱系：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;认证方式&lt;/th&gt;
&lt;th&gt;何时使用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;基于密钥&lt;/td&gt;
&lt;td&gt;组织范围内部工具的简单共享访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Agent Identity&lt;/td&gt;
&lt;td&gt;服务间；代理以自身身份认证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Managed Identity&lt;/td&gt;
&lt;td&gt;按项目隔离；无凭证管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAuth Identity Passthrough&lt;/td&gt;
&lt;td&gt;用户委托访问；代理代表用户行事&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OAuth Identity Passthrough 是有趣的那个。当用户需要授予代理访问他们的个人数据 — 他们的 OneDrive、Salesforce 组织、按用户范围的 SaaS API — 代理使用标准 OAuth 流程代表他们行事。没有假装是所有人的共享系统身份。&lt;/p&gt;
&lt;h2 id="voice-live无需管道工程的语音对语音"&gt;Voice Live：无需管道工程的语音对语音&lt;/h2&gt;
&lt;p&gt;给代理添加语音曾经意味着拼凑 STT、LLM 和 TTS — 三个服务、三次延迟跳转、三个计费面，全部手动同步。&lt;strong&gt;Voice Live&lt;/strong&gt; 将这一切压缩为单个托管 API：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语义语音活动和轮次结束检测（理解含义，不仅仅是沉默）&lt;/li&gt;
&lt;li&gt;服务端噪声抑制和回声消除&lt;/li&gt;
&lt;li&gt;插话支持（用户可以在响应中途打断）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;语音交互通过与文本相同的代理运行时。相同的评估器、相同的追踪、相同的成本可见性。对于客户支持、现场服务或无障碍场景，这取代了以前需要自定义音频管道的方案。&lt;/p&gt;
&lt;h2 id="评估从勾选框到持续监控"&gt;评估：从勾选框到持续监控&lt;/h2&gt;
&lt;p&gt;这是 Foundry 认真对待生产质量的地方。评估系统现在有三层：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;开箱即用评估器&lt;/strong&gt; — 连贯性、相关性、扎实度、检索质量、安全性。连接到数据集或实时流量获取分数。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自定义评估器&lt;/strong&gt; — 编码你自己的业务逻辑、语调标准和领域特定合规规则。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;持续评估&lt;/strong&gt; — Foundry 采样实时生产流量，运行你的评估器套件，并在仪表板中显示结果。设置 Azure Monitor 告警以监控扎实度下降或安全阈值突破。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一切发布到 Azure Monitor Application Insights。代理质量、基础设施健康、成本和应用遥测 — 全在一处。&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;eval_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&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;Agent Quality Evaluation&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;data_source_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DataSourceConfigCustom&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="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;custom&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;item_schema&lt;/span&gt;&lt;span class="o"&gt;=&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="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&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="s2"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&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="s2"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&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;include_sample_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&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;testing_criteria&lt;/span&gt;&lt;span class="o"&gt;=&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="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;azure_ai_evaluator&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="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fluency&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="s2"&gt;&amp;#34;evaluator_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;builtin.fluency&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="s2"&gt;&amp;#34;initialization_parameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&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="s2"&gt;&amp;#34;deployment_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&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="s2"&gt;&amp;#34;data_mapping&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&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="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{item.query}}&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="s2"&gt;&amp;#34;response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{sample.output_text}}&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="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="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;托管代理现在在 East US、North Central US、Sweden Central、Southeast Asia、Japan East 等区域可用。这对数据驻留要求很重要，也有助于在代理靠近数据源运行时压缩延迟。&lt;/p&gt;
&lt;h2 id="为什么这对-net-开发者重要"&gt;为什么这对 .NET 开发者重要&lt;/h2&gt;
&lt;p&gt;虽然 GA 公告中的代码示例是 Python 优先的，但底层基础设施是语言无关的 — &lt;code&gt;azure-ai-projects&lt;/code&gt; 的 .NET SDK 遵循相同的模式。Responses API、评估框架、私有网络、MCP 认证 — 这些都可以从 .NET 使用。&lt;/p&gt;
&lt;p&gt;如果你一直在等 AI 代理从&amp;quot;酷炫演示&amp;quot;变成&amp;quot;我真的可以在工作中交付&amp;quot;，这个 GA 版本就是信号。私有网络、适当的认证、持续评估和生产监控是缺失的那些拼图。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Foundry Agent Service 现在可用。安装 SDK，打开&lt;a href="https://ai.azure.com"&gt;门户&lt;/a&gt;，开始构建。&lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;快速入门指南&lt;/a&gt;带你在几分钟内从零到运行中的代理。&lt;/p&gt;
&lt;p&gt;包含所有代码示例的完整技术深度分析，请查看 &lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;GA 公告&lt;/a&gt;。&lt;/p&gt;</content:encoded></item><item><title>Microsoft Agent Framework 中的后台响应：告别超时焦虑</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/background-responses-agent-framework-long-running-tasks/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/background-responses-agent-framework-long-running-tasks/</guid><description>Microsoft Agent Framework 现在允许通过延续令牌卸载长时间运行的 AI 任务。了解后台响应如何工作以及为什么它们对你的 .NET 代理很重要。</description><content:encoded>&lt;p&gt;如果你用 o3 或 GPT-5.2 等推理模型构建过任何东西，你就知道那种痛苦。你的代理开始思考一个复杂的任务，客户端在那里等待，在&amp;quot;没问题&amp;quot;和&amp;quot;它是不是崩了？&amp;ldquo;之间的某个时刻，你的连接超时了。那些工作？全没了。&lt;/p&gt;
&lt;p&gt;Microsoft Agent Framework 刚刚推出了&lt;a href="https://devblogs.microsoft.com/agent-framework/handling-long-running-operations-with-background-responses/"&gt;后台响应&lt;/a&gt; — 说实话，这是那种从第一天就应该存在的功能。&lt;/p&gt;
&lt;h2 id="阻塞调用的问题"&gt;阻塞调用的问题&lt;/h2&gt;
&lt;p&gt;在传统的请求-响应模式中，你的客户端会阻塞直到代理完成。对于快速任务来说没问题。但当你让推理模型做深度研究、多步分析或生成 20 页报告时？你面对的是几分钟的实际等待时间。在这个窗口期：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP 连接可能超时&lt;/li&gt;
&lt;li&gt;网络抖动会杀死整个操作&lt;/li&gt;
&lt;li&gt;你的用户盯着一个加载动画想知道是否有事情在发生&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后台响应彻底翻转了这个局面。&lt;/p&gt;
&lt;h2 id="延续令牌如何工作"&gt;延续令牌如何工作&lt;/h2&gt;
&lt;p&gt;你不再阻塞等待，而是启动代理任务并获得一个&lt;strong&gt;延续令牌&lt;/strong&gt;。把它想象成修理店的取件单 — 你不需要站在柜台前等着，准备好了再回来取就行。&lt;/p&gt;
&lt;p&gt;流程很简单：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 &lt;code&gt;AllowBackgroundResponses = true&lt;/code&gt; 发送请求&lt;/li&gt;
&lt;li&gt;如果代理支持后台处理，你会收到一个延续令牌&lt;/li&gt;
&lt;li&gt;按你的节奏轮询，直到令牌返回 &lt;code&gt;null&lt;/code&gt; — 这意味着结果准备好了&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这是 .NET 版本：&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;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="s"&gt;&amp;#34;https://&amp;lt;myresource&amp;gt;.openai.azure.com&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="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;GetResponsesClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;deployment-name&amp;gt;&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 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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentRunOptions&lt;/span&gt; &lt;span class="n"&gt;options&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&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;AllowBackgroundResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;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;AgentResponse&lt;/span&gt; &lt;span class="n"&gt;response&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;Write a detailed market analysis for the Q4 product launch.&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 class="n"&gt;options&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="c1"&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;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;null&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="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&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;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&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;response&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="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&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;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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&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;/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;AgentRunOptions&lt;/span&gt; &lt;span class="n"&gt;options&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&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;AllowBackgroundResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;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 class="n"&gt;AgentResponseUpdate&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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="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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Write a detailed market analysis for the Q4 product launch.&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 class="n"&gt;options&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 class="n"&gt;Text&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;latestUpdate&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="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&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="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="c1"&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;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&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;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="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&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 class="n"&gt;Text&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;/p&gt;
&lt;h2 id="什么时候该真正使用这个"&gt;什么时候该真正使用这个&lt;/h2&gt;
&lt;p&gt;不是每个代理调用都需要后台响应。对于快速完成，你只是在无故增加复杂性。但以下场景是它们大放异彩的地方：&lt;/p&gt;
&lt;ul&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; — 移动客户端、边缘部署、不稳定的企业 VPN&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步 UX 模式&lt;/strong&gt; — 提交任务，去做别的事，回来取结果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于构建企业应用的 .NET 开发者来说，最后一点特别有趣。想想一个 Blazor 应用，用户请求一个复杂的报告 — 你启动代理任务，显示进度指示器，让他们继续工作。不需要 WebSocket 体操，不需要自定义队列基础设施，只需一个令牌和一个轮询循环。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;后台响应现在通过 Microsoft Agent Framework 在 .NET 和 Python 中都可用。如果你构建的代理做的事情比简单的问答更复杂，这值得加入你的工具包。延续令牌模式保持简单的同时解决了一个非常真实的生产问题。&lt;/p&gt;
&lt;p&gt;查看&lt;a href="https://devblogs.microsoft.com/agent-framework/handling-long-running-operations-with-background-responses/"&gt;完整文档&lt;/a&gt;获取完整的 API 参考和更多示例。&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.112：.NET 开发者真正应该关注的内容</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-112-dotnet-developers/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/vscode-1-112-dotnet-developers/</guid><description>VS Code 1.112 刚刚发布，满载代理升级、集成浏览器调试器、MCP 沙箱和 monorepo 支持。如果你用 .NET 开发，这些是真正重要的内容。</description><content:encoded>&lt;p&gt;VS Code 1.112 刚落地，说实话？如果你每天都在 .NET 的世界里，这个版本感觉不一样。&lt;a href="https://code.visualstudio.com/updates/v1_112"&gt;官方发布说明&lt;/a&gt; 里有很多内容，但让我帮你省点滚动，专注于对我们真正重要的东西。&lt;/p&gt;
&lt;h2 id="copilot-cli-变得更有用了"&gt;Copilot CLI 变得更有用了&lt;/h2&gt;
&lt;p&gt;这个版本的大主题是&lt;strong&gt;代理自主性&lt;/strong&gt; — 给 Copilot 更多空间做它的事，不需要你看管每一步。&lt;/p&gt;
&lt;h3 id="消息引导和排队"&gt;消息引导和排队&lt;/h3&gt;
&lt;p&gt;你知道 Copilot CLI 在任务进行到一半时，你突然想起忘了提什么东西的那个时刻吗？以前你只能等。现在你可以在请求还在运行时发送消息 — 要么引导当前响应，要么排队后续指令。&lt;/p&gt;
&lt;p&gt;这对那些较长的 &lt;code&gt;dotnet&lt;/code&gt; 脚手架任务来说太棒了，你看着 Copilot 设置项目然后想&amp;quot;哦等等，我还需要 MassTransit&amp;quot;。&lt;/p&gt;
&lt;h3 id="权限级别"&gt;权限级别&lt;/h3&gt;
&lt;p&gt;这是我最兴奋的。Copilot CLI 会话现在支持三个权限级别：&lt;/p&gt;
&lt;ul&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;如果你在做类似用 Entity Framework、migrations 和 Docker 设置创建新的 ASP.NET Core API 这样的事 — 自动驾驶模式意味着你描述想要什么然后去拿杯咖啡。它会搞定的。&lt;/p&gt;
&lt;p&gt;你可以用 &lt;code&gt;chat.autopilot.enabled&lt;/code&gt; 设置启用自动驾驶。&lt;/p&gt;
&lt;h3 id="委托前预览更改"&gt;委托前预览更改&lt;/h3&gt;
&lt;p&gt;当你把任务委托给 Copilot CLI 时，它会创建一个 worktree。以前如果你有未提交的更改，你得检查源代码管理来看什么会受影响。现在聊天视图会在你决定复制、移动或忽略之前直接显示待处理的更改。&lt;/p&gt;
&lt;p&gt;小事情，但省去了&amp;quot;等等，我 staging 了什么？&amp;ldquo;的时刻。&lt;/p&gt;
&lt;h2 id="不离开-vs-code-就能调试-web-应用"&gt;不离开 VS Code 就能调试 Web 应用&lt;/h2&gt;
&lt;p&gt;集成浏览器现在支持&lt;strong&gt;完整调试&lt;/strong&gt;。你可以设断点、单步执行代码、检查变量 — 全在 VS Code 内。不用再切换到 Edge DevTools 了。&lt;/p&gt;
&lt;p&gt;有一个新的 &lt;code&gt;editor-browser&lt;/code&gt; 调试类型，如果你已经有 &lt;code&gt;msedge&lt;/code&gt; 或 &lt;code&gt;chrome&lt;/code&gt; 的启动配置，迁移只需改 &lt;code&gt;launch.json&lt;/code&gt; 里的 &lt;code&gt;type&lt;/code&gt; 字段：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;editor-browser&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="nt"&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;launch&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="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Debug Blazor App&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="nt"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://localhost:5001&amp;#34;&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;对 Blazor 开发者来说，这是颠覆性的。你已经在终端运行 &lt;code&gt;dotnet watch&lt;/code&gt; — 现在调试也留在同一个窗口里。&lt;/p&gt;
&lt;p&gt;浏览器还获得了独立的缩放级别（终于）、正确的右键上下文菜单，缩放按网站记忆。&lt;/p&gt;
&lt;h2 id="mcp-服务器沙箱"&gt;MCP 服务器沙箱&lt;/h2&gt;
&lt;p&gt;这比你想的更重要。如果你在用 MCP 服务器 — 也许你为 Azure 资源或数据库查询设置了自定义的 — 它们一直以和你的 VS Code 进程相同的权限运行。这意味着对你的文件系统、网络等一切的完全访问。&lt;/p&gt;
&lt;p&gt;现在你可以对它们做沙箱处理。在你的 &lt;code&gt;mcp.json&lt;/code&gt; 中：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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="nt"&gt;&amp;#34;servers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&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="nt"&gt;&amp;#34;my-azure-tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&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="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;node&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="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./mcp-server.js&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="nt"&gt;&amp;#34;sandboxEnabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="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;当沙箱化的服务器需要访问它没有的东西时，VS Code 会提示你授予权限。比&amp;quot;希望没人做奇怪的事&amp;quot;的方式好太多了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 沙箱目前在 macOS 和 Linux 上可用。Windows 支持即将到来 — 不过 WSL 等远程场景是可以工作的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="monorepo-自定义发现"&gt;Monorepo 自定义发现&lt;/h2&gt;
&lt;p&gt;如果你在 monorepo 中工作（说实话，很多企业 .NET 解决方案最终都变成了 monorepo），这解决了一个真正的痛点。&lt;/p&gt;
&lt;p&gt;以前，如果你打开仓库的子文件夹，VS Code 找不到仓库根目录的 &lt;code&gt;copilot-instructions.md&lt;/code&gt;、&lt;code&gt;AGENTS.md&lt;/code&gt; 或自定义技能。现在通过 &lt;code&gt;chat.useCustomizationsInParentRepositories&lt;/code&gt; 设置，它会向上查找到 &lt;code&gt;.git&lt;/code&gt; 根目录并发现所有内容。&lt;/p&gt;
&lt;p&gt;这意味着你的团队可以在 monorepo 中跨所有项目共享代理指令、提示文件和自定义工具，不需要每个人都打开根文件夹。&lt;/p&gt;
&lt;h2 id="troubleshoot-用于代理调试"&gt;/troubleshoot 用于代理调试&lt;/h2&gt;
&lt;p&gt;有没有设置过自定义指令或技能，然后纳闷为什么没被检测到？新的 &lt;code&gt;/troubleshoot&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-json" data-lang="json"&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="nt"&gt;&amp;#34;github.copilot.chat.agentDebugLog.enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="nt"&gt;&amp;#34;github.copilot.chat.agentDebugLog.fileLogging.enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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;/troubleshoot why is my custom skill not loading?&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;你现在还可以导出和导入这些调试日志，当某些东西不按预期工作时，和团队分享很方便。&lt;/p&gt;
&lt;h2 id="图像和二进制文件支持"&gt;图像和二进制文件支持&lt;/h2&gt;
&lt;p&gt;代理现在可以从磁盘原生读取图像文件和二进制文件。二进制文件以 hexdump 格式呈现，图像输出（如集成浏览器的截图）以轮播视图显示。&lt;/p&gt;
&lt;p&gt;对 .NET 开发者来说：把 UI bug 的截图粘贴到聊天中让代理理解问题所在，或者让它分析 Blazor 组件渲染的输出。&lt;/p&gt;
&lt;h2 id="自动符号引用"&gt;自动符号引用&lt;/h2&gt;
&lt;p&gt;小的生活质量改善：当你复制一个符号名称（类、方法等）并粘贴到聊天中时，VS Code 现在自动将其转换为 &lt;code&gt;#sym:Name&lt;/code&gt; 引用。这给代理提供了关于该符号的完整上下文，无需手动添加。&lt;/p&gt;
&lt;p&gt;如果你想要纯文本，使用 &lt;code&gt;Ctrl+Shift+V&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="插件现在可以启用禁用"&gt;插件现在可以启用/禁用&lt;/h2&gt;
&lt;p&gt;以前禁用 MCP 服务器或插件意味着卸载它。现在你可以开关它们 — 全局和按工作区都可以。在扩展视图或自定义视图中右键单击就行。&lt;/p&gt;
&lt;p&gt;npm 和 pypi 的插件现在也可以自动更新了，不过会先请求批准，因为更新意味着在你的机器上运行新代码。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;VS Code 1.112 明显在大力推进代理体验 — 更多自主性、更好的调试、更严格的安全。对 .NET 开发者来说，集成浏览器调试和 Copilot CLI 改进是最突出的功能。&lt;/p&gt;
&lt;p&gt;如果你还没试过为 .NET 项目在自动驾驶模式下运行完整的 Copilot CLI 会话，这个版本是开始的好时机。记得设置你的权限然后让它干活。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_112"&gt;下载 VS Code 1.112&lt;/a&gt; 或在 VS Code 内通过&lt;strong&gt;帮助 &amp;gt; 检查更新&lt;/strong&gt;进行更新。&lt;/p&gt;</content:encoded></item><item><title>从笔记本到生产：用两个命令将 AI 代理部署到 Microsoft Foundry</title><link>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/deploy-ai-agents-foundry-azd-two-commands/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/zh/news/emiliano-montesdeoca/deploy-ai-agents-foundry-azd-two-commands/</guid><description>Azure Developer CLI 现在有了 'azd ai agent' 命令，可以在几分钟内将你的 AI 代理从本地开发带到 Foundry 的生产端点。这是完整的工作流程。</description><content:encoded>&lt;p&gt;你知道&amp;quot;在我的机器上能跑&amp;quot;和&amp;quot;已部署并正在处理流量&amp;quot;之间的鸿沟吗？对于 AI 代理来说，这个鸿沟一直痛苦地大。你需要配置资源、部署模型、配置身份、设置监控 — 这些都是在任何人能实际调用你的代理之前要做的。&lt;/p&gt;
&lt;p&gt;Azure Developer CLI 刚刚把这变成了&lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-ai-agent-end-to-end/"&gt;两个命令的事&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="新的-azd-ai-agent-工作流"&gt;新的 &lt;code&gt;azd ai agent&lt;/code&gt; 工作流&lt;/h2&gt;
&lt;p&gt;让我带你看看这实际是什么样子。你有一个 AI 代理项目 — 比如说一个酒店礼宾代理。它在本地运行正常。你想让它在 Microsoft Foundry 上运行。&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;azd ai agent init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;就这样。两个命令。&lt;code&gt;azd ai agent init&lt;/code&gt; 在你的仓库中生成基础设施即代码，&lt;code&gt;azd up&lt;/code&gt; 在 Azure 上配置一切并发布你的代理。你会得到一个直接指向 Foundry 门户中你的代理的链接。&lt;/p&gt;
&lt;h2 id="底层发生了什么"&gt;底层发生了什么&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;init&lt;/code&gt; 命令在你的仓库中生成真实的、可检查的 Bicep 模板：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 &lt;strong&gt;Foundry Resource&lt;/strong&gt;（顶层容器）&lt;/li&gt;
&lt;li&gt;一个 &lt;strong&gt;Foundry Project&lt;/strong&gt;（你的代理所在的地方）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;模型部署&lt;/strong&gt;配置（GPT-4o 等）&lt;/li&gt;
&lt;li&gt;带有适当 RBAC 角色分配的&lt;strong&gt;托管身份&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;服务映射用的 &lt;code&gt;azure.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;带有代理元数据和环境变量的 &lt;code&gt;agent.yaml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关键是：这一切都是你的。它是仓库中的版本化 Bicep。你可以检查它、自定义它，并与你的代理代码一起提交。没有魔法黑盒。&lt;/p&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这会在本地启动你的代理。配合 &lt;code&gt;azd ai agent invoke&lt;/code&gt; 发送测试提示，你就有了一个紧密的反馈循环。编辑代码、重启、调用、重复。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;invoke&lt;/code&gt; 命令的路由也很智能 — 当本地代理在运行时，它会自动指向本地。不在运行时，指向远程端点。&lt;/p&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-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent monitor --follow
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;流经你的代理的每个请求和响应都会实时传输到你的终端。对于调试生产问题，这是无价之宝。不用挖 Log Analytics，不用等指标聚合 — 你看到的就是现在正在发生的事情。&lt;/p&gt;
&lt;h2 id="完整的命令集"&gt;完整的命令集&lt;/h2&gt;
&lt;p&gt;快速参考：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用 IaC 搭建 Foundry 代理项目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;配置 Azure 资源并部署代理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent invoke&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;向远程或本地代理发送提示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在本地运行代理用于开发&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent monitor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从已发布的代理流式传输实时日志&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查代理健康状态和状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd down&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;清理所有 Azure 资源&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="为什么这对-net-开发者重要"&gt;为什么这对 .NET 开发者重要&lt;/h2&gt;
&lt;p&gt;虽然公告中的示例是基于 Python 的，但基础设施的故事是语言无关的。你的 .NET 代理得到相同的 Bicep 脚手架、相同的托管身份设置、相同的监控管道。如果你已经在用 &lt;code&gt;azd&lt;/code&gt; 部署 .NET Aspire 应用或 Azure 部署，这直接融入你现有的工作流。&lt;/p&gt;
&lt;p&gt;AI 代理的部署鸿沟一直是生态系统中最大的摩擦点之一。从一个工作原型到一个具有适当身份、网络和监控的生产端点，不应该需要一周的 DevOps 工作。现在只需要两个命令和几分钟。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd ai agent&lt;/code&gt; 现在可用。如果你一直因为基础设施设置看起来工作量太大而推迟部署 AI 代理，试试看。查看&lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-ai-agent-end-to-end/"&gt;完整教程&lt;/a&gt;获取包括前端聊天应用集成在内的完整步骤。&lt;/p&gt;</content:encoded></item></channel></rss>