news 2026/2/5 8:49:38

Microsoft Agent Framework在微信公众号AI辅助撰文中的应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Microsoft Agent Framework在微信公众号AI辅助撰文中的应用

对于一些技术性比较强的文章,我都会使用AI来帮助我生成部分文章内容,并自动推送到微信公众号的草稿箱。简单地说,在写文章这件事情上,我和AI是责任共担的,AI负责生成封面图片,并根据我的要求产生文章内容主体,我则负责审核生成的内容,并根据自己的需要和技术细节进行修改,这不仅能够提高我的撰文效率,而且还可以保证输出优质的文章内容。

目前,这个小工具是以ASP.NET Core Web API托管了AI服务和微信公众号服务,它以容器的形式运行在Azure WebApp上,后端数据库采用了PostgreSQL,代码实现本身使用了Microsoft Semantic Kernel,它的整体架构如下图:

这样的一个小工具基本可以满足我的撰文需求,但是使用一段时间后发现,AI自动生成的文章中的有些内容并不是特别贴合主题,而且还会存在错误的情况,这可能是由于模型本身所感知的外部信息有限,无法提供更为准确的内容输出。此外,有些特殊需求无法通过单一的问答式模型实现,比如:

  • 我想写篇文章,基于已有代码,介绍这套代码的设计思想

  • 我想写篇文章,收集公开文献中针对某种前沿技术的主流观点,并进行总结归纳

  • 我想写篇文章,对现行主流思想给出相对客观的评价

  • (等等)

于是,我决定对这个小工具进行重构,尝试引入Agent的概念,并通过Agent Workflow达到多Agent合作并生成高质量文章的目的。相比Semantic Kernel,Microsoft Agent Framework在多Agent支持方面做得更为完善和易用,所以,决定使用Agent Framework来替换Semantic Kernel的部分功能。

| 重构:引入Agent Framework

在ASP.NET Core Web API中引入Agent Framework是很简单的,只需要引入Microsoft.Agents.AI.Hosting这个NuGet包就可以了。之后,就是对代码的一顿魔改,首先从环境变量读入Azure OpenAI中配置的大语言模型的相关信息:

var aiModel = builder.Configuration[ComposerAzureOpenAiModelConfigKey] ?? throw new ApplicationException("Azure OpenAI Model is not configured.");var aiApiKey = builder.Configuration[ComposerAzureOpenAiApiKeyConfigKey] ?? throw new ApplicationException("Azure OpenAI ApiKey is not configured.");var aiEndpoint = builder.Configuration[ComposerAzureOpenAiEndpointConfigKey] ?? throw new ApplicationException("Azure OpenAI Endpoint is not configured.");

然后,注入OpenAIClient对象:

builder.Services.AddSingleton(_ => new AzureOpenAIClient( new Uri(aiEndpoint), new ApiKeyCredential(aiApiKey)) .GetChatClient(aiModel) .AsIChatClient());

接下来就是注入Agent实例,并通过这个Agent产生一个简单的Agent Workflow:

builder.AddAIAgent("Composer", (sp, key) =>{ var chatClient = sp.GetRequiredService<IChatClient>(); var agent = chatClient.AsAIAgent(new ChatClientAgentOptions { Name = key, Id = "FD61B233-5CFA-4124-AE5B-1561F3530135", ChatOptions = new ChatOptions { Temperature = 0.3f, Instructions = """ 你是一个技术博客写作助手,帮助用户生成文章。请根据用户提供的摘要生成一篇文章。请确保文章内容与摘要相关,并且逻辑清晰。 你可以使用一些常见的写作技巧来增强文章的质量,比如使用比喻、类比等修辞手法,尽量做到文章内容通俗易懂, 请注意,生成的内容应该是原创的,不要抄袭或引用其他人的作品,也不要使用Markdown格式,直接生成文本就可以。 请确保生成的内容符合相关法律法规,不包含任何违法或不当内容。请遵循这些指导原则,帮助用户生成高质量的文章。文章最后 不要提出任何询问用户的问题。 """ } }, services: sp); return agent;}); builder.AddWorkflow("WechatAIComposerWorkflow", (sp, key) =>{ var agent = sp.GetRequiredKeyedService<AIAgent>("Composer"); return AgentWorkflowBuilder.BuildSequential(key, agent);}).AddAsAIAgent("WechatAIComposerAgent");

在使用的时候,可以通过构造器注入,获得由Workflow创建的AI Agent的实例:

