Ben.SemanticKernel 5.2.29

There is a newer version of this package available.
See the version list below for details.
dotnet add package Ben.SemanticKernel --version 5.2.29
                    
NuGet\Install-Package Ben.SemanticKernel -Version 5.2.29
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ben.SemanticKernel" Version="5.2.29" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Ben.SemanticKernel" Version="5.2.29" />
                    
Directory.Packages.props
<PackageReference Include="Ben.SemanticKernel" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Ben.SemanticKernel --version 5.2.29
                    
#r "nuget: Ben.SemanticKernel, 5.2.29"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Ben.SemanticKernel@5.2.29
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Ben.SemanticKernel&version=5.2.29
                    
Install as a Cake Addin
#tool nuget:?package=Ben.SemanticKernel&version=5.2.29
                    
Install as a Cake Tool

Ben.SemanticKernel 完整指南

基于 Microsoft Semantic Kernel 的企业级 AI Agent 框架
版本: v3.0 (ReAct Agent)
更新时间: 2025-10-24
.NET 版本: 8.0


📑 目录

  1. 项目概览
  2. 快速开始
  3. 核心架构
  4. 功能特性
  5. 配置说明
  6. API 接口
  7. ReAct Agent 模式
  8. 联网搜索系统
  9. MCP 工具集成
  10. 知识库 RAG
  11. 测试指南
  12. 开发指南
  13. 部署指南
  14. 常见问题
  15. 性能优化

1. 项目概览

1.1 项目简介

Ben.SemanticKernel 是一个生产级的 .NET AI Agent 框架,提供完整的 ReAct(Reasoning + Acting)模式实现、智能联网搜索、知识库管理和企业工具集成能力。

核心亮点:

  • ReAct Agent 模式:完整的 Planning → Action → Observation 循环
  • 深度思考可见:捕获 DeepSeek/OpenAI o1 的 reasoning_content
  • 智能分支选择:自动判断简单/复杂问题,优化执行策略
  • 企业级搜索:多引擎聚合(百度/Bing/Google)+ 语义重排
  • 专业 API 集成:天气(和风/OpenWeatherMap)、可扩展股票/新闻
  • MCP 工具支持:Model Context Protocol 企业工具集成
  • 知识库 RAG:向量检索(Qdrant/PgVector)+ 知识图谱

1.2 技术栈

组件 技术 版本
框架 Microsoft Semantic Kernel 1.66.0
运行时 .NET 8.0
AI 模型 DeepSeek / OpenAI / Ollama -
向量数据库 Qdrant / PostgreSQL (pgvector) -
浏览器自动化 Playwright 1.x
弹性策略 Polly 8.x

1.3 架构演进

v1.0 预检索 RAG (2024 Q1)
├─ 用户问题 → 系统强制搜索 → 注入结果 → LLM 生成
└─ ❌ 总是搜索,浪费资源;无深度思考

v2.0 简单 Agent RAG (2024 Q3)
├─ 用户问题 → LLM 自主决策 → 自动执行工具 → 返回结果
└─ ✅ LLM 自主决策  ❌ 思考不可见,无迭代

v3.0 ReAct Agent (2025 Q1) ⭐ 当前版本
├─ Planning → Action → Observation → Planning → ...
├─ ✅ 深度思考完全可见 (reasoning_content)
├─ ✅ 决策链透明 (planning/action/observation)
├─ ✅ 多轮迭代支持 (最多10次)
└─ ✅ 智能分支选择 (简单问题快速响应)

2. 快速开始 (10分钟)

2.1 环境要求

  • ✅ .NET 8.0 SDK 或更高版本
  • ✅ AI 服务 API Key (DeepSeek/OpenAI/Ollama)
  • ⚡ 可选:Playwright(联网搜索)
  • ⚡ 可选:Qdrant/PostgreSQL(知识库)

2.2 三步启动

步骤 1:安装 Playwright(可选,用于联网搜索)
cd Ben.SemanticKernel
.\install-playwright.ps1
步骤 2:配置 appsettings.json
{
  "BEN_SK": {
    "AIConfig": {
      "TextInfo": {
        "ApiKey": "sk-your-api-key",
        "Model": "deepseek-chat",
        "BaseUri": "https://api.deepseek.com",
        "Provider": "openai"
      },
      "EmbeddingInfo": {
        "ApiKey": "sk-your-api-key",
        "Model": "text-embedding-3-small",
        "BaseUri": "https://api.openai.com/v1",
        "Provider": "openai",
        "VectorSize": 1536,
        "Index": "default"
      }
    }
  }
}
步骤 3:运行示例项目
# 编译项目
dotnet build -c Release

# 启动 Web 服务
cd Ben.Examples
dotnet run

预期输出:

Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

2.3 快速测试

使用 REST Client 或 curl 测试:

POST http://localhost:5000/api/Chat/Chat
Content-Type: application/json

{
  "sessionId": 1,
  "text": "今天深圳天气怎么样?",
  "networking": true
}

预期响应(SSE 流式):

data: {"type":"thinking","data":"用户询问今天深圳天气,需要使用工具..."}

data: {"type":"planning","data":{"name":"search_weather",...}}

data: {"type":"action","data":"执行中..."}

data: {"type":"observation","data":"【深圳天气预报】..."}

data: {"type":"chat","data":"根据最新天气预报[1],深圳今天..."}

data: {"type":"times","data":4850}

data: {"type":"done","data":"done"}

3. 核心架构

3.1 整体架构图

graph TB
    User[用户请求] --> Controller[ChatController]
    Controller --> ChatService[ChatService<br/>核心编排器]
    
    ChatService --> Branch{智能分支选择}
    Branch -->|简单问题| Simple[简单模式<br/>快速响应 < 1s]
    Branch -->|复杂问题| ReAct[ReAct 模式<br/>完整循环]
    
    ReAct --> Loop{迭代循环}
    Loop --> Planning[💭 Planning<br/>决策阶段]
    Planning --> Action[⚡ Action<br/>执行工具]
    Action --> Observation[👁️ Observation<br/>获取结果]
    Observation --> Check{是否需要<br/>继续迭代?}
    Check -->|是| Loop
    Check -->|否| Answer[📢 Final Answer]
    
    Action --> Tools[工具层]
    Tools --> WebSearch[联网搜索]
    Tools --> Weather[天气 API]
    Tools --> MCP[MCP 工具]
    Tools --> KMS[知识库]
    
    WebSearch --> Aggregator[SearchAggregator<br/>多引擎聚合]
    Aggregator --> Baidu[百度]
    Aggregator --> Bing[Bing]
    Aggregator --> Google[Google]
    
    Aggregator --> Reranker[SemanticReranker<br/>语义重排]
    
    Answer --> SSE[SSE 流式输出]
    SSE --> User

