当前位置: 首页 > article >正文

Agent Framework 中为 Agent Skill 接入依赖注入 DI

在前面的文章中我们介绍过 FileBased、CodeBased 和 ClassBased 等不同的 Skill 实现方式也演示了如何通过 AgentSkillsProvider 或 AgentSkillsProviderBuilder 将多个 Skill 组合起来让一个 Agent 同时具备多种能力。在实际项目中Skill 通常不只是简单的本地函数它往往需要依赖应用中的各种服务例如数据库访问HTTP API 调用缓存或配置服务如果每个 Skill 都自行创建和管理这些依赖不仅会导致代码重复还会增加测试和维护的成本。因此在 Agent Framework 中可以将 Skill 与 .NET 的依赖注入机制结合使用。下面通过一个单位换算的例子来看一下如何在 Skill 中使用 DI。1. 核心设计思想在 Agent 架构中用户 → Agent → Skill → DI → Service → 业务逻辑分层层级职责Agent理解用户意图Skill能力入口AI 可调用Service业务实现DI生命周期与依赖管理Skill 不承载业务逻辑只负责能力编排。2. 示例场景构建一个“单位换算 Agent”支持距离换算英里 ⇄ 千米重量换算磅 ⇄ 千克实现方式Skill类型功能distance-converterInline距离weight-converterClass重量两者共用同一个业务服务ConversionService2. 创建项目并安装依赖包首先创建一个控制台项目然后安装相关依赖包dotnet add package Azure.AI.OpenAI dotnet add package Azure.Identity dotnet add package Microsoft.Agents.AI.OpenAI dotnet add package Microsoft.Extensions.DependencyInjection3. 环境准备安装依赖dotnet add package Azure.AI.OpenAI --version 2.9.0-beta.1 dotnet add package Azure.Identity dotnet add package Microsoft.Agents.AI.OpenAI dotnet add package Microsoft.Extensions.DependencyInjection版本说明GetResponsesClient()需要Azure.AI.OpenAI 2.9.0-beta.1否则可能出现404或 API 不兼容问题。4. 配置 Azure OpenAI示例中通过环境变量读取 Azure OpenAI 的终结点和模型部署名称string endpoint Environment.GetEnvironmentVariable(AZURE_OPENAI_ENDPOINT) ?? throw new InvalidOperationException(AZURE_OPENAI_ENDPOINT is not set.); string deploymentName Environment.GetEnvironmentVariable(AZURE_OPENAI_DEPLOYMENT_NAME) ?? gpt-5.4-mini;这里需要提前配置环境变量在Windows中可以使用setx AZURE_OPENAI_ENDPOINT https://你的资源名.openai.azure.com/ setx AZURE_OPENAI_DEPLOYMENT_NAME 你的模型部署名在 Linux 或 macOS 中可以使用export AZURE_OPENAI_ENDPOINThttps://你的资源名.openai.azure.com/ export AZURE_OPENAI_DEPLOYMENT_NAME你的模型部署名5. 创建 DI 容器在.NET 中依赖注入通常从 ServiceCollection 开始。示例中注册了一个 ConversionServiceServiceCollection services new(); services.AddSingletonConversionService(); IServiceProvider serviceProvider services.BuildServiceProvider();6. 定义业务服务 ConversionServiceConversionService 是一个普通的 C# 服务类用于提供单位换算能力。它主要包含三个方法internal sealedclassConversionService { public string GetDistanceTable() # 距离转换 公式**结果 值 × 系数** | 从 | 到 | 系数 | |-------------|-------------|----------| | 英里 | 千米 | 1.60934 | | 千米 | 英里 | 0.621371 | ; public string GetWeightTable() # 重量转换 公式**结果 值 × 系数** | 从 | 到 | 系数 | |-------------|-------------|----------| | 磅 | 千克 | 0.453592 | | 千克 | 磅 | 2.20462 | ; public string Convert(double value, double factor) { double result Math.Round(value * factor, 4); return JsonSerializer.Serialize(new { value, factor, result }); } }这里的设计思路很清晰GetDistanceTable()提供距离换算表。GetWeightTable()提供重量换算表。Convert()根据传入的值和换算系数返回计算结果。7. 使用 AgentInlineSkill 实现距离换算第一个 Skill 使用 AgentInlineSkill 实现。它适合比较简单、轻量的场景直接在代码中定义 Skill 的资源和脚本。var distanceSkill new AgentInlineSkill( name: distance-converter, description: 在距离单位之间转换。当要求将英里转换为千米或将千米转换为英里时使用。, instructions: 当用户要求在距离单位英里和千米之间转换时请使用此技能。 1. 查看 distance-table 资源找到所请求转换的系数。 2. 使用 convert 脚本传入值和表中的系数。 ) .AddResource(distance-table, (IServiceProvider serviceProvider) { var service serviceProvider.GetRequiredServiceConversionService(); return service.GetDistanceTable(); }) .AddScript(convert, (double value, double factor, IServiceProvider serviceProvider) { var service serviceProvider.GetRequiredServiceConversionService(); return service.Convert(value, factor); });这里有一个关键点资源和脚本方法中都声明了IServiceProvider参数。例如.AddResource(distance-table, (IServiceProvider serviceProvider) { var service serviceProvider.GetRequiredServiceConversionService(); return service.GetDistanceTable(); })Agent Framework 会自动注入IServiceProvider。然后我们就可以通过var service serviceProvider.GetRequiredServiceConversionService();距离换算的执行过程大致如下用户提出距离换算问题。Agent 判断需要使用distance-converter。Skill 读取distance-table资源。Agent 根据换算表选择正确的系数。调用convert脚本完成计算。返回最终结果。8. 使用 AgentClassSkill 实现重量换算第二个 Skill 使用基于类的方式实现也就是 AgentClassSkill。 这种方式更适合结构稍复杂的 Skill因为可以把资源、脚本、说明信息都封装在一个类中。internal sealedclassWeightConverterSkill : AgentClassSkillWeightConverterSkill { publicoverride AgentSkillFrontmatter Frontmatter { get; } new( weight-converter, 在重量单位之间转换。当要求将磅转换为千克或将千克转换为磅时使用。); protectedoverridestring Instructions 当用户要求在重量单位磅和千克之间转换时请使用此技能。 1. 查看 weight-table 资源找到所请求转换的系数。 2. 使用 convert 脚本传入值和表中的系数。 3. 使用两个单位清晰呈现结果。 ; [AgentSkillResource(weight-table)] [Description(重量转换乘法系数的查找表。)] private static string GetWeightTable(IServiceProvider serviceProvider) { var service serviceProvider.GetRequiredServiceConversionService(); return service.GetWeightTable(); } [AgentSkillScript(convert)] [Description(将值乘以转换系数并以 JSON 形式返回结果。)] private static string Convert(double value, double factor, IServiceProvider serviceProvider) { var service serviceProvider.GetRequiredServiceConversionService(); return service.Convert(value, factor); } }基于ClassBased的 Skill里面属性和方法的作用我们在前面的文章中已经介绍过了这里不再赘述。在类形式的 Skill 中同样可以通过IServiceProvider使用 DI。例如资源方法[AgentSkillResource(weight-table)] [Description(重量转换乘法系数的查找表。)] private static string GetWeightTable(IServiceProvider serviceProvider) { var service serviceProvider.GetRequiredServiceConversionService(); return service.GetWeightTable(); }脚本方法[AgentSkillScript(convert)] [Description(将值乘以转换系数并以 JSON 形式返回结果。)] private static string Convert(double value, double factor, IServiceProvider serviceProvider) { var service serviceProvider.GetRequiredServiceConversionService(); return service.Convert(value, factor); }只要方法参数中声明了IServiceProvider, Agent Framework 就会在执行时自动注入它。这样ClassBased Skill 也可以和普通 ASP.NET Core 或 Worker Service 一样通过 DI 使用应用中的业务服务。9. 注册多个 Skill定义好距离 Skill 和重量 Skill 后需要把它们注册到统一的技能提供者中。var weightSkill new WeightConverterSkill(); var skillsProvider new AgentSkillsProvider(distanceSkill, weightSkill);它们分别负责不同的领域Skill实现方式能力distance-converterAgentInlineSkill英里和千米转换weight-converterAgentClassSkill磅和千克转换这意味着同一个 Agent 可以根据用户问题自动选择合适的 Skill。如果用户问26.2 英里是多少千米Agent 会倾向于使用distance-converter。如果用户问75 千克是多少磅Agent 会倾向于使用weight-converter。如果用户同时问两个问题Agent 也可以分别调用不同的 Skill 来完成任务。10. 创建 Agent 并注入AgentSkillsProvider和IServiceProvider接下来创建 AgentAIAgent agent new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()) .GetResponsesClient() .AsAIAgent( options: new ChatClientAgentOptions { Name UnitConverterAgent, ChatOptions new() { Instructions 你是一个可以转换单位的实用助手。, }, AIContextProviders [skillsProvider], }, model: deploymentName, services: serviceProvider);这里有两个地方非常重要。第一个是AIContextProviders [skillsProvider]这表示把前面定义的 Skill 提供给 Agent。第二个是services: serviceProvider这表示把 DI 容器传递给 Agent。 正因为传入了serviceProvider所以 Skill 在执行资源和脚本时才能自动获得IServiceProvider然后解析出ConversionService。 如果没有传入这个服务提供者Skill 中依赖 DI 的代码就无法正常解析服务。11. 运行示例最后我们向 Agent 提出一个同时包含距离和重量换算的问题AgentResponse response await agent.RunAsync( 一场马拉松26.2 英里是多少千米75 千克是多少磅); Console.WriteLine($智能体{response.Text});根据示例中的转换系数计算结果如下为12. 为什么要在 Skill 中使用 DI把 DI 引入 Agent Skill最大的好处是让 Skill 不再直接依赖具体实现。 比如在当前示例中Skill 并不负责保存换算表也不直接维护业务规则而是通过ConversionService来完成具体业务。这样做有几个好处。1. 业务逻辑可以复用ConversionService 不只可以被 Agent Skill 使用也可以被普通 API、后台任务、命令行工具或测试代码使用。 Skill 只是业务能力的一种入口。2. 更容易测试如果未来要测试 Skill可以替换掉真实的服务实现注入 Mock 服务或测试服务。 例如可以把ConversionService抽象成接口IConversionService然后在测试中注入假的实现。3. 更容易扩展如果以后换算规则不再写死在代码中而是来自数据库只需要修改服务层即可。 Skill 的调用方式可以保持不变。4. 更符合 .NET 应用架构在 ASP.NET Core、Worker Service 和现代 .NET 应用中DI 是非常核心的基础设施。 Agent Skill 支持 DI意味着它可以自然融入现有 .NET 应用架构。13. Agent Skill 和传统服务的关系可以把 Agent Skill 理解成一层“AI 可调用的能力入口”。 传统代码中我们可能这样调用服务var result conversionService.Convert(value, factor);而在 Agent Framework 中用户通过自然语言提出问题 26.2 英里是多少千米Agent 会根据问题自动选择 Skill然后 Skill 再调用服务var service serviceProvider.GetRequiredServiceConversionService(); return service.Convert(value, factor);所以它们的关系可以理解为用户自然语言 ↓ Agent ↓ Skill ↓ DI 服务 ↓ 业务逻辑Skill 并不是替代业务服务而是把业务服务包装成 Agent 可以理解和调用的能力。总结本文演示了如何在 Agent Framework 中结合依赖注入使用 Agent Skill。 示例中包含两种 SkillAgentInlineSkill用于距离换算。AgentClassSkill用于重量换算。这两个 Skill 都没有直接维护复杂业务逻辑而是通过 IServiceProvider 从 DI 容器中解析同一个 ConversionService。通过这种方式Agent Skill 可以像普通 .NET 组件一样使用应用中的服务。 这让 Skill 的设计更加清晰也让 Agent 更容易接入真实业务系统。 随着 Skill 接入的服务越来越多Agent 的能力也会不断增强。从简单的单位换算到数据库查询、HTTP API 调用、企业系统集成最终都可以通过同样的方式扩展出来。源代码地址https://github.com/bingbing-gui/dotnet-platform/tree/master/src/09-AI-Agent/Agent-Framework/32-AgentSkill-Integration-DI

