---
URL: "/zh-CN/blog/2026-07/AgentFramework-Skill.html"
LLMS_URL: "/zh-CN/blog/2026-07/AgentFramework-Skill.md"
lastUpdated: true
commentabled: true
recommended: true
title: "AgentFramework实现AI智能体Skill和工具动态管理和加载"
description: "AgentFramework实现AI智能体Skill和工具动态管理和加载"
date:

pageClass: "blog-page-class"
cover: "/covers/dotnet.svg"
---

## 背景与目标

在大模型应用开发中，智能体需要灵活组合各种 工具（Tool） 与 技能（Skill） 来完成任务。NetCoreKevin 框架基于自主研发的 AgentFramework 底层，提供了一套“数据驱动 + 文件热加载”的动态能力扩展方案，让开发者无需修改核心代码即可为不同智能体按需配置工具和技能。

本文深入剖析该方案的实现细节，涵盖从数据库定义、动态注入 `AITool`，到 `.zip` 技能包的自动解压与加载全过程，帮助读者快速理解底层架构并应用于实际项目。

## 整体架构概览

能力管理分为两个维度：

- 工具（Tool）：粒度小、无状态，通过 `AIFunctionFactory` 将普通 C# 方法包装为 AI 可调用的函数，直接注入 ChatOptions.Tools 列表。
- 技能（Skill）：有状态的复合能力单元，以文件包（`.zip`）形式存储，通过 `AgentSkillsProviderBuilder` 构建为 AIContextProvider，由 AgentFramework 负责调度。

核心组件协作关系如下：

```mermaid
flowchart TD
    ChatClient[ChatClientAgent<br>（ChatOptions.Tools + AIContextProviders）]

    ChatClient -->|Tools| LeftGroup
    ChatClient -->|Skills| RightGroup

    subgraph LeftGroup [工具侧]
        direction TB
        ToolComponent[AIAgentTool / SkillService]
        ToolComponent --> SysTools[SysTools（静态工具）]
        ToolComponent --> IKevinTask[IKevinAITaskService 等]
        SysTools --> DB[AISkillToolManagementService（数据库）]
        IKevinTask --> DB
    end

    subgraph RightGroup [技能侧]
        direction TB
        SkillComponent[AgentSkillsProvider / Builder（AgentFramework）]
        SkillComponent --> FileSys[文件系统 Skill 目录]
    end
```

底层完全依赖 AgentFramework 提供的：

- AgentSkillsProviderBuilder、AgentFileSkillsSourceOptions
- AITool、AIFunctionFactory
- PySubprocessScriptRunner 等执行器

## 数据驱动的 Skill 与 Tool 定义

框架将工具和技能统一存储在 `TAISkillToolManagement` 实体中，由 `IAISkillToolManagementService` 提供管理服务。关键字段包括：

| 字段          | 说明                                        |
| :------------ | :------------------------------------------ |
| Name          | 工具/技能唯一标识名                         |
| SkillToolType | 枚举：Tool / Skill                          |
| ClassMethod   | 工具绑定的方法名（如 AddOrUpdateCronTask ） |
| Description   | 功能描述，供大模型决策用                    |
| ActiveStatus  | 是否启用                                    |
| IsSystem      | 是否系统内置（禁止删除）                    |

技能还附带一个 `.zip` 附件，包含脚本文件、资源等，通过文件服务管理。

```csharp
// 获取所有启用的工具
public async Task<List<AISkillToolManagementDto>> GetAllTools()
{
    return (await AISkillToolManagementRp.Query(...)
        .Where(t => t.SkillToolType == AISkillToolTypeEnums.Tool
                  && t.ActiveStatus == InActiveStatusEnums.Active)
        .ToListAsync())
        .MapToList<TAISkillToolManagement, AISkillToolManagementDto>();
}
```

## 工具的动态注入

工具注入由 `AIAgentToolSkillService` 实现，其核心流程为：

- 根据 agentId 查询绑定表 IAISkillToolBindIdService，获得该智能体允许使用的工具管理 ID。
- 通过 `AISkillToolManagementService.GetAllTools()` 过滤出这些 ID 对应的工具记录，提取 ClassMethod 名称。
- 调用 GetAITools 将方法名转化为 AITool 实例。

### 静态工具与动态工具的区分

SysTools.Tools 是一个预注册的全局字典，存放所有“静态工具”（无需依赖注入即可直接使用的工具）。如果工具名存在于字典，直接取出；否则进入 `switch` 分支，通过 `AIFunctionFactory.Create` 将具体服务方法包装为 AITool。

```csharp
private async Task<List<AITool>> GetAITools(object data, List<string> toolNames)
{
    var aiTools = new List<AITool>();
    _kevinAITaskService.InitData(data);
    foreach (var item in toolNames)
    {
        if (SysTools.Tools.ContainsKey(item))
        {
            aiTools.Add(SysTools.Tools[item]); // 静态工具
        }
        else
        {
            switch (item)
            {
                case "AddOrUpdateCronTask":
                    aiTools.Add(AIFunctionFactory.Create(
                        _kevinAITaskService.AddOrUpdateCronTask,
                        new AIFunctionFactoryOptions { Name = "AddOrUpdateCronTask",
                            Description = "创建或更新一个周期性自动任务" }));
                    break;
                case "RemoveCronTask":
                    // ... 类似
                    break;
                // ... 更多工具
            }
        }
    }
    return aiTools;
}
```