3.2 目录结构

Ben.SemanticKernel/
├── AI/                          # AI 核心
│   ├── KernelFactory.cs         # Kernel 工厂(缓存、多提供商)
│   ├── KernelFactory.WebSearch.cs  # 联网搜索工具注册
│   ├── KernelFactory.Mcp.cs     # MCP 工具注册
│   └── MemoryKernelFactory.cs   # 向量检索
│
├── Services/
│   ├── ChatService/
│   │   ├── ChatService.cs       # 🔥 核心对话编排(1768行)
│   │   ├── WebSearchPlugin.cs   # Kernel 插件
│   │   └── ChatServiceExtension.cs  # DI 注册
│   │
│   ├── Common/
│   │   ├── SearchAggregator.cs  # 多引擎聚合
│   │   ├── SemanticReranker.cs  # 语义重排
│   │   ├── WeatherApiService.cs # 天气 API(三层降级)
│   │   ├── BingScraper.cs       # 搜索引擎抓取
│   │   ├── ContentExtractor.cs  # 网页正文提取
│   │   └── QueryClassifier.cs   # 查询分类(6大类)
│   │
│   ├── TextMemory/              # 向量存储
│   ├── KnowledgeGraph/          # 知识图谱
│   ├── Mcp/                     # MCP 服务
│   └── Tools/                   # 工具服务
│
├── Models/                      # 数据模型
├── Prompts/                     # 提示词模板
└── Utils/                       # 工具类

Ben.Examples/                    # 示例 Web 项目
├── Controllers/
│   ├── ChatController.cs        # 🔥 ReAct Agent API
│   ├── McpController.cs         # MCP 测试 API
│   └── KnowledgeController.cs   # 知识库管理
├── appsettings.json             # 配置文件
└── Program.cs                   # 启动入口

3.3 数据流

HTTP 请求 (POST /api/Chat/Chat)
  ↓
ChatController 接收
  ↓
构建系统提示词 + 历史消息
  ↓
ChatService.ChatAsync()
  ├─ IsLikelyNeedingTools("今天深圳天气") → true
  ├─ 用户启用工具 (networking=true) → true
  └─ 选择 ReAct 模式
  ↓
创建 Kernel + 注册 WebSearchPlugin
  ├─ search_web
  ├─ search_weather
  └─ search_news
  ↓
ReAct 循环 - 迭代 1
  ├─ 💭 Planning(非流式调用)
  │   └─ 捕获 reasoning_content → yield "thinking" 事件
  ├─ 检测 FunctionCallContent → search_weather("深圳", 1)
  └─ ⚡ Action:手动执行工具
  ↓
WebSearchPlugin.SearchWeatherAsync()
  ├─ 优先:WeatherApiService.GetWeatherAsync()
  │   ├─ 和风天气 API → 成功 ✅
  │   └─ 失败 → OpenWeatherMap → 失败 → 网页搜索
  └─ 降级:SearchWebAsync(..., extractFullContent: true)
  ↓
网页搜索流程(降级时)
  ├─ SearchAggregator.AggregateAsync()
  │   ├─ 智能引擎选择:百度 + Bing(并行)
  │   ├─ 合并去重:URL 归一化
  │   └─ ContentExtractor 抓取完整正文(Top 5)
  └─ SemanticReranker.RerankAsync()
      └─ Score = 余弦相似度 + 新鲜度 + 质量
  ↓
👁️ Observation:工具结果添加到历史
  ↓
ReAct 循环 - 迭代 2
  ├─ 💭 Planning(再次非流式调用)
  │   └─ 捕获 reasoning_content: "已获取信息,可以回答…"
  ├─ 无 FunctionCall → 最终答案阶段
  └─ 使用 chatResult.Content 伪流式输出(逐字符 3ms)
  ↓
输出完成
  ├─ yield "times" 事件(总耗时)
  ├─ yield "done" 事件
  └─ 触发 onCompletion 回调

4. 功能特性

4.1 ReAct Agent 模式

Planning → Action → Observation 完整循环

// 自动进入 ReAct 模式(系统智能判断)
await chatService.ChatAsync(
    input: "今天深圳天气",
    assistantPrompt: systemPrompt,
    aiOptions: options,
    _history: null,
    netWork: true,                     // 启用联网搜索
    serviceProvider: serviceProvider,  // 必须传递(工具注册)
    enableDeepThinking: true,          // 捕获深度思考
    maxIterations: 10                  // 最大迭代次数
);

控制台输出示例:

================================================================================
🧠 ReAct Agent 模式 - Planning → Action → Observation
================================================================================
📝 用户问题: 今天深圳天气怎么样?
💭 深度思考: 已启用(DeepSeek 兼容)
--------------------------------------------------------------------------------

[智能分支选择]
  - 系统判断需要工具: True
  - 用户启用工具: True
  - 系统自动选择: ReAct 模式(复杂问题)

💭 [Thinking] 用户询问今天深圳的天气,这是实时信息查询...

📋 [Planning] 决定调用工具: search_weather
    参数: {"location":"深圳","days":1}

⚡ [Action] 执行中...

✅ 天气 API 调用成功,返回 1 天预报

【深圳天气预报】来源: 和风天气
📅 10月24日(周四)
   天气: 多云 转 晴
   温度: 25°C ~ 31°C
   风向: 东南风 2级

👁️ [Observation] 工具执行成功

🔄 迭代 2/10

💭 [Thinking] 已获取天气信息,可以回答了...

📢 AI回答: 根据最新天气预报[1],深圳今天(10月24日)天气多云转晴...

⏱️  耗时: 4850ms (4.85秒)
================================================================================

4.2 智能分支选择

自动判断简单/复杂问题,优化执行策略

场景 判断 模式 响应时间 特点
"你好" 简单问题 简单模式 < 1秒 不传 tools,真流式,极速响应
"1+1=?" 简单问题 简单模式 < 1秒 直接回答,无工具调用
"今天深圳天气" 复杂问题 ReAct 模式 4-8秒 完整流程,思考可见
"特斯拉股价" 复杂问题 ReAct 模式 8-12秒 多引擎搜索 + 分析

