现代 AI 应用在将自然语言提示转换为执行外部服务时获得了真正的普及。本文描述了对关键组件(语义内核、Azure OpenAI 和 MCP 客户端 - 服务器)的基本理解,还描述了将语义内核连接到 Azure 托管的 OpenAI 资源的实现,以便可以直接查询 LLM。
此外,还将学习如何创建MCP 客户端、运行 MCP 服务器并公开 MCP 工具。发现的工具可以在语义内核中注册为内核函数,从而通过 MCP 服务器提供的服务增强 LLM 执行外部工具的能力。
语义内核与 Azure Open AI 集成
语义内核
Microsoft SDK,可实现 LLM 与外部工具插件、内存和规划功能的集成,是 LLM 和工具插件之间的一层,可使提示调用注册的外部工具或 API。要深入了解语义内核,请遵循语义内核简介。
Azure OpenAI 资源
Microsoft Azure 资源,可在 Azure 上运行 Open AI 模型(如 GPT-4),提供对 LLM 功能的访问,并将 LLM 功能提供给语义内核。更多详情请遵循Azure OpenAI。
以下代码片段负责创建和配置语义内核实例。该类使用 Azure OpenAI 作为聊天完成服务的后端,并将其添加到内核生成器中。
C#
namespace AIWebAPIs.Common
{
using AIWebAPIs.PlugIns;
using Azure.Identity;
using Microsoft.SemanticKernel;
public class KernelBuilder
{
private const string AZURE_OPENAI_ENDPOINT = "https://tdmintdeveusaoai.openai.azure.com/";
private const string MODEL_DEPLOYMENT = "gpt-4o";
private Kernel? _kernel;
public Kernel BuildKernel()
{
var options = new DefaultAzureCredentialOptions
{
TenantId = "b1a4f7cb-a159-44a6-ac48-6674e85c4ddc"
};
var azureCredential = new DefaultAzureCredential(options);
// Step 1: Create a Kernel Builder
var kernelBuilder = Kernel.CreateBuilder();
// Step 2: Add Azure OpenAI Chat Completion Service
kernelBuilder.AddAzureOpenAIChatCompletion(
deploymentName: MODEL_DEPLOYMENT,
endpoint: AZURE_OPENAI_ENDPOINT,
credentials: azureCredential
);
// Step 3: Build and return the Kernel
_kernel= kernelBuilder.Build();
return _kernel;
}
}
}
MCP 客户端 - 服务器交互以发现 MCP 工具
MCP 客户端
使用 MCP 协议连接到 MCP 服务器的客户端,获取 MCP 服务器工具及其执行结果,实现从 MCP 服务器实例发现和执行工具。
以下代码显示如何创建 MCP 客户端并连接到 MCP 服务器,还显示如何从 MCP 服务器检索所有 MCP 工具。这称为动态工具发现,可以注册到语义内核作为内核函数。如果不熟悉 MCP 服务器设置和 MCP 工具,请参考题为“使用 C# 在 MCP 服务器中构建 AI 代理并在 VS Code 中运行”的文章以获取详细实现。
C#
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Transport;
namespace AIWebAPIs.MCPClient
{
public class MCPClient
{
private IMcpClient? _client;
private List<McpClientTool>? _tools;
// Public async method for the client, initializes if null
public async Task<IMcpClient> GetClientAsync()
{
if (_client == null)
{
_client = await GetMCPClient();
}
return _client;
}
// Getter property for tools, initializes if null
public List<McpClientTool> Tools
{
get { return _tools; }
set { _tools = value; }
}
// Method to create and return an MCPClient instance
public async Task<IMcpClient> GetMCPClient()
{
// Create a transport channel to communicate with an MCP Server process using standard input/output (stdio).
var clientTransport = new StdioClientTransport(new StdioClientTransportOptions
{
Name = "Everything",
Command = "dotnet",
Arguments = ["run",
"--project",
"C:/Users/anupra/source/repos/AIWebAPIs/AIWebAPIs/AIWebAPIs.csproj"],
});
var client = await McpClientFactory.CreateAsync(clientTransport);
Tools = (await client.ListToolsAsync()).ToList();
_client = client;
return client;
}
}
}
发现并将 MCP 工具注册为语义内核函数以供调用
C#
using Microsoft.AspNetCore.Mvc;
using AIWebAPIs.Common;
using Microsoft.SemanticKernel;
namespace AIWebAPIs.Controllers
{
[ApiController]
[Route("[controller]")]
public class ChatController : ControllerBase
{
[HttpPost("GenerateResponse")]
public async Task<IActionResult> GenerateResponse([FromBody] ChatRequest request)
{
// Check if Messages is null or empty
if (request.Messages == null ||!request.Messages.Any())
{
return BadRequest("Messages cannot be null or empty.");
}
// Aggregate messages into a single string with each message on a new line
var prompt = string.Join(Environment.NewLine, request.Messages.Select(m => m.Content));
// create mcp client
var mcpClientObj = new MCPClient();
var client = await mcpClientObj.GetClientAsync();
// create openAIclient obj to access Semantic Kernel obj
var openaiClient = new Common.OpenAI();
#pragma warning disable SKEXP0001
openaiClient.Kernel.Plugins.AddFromFunctions("mcptools", mcpClientObj.Tools.Select(tool => tool.AsKernelFunction()));
#pragma warning restore SKEXP0001
// Create a function using the prompt
var chatFunction = openaiClient.Kernel.CreateFunctionFromPrompt(prompt);
// Invoke the function
var result = await openaiClient.Kernel.InvokeAsync(chatFunction);
return Ok(new { Response = result });
}
}
}
序列图:将 MCP 工具注册为语义内核函数并通过语义内核调用
以下是所有组件如何通信的完整流程图。下图显示了通过语义内核和 LLM 发现和调用 MCP 工具的端到端流程。
组件交互流程总结
- MCP 客户端连接到 MCP 服务器进行工具发现:向 MCP 服务器发送请求以从 MCP 服务器检索可用工具。
- 工具注册为内核函数:MCP 客户端使用返回的工具列表将其注册为语义内核的内核函数。
- 语义内核处理提示:语义内核接收提示并将其与 MCP 工具一起发送到托管 LLM(如 GPT 4)的 Azure OpenAI 进行聊天完成。
- LLM 生成响应:LLM 根据 MCP 工具的描述评估提示,以选择要调用的相关 MCP 工具。如果需要工具执行,语义内核将调用所选工具,并将最终结果返回给 MCP 客户端。
结论
使用 Azure OpenAI 将 MCP 与语义内核集成,展示了一种强大的架构,其中 LLM 可以通过调用 MCP 工具提供特定领域的答案。通过 MCP 客户端 - 服务器生态系统,MCP 服务器中托管的工具可供客户端使用。这些工具可以在语义内核中注册为内核函数。此设置使 LLM 能够通过将提示映射到相关工具来评估提示与内核函数,从而使 LLM 更有能力进行文本生成之外的操作。这种方法非常适合构建AI 代理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。