首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >在 .NET 应用中集成大语言模型:使用 Microsoft.Extensions.AI 的实战指南

在 .NET 应用中集成大语言模型:使用 Microsoft.Extensions.AI 的实战指南

作者头像
郑子铭
发布2025-05-08 16:16:48
发布2025-05-08 16:16:48
5790
举报
Image
Image

我一直在尝试将大语言模型(LLMs)集成到 .NET 应用中的不同方法,并希望分享我在使用 Microsoft.Extensions.AI 时学到的东西。

大语言模型(LLMs)已经彻底改变了我们构建 AI 驱动应用的方式。虽然许多开发者熟悉基于云的解决方案(如 OpenAI 的 GPT 模型),但得益于像 Ollama 这样的项目,本地运行 LLMs 变得越来越容易。

在本文中,我们将探讨如何使用 Microsoft.Extensions.AI 在 .NET 应用中使用 LLMs。这是一个强大的抽象层,扩展了 Semantic Kernel SDK 的功能。


理解基础组件

大语言模型(LLMs)

LLMs 是基于大量数据训练的深度学习模型,能够理解和生成类似人类的文本。这些模型可以执行各种任务,如文本补全、摘要、分类和对话。虽然传统上通过云 API 访问,但最近的进展使得在标准硬件上本地运行它们成为可能。

Ollama

Ollama 是一个开源项目,简化了在本地运行 LLMs 的过程。它提供了一个 Docker 容器,可以运行各种开源模型(如 Llama),使得在不依赖云服务的情况下进行 AI 实验变得容易。Ollama 处理模型管理和优化,并提供了一个简单的 API 用于交互。

Microsoft.Extensions.AI

Microsoft.Extensions.AI 是一个为 .NET 应用提供统一接口的库,用于与 LLMs 交互。它基于 Microsoft 的 Semantic Kernel 构建,抽象了不同 LLM 实现的复杂性,使开发者可以在不更改应用代码的情况下切换提供者(如 Ollama、Azure 或 OpenAI)。


入门指南

在深入示例之前,以下是本地运行 LLMs 所需的内容:

1. Docker 在您的机器上运行。

2. Ollama 容器 运行 llama3 模型:

代码语言:javascript
复制
# 拉取 Ollama 容器
docker run --gpus all -d -v ollama_data:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

# 拉取 llama3 模型
docker exec -it ollama ollama pull llama3

3. 安装一些 NuGet 包(我使用 .NET 9 控制台应用程序构建):

代码语言:javascript
复制
Install-Package Microsoft.Extensions.AI # 基础 AI 库
Install-Package Microsoft.Extensions.AI.Ollama # Ollama 提供者实现
Install-Package Microsoft.Extensions.Hosting # 用于构建 DI 容器

简单聊天补全

让我们从一个基本的聊天补全示例开始。以下是最小设置:

代码语言:javascript
复制
var builder = Host.CreateApplicationBuilder();

builder.Services.AddChatClient(new OllamaChatClient(new Uri("http://localhost:11434"), "llama3"));

var app = builder.Build();

var chatClient = app.Services.GetRequiredService<IChatClient>();

var chatCompletion = await chatClient.CompleteAsync("What is .NET? Reply in 50 words max.");

Console.WriteLine(chatCompletion.Message.Text);

这里没有什么花哨的东西——我们只是设置了依赖注入并提出了一个简单的问题。如果您习惯于使用原始 API 调用,您会注意到这种方式是多么简洁。

AddChatClient 扩展方法将聊天客户端注册到 DI 容器中。这允许您将 IChatClient 注入到您的服务中,并使用简单的 API 与 LLMs 交互。该实现使用 OllamaChatClient 与本地运行的 Ollama 容器通信。


实现带历史的聊天

基于前面的示例,我们可以创建一个交互式聊天,维护对话历史记录。这对于上下文感知的交互和实时聊天应用程序非常有用。我们只需要一个 List<ChatMessage> 来存储聊天历史:

代码语言:javascript
复制
var chatHistory = new List<ChatMessage>();