判断规则(IsLikelyNeedingTools):

// ✅ 明确需要工具
if (input.Contains("天气") || input.Contains("新闻") || input.Contains("股票"))
    return true;

// ❌ 明确不需要工具
if (input.Matches(@"^\s*\d+\s*[\+\-\*/]\s*\d+"))  // 简单数学
    return false;
if (input.Matches(@"^(你好|hello|hi)"))  // 打招呼
    return false;

// 🤔 启发式判断
if (input.Length > 50)  // 长问题可能需要工具
    return true;

return input.Length >= 10;  // 保守策略

4.3 联网搜索系统

多引擎聚合 + 语义重排 + 全文抓取

搜索引擎策略
策略 引擎组合 适用场景
smart (推荐) 智能选择 中文→百度+Bing;英文→Google+Bing
baidu 仅百度 中文查询、中国本地信息
bing 仅 Bing 国际信息、平衡搜索
google 仅 Google 学术研究、技术文档
all 三引擎全开 需要最全面结果(较慢)
查询分类(6大类)
public enum QueryCategory
{
    Stock,      // 股票财经 → 东方财富、雪球
    News,       // 新闻资讯 → 全文抓取 + 时间优先
    Weather,    // 天气查询 → 优先天气 API
    Technical,  // 技术问题 → 增加 Google
    Academic,   // 学术研究 → Google + Bing
    General     // 通用查询 → 智能引擎
}
语义重排算法
最终分数 = 基础分 + 加权分

基础分 = Cosine(查询向量, 结果向量)  // 0.0-1.0

加权分 =
  + 标题匹配 × 0.05       // 标题包含关键词
  + 时间新鲜度 × 0.15     // 越新越好(时间敏感查询)
  + 内容质量 × 0.10       // 有 FullContent 优先

内容质量分 =
  + 有 FullContent: 0.5
  + 长度适中 (500-5000字): 0.2
  + ContentQuality 分数: 0.3

4.4 天气 API(三层降级)

search_weather("深圳", 7)
  ↓
① 和风天气 API
  ├─ 有 ApiKey → Web API 认证
  ├─ 成功 → 返回详细数据 ✅ (1-2秒)
  └─ 失败 ↓
② OpenWeatherMap API
  ├─ 成功 → 返回详细数据 ✅ (2-3秒)
  └─ 失败 ↓
③ 网页搜索(extractFullContent: true)
  └─ 返回网页抓取内容 ⚠️ (25-30秒)

配置示例:

{
  "WeatherApi": {
    "QWeather": {
      "ApiKey": "your-qweather-api-key",
      "Enabled": true
    },
    "OpenWeather": {
      "ApiKey": "your-openweather-api-key",
      "Enabled": true
    }
  }
}

4.5 深度思考捕获

兼容 DeepSeek / OpenAI o1 的 reasoning_content

// 自动捕获并输出
var jsonContent = JsonNode.Parse(ModelReaderWriter.Write(chatResult.InnerContent));
var reasoningNode = jsonContent["choices"]?[0]?["message"]?["reasoning_content"];

if (reasoningNode != null)
{
    var thought = reasoningNode.ToString();
    yield return JsonSerializer.Serialize(new
    {
        data = thought,
        type = "thinking",  // ReAct 模式用 "thinking"
    });
}

SSE 事件流:

{"type":"thinking","data":"用户询问今天深圳天气,这是实时信息查询..."}
{"type":"planning","data":{"name":"search_weather",...}}
{"type":"action","data":"执行中..."}
{"type":"observation","data":"【深圳天气预报】..."}
{"type":"chat","data":"根据最新天气预报[1]..."}
{"type":"times","data":4850}
{"type":"done","data":"done"}

5. 配置说明

5.1 完整配置文件(appsettings.json)

{
  "BEN_SK": {
    "AIConfig": {
      // 🔥 文本生成模型(必需)
      "TextInfo": {
        "ApiKey": "sk-112e82a5f6fa4be89ed223fbf955b565",
        "Model": "deepseek-chat",
        "BaseUri": "https://api.deepseek.com",
        "Provider": "openai"  // openai/deepseek/ollama/azure/grok
      },
      
      // 🔥 向量嵌入模型(知识库必需)
      "EmbeddingInfo": {
        "ApiKey": "sk-112e82a5f6fa4be89ed223fbf955b565",
        "Model": "bge-m3:latest",
        "BaseUri": "http://localhost:11434",
        "Provider": "ollama",
        "VectorSize": 1024,
        "Index": "MES-V002-test",
        
        // 向量数据库连接
        "KmsPoint": "Host=localhost;Port=5432;Username=postgres;Password=admin;Database=mes_vector",
        "VertorType": "pgsql",  // qdrant/pgsql/sqlite
        
        // 检索配置
        "SearchOption": {
          "SearchMinRelevance": 0.5,
          "SearchLimit": 3,
          "NodeDepth": 3,
          "MaxNodes": 300,
          "MaxTokens": 32000
        }
      },
      
      // ⚡ 知识图谱(可选)
      "Neo4j": {
        "Uri": "neo4j://localhost:7687",
        "User": "neo4j",
        "Password": "strongpassword"
      }
    },
    
    // 🔥 MCP 配置(可选)
    "McpConfig": {
      "Enabled": true,
      "DefaultTimeoutSeconds": 30,
      "RetryCount": 3,
      "EnableDebugLogging": true,
      "Servers": [
        {
          "Name": "mes-mcp-server",
          "Type": "http",
          "Url": "http://localhost:5278/api/mcp",
          "Description": "MES系统MCP服务器",
          "Enabled": true,
          "TimeoutSeconds": 60
        }
      ]
    }
  },
  
  // 🔥 天气 API 配置(可选,提升天气查询质量)
  "WeatherApi": {
    "QWeather": {
      "ApiKey": "your-qweather-api-key",
      "Enabled": true
    },
    "OpenWeather": {
      "ApiKey": "your-openweather-api-key",
      "Enabled": true
    }
  },
  
  // 🔥 内容抓取配置(可选)
  "ContentExtraction": {
    "Enabled": true,
    "MaxConcurrent": 3,
    "TimeoutSeconds": 10,
    "MaxContentLength": 5000
  }
}