相关文章:

Agent Framework 中为 Agent Skill 接入依赖注入 DI

在前面的文章中,我们介绍过 FileBased、CodeBased 和 ClassBased 等不同的 Skill 实现方式,也演示了如何通过 AgentSkillsProvider 或 AgentSkillsProviderBuilder 将多个 Skill 组合起来,让一个 Agent 同时具备多种能力。在实际项目中&#…...

一夜爆火!这个4千星的开源项目让Agent重回文档

一个登上 GitHub 热榜的桌面端 GUI在 AI Agent 的开源战场上,一个名字正在被越来越多开发者反复提起:lukilabs/craft-agents-oss。4 月中旬,这个项目登上 GitHub 日热榜 AI 类榜单,短时间内积累四千余 Star。与一众「命令行型」智…...

基于Azure OpenAI构建企业级AI聊天应用:架构、部署与生产就绪指南

1. 项目概述与核心价值 最近在帮一个客户做企业级AI应用落地,他们想基于Azure OpenAI服务快速搭建一个内部使用的ChatGPT风格应用,同时要求具备企业级的身份认证、日志审计和对话数据持久化能力。在评估了几个方案后,我们最终选择了微软官方…...

独立开发者如何借助Taotoken模型广场为应用选择性价比最优模型

独立开发者如何借助Taotoken模型广场为应用选择性价比最优模型 1. 模型选型对独立开发者的挑战 独立开发者在集成AI功能时往往面临资源有限的困境。模型性能、调用成本和开发效率之间的平衡成为关键考量。传统方式需要开发者逐一注册不同厂商账号、申请API权限并手动测试&…...