public class WechatArticleComposer( // ... [FromKeyedServices("WechatAIComposerAgent")] AIAgent wechatComposerAgent, // ...) : IWechatArticleComposer{ // ...}

最后,直接调用AI Agent的RunAsync方法即可:

var response = await wechatComposerAgent.RunAsync(summary);

经过重构之后,文章生成的整个过程就是基于Agent Framework了,这为接下来引入新的设计做好了准备。

| 思考:新的设计

虽然重构后,技术栈从Semantic Kernel换到了Agent Framework,但是从用户使用的角度,并没有明显变化,也就是仍然无法满足之前我列举出来的几个主要需求。考虑上面的实现不难发现,在应用程序启动的时候,AI Agent和Agent Workflow的创建过程就已经决定了,其实这也就意味着单个AI Agent单兵作战的模式就已经确定了。为什么单兵作战有问题呢?因为从满足需求的角度以及日后方便扩展的角度,我更希望能够让某个AI Agent负责某个方面的任务,最后可以由另一个AI Agent对其它负责各个方面的AI Agent的结论进行总结,完成文章撰写。这样的设计,有两个主要亮点:

  1. 处理特定任务的Agent是可以扩展的,比如我可以让某个Agent具有阅读源代码并总结代码设计的能力,而另一个Agent则可以上网搜索相关设计模式的实践经验

  2. 各个Agent之间的合作方式,也是可以自定义的,比如我可以让“代码阅读Agent”完成代码解读,并让“设计评估Agent”根据已有的成功案例,评估我的代码设计,最后由“总结撰文Agent”根据这两个Agent的结论,总结成一篇文章;我也可以选择不使用“设计评估Agent”,而是由“代码阅读Agent”完成代码解读之后,直接产生文章内容;我还可以面向多个不同的领域收集最前沿的科技信息,然后汇总成文

【Agent工作流:跨领域科技文章撰写】

根据这样的技术需求,可以将设计调整成这个样子(点击图片放大):

基本设计思路是,用户可以自定义AI Agent和Workflow,AI Agent和Workflow的元数据(Metadata)可以通过数据库访问组件进行存储和读取,这里仍然使用PostgreSQL数据库,这部分逻辑使用仓储模式实现。接下来,AgentWorkflowService会使用AI Agent和Workflow的仓储,根据需要从数据库中获取相关元数据,并创建Workflow,最后,将Workflow转化为AI Agent并返回到调用方。

于是,在界面上,用户可以创建具有各种能力的AI Agent,并且通过自定义Workflow,将这些Agents编排在一起,以完成特定的撰文任务。由于Workflow也是可管理的,所以在分配撰文任务的时候,还可以让Agent自己选择合适的Workflow来完成文章撰写。

下面是AgentWorkflowService的部分代码实现,通过这个代码可以看到,这个服务是如何通过AgentMetadata构建AI Agent,并通过这些Agents来创建Workflow的。在这里仅仅创建了一个简单的Sequential Workflow,实际上应该通过WorkflowMetadataRepository读取WorkflowMetadata的信息,然后根据WorkflowMetadata动态创建Workflow,这里就不详细展开介绍了。

public async Task<AIAgent> GetOrCreateWorkflowAgentAsync(CancellationToken cancellationToken = default){ if (_workflowAgent is not null) { logger.LogDebug("Returns the workflow agent from cache."); return _workflowAgent; } logger.LogDebug("Building the workflow agent."); var agentMetadataList = await agentRepository.GetAgentsAsync(cancellationToken); List<AIAgent> agents = []; foreach (var agentMetadata in agentMetadataList) { agents.Add(new ChatClientAgent(chatClient, new ChatClientAgentOptions { Id = $"chat_agent_{agentMetadata.Id}", Name = agentMetadata.Name, Description = agentMetadata.Description, ChatOptions = new ChatOptions { Instructions = agentMetadata.Instructions, Temperature = agentMetadata.Temperature, } })); } logger.LogDebug($"Number of agents from repository: {agents.Count}"); _workflowAgent = AgentWorkflowBuilder.BuildSequential(agents).AsAgent(); return _workflowAgent;}

| 总结

通过Microsoft Agent Framework可以非常方便地搭建Agent工作流,并且AI Agent和工作流的构建是非常灵活的。其实对于现有的设计再向外扩展一下,比如加入插件式的Tools和Skills的支持,就能得到一款看上去像Clawdbot的个人AI助理工具,只不过这个工具会更专注于文章撰写,而且也会相对安全可控。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/3 19:20:22

UVM-override与sequence的多态特性使用

Exploiting Sequence Polymorphism 上述示例展示了,UVM中利用序列多态性(Sequence Polymorphism)来实现测试场景随机化与自动化的高级技巧,其核心思想、实现方法及优势如下: 核心思想 通过定义一个通用的序列基类(图中为 bus_seq_base),让所有具体测试序列(如 rw_in…

作者头像 李华
网站建设 2026/2/3 19:19:04

块压缩解码实战:ETC1/ETC2详解

你可以把 GPU 纹理压缩想象成一件非常“抠门但聪明”的事&#xff1a; 手机显存就那么点&#xff0c;带宽也紧张&#xff0c;GPU 还得每秒采样几十亿次纹理。于是工程师们想了个办法——“别把每个像素老老实实存 RGBA 四个通道了&#xff0c;太费。 咱们一小块一小块地存&…

作者头像 李华
网站建设 2026/2/5 13:43:13

基于SpringBoot的校园一卡通系统毕设

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。一、研究目的本研究旨在设计并实现一个基于SpringBoot框架的校园一卡通系统&#xff0c;以满足现代校园对高效、便捷、安全的一卡通服务需求。具体研究目的如下&#xff1a; …

作者头像 李华
网站建设 2026/2/3 19:13:30

基于Springboot+Vue的物品租赁管理系统源码文档部署文档代码讲解等

课题介绍 本课题旨在设计并实现一套基于SpringBootVue的物品租赁管理系统&#xff0c;解决当前物品租赁行业中租赁流程繁琐、库存管控低效、订单跟踪不便、押金与归还管理混乱等问题&#xff0c;适配个人及中小型租赁企业的信息化管理需求。系统采用前后端分离架构&#xff0c;…

作者头像 李华
网站建设 2026/2/3 18:56:21

什么是向量单位化 (vector normalization)

想象一下&#xff0c;向量就像一支箭头&#xff1a;它有方向&#xff08;箭头指向哪里&#xff09;&#xff0c;也有长度&#xff08;箭头有多长&#xff09;。比如在2D平面里&#xff0c;一个向量可以表示“向右走3步&#xff0c;再向上走4步”&#xff0c;写成 (3, 4)。这支箭…

作者头像 李华