### 与智能体集成

在构造 `ChatClientAgentOptions` 时，如果配置启用了工具，则从服务中获取工具列表，合并到 ChatOptions.Tools：

```csharp
if (aiapp.IsAITools)
{
    chatAgOs.ChatOptions.Tools ??= new List<AITool>();
    chatAgOs.ChatOptions.Tools.AddRange(
        _aIAgentToolSkillService.GetUserAIAgentToolsAsync(
            new { AIChatsId = add.AIChatsId },
            aiapp.Id.ToString(),
            CurrentUser.UserId.ToString()
        ).Result
    );
}
```

这样每个智能体实例都能拥有不同的工具集，实现多租户级别的能力隔离。

## 技能文件的动态加载

技能本质上是包含脚本（`.py`、`.sh`、`.ps1`）和资源文件的目录包。上传时打包为 `.zip`，由 AISkillToolManagementService.AddEdit 负责下载、解压并放置到应用根目录下的 Skills/{技能名称}/ 路径中。

```csharp
// 处理技能 zip 包
if (data.SkillToolType == AISkillToolTypeEnums.Skill)
{
    var flieData = _FileRp.Query().FirstOrDefault(t =>
        t.Table == "AISkillToolManagement" && t.Sign == "SkillZip" && t.TableId == data.Id.ToString());
    if (flieData != null)
    {
        var path = Path.Combine(AppContext.BaseDirectory, "Skills", data.Name, data.Name);
        if (Directory.Exists(path))
            Directory.Delete(path, true);
        Directory.CreateDirectory(path);
        _FileStorage.FileDownload(flieData.Url, path + flieData.Name);
        using var fileStream = File.OpenRead(path + flieData.Name);
        FileZipHelper.ExtractZipStreamToDirectory(fileStream, path);
        File.Delete(path + flieData.Name); // 删除原始 zip
    }
}
```

### 通过 AgentFramework 注册文件技能

在构建智能体时，从服务获取该智能体绑定的技能路径列表，然后利用 AgentSkillsProviderBuilder 将它们逐一注册为 FileSkill：

```csharp
if (aiapp.IsSkill)
{
    var skillPaths = _aIAgentToolSkillService.GetUserAIAgentSkillsAsync(...).Result;
    var skillsProvider = new AgentSkillsProviderBuilder()
        .UseFileScriptRunner(PySubprocessScriptRunner.StaticRunAsync)
        .UseOptions(options => options.DisableCaching = true);

    foreach (var skillPath in skillPaths)
    {
        skillsProvider.UseFileSkill(
            Path.Combine(AppContext.BaseDirectory, "Skills", skillPath),
            new AgentFileSkillsSourceOptions
            {
                AllowedScriptExtensions = [".py", ".sh", ".ps1"],
                ScriptDirectories = ["scripts", "tools", "templates"],
            });
    }
    chatAgOs.AIContextProviders = [skillsProvider.Build()];
}
```

AgentSkillsProviderBuilder 属于 AgentFramework 核心，它负责扫描指定目录下的脚本文件，并与 PySubprocessScriptRunner 等执行器关联，生成可以响应大模型调用的技能上下文。

## 管理与绑定服务

### 技能/工具管理服务

AISkillToolManagementService 提供标准 CRUD 操作：

- 分页查询，支持按类型筛选；
- 新增/编辑时自动处理附件解压；
- 删除（逻辑删除）并对系统内置项进行保护。

### 智能体绑定

IAISkillToolBindIdService 维护智能体与技能/工具管理 ID 的映射关系，决定每个智能体可用的能力列表。AIAgentToolSkillService 正是依赖此服务实现按 agentId 和 userId 的动态过滤。

```csharp
public async Task<List<AITool>> GetAIAgentToolsAsync(object data, string agentId)
{
    var agentBindIds = (await _iAISkillToolBindIdService.GetListById(agentId))
        .Select(t => t.AISkillToolManagementId).ToList();
    var tools = (await _iAISkillToolManagementService.GetAllTools())
        .Where(t => agentBindIds.Contains(t.Id)).ToList();
    return await GetAITools(data, tools.Select(t => t.ClassMethod ?? "").ToList());
}
```

这种方式使得能力配置完全与代码分离，可通过后台管理界面灵活调整，而无需重启服务。

## 总结

基于 AgentFramework，通过 数据库驱动 + 文件系统热加载 实现了 AI 智能体工具与技能的动态管理。其核心优势在于：

- 工具注入：方法名映射与 AIFunctionFactory 结合，可零侵入地将业务方法暴露给大模型。
- 技能加载：`.zip` 文件包上传自动解压，再利用 AgentSkillsProviderBuilder 注册为上下文提供者，支持脚本类技能的热插拔。
- 权限隔离：通过绑定表实现不同智能体、不同用户的能力差异化，满足多租户场景。

该方案已在生产环境中验证，显著提升了智能体应用的迭代效率和可维护性。未来框架还将引入远程插件仓库、版本回滚等高级特性，持续降低智能体扩展的门槛。