别再手动降质了!用Python+OpenCV一键生成超分训练集(支持BI/BD/X2/X4/X6)

用PythonOpenCV打造智能超分训练集生成工具:从原理到实战 在计算机视觉领域,超分辨率重建技术正以前所未有的速度发展,而高质量的数据集是这一切的基础。传统手动处理高分辨率图像的方式不仅耗时耗力,还难以保证不同缩放比例下的一…...

微信聊天记录本地化提取与数据分析:从数据解密到个人AI记忆库构建

1. 项目概述:从微信聊天记录到个人AI记忆库在数字生活的洪流中,微信早已不是简单的通讯工具,它承载了我们与亲友的日常絮语、工作伙伴的严肃讨论,以及无数个一闪而过的灵感与情绪。这些看似零散的对话,实则构成了我们数…...

别急着pip install!遇到‘No module named transformers’时,先检查这3个地方(附快速诊断脚本)

别急着pip install!遇到‘No module named transformers’时,先检查这3个地方(附快速诊断脚本) 当你满心欢喜地准备运行一个基于transformers库的NLP项目时,命令行突然抛出ModuleNotFoundError: No module named trans…...

别再死磕公式了!用VASP/Quantum ESPRESSO理解平面波基组截断能(附实战参数设置)

平面波截断能实战指南:从物理图像到VASP/Quantum ESPRESSO参数优化 1. 理解截断能的物理本质 当第一次打开VASP的INCAR文件或Quantum ESPRESSO的输入文件时,"ENCUT"或"ecutwfc"这个参数往往让人困惑——它就像一扇神秘的门&#xff…...

