解锁GraphRag.Net的无限可能:手把手教你集成国产模型和本地模型
在上次的文章中,我们已经详细介绍了GraphRag的基本功能和使用方式。如果你还不熟悉,建议先阅读前面的文章
通过前两篇文章,相信你已经了解到GraphRag.Net目前只支持OpenAI规范的接口,但许多小伙伴在社区中提议,希望能增加对本地模型(例如:ollama等)的支持。所以这次,我们将探讨如何在GraphRag.Net中使用自定义模型和本地模型。
为什么选择GraphRag.Net?
GraphRag.Net采用了Semantic Kernel作为基础,让我们能够非常简洁地抽象出会话与向量接口。因此,用户可以非常方便地实现自己定制的解决方案。接下来,我们会通过一个具体的例子,展示如何将本地模型和国产模型集成到GraphRag.Net中。
默认配置方法
首先,我们来看看如何进行默认配置:
1 2 3 4 5 6 7 8 9 | // OpenAI配置 builder.Configuration.GetSection( "OpenAI" ).Get<OpenAIOption>(); // 文档切片配置 builder.Configuration.GetSection( "TextChunker" ).Get<TextChunkerOption>(); // 配置数据库连接 builder.Configuration.GetSection( "GraphDBConnection" ).Get<GraphDBConnectionOption>(); // 注意,需要先注入配置文件,然后再注入GraphRag.Net builder.Services.AddGraphRagNet(); |
这里,我们将在默认配置中注入OpenAI的配置、文本切片的配置和数据库连接的配置。然后,依次注入这些配置文件和GraphRag.Net的服务。
自定义配置方法
如果需要自定义模型或本地模型,可能需要实现一些额外的服务接口,下面是自定义配置的示例:
1 2 3 4 5 6 7 | var kernelBuild = Kernel.CreateBuilder(); kernelBuild.Services.AddKeyedSingleton<ITextGenerationService>( "mock-text" , new MockTextCompletion()); kernelBuild.Services.AddKeyedSingleton<IChatCompletionService>( "mock-chat" , new MockChatCompletion()); kernelBuild.Services.AddSingleton<ITextEmbeddingGenerationService>( new MockTextEmbeddingGeneratorService()); kernelBuild.Services.AddKeyedSingleton( "mock-embedding" , new MockTextEmbeddingGeneratorService()); builder.Services.AddGraphRagNet(kernelBuild.Build()); |
在这个自定义配置示例中,我们引入了三个自定义服务接口:ITextGenerationService
、IChatCompletionService
和ITextEmbeddingGenerationService
。
实现自定义服务接口
接下来,我们需要为每个服务接口提供具体的实现。以下是三个接口的具体实现:
实现IChatCompletionService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public class MockChatCompletion : IChatCompletionService { private readonly Dictionary< string , object ?> _attributes = new (); private string _chatId; private static readonly JsonSerializerOptions _jsonSerializerOptions = new () { NumberHandling = JsonNumberHandling.AllowReadingFromString, Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) }; public IReadOnlyDictionary< string , object ?> Attributes => _attributes; public MockChatCompletion() { } public async Task<IReadOnlyList<ChatMessageContent>> GetChatMessageContentsAsync(ChatHistory chatHistory, PromptExecutionSettings? executionSettings = null , Kernel? kernel = null , [EnumeratorCancellation] CancellationToken cancellationToken = default ) { StringBuilder sb = new (); string result = $ "这是一条Mock数据,便于聊天测试,你的消息是:{chatHistory.LastOrDefault().ToString()}" ; return [ new (AuthorRole.Assistant, result.ToString())]; } public async IAsyncEnumerable<StreamingChatMessageContent> GetStreamingChatMessageContentsAsync(ChatHistory chatHistory, PromptExecutionSettings? executionSettings = null , Kernel? kernel = null , [EnumeratorCancellation] CancellationToken cancellationToken = default ) { StringBuilder sb = new (); string result = $ "这是一条Mock数据,便于聊天测试,你的消息是:{chatHistory.LastOrDefault().ToString()}" ; foreach ( var c in result) { yield return new StreamingChatMessageContent(AuthorRole.Assistant, c.ToString()); } } } |
实现ITextGenerationService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class MockTextCompletion : ITextGenerationService, IAIService { private readonly Dictionary< string , object ?> _attributes = new (); private string _chatId; private static readonly JsonSerializerOptions _jsonSerializerOptions = new () { NumberHandling = JsonNumberHandling.AllowReadingFromString, Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) }; public IReadOnlyDictionary< string , object ?> Attributes => _attributes; public MockTextCompletion() { } public async Task<IReadOnlyList<TextContent>> GetTextContentsAsync( string prompt, PromptExecutionSettings? executionSettings = null , Kernel? kernel = null , CancellationToken cancellationToken = default ) { StringBuilder sb = new (); string result = $ "这是一条Mock数据,便于聊天测试,你的消息是:{prompt}" ; return [ new (result.ToString())]; } public async IAsyncEnumerable<StreamingTextContent> GetStreamingTextContentsAsync( string prompt, PromptExecutionSettings? executionSettings = null , Kernel? kernel = null , CancellationToken cancellationToken = default ) { StringBuilder sb = new (); string result = $ "这是一条Mock数据,便于聊天测试,你的消息是:{prompt}" ; foreach ( var c in result) { var streamingTextContent = new StreamingTextContent(c.ToString(), modelId: "mock" ); yield return streamingTextContent; } } } |
实现ITextEmbeddingGenerationService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public sealed class MockTextEmbeddingGeneratorService : ITextEmbeddingGenerationService { private Dictionary< string , object ?> AttributesInternal { get ; } = []; public IReadOnlyDictionary< string , object ?> Attributes => this .AttributesInternal; public MockTextEmbeddingGeneratorService() { } public async Task<IList<ReadOnlyMemory< float >>> GenerateEmbeddingsAsync( IList< string > data, Kernel? kernel = null , CancellationToken cancellationToken = default ) { IList<ReadOnlyMemory< float >> results = new List<ReadOnlyMemory< float >>(); float [] array1 = { 1.0f, 2.0f, 3.0f }; float [] array2 = { 4.0f, 5.0f, 6.0f }; float [] array3 = { 7.0f, 8.0f, 9.0f }; // 将数组包装为ReadOnlyMemory<float>并添加到列表中 results.Add( new ReadOnlyMemory< float >(array1)); results.Add( new ReadOnlyMemory< float >(array2)); results.Add( new ReadOnlyMemory< float >(array3)); return results; } public void Dispose() { } } |
看到这里,你可能已经发现,集成自定义模型和本地模型非常简单。只需按照上述步骤,实现相应的接口并注入配置,你就可以在GraphRag.Net中使用这些自定义的功能。
结语
通过本文的介绍,我们了解了如何在GraphRag.Net中集成国产模型和本地模型。希望大家能够根据这些示例,开发出更多适合自己需求的功能。更多精彩内容,欢迎关注我的公众号,并发送进群加入我们的GraphRag.Net交流群,与社区小伙伴们一起交流学习!
感谢阅读,我们下期再见!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验