5.2 支持的 AI 模型提供商

DeepSeek(推荐,支持深度思考)
{
  "TextInfo": {
    "ApiKey": "sk-xxx",
    "Model": "deepseek-chat",
    "BaseUri": "https://api.deepseek.com",
    "Provider": "openai"
  }
}

优势:

  • ✅ 支持 reasoning_content(深度思考)
  • ✅ 支持 Function Calling
  • ✅ 价格低廉(1元/百万token)
  • ✅ 完美适配 ReAct 模式
OpenAI GPT-4
{
  "TextInfo": {
    "ApiKey": "sk-xxx",
    "Model": "gpt-4",
    "BaseUri": "https://api.openai.com/v1",
    "Provider": "openai"
  }
}
Ollama(本地模型)
{
  "TextInfo": {
    "ApiKey": "not-needed",
    "Model": "qwen2.5:7b",
    "BaseUri": "http://localhost:11434",
    "Provider": "ollama"
  }
}

安装:

# 下载 Ollama: https://ollama.ai/download

# 启动模型
ollama pull qwen2.5:7b
ollama pull nomic-embed-text

6. API 接口

6.1 接口清单

接口 路由 方法 说明 响应格式
通用对话 /api/Chat/Chat POST ReAct Agent 模式(详细流程) SSE
MCP 对话 /api/Chat/ChatWithMcp POST 支持 MCP 工具 + 联网 SSE
知识库对话 /api/Chat/KmsChatCompleteAsync POST 基于向量库的 RAG 对话 SSE

6.2 通用对话接口(ReAct Agent)

请求:

POST /api/Chat/Chat
Content-Type: application/json

{
  "sessionId": 123,
  "parentId": null,
  "assistantMessageId": 456,
  "text": "今天深圳天气怎么样?",
  "functionCalls": [],
  "networking": true
}

响应事件类型:

事件类型 说明 示例
thinking 💭 深度思考(DeepSeek reasoning_content) "用户询问天气,需要工具..."
planning 📋 规划阶段(决定调用哪个工具) {"name":"search_weather",...}
action ⚡ 行动阶段(执行工具) "执行中..."
observation 👁️ 观察阶段(工具结果) "【深圳天气预报】..."
iteration 🔄 迭代信息 "迭代 2/10"
chat 💬 最终回答(逐 token 流式) "根据最新天气预报[1]..."
times ⏱️ 耗时统计(毫秒) 4850
done ✅ 完成标记 "done"
error ❌ 错误信息 {"message":"..."}

响应示例(SSE):

data: {"type":"thinking","data":"用户询问今天深圳天气..."}

data: {"type":"planning","data":{"name":"search_weather","arguments":"..."}}

data: {"type":"action","data":"执行中..."}

data: {"type":"observation","data":"【深圳天气预报】来源: 和风天气\n..."}

data: {"type":"chat","data":"根"}
data: {"type":"chat","data":"据"}
data: {"type":"chat","data":"最"}
data: {"type":"chat","data":"新"}

data: {"type":"times","data":4850}

data: {"type":"done","data":"done"}

6.3 MCP 对话接口

请求:

POST /api/Chat/ChatWithMcp
Content-Type: application/json

{
  "message": "查询编号为 WO-2025-001 的生产工单信息",
  "enableMcp": true,
  "enableNetwork": false,
  "searchEngine": "smart",
  "siteFilters": null,
  "systemPrompt": "你是MES系统助手,可以查询生产数据..."
}

适用场景:

  • 需要调用企业内部系统(MES/ERP/数据库)
  • 同时需要联网搜索补充信息
  • 混合使用内外部工具

6.4 前端集成示例

JavaScript (EventSource)
const eventSource = new EventSource('/api/Chat/Chat');

eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    
    switch (data.type) {
        case 'thinking':
            displayThinking(data.data);  // 显示思考过程
            break;
        
        case 'chat':
            appendChatContent(data.data);  // 追加回答内容
            break;
        
        case 'times':
            showElapsedTime(data.data);  // 显示耗时
            break;
        
        case 'done':
            eventSource.close();
            enableInput();  // 启用输入框
            break;
        
        case 'error':
            showError(data.data);
            break;
    }
};

eventSource.onerror = (error) => {
    console.error('SSE 连接错误:', error);
    eventSource.close();
};
Python (requests)
import requests
import json

def chat_stream(message):
    url = "http://localhost:5000/api/Chat/Chat"
    response = requests.post(url, json={"text": message}, stream=True)
    
    for line in response.iter_lines():
        if line and line.startswith(b'data: '):
            data = json.loads(line[6:].decode('utf-8'))
            
            if data['type'] == 'thinking':
                print(f"💭 {data['data']}")
            elif data['type'] == 'chat':
                print(data['data'], end='', flush=True)
            elif data['type'] == 'done':
                print("\n✅ 完成")
                break

# 使用
chat_stream("今天深圳天气怎么样?")

7. ReAct Agent 模式

7.1 什么是 ReAct?

ReAct (Reasoning + Acting) 是一种 AI Agent 模式,结合了推理和行动:

Planning (思考)
   ↓
Action (行动)
   ↓
Observation (观察)
   ↓
Planning (再次思考)
   ↓
... (循环)
   ↓
Final Answer (最终答案)

7.2 实现细节

ToolCallBehavior 策略
if (useReActLoop)
{
    if (enableDeepThinking)
    {
        // 🔥 手动执行工具,保留完整思考过程
        toolBehavior = ToolCallBehavior.EnableKernelFunctions;
    }
    else
    {
        // ⚡ 自动执行工具,快速响应
        toolBehavior = ToolCallBehavior.AutoInvokeKernelFunctions;
    }
}
else
{
    // 简单问题:不传 tools,性能最优
    toolBehavior = null;
}
循环控制
for (int iteration = 1; iteration <= maxIterations; iteration++)
{
    Console.WriteLine($"🔄 迭代 {iteration}/{maxIterations}");
    
    // 1. Planning(非流式调用)
    var chatResult = await chat.GetChatMessageContentAsync(history, settings, kernel);
    
    // 2. 捕获深度思考
    var reasoning = ExtractReasoningContent(chatResult);
    if (!string.IsNullOrEmpty(reasoning))
    {
        yield return JsonSerializer.Serialize(new { type = "thinking", data = reasoning });
    }
    
    // 3. 检测工具调用
    if (chatResult.Items.Any(item => item is FunctionCallContent))
    {
        // 4. Action: 手动执行工具
        var functionResult = await ExecuteFunction(functionCall);
        
        // 5. Observation: 添加结果到历史
        history.Add(new ChatMessageContent
        {
            Role = AuthorRole.Tool,
            Content = functionResult
        });
        
        continue; // 下一轮迭代
    }
    else
    {
        // 6. Final Answer: 伪流式输出
        foreach (char c in chatResult.Content)
        {
            yield return JsonSerializer.Serialize(new { type = "chat", data = c.ToString() });
            await Task.Delay(3);
        }
        break;
    }
}

