解锁GraphRag.Net的无限可能:手把手教你集成国产模型和本地模型
来源:互联网
时间:2026-08-22 14:46:07
前两篇文章聊下来,大家应该已经清楚
GraphRag.Net
为什么选择GraphRag.Net?
为什么选择GraphRag.Net?
GraphRag.Net 底层基于
Semantic Kernel
默认配置方法
默认配置方法
先回顾一下默认配置长什么样——这也是理解自定义配置的基础:
// OpenAI配置
builder.Configuration.GetSection("OpenAI").Get();
// 文档切片配置
builder.Configuration.GetSection("TextChunker").Get();
// 配置数据库连接
builder.Configuration.GetSection("GraphDBConnection").Get();
// 注意,需要先注入配置文件,然后再注入GraphRag.Net
builder.Services.AddGraphRagNet();
这段代码做的事情很清晰:注入 OpenAI 的配置、文本切片的配置和数据库连接的配置,然后注册 GraphRag.Net 的服务。默认情况下,它自然使用的是 OpenAI 的接口。
自定义配置方法
自定义配置方法
如果想把背后的模型换成自定义的,需要自己实现几个关键服务接口。下面是一个完整的自定义配置示例:
var kernelBuild = Kernel.CreateBuilder();
kernelBuild.Services.AddKeyedSingleton("mock-text", new MockTextCompletion());
kernelBuild.Services.AddKeyedSingleton("mock-chat", new MockChatCompletion());
kernelBuild.Services.AddSingleton(new MockTextEmbeddingGeneratorService());
kernelBuild.Services.AddKeyedSingleton("mock-embedding", new MockTextEmbeddingGeneratorService());
builder.Services.AddGraphRagNet(kernelBuild.Build());
这里用到了三个核心接口:
ITextGenerationService
IChatCompletionService
ITextEmbeddingGenerationService
实现自定义服务接口
接下来,我们分别给出三个接口的示例实现(这里是 Mock 版本,方便你理解骨架,实际替换成本地模型的 API 调用即可)。
实现 IChatCompletionService
public class MockChatCompletion : IChatCompletionService
{
private readonly Dictionary _attributes = new();
private string _chatId;
private static readonly JsonSerializerOptions _jsonSerializerOptions = new()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString,
Encoder = Ja vaScriptEncoder.Create(UnicodeRanges.All)
};
public IReadOnlyDictionary Attributes => _attributes;
public MockChatCompletion() { }
public async Task> GetChatMessageContentsAsync(
ChatHistory chatHistory,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default)
{
string result = $"这是一条Mock数据,便于聊天测试,你的消息是:{chatHistory.LastOrDefault().ToString()}";
return [new(AuthorRole.Assistant, result.ToString())];
}
public async IAsyncEnumerable GetStreamingChatMessageContentsAsync(
ChatHistory chatHistory,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default)
{
string result = $"这是一条Mock数据,便于聊天测试,你的消息是:{chatHistory.LastOrDefault().ToString()}";
foreach (var c in result)
{
yield return new StreamingChatMessageContent(AuthorRole.Assistant, c.ToString());
}
}
}
实现 ITextGenerationService
public class MockTextCompletion : ITextGenerationService, IAIService
{
private readonly Dictionary _attributes = new();
private string _chatId;
private static readonly JsonSerializerOptions _jsonSerializerOptions = new()
{
NumberHandling = JsonNumberHandling.AllowReadingFromString,
Encoder = Ja vaScriptEncoder.Create(UnicodeRanges.All)
};
public IReadOnlyDictionary Attributes => _attributes;
public MockTextCompletion() { }
public async Task> GetTextContentsAsync(
string prompt,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default)
{
string result = $"这是一条Mock数据,便于聊天测试,你的消息是:{prompt}";
return [new(result.ToString())];
}
public async IAsyncEnumerable GetStreamingTextContentsAsync(
string prompt,
PromptExecutionSettings? executionSettings = null,
Kernel? kernel = null,
CancellationToken cancellationToken = default)
{
string result = $"这是一条Mock数据,便于聊天测试,你的消息是:{prompt}";
foreach (var c in result)
{
yield return new StreamingTextContent(c.ToString(), modelId: "mock");
}
}
}
实现 ITextEmbeddingGenerationService
public sealed class MockTextEmbeddingGeneratorService : ITextEmbeddingGenerationService
{
private Dictionary AttributesInternal { get; } = [];
public IReadOnlyDictionary Attributes => this.AttributesInternal;
public MockTextEmbeddingGeneratorService() { }
public async Task>> GenerateEmbeddingsAsync(
IList data,
Kernel? kernel = null,
CancellationToken cancellationToken = default)
{
IList> results = new List>();
float[] array1 = { 1.0f, 2.0f, 3.0f };
float[] array2 = { 4.0f, 5.0f, 6.0f };
float[] array3 = { 7.0f, 8.0f, 9.0f };
results.Add(new ReadOnlyMemory(array1));
results.Add(new ReadOnlyMemory(array2));
results.Add(new ReadOnlyMemory(array3));
return results;
}
public void Dispose() { }
}
看到这里,你应该已经发现了——整个集成思路其实很直白:把三个接口按照你需要调用的模型逻辑实现一遍,然后在初始化时注入到 Kernel 里,再传给 GraphRag.Net。无论是国产模型(比如百度文心、阿里通义)还是本地部署的 ollama、llama.cpp,都可以用同样的模式接入。只需要把 Mock 代码里返回固定字符串的逻辑,换成真正的 HTTP 调用或本地推理接口即可。
结语
通过这几步,你就能在 GraphRag.Net 中自由切换模型了。实际项目中,你只需要根据自己的模型 SDK 替换掉实现类中的核心逻辑。希望这个框架能帮你省下大量对接和抽象的工作,让你更专注于业务本身。如果有任何疑问,欢迎在社区里一起讨论。
感谢阅读,我们下期再见。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名