返回

IChatClient 缺少 CompleteStreamingAsync?问题解决

Ai

IChatClient 缺少 CompleteStreamingAsync 定义?问题排查与解决

在使用 .NET 进行本地 AI 开发时,有时会遇到 IChatClient 接口缺少 CompleteStreamingAsync 方法定义的错误。 别慌!这篇博客就来帮你搞定它。

问题

跟着微软官方教程尝试构建一个基于本地 Ollama 的聊天应用时,编译代码报错:'IChatClient' does not contain a definition for 'CompleteStreamingAsync' 。 即使已经安装了教程中提及的 NuGet 包,问题依旧。

原因分析

出现这个问题的根本原因,往往是 NuGet 包版本不匹配,或者是包本身存在一些问题没有暴露接口。更具体的:

  1. 版本冲突: 教程中使用的 Microsoft.Extensions.AI 相关包可能和你实际安装的版本存在差异。 预览版 (preview) 的包尤其需要注意版本号是否完全一致。
  2. API 变更: 即使版本号相同, Microsoft.Extensions.AI 的预览版也可能在不同小版本间发生了 API 变更, 导致 CompleteStreamingAsync 方法被移除、重命名或移动到其他接口。
  3. Ollama 包的问题: 在较老版本的Microsoft.Extensions.AI.Ollama中, 相关实现可能确实有缺失。

解决方案

针对以上原因,可以尝试以下解决方案,通常能解决你的问题。

1. 检查并统一 NuGet 包版本

最直接的办法是严格按照教程中指定的版本安装 NuGet 包。

  • 操作步骤:

    1. 打开项目的 .csproj 文件。

    2. 找到 <PackageReference> 部分,仔细核对 Microsoft.Extensions.AIMicrosoft.Extensions.AI.AbstractionsMicrosoft.Extensions.AI.Ollama 这三个包的版本号。

    3. 如果与教程不一致,修改 Version 属性的值,使其与教程完全匹配。例如:

      <PackageReference Include="Microsoft.Extensions.AI" Version="8.0.0-preview.4.24180.3" />
      <PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="8.0.0-preview.4.24180.3" />
      <PackageReference Include="Microsoft.Extensions.AI.Ollama" Version="8.0.0-preview.4.24180.3" />
      

      需要特别注意, 一些教程为了稳定可能会使用 8.0.0 系列, 但仍旧提示 CompleteStreamingAsync 不存在.

    4. 保存 .csproj 文件。

    5. 在 Visual Studio 中,右键单击项目,选择“还原 NuGet 包”。

    6. 重新编译。

  • 尝试将版本直接升级为 8.0.0系列中, 不需要带 preview的版本. 例如:

<PackageReference Include="Microsoft.Extensions.AI" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.AI.Ollama" Version="8.0.0" />

2. 使用 CompleteStreamAsync (新版本方法名)

如果使用了更新版本的 Microsoft.Extensions.AI.Ollama 包(例如 8.0.0 或更高),CompleteStreamingAsync 方法很可能已经被重命名为 CompleteStreamAsync

  • 原理:
    API 设计者可能出于命名一致性或其他考虑,对方法名进行了调整。

  • 代码示例:

    using Microsoft.Extensions.AI;
    using Microsoft.Extensions.AI.Ollama;
    
    namespace Chat
    {
        internal class Program
        {
            static async Task Main(string[] args)
            {
                IChatClient chatClient =
                    new OllamaChatClient(new Uri("http://localhost:11434/"), "phi"); //模型名字也顺便修改了
    
                // Start the conversation with context for the AI model
                List<ChatMessage> chatHistory = new();
    
                while (true)
                {
                    // Get user prompt and add to chat history
                    Console.WriteLine("Your prompt:");
                    var userPrompt = Console.ReadLine();
                    chatHistory.Add(new ChatMessage(ChatRole.User, userPrompt));
    
                    // Stream the AI response and add to chat history
                    Console.WriteLine("AI Response:");
                    var response = "";
                    await foreach (var item in
                        chatClient.CompleteStreamAsync(chatHistory)) // 注意这里的方法名
                    {
                        Console.Write(item.Text);
                        response += item.Text;
                    }
                    chatHistory.Add(new ChatMessage(ChatRole.Assistant, response));
                    Console.WriteLine();
                }
            }
        }
    }
    

    如果遇到'OllamaChatClient' does not contain a constructor that takes 2 arguments, 则按如下方法使用:

    static async Task Main(string[] args)
           {
    
            var builder = new OllamaClientBuilder()
             .WithBaseAddress(new Uri("http://localhost:11434/"))
            .WithModel("phi");
    
            IChatClient chatClient = builder.BuildChatClient();
               //...后续不变...
    }
    
  • 也可以修改模型, 改用其他模型测试:

IChatClient chatClient =
    new OllamaChatClient(new Uri("http://localhost:11434/"), "llama2"); //可以修改成其他的试试

3. 降级 Microsoft.Extensions.AI.Ollama

如果确定教程使用的就是 CompleteStreamingAsync,并且较新版本的包无法工作, 一个临时的解决方案是尝试降低 Microsoft.Extensions.AI.Ollama 的版本。
但是不建议使用预览版.

  • 操作步骤:
    Microsoft.Extensions.AI.Ollama 包降低版本后, 清理并重新生成项目。

4. 查看官方文档和 GitHub Issues

如果以上方法都不行,可能是包本身的问题,或者文档过时。 建议:

  • 查看官方文档: 访问 Microsoft.Extensions.AIMicrosoft.Extensions.AI.Ollama 的最新官方文档,确认 CompleteStreamingAsyncCompleteStreamAsync 的用法。
  • 搜索 GitHub Issues:Microsoft.Extensions.AI 的 GitHub 仓库中搜索相关 Issues,看看是否有其他人遇到类似问题,以及是否有官方的回复或解决方案。

5. (进阶) 自定义扩展方法

如果对 .NET 扩展方法比较熟悉,可以自己实现一个 CompleteStreamingAsync 扩展方法,作为临时解决方案。 但这种方法比较 hacky,不推荐长期使用。

  • 原理:
    .NET 扩展方法允许你在不修改现有类的情况下,为其添加新的方法。

  • 代码示例:(仅作思路参考,不保证在所有版本都能用)

    // 谨慎使用, 仅供参考
    public static class ChatClientExtensions
    {
        public static IAsyncEnumerable<ChatMessage> CompleteStreamingAsync(this IChatClient chatClient, IList<ChatMessage> messages)
        {
             //需要自行适配 CompleteStreamAsync 方法.
             return chatClient.CompleteStreamAsync(messages);
        }
    }
    

    使用扩展方法的时候, 可以保持和教程一样的调用方法.

总结

遇到 IChatClient 缺少 CompleteStreamingAsync 定义的问题,首先别慌。 大概率是版本问题或者方法名在新版本做了调整。 通过仔细检查版本、查阅文档、或者使用新方法名(CompleteStreamAsync), 大部分情况下能快速解决。实在不行, 再考虑其他方案. 希望这几种方法能帮到你!