【YOLOv11】087、YOLOv11多任务学习:检测、分割、分类联合学习

上周在部署一个工业质检项目时遇到个头疼问题:产线上既要定位缺陷位置(检测),又要判断缺陷类型(分类),还得精确测量缺陷面积(分割)。 客户最初方案是跑三个独立模型——检测用YOLO,分割用UNet,分类用ResNet。结果在Jetson Orin上帧率直接掉到3FPS,内存占用爆满。这…...

B站缓存视频转换终极指南:3分钟学会永久保存珍贵内容

B站缓存视频转换终极指南:3分钟学会永久保存珍贵内容 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾为B站视频突然下架而措…...

从“驴拉磨”到“磁悬浮”:用生活化比喻拆解FOC(磁场定向控制)到底在干啥

从“驴拉磨”到“磁悬浮”:用生活化比喻拆解FOC(磁场定向控制)到底在干啥 想象一下,你正试图让一头倔强的驴子拉磨。传统方法是用鞭子抽打(六步换向),而现代方法则像用磁悬浮列车牵引&#xff0…...

FanControl终极指南:深度掌握Windows风扇控制与性能优化实战

FanControl终极指南:深度掌握Windows风扇控制与性能优化实战 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trend…...

告别笨重模拟器:3分钟在Windows电脑安装安卓应用的终极方案

