
本文教大家使用AgentFramework集成Agent Skill智能体技能1.基础知识代理技能是指令、脚本和资源的可移植包可提供代理的专用功能和域专业知识。 技能遵循开放规范并实现渐进式披露模式以便代理在需要时仅加载所需的上下文。在需要时使用代理技能封装领域专业知识 - 将专业知识费用策略、法律工作流、数据分析管道捕获为可重用且可移植的包。扩展代理功能 - 为代理提供新功能而无需更改其核心指令。确保一致性 - 将多步骤任务转换为可重复的可审核工作流。启用互作性 - 在不同的代理技能兼容产品中重复使用相同的技能。技能结构技能是一个目录包含一个 SKILL.md 文件并且可以选择包括用于存放资源的子目录expense-report/├── SKILL.md # Required — frontmatterinstructions ├── scripts/│ └── validate.py # Executable code agents can run ├── references/│ └── POLICY_FAQ.md # Reference documents loadedondemand └── assets/└── expense-report-template.md # TemplatesandstaticresourcesSKILL.md 格式该文件 SKILL.md 必须包含 YAML 前置数据后跟 Markdown 内容name:expense-reportdescription:Fileandvalidate employee expense reports according to company policy.Usewhenasked aboutexpensesubmissions,reimbursementrules,orspending limits.license:Apache-2.0compatibility:Requirespython3metadata:author:contoso-financeversion:2.1---## Shell SKILL 文件夹https://github.com/junkai-li/NetCoreKevin/tree/master/Kevin/kevin.Module/kevin.AI.AgentFramework/Skills基本设置创建一个指向包含您技能的目录的FileAgentSkillsProvider并将其添加到代理的上下文提供者中。源代码地址https://github.com/junkai-li/NetCoreKevin/blob/master/Kevin/kevin.Module/kevin.AI.AgentFramework/AIAgentService.csusingAzure.AI.OpenAI;usingAzure.Identity;usingMicrosoft.Agents.AI;// Discover skills from the skills directoryvarskillsProvidernewFileAgentSkillsProvider(skillPaths:[Path.Combine(AppContext.BaseDirectory/Skills,expense-report-skills),Path.Combine(AppContext.BaseDirectory/Skills,system-ops-skills)],options:newFileAgentSkillsProviderOptions{SkillsInstructionPrompt 你可以使用以下技能获取领域知识和操作指引。 每个技能提供专业指令、参考文档和可执行脚本 它们如下:{0}使用 expense-report 这个技能用于 按照NetCoreKevin科技公司政策填写和审核员工费用报销。适用于费用报销、报销规则、收据要求、支出限额或费用类别等相关问题。 使用 system-ops 这个技能 工作流程1.当用户任务匹配技能描述时使用 load_skill 加载该技能的完整指令2.技能指令中会标明可用脚本及其执行命令3.使用 run_shell 工具执行技能中标注的命令4.需要时使用 read_skill_resource 读取参考资料。 重要原则先加载知识再执行操作。});// Create an agent with the skills providerAIAgentagentnewAzureOpenAIClient(newUri(endpoint),newDefaultAzureCredential()).GetResponsesClient(deploymentName).AsAIAgent(newChatClientAgentOptions{NameSkillsAgent,ChatOptionsnew(){InstructionsYou are a helpful assistant.,// 能力层工具ToolsnewListAITool(){AIFunctionFactory.Create(KevinBasicAI.GetNetCoreKevinInfo,newAIFunctionFactoryOptions{NameGetNetCoreKevinInfo,Description获取NetCoreKevin框架的介绍信息}),AIFunctionFactory.Create(ShellTools.RunShell,newAIFunctionFactoryOptions{NameRunShell,Description执行 Shell 命令。通过操作系统原生 Shell 执行命令Windows 用 cmdLinux/Mac 用 bash。包含安全护栏危险命令阻止、输出截断50KB、超时控制60秒。})};},AIContextProviders[skillsProvider],});自定义系统提示默认情况下技能提供程序会注入系统提示其中列出了可用的技能并指示代理使用 load_skill 和 read_skill_resource。 可以自定义此提示varskillsProvidernewFileAgentSkillsProvider(skillPath:Path.Combine(AppContext.BaseDirectory,skills),options:newFileAgentSkillsProviderOptions{SkillsInstructionPrompt You have skills available.Heretheyare:{0}Use the load_skill function togetskill instructions.Use the read_skill_resource function to read skill files.});Tools工具ShellTools.csusingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Diagnostics;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacekevin.AI.AgentFramework.Tools{publicclassShellTools{// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━// run_shell — 一个 Shell 工具做一切含安全护栏// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━// ️ 安全护栏 1危险命令黑名单privatestaticstring[]dangerousPatterns[rm -rf /,rm -rf /*,// 删除根目录sudo ,// 提权shutdown,reboot,// 系统操作 /dev/,// 设备写入:(){ :|: };:,// Fork bombmkfs.,// 格式化dd if,// 磁盘覆写format ,// Windows 格式化del /f /s /q,// Windows 递归删除];[Description(执行 Shell 命令。通过操作系统原生 Shell 执行命令Windows 用 cmdLinux/Mac 用 bash。包含安全护栏危险命令阻止、输出截断50KB、超时控制60秒。)]publicstaticstringRunShell([Description(要执行的 Shell 命令。例如pwsh -File /path/to/script.ps1 或 dir)]stringcommand,[Description(命令执行的工作目录可选。如果不指定使用当前目录。)]string?workingDirectorynull){try{// ️ 安全护栏 1危险命令检查if(dangerousPatterns.Any(dcommand.Contains(d,StringComparison.OrdinalIgnoreCase))){return❌ 安全拦截检测到危险命令已阻止执行。;}Console.WriteLine($ 正在执行 Shell 命令{command});// 跨平台 Shell 适配// Windows → cmd /c command 原生命令提示符// Linux/Mac → bash -c command 原生 Bash//// 为什么不直接用 pwsh// SKILL.md 中的命令已经是 pwsh -File ...// 如果 RunShell 也用 pwsh -Command 包裹 → pwsh 套 pwsh冗余嵌套// 用原生 shell 分发 → pwsh -File 直接执行零嵌套varisWindowsOperatingSystem.IsWindows();varprocessInfonewProcessStartInfo{FileNameisWindows?cmd:bash,ArgumentsisWindows?$/c{command}:$-c \{command.Replace(\,\\\)}\,RedirectStandardOutputtrue,RedirectStandardErrortrue,UseShellExecutefalse,CreateNoWindowtrue};// 设置工作目录if(!string.IsNullOrWhiteSpace(workingDirectory)Directory.Exists(workingDirectory)){processInfo.WorkingDirectoryworkingDirectory;}usingvarprocessProcess.Start(processInfo);if(processnull){return❌ 无法启动 Shell 进程;}varstdoutprocess.StandardOutput.ReadToEnd();varstderrprocess.StandardError.ReadToEnd();// ️ 安全护栏 3超时控制60秒if(!process.WaitForExit(60_000)){process.Kill(entireProcessTree:true);return❌ 命令执行超时60秒已强制终止。;}varresultnewStringBuilder();if(!string.IsNullOrWhiteSpace(stdout)){result.AppendLine(stdout.Trim());}if(!string.IsNullOrWhiteSpace(stderr)){result.AppendLine($⚠️ stderr:{stderr.Trim()});}if(process.ExitCode!0){result.AppendLine($⚠️ 退出码:{process.ExitCode});}varoutputresult.Length0?result.ToString():(命令执行成功无输出);// ️ 安全护栏 2输出截断50KBconstintmaxOutputLength50_000;if(output.LengthmaxOutputLength){outputoutput[..maxOutputLength]\n... (输出已截断超过 50KB 上限);}returnoutput;}catch(Exceptionex){return$❌ 执行失败:{ex.Message};}}}}效果图AI使用Shell命名进行相关电脑本机操作参考源代码 NetCoreKevin框架下的kevin.AI.AgentFramework模块基于.NET构建的企业级SaaSAI智能体应用架构采用前后端分离设计具备以下核心特性AI智能体框架RAG检索增强AI知识库AI智能体技能集成-RabbitMQ消息队列一库多租户解决方案多级缓存机制CAP事件集成SignalR实时通信领域驱动设计等等…项目地址githubhttps://github.com/junkai-li/NetCoreKevinGitee: https://gitee.com/netkevin-li/NetCoreKevin参考文献https://learn.microsoft.com/zh-cn/agent-framework/agents/skills?pivotsprogramming-language-csharp