7.3 对比:三种模式

特性 简单模式 AutoInvoke ReAct (手动执行)
工具调用 ❌ 不支持 ✅ 自动 ✅ 手动
深度思考 ⚡ 可能有 ❌ 不可见 ✅ 完全可见
迭代循环 ❌ 无 ❌ 无 ✅ 支持
响应速度 ⭐⭐⭐⭐⭐ < 1s ⭐⭐⭐⭐ 4-6s ⭐⭐⭐ 4-8s
流程透明 ❌ 无流程 ⚠️ 部分可见 ✅ 完全透明
适用场景 简单问答 中等复杂 复杂任务

8. 联网搜索系统

8.1 搜索流程

用户输入: "分析寒武纪2025/10/10股价走势"
  ↓
QueryClassifier.Classify() → Stock
  ↓
生成查询变体(移除日期,简化关键词):
  [1] 寒武纪 股价
  [2] 寒武纪 股票
  [3] 寒武纪 行情
  [4] 寒武纪 最新消息
  ↓
SearchAggregator.AggregateAsync()
  ├─ 智能引擎选择: 百度 + Bing
  ├─ 并行搜索(5个变体 × 2个引擎)
  └─ 合并去重: 18条 → 13条(URL归一化)
  ↓
ContentExtractor.ExtractBatchAsync()(可选)
  └─ 抓取 Top 5 完整网页内容(并发 3)
  ↓
SemanticReranker.RerankAsync()
  ├─ 计算相似度分数
  ├─ 时间新鲜度加权
  ├─ 内容质量加权
  └─ 选出 Top 8 结果
  ↓
返回搜索结果 JSON

8.2 查询优化示例

股票查询
输入: "分析寒武纪2025/10/10股价走势"

ExtractCoreEntity():
  - 移除: "分析|股价|走势|2025/10/10|并给出|策略"
  - 结果: "寒武纪"

BuildStockQueryVariants():
  [1] 寒武纪 股价
  [2] 寒武纪 股票
  [3] 寒武纪 行情
  [4] 寒武纪 最新消息

推荐站点: eastmoney.com, xueqiu.com, finance.sina.com.cn
时间范围: 最近 30 天
天气查询
输入: "深圳近7天天气预报"

ExtractCoreEntity():
  - 移除: "天气|预报|近7天|一周"
  - 结果: "深圳"

BuildWeatherQueryVariants():
  [1] 深圳天气
  [2] 深圳天气预报
  [3] 深圳7天天气预报
  [4] 深圳一周天气预报

优先: 天气 API (和风/OpenWeatherMap)
降级: 网页搜索 + 全文抓取

8.3 内容提取器

智能识别网页类型并提取关键信息

public enum PageType
{
    Weather,      // 天气网站 → 提取温度、湿度、风向
    News,         // 新闻网站 → 提取正文、发布时间
    Encyclopedia, // 百科网站 → 提取定义、描述
    Forum,        // 论坛网站 → 提取问题、回答
    Stock,        // 股票网站 → 提取价格、涨跌
    General       // 通用网站 → 智能提取 <main>/<article>
}

内容质量评分:

int score = 50;  // 基础分

// 长度适中(+20分)
if (length > 500 && length < 5000) score += 20;

// 包含数字(+10分)- 数据类查询
if (Regex.Matches(content, @"\d+").Count > 5) score += 10;

// 包含日期(+10分)- 新鲜度
if (Regex.IsMatch(content, @"\d{4}[年\-/]\d{1,2}")) score += 10;

// 特定类型(+10分)
if (pageType == PageType.Weather) score += 10;

9. MCP 工具集成

9.1 什么是 MCP?

Model Context Protocol (MCP) 是 Anthropic 推出的企业工具集成标准,允许 AI 模型调用外部工具和服务。

9.2 配置 MCP 服务器

appsettings.json:

{
  "BEN_SK": {
    "McpConfig": {
      "Enabled": true,
      "DefaultTimeoutSeconds": 30,
      "RetryCount": 3,
      "Servers": [
        {
          "Name": "mes-mcp-server",
          "Type": "http",
          "Url": "http://localhost:5278/api/mcp",
          "Description": "MES系统MCP服务器",
          "Enabled": true,
          "TimeoutSeconds": 60
        }
      ]
    }
  }
}

9.3 使用 MCP 工具

Program.cs:

var builder = WebApplication.CreateBuilder(args);

// 注册所有服务(包括 MCP)
builder.Services.AddBenSKAllService(builder.Configuration);

var app = builder.Build();

// 🔥 初始化 MCP 服务(重要!)
app.Services.InitializeMcpServices();

app.Run();

调用示例:

POST /api/Chat/ChatWithMcp
Content-Type: application/json

{
  "message": "查询编号为 WO-2025-001 的生产工单信息",
  "enableMcp": true,
  "enableNetwork": false
}

9.4 MCP 工具清单

根据 MES MCP 服务器,可用的工具包括:

工具 参数 说明
query_production_orders orderId, status, pageSize 查询生产订单
query_material_inventory materialCode, materialName 查询物料库存
query_bom_info productCode, version 查询BOM信息
generate_production_report reportType, startDate, endDate 生成生产报表

9.5 混合使用(MCP + 联网)

POST /api/Chat/ChatWithMcp
Content-Type: application/json

{
  "message": "搜索深圳今天的天气情况,并记录到系统日志",
  "enableMcp": true,      // 启用 MCP 工具
  "enableNetwork": true,  // 同时启用联网搜索
  "searchEngine": "smart"
}

预期流程:

  1. AI 调用 search_weather 获取天气信息
  2. AI 调用 MCP 工具 create_system_log 保存记录
  3. 返回完整结果

10. 知识库 RAG