while (true)
{
   Console.WriteLine("Enter your prompt:");
   var userPrompt = Console.ReadLine();
   chatHistory.Add(new ChatMessage(ChatRole.User, userPrompt));

   Console.WriteLine("Response from AI:");
   var chatResponse = "";
   awaitforeach (var item in chatClient.CompleteStreamingAsync(chatHistory))
   {
       // 我们正在流式传输响应,因此每条消息到达时都会显示
       Console.Write(item.Text);
       chatResponse += item.Text;
   }
   chatHistory.Add(new ChatMessage(ChatRole.Assistant, chatResponse));
   Console.WriteLine();
}

这里的亮点是流式响应——您会像在 ChatGPT 中那样逐渐看到文本的出现。我们还维护了聊天历史记录,这使得模型能够理解之前消息的上下文,使对话感觉更自然。


实际应用:文章摘要

让我们尝试一些更有用的东西——自动摘要文章。我一直在使用这个功能来处理博客文章:

代码语言:javascript
复制
var posts = Directory.GetFiles("posts").Take().ToArray();
foreach (var post in posts)
{
   string prompt = $$"""
         You will receive an input text and the desired output format.
         You need to analyze the text and produce the desired output format.
         You not allow to change code, text, or other references.

         # Desired response

         Only provide a RFC8259 compliant JSON response following this format without deviation.

         {
            "title": "Title pulled from the front matter section",
            "summary": "Summarize the article in no more than  words"
         }

         # Article content:

         {{File.ReadAllText(post)}}
         """;

   var chatCompletion = await chatClient.CompleteAsync(prompt);
   Console.WriteLine(chatCompletion.Message.Text);
   Console.WriteLine(Environment.NewLine);
}

专业提示:明确指定输出格式(如要求 RFC8259 兼容的 JSON)有助于获得一致的结果。我在处理偶尔格式错误的响应后学到了这一点!


更进一步:智能分类

这里变得非常有趣——我们可以直接从 LLM 获取强类型响应:

代码语言:javascript
复制
class PostCategory
{
    publicstring Title { get; set; } = string.Empty;
    publicstring[] Tags { get; set; } = [];
}

var posts = Directory.GetFiles("posts").Take().ToArray();
foreach (var post in posts)
{
    string prompt = $$"""
          You will receive an input text and the desired output format.
          You need to analyze the text and produce the desired output format.
          You not allow to change code, text, or other references.

          # Desired response

          Only provide a RFC8259 compliant JSON response following this format without deviation.

          {
             "title": "Title pulled from the front matter section",
             "tags": "Array of tags based on analyzing the article content. Tags should be lowercase."
          }

          # Article content:

          {{File.ReadAllText(post)}}
          """;

    var chatCompletion = await chatClient.CompleteAsync<PostCategory>(prompt);

    Console.WriteLine(
      $"{chatCompletion.Result.Title}. Tags: {string.Join(",",chatCompletion.Result.Tags)}");
}

强类型方法提供了编译时安全性和更好的 IDE 支持,使得维护和重构与 LLM 响应交互的代码更加容易。


不同 LLM 提供者的灵活性

Microsoft.Extensions.AI 的一个关键优势是支持不同的提供者。虽然我们的示例使用 Ollama,但您可以轻松切换到其他提供者:

代码语言:javascript
复制
// 使用 Azure OpenAI
builder.Services.AddChatClient(new AzureOpenAIClient(
        new Uri("AZURE_OPENAI_ENDPOINT"),
        new DefaultAzureCredential())
            .AsChatClient());

// 使用 OpenAI
builder.Services.AddChatClient(new OpenAIClient("OPENAI_API_KEY").AsChatClient());

这种灵活性使您可以:

  • • 使用本地模型开始开发
  • • 迁移到云提供者进行生产
  • • 在不更改应用代码的情况下切换提供者
  • • 为不同用例(分类、图像识别等)混合使用不同的提供者
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 理解基础组件
    • 大语言模型(LLMs)
    • Ollama
    • Microsoft.Extensions.AI
  • 入门指南
  • 简单聊天补全
  • 实现带历史的聊天
  • 实际应用:文章摘要
  • 更进一步:智能分类
  • 不同 LLM 提供者的灵活性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档