告别笨重模拟器:3分钟在Windows电脑安装安卓应用的终极方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾为在Windows电脑上运行安卓应用而烦恼&…...

终极Cursor Pro破解指南:从设备限制到永久免费使用的创新方案

终极Cursor Pro破解指南:从设备限制到永久免费使用的创新方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached y…...

自举C编译器shecc:从编译原理到RISC-V/x86-64代码生成实践

1. 项目概述:一个自举的C语言编译器在嵌入式开发、操作系统内核研究,甚至是计算机科学教育领域,自己动手写一个编译器,常常被视为一项“屠龙之术”。它听起来高深莫测,似乎离日常开发很远。但今天要聊的这个项目——sy…...

Mastodon智能光标代理:优化去中心化社交信息流体验

1. 项目概述:一个让Mastodon“动”起来的智能光标代理如果你玩过Mastodon,或者对去中心化社交网络感兴趣,那你肯定知道,在信息流里快速、精准地找到自己关心的内容,有时候就像大海捞针。传统的滚动浏览方式&#xff0c…...

10倍速硬字幕提取革命:SubtitleOCR如何重新定义视频处理效率

10倍速硬字幕提取革命:SubtitleOCR如何重新定义视频处理效率 【免费下载链接】SubtitleOCR 快如闪电的硬字幕提取工具。仅需苹果M1芯片或英伟达3060显卡即可达到10倍速提取。A very fast tool for video hardcode subtitle extraction 项目地址: https://gitcode.…...

Word论文党必看:用页眉插入背景图,完美解决转PDF图片重叠的坑

Word论文排版进阶:页眉插入背景图解决PDF导出重叠问题 对于学术写作和商务报告而言,文档的视觉呈现与内容质量同等重要。许多用户在Word中精心设计的背景图案,在转换为PDF时却遭遇图片错位、重复堆叠的尴尬。这种技术痛点不仅影响专业形象&am…...

教育科技公司利用Taotoken构建多模型对比演示平台的设计思路

教育科技公司利用Taotoken构建多模型对比演示平台的设计思路 1. 需求背景与架构设计 教育科技公司在开发AI教学工具时,常需要向学生展示不同大模型的能力差异。传统方案需要对接多个厂商API,面临密钥管理复杂、计费分散、响应格式不统一等问题。通过Ta…...

LLC电源设计踩坑记:磁化电感选大了还是选小了?一个参数引发的ZVS与关断损耗“战争”