10.1 向量数据库配置

使用 Qdrant
docker run -p 6333:6333 qdrant/qdrant
{
  "EmbeddingInfo": {
    "KmsPoint": "http://localhost:6333",
    "VertorType": "qdrant",
    "Index": "my-knowledge-base"
  }
}
使用 PostgreSQL (pgvector)
docker run -p 5432:5432 -e POSTGRES_PASSWORD=password pgvector/pgvector:pg16
{
  "EmbeddingInfo": {
    "KmsPoint": "Host=localhost;Port=5432;Database=vectors;Username=postgres;Password=password",
    "VertorType": "pgsql",
    "Index": "my-knowledge-base"
  }
}

10.2 导入文档

POST /api/Knowledge/ImportDocument
Content-Type: multipart/form-data

file: document.pdf
indexName: my-knowledge-base

10.3 知识库对话

POST /api/Chat/KmsChatCompleteAsync
Content-Type: application/json

{
  "sessionId": 123,
  "text": "生产车间的工单流程是什么?",
  "networking": false
}

流程:

用户问题: "生产车间的工单流程是什么?"
  ↓
向量检索 (SearchMinRelevance: 0.5, SearchLimit: 3)
  ↓
找到相关文档片段:
  [1] 工单管理流程.pdf - 第3页 (相似度: 0.87)
  [2] 生产作业指导书.docx - 第2章 (相似度: 0.76)
  [3] MES系统操作手册.pdf - 第15页 (相似度: 0.68)
  ↓
拼接文档内容注入提示词
  ↓
LLM 生成回答(基于检索到的内容)
  ↓
返回答案 + 来源标注 [1][2][3]

11. 测试指南

11.1 测试用例(6大类)

1. 股票财经 📈
POST /api/Chat/Chat
Content-Type: application/json

{"text": "分析寒武纪2025/10/10股价走势", "networking": true}

预期:

  • 分类: Stock
  • 引擎: 百度 + Bing
  • 结果: 15-25条(东方财富、雪球、新浪财经)
  • 回答: 包含具体数据(价格、涨跌幅)
2. 新闻资讯 📰
POST /api/Chat/Chat
Content-Type: application/json

{"text": "最近一周AI芯片行业新闻", "networking": true}

预期:

  • 自动识别为新闻类查询
  • 启用全文抓取
  • 语义重排优先最新内容
  • 回答包含多个来源 [1][2][3]
3. 技术问题 💻
POST /api/Chat/Chat
Content-Type: application/json

{"text": "如何使用C# Semantic Kernel实现RAG", "networking": true}

预期:

  • 分类: Technical
  • 引擎: 百度 + Bing + Google
  • 结果: 技术文档、Stack Overflow、GitHub
4. 学术研究 🎓
POST /api/Chat/Chat
Content-Type: application/json

{"text": "Transformer模型最新研究论文", "networking": true}

预期:

  • 引擎: Google + Bing
  • 结果: Google Scholar、arXiv
5. 天气查询 ⛅
POST /api/Chat/Chat
Content-Type: application/json

{"text": "今天北京天气", "networking": true}

预期:

  • 优先: 和风天气 API(1-2秒)
  • 降级: 网页搜索 + 完整内容抓取
  • 结果: 包含温度、湿度、风向、降水
6. 通用查询 🔍
POST /api/Chat/Chat
Content-Type: application/json

{"text": "什么是量子计算机", "networking": true}

预期:

  • 分类: General
  • 引擎: 百度 + Bing
  • 结果: 百科、技术博客

11.2 性能基准

场景 目标时间 实际时间 状态
简单问题("你好") < 1秒 0.5-0.8秒
天气查询(API) < 10秒 4-8秒
天气查询(网页) < 35秒 25-30秒
新闻查询(全文) < 35秒 28-32秒
股票查询 < 15秒 8-12秒
通用搜索 < 15秒 6-10秒

11.3 HTTP 测试文件

Ben.Examples/ChatService_AgentRAG测试示例.http

包含完整的测试用例和预期输出示例,涵盖:

  • 天气查询(完整 ReAct 流程)
  • 简单计算(不需要工具)
  • 复杂查询(多次迭代)
  • 股票分析(深度思考)
  • 禁用联网(对比测试)

12. 开发指南

12.1 依赖注入注册

Program.cs:

using Ben.SemanticKernel.Services;
using Ben.SemanticKernel.Services.ChatService;
using Ben.SemanticKernel.Services.Mcp;

var builder = WebApplication.CreateBuilder(args);

// 🔥 一行注册所有核心服务
builder.Services.AddBenSKAllService(builder.Configuration);

// 或分别注册
// builder.Services.AddChatService(builder.Configuration);    // 对话服务
// builder.Services.AddGraphRagNetService(builder.Configuration);  // 知识图谱
// builder.Services.AddMcpServices(builder.Configuration);    // MCP 服务

builder.Services.AddControllers();
builder.Services.AddHttpContextAccessor();

var app = builder.Build();

// 初始化 MCP 服务(可选但推荐)
app.Services.InitializeMcpServices();

app.MapControllers();
app.Run();

12.2 创建自定义 Kernel 工具

1. 创建插件类:

public class CustomToolPlugin
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly ILogger<CustomToolPlugin> _logger;

    public CustomToolPlugin(
        IHttpClientFactory httpClientFactory,
        ILogger<CustomToolPlugin> logger)
    {
        _httpClientFactory = httpClientFactory;
        _logger = logger;
    }

    [KernelFunction("custom_tool")]
    [Description(@"自定义工具的描述,告诉 LLM 何时使用。
用途:具体用途
示例:custom_tool(param='value')")]
    public async Task<string> CustomToolAsync(
        [Description("参数描述")] string param1,
        [Description("可选参数")] string param2 = "default",
        CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogDebug($"🔧 LLM 调用自定义工具 - 参数: {param1}");

            // 实现工具逻辑
            var result = await DoSomethingAsync(param1, param2, cancellationToken);

            _logger.LogDebug($"✅ 工具执行成功");
            return result;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"工具执行失败: {param1}");
            return $"工具执行失败: {ex.Message}";
        }
    }
}

2. 注册到 DI 容器:

// ChatServiceExtension.cs
services.AddScoped<CustomToolPlugin>();

3. 注册到 Kernel:

// KernelFactory.CustomTools.cs
public static Kernel CreateKernelWithCustomTools(
    AIOptions aiOptions,
    IServiceProvider serviceProvider)
{
    var kernel = CreateKernel(aiOptions);
    var customToolPlugin = serviceProvider.GetRequiredService<CustomToolPlugin>();
    
    kernel.Plugins.AddFromObject(customToolPlugin, "CustomTools");
    
    return kernel;
}

12.3 添加新的搜索引擎

扩展 BingScraper.cs:

private string BuildSearchUrl(string query, string engine, ...)
{
    return engine.ToLower() switch
    {
        "baidu" => BuildBaiduUrl(query, ...),
        "bing" => BuildBingUrl(query, ...),
        "google" => BuildGoogleUrl(query, ...),
        "duckduckgo" => BuildDuckDuckGoUrl(query, ...), // 🆕
        _ => BuildBaiduUrl(query, ...)
    };
}

private string BuildDuckDuckGoUrl(string query, ...)
{
    var encodedQuery = Uri.EscapeDataString(query);
    return $"https://duckduckgo.com/?q={encodedQuery}&t=h_&ia=web";
}

private List<SearchResultDto> ParseDuckDuckGoResults(string html)
{
    // 使用 XPath/CSS 选择器解析
    var results = new List<SearchResultDto>();
    // ...
    return results;
}

12.4 自定义查询分类

编辑 ChatService.cs 的 IsLikelyNeedingTools:

// 添加业务规则
if (Regex.IsMatch(trimmedInput, @"(工单|订单|生产|库存|MES)", RegexOptions.IgnoreCase))
    return true;  // MES 系统查询必须使用工具

if (trimmedInput.Contains("公司制度") || trimmedInput.Contains("内部文档"))
    return false; // 内部文档不需要联网

13. 部署指南

13.1 Docker 容器化

Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["Ben.SemanticKernel/Ben.SemanticKernel.csproj", "Ben.SemanticKernel/"]
COPY ["Ben.Examples/Ben.Examples.csproj", "Ben.Examples/"]
RUN dotnet restore "Ben.Examples/Ben.Examples.csproj"

COPY . .
WORKDIR "/src/Ben.Examples"
RUN dotnet build "Ben.Examples.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Ben.Examples.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

# 安装 Playwright 浏览器(可选)
RUN apt-get update && apt-get install -y wget \
    && playwright install chromium \
    && apt-get clean

ENTRYPOINT ["dotnet", "Ben.Examples.dll"]

docker-compose.yml:

version: '3.8'

services:
  app:
    build: .
    ports:
      - "5000:80"
    environment:
      - BEN_SK__AIConfig__TextInfo__ApiKey=sk-xxx
      - BEN_SK__AIConfig__TextInfo__Model=deepseek-chat
      - BEN_SK__AIConfig__TextInfo__BaseUri=https://api.deepseek.com
    depends_on:
      - qdrant

  qdrant:
    image: qdrant/qdrant
    ports:
      - "6333:6333"
    volumes:
      - qdrant_data:/qdrant/storage

volumes:
  qdrant_data:

13.2 生产环境配置

环境变量:

# AI 配置
BEN_SK__AIConfig__TextInfo__ApiKey=sk-xxx
BEN_SK__AIConfig__TextInfo__Model=deepseek-chat
BEN_SK__AIConfig__TextInfo__BaseUri=https://api.deepseek.com

# 天气 API
WeatherApi__QWeather__ApiKey=your-key

# 日志级别
Logging__LogLevel__Default=Information
Logging__LogLevel__Ben.SemanticKernel=Warning

13.3 横向扩展

无状态设计:

  • ✅ ChatService 无状态(历史由调用方管理)
  • ✅ Kernel 缓存共享(ConcurrentDictionary 线程安全)
  • ✅ PlaywrightHelper Singleton(跨请求共享)

负载均衡:

  • 使用 Nginx/Traefik 负载均衡
  • Session Sticky 不需要(无状态)
  • 数据库连接池(向量库)需要配置

14. 常见问题

Q1: 所有查询返回 0 结果?

症状:

⏳ 开始并行搜索...
   查询 [1] 返回 0 条结果 ⚠️
   查询 [2] 返回 0 条结果 ⚠️

原因 & 解决:

  1. Playwright 未安装

    cd Ben.SemanticKernel
    .\install-playwright.ps1
    
  2. 验证安装

    playwright --version
    

Q2: 天气 API 调用失败?

症状:

⚠️ 天气 API 调用失败: 401 Unauthorized

解决:

  1. 检查配置

    {
      "WeatherApi": {
        "QWeather": {
          "ApiKey": "your-key"  // 注意大小写
        }
      }
    }
    
  2. 验证 API Key

    curl "https://devapi.qweather.com/v7/weather/now?location=101280601&key=YOUR_KEY"
    
  3. 自动降级机制

    • 即使 API 失败,也会自动降级到网页搜索

Q3: DeepSeek 不显示深度思考?

症状:

  • 启用 enableDeepThinking: true
  • 控制台无 reasoning_content 输出

原因 & 解决:

  1. 简单问题被优化

    • 系统判断为简单问题(如"你好"),不传递 tools
    • 这是正常的性能优化
  2. 检查模型配置

    • 确保使用 DeepSeek 模型
    • 确保 Provider 设置正确

Q4: Google 搜索失败(中国环境)?

症状:

✗ google 失败: Timeout

解决:

  1. 使用 Smart 策略(推荐)

    engine: "smart"  // 中文查询自动避开 Google
    
  2. 强制使用百度

    engine: "baidu"
    

Q5: MCP 工具调用失败?