LLC电源设计中的磁化电感博弈:ZVS与关断损耗的平衡艺术 在LLC谐振变换器的设计过程中,磁化电感(Lm)的取值往往让工程师们陷入两难境地。这个看似简单的参数,实际上牵动着整个电源系统的性能神经——它既决定了零电压开关(ZVS)的实现难度&…...

避坑指南:STM32+ESP8266连接巴法云,这5个错误千万别犯

STM32ESP8266连接巴法云实战避坑手册:从实验室到量产的关键五步 当你把实验室里运行良好的STM32ESP8266组合部署到真实环境中,突然发现设备频繁掉线、数据丢失甚至莫名重启——这种从理想跌入现实的体验,相信很多开发者都深有体会。本文将分…...

如何在Windows上轻松安装Android应用:APK Installer完全指南

如何在Windows上轻松安装Android应用:APK Installer完全指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想过在Windows电脑上直接安装Androi…...

ROS开发者的远程办公指南:用Nomachine流畅控制Ubuntu和Jetson双系统

ROS开发者高效远程办公实战:Nomachine跨平台控制与性能调优全攻略 引言 清晨六点,机器人工程师张工被紧急电话惊醒——部署在测试场的移动机器人突然失去响应。传统方案需要两小时车程赶往现场,但通过预先配置的Nomachine远程连接&#xff0c…...

通过 Taotoken CLI 工具一键配置多款 AI 助手开发环境

通过 Taotoken CLI 工具一键配置多款 AI 助手开发环境 1. 安装 Taotoken CLI Taotoken CLI 工具提供两种安装方式,适用于不同使用场景: # 全局安装(适合频繁使用) npm install -g taotoken/taotoken# 临时调用(无需…...

AEUX终极指南:如何用5个步骤彻底告别动效设计中的重复劳动

AEUX终极指南:如何用5个步骤彻底告别动效设计中的重复劳动 【免费下载链接】AEUX Editable After Effects layers from Sketch artboards 项目地址: https://gitcode.com/gh_mirrors/ae/AEUX 你是否曾经花费数小时在Figma或Sketch中精心设计了完美的界面&…...

2026年5月阿里云集成Hermes Agent/OpenClaw步骤,百炼token Plan配置教程

2026年5月阿里云集成Hermes Agent/OpenClaw步骤,百炼token Plan配置教程。本文面向零基础用户,完整说明在轻量服务器与本地Windows11、macOS、Linux系统中部署OpenClaw(Clawdbot)的流程,包含环境配置、服务启动、Skill…...

从毫米波雷达到YOLO:手把手拆解一个真实的FCW预警系统(附Python/ROS代码片段)

从毫米波雷达到YOLO:手把手拆解一个真实的FCW预警系统(附Python/ROS代码片段) 在自动驾驶技术快速发展的今天,前向碰撞预警(FCW)系统已经从高端车型的选配逐渐成为主流安全配置。不同于传统汽车安全系统在事故发生后减轻伤害的被动…...

一站式MapleStory游戏资源编辑神器:Harepacker-resurrected完全指南

一站式MapleStory游戏资源编辑神器:Harepacker-resurrected完全指南 【免费下载链接】Harepacker-resurrected All in one .wz file/map editor for MapleStory game files 项目地址: https://gitcode.com/gh_mirrors/ha/Harepacker-resurrected 想要轻松编辑…...

MySQL InnoDB的‘双保险’:手把手教你理解并配置Doublewrite Buffer(附性能调优建议)

MySQL InnoDB双写缓冲区实战指南:从原理到调优的深度解析 引言 数据库系统的可靠性是每个DBA和开发者最关心的问题之一。在众多保障数据完整性的机制中,InnoDB存储引擎的Doublewrite Buffer(双写缓冲区)扮演着至关重要的角色。这个…...

Windows上轻量级安卓应用安装神器:告别臃肿模拟器,APK Installer带你开启高效跨平台体验

Windows上轻量级安卓应用安装神器:告别臃肿模拟器,APK Installer带你开启高效跨平台体验 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否…...