检查清单:

  • MCP 服务器已启动 (http://localhost:5278/api/mcp)
  • appsettings.json 配置正确
  • 已调用 app.Services.InitializeMcpServices()
  • 查看日志获取详细错误信息

15. 性能优化

15.1 Kernel 缓存

当前实现:

private static readonly ConcurrentDictionary<string, Lazy<Kernel>> Kernels = new();

// 缓存键:Model + Provider + BaseUri + ApiKey(哈希)
var key = $"{textConfig.Model}_{textConfig.BaseUri}_{textConfig.ApiKey}_{textConfig.Provider}";

return Kernels.GetOrAdd(key, _ => new Lazy<Kernel>(() => CreateNewKernel(...))).Value;

优势:

  • ✅ 避免重复创建 Kernel(节省 200-500ms)
  • ✅ 线程安全(ConcurrentDictionary)
  • ✅ 懒加载(Lazy<T>)

15.2 并行搜索

// 查询变体并行(5个查询同时搜索)
var variantTasks = variants.Select(v => SearchSingleVariantAsync(v, engine));
await Task.WhenAll(variantTasks);

// 引擎并行(多个搜索引擎同时抓取)
var engineTasks = engines.Select(e => SearchEngineAsync(query, e));
await Task.WhenAll(engineTasks);

// 全文抓取并发(最多 3 个网页同时抓取)
var semaphore = new SemaphoreSlim(3);
var contentTasks = urls.Select(async url => {
    await semaphore.WaitAsync();
    try { return await ExtractAsync(url); }
    finally { semaphore.Release(); }
});

15.3 智能降级

场景 降级策略
引擎失败 使用其他引擎的结果
语义重排失败 使用原始排序
搜索完全失败 基于 AI 知识回答
天气 API 失败 降级网页搜索(全文抓取)

15.4 资源管理

服务 生命周期 原因
PlaywrightHelper Singleton 避免 ReAct 多轮迭代中释放
BingScraper Scoped 每次请求新实例
ChatService Scoped 每次请求新实例
HttpClient 池化管理 使用 IHttpClientFactory

🎉 总结

Ben.SemanticKernel 提供了一个生产级的 AI Agent 框架

  • 10分钟快速开始:简单配置即可运行
  • ReAct Agent 模式:完整的 Planning → Action → Observation 循环
  • 深度思考可见:捕获 DeepSeek/OpenAI o1 的 reasoning_content
  • 智能分支选择:简单问题 < 1秒,复杂问题完整流程
  • 企业级搜索:多引擎聚合 + 语义重排 + 全文抓取
  • 专业 API 集成:天气、股票、新闻等垂直领域
  • MCP 工具支持:企业系统无缝集成
  • 知识库 RAG:向量检索 + 知识图谱
  • 开发友好:详细日志、丰富示例、完整文档

现在,开始构建你的智能应用吧! 🚀


📚 相关资源


文档版本: v1.0
更新时间: 2025-10-24
维护者: Ben.SemanticKernel Team
许可证: MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.0.0 87 10/31/2025
5.3.4 91 10/31/2025
5.3.3 90 10/31/2025
5.3.2 88 10/31/2025
5.3.1 118 10/28/2025
5.3.0 123 10/28/2025
5.2.29 100 10/24/2025
5.2.28 121 10/24/2025
5.2.27 119 10/22/2025
5.2.26 120 10/22/2025
5.2.25 123 10/21/2025
5.2.24 118 10/21/2025
5.2.23 121 10/21/2025
5.2.22 115 10/21/2025
5.2.21 126 10/21/2025
5.2.20 121 10/20/2025
5.2.19 114 10/19/2025
5.2.18 128 10/14/2025
5.2.17 125 10/14/2025
5.2.16 128 10/13/2025
5.2.15 121 10/13/2025
5.2.13 125 10/13/2025
5.2.12 123 10/13/2025
5.2.11 123 10/13/2025
5.2.10 64 10/11/2025
5.2.9 124 10/7/2025
5.2.8 122 10/7/2025
5.2.7 125 10/7/2025
5.2.6 309 6/10/2025
5.2.5 265 6/10/2025
5.2.4 264 6/10/2025
5.2.3 219 6/9/2025
5.2.2 212 6/9/2025
5.2.1 213 6/9/2025
5.2.0 222 6/9/2025
5.1.9 189 6/9/2025
5.1.8 77 6/7/2025
5.1.7 64 6/7/2025
5.1.6 113 6/6/2025
5.1.5 139 6/5/2025
5.1.4 140 6/5/2025
5.1.3 133 6/4/2025
5.1.2 129 6/4/2025
5.1.1 140 6/2/2025
5.0.1 167 5/28/2025
4.10.3 98 5/24/2025
4.10.2 103 5/24/2025
4.10.1 119 5/24/2025
4.9.15 191 5/22/2025
4.9.14 176 5/21/2025
4.9.13 182 5/21/2025
4.9.12 189 5/19/2025
4.9.11 255 5/15/2025
4.9.10 258 5/15/2025
4.9.9 256 5/15/2025
4.9.8 259 5/15/2025
4.9.7 275 5/15/2025
4.9.6 276 5/15/2025
4.9.5 251 5/12/2025
4.9.4 220 5/12/2025
4.9.3 152 5/9/2025
4.9.2 199 5/9/2025
4.9.1 177 5/9/2025
4.8.5 459 4/25/2025
4.8.4 262 4/25/2025 4.8.4 is deprecated because it is no longer maintained.
4.8.3 276 4/24/2025 4.8.3 is deprecated because it is no longer maintained and has critical bugs.
4.8.2 288 4/24/2025 4.8.2 is deprecated because it is no longer maintained and has critical bugs.
4.8.1 213 4/24/2025
4.7.10 199 4/23/2025
4.7.9 221 4/15/2025
4.7.8 214 4/14/2025
4.7.7 226 4/14/2025
4.7.6 238 4/14/2025
4.7.5 214 4/14/2025
4.7.4 223 4/14/2025
4.7.3 226 4/14/2025
4.7.2 215 4/14/2025
4.7.1 221 4/14/2025
4.6.1 193 4/9/2025
4.6.0 200 4/9/2025
4.5.9 188 4/8/2025
4.5.8 189 4/8/2025
4.5.7 195 4/7/2025
4.5.6 234 4/7/2025
4.5.5 205 4/7/2025
4.5.4 191 4/7/2025
4.5.3 223 4/7/2025
4.5.2 182 4/7/2025
4.5.1 197 4/7/2025
4.5.0 200 4/7/2025
4.3.0 208 4/2/2025
4.2.1 181 4/2/2025
4.2.0 196 4/2/2025
4.1.0 191 4/1/2025
4.0.0 220 4/1/2025
3.2.1 523 3/25/2025
3.2.0 516 3/25/2025
3.1.0 114 3/22/2025
3.0.0 149 3/21/2025
2.0.0 195 3/20/2025
1.5.0 161 3/20/2025
1.4.0 180 3/20/2025
1.3.0 187 3/20/2025
1.2.0 115 3/15/2025
1.1.0 115 3/15/2025
1.0.0 108 3/15/2025