/GraphRag.Net

参考GraphRag使用 Semantic Kernel 来实现的dotnet版本

Primary LanguageC#Apache License 2.0Apache-2.0

这是一个参考GraphRag的dotnet简易实现

基于微软在论文中提到的实现思路,执行过程GraphRAG主要实现了如下功能:

  • Source Documents → Text Chunks:将源文档分割成文本块。
  • Text Chunks → Element Instances:从每个文本块中提取图节点和边的实例。
  • Element Instances → Element Summaries:为每个图元素生成摘要。
  • Element Summaries → Graph Communities:使用社区检测算法将图划分为社区。
  • Graph Communities → Community Summaries:为每个社区生成摘要。
  • Community Summaries → Community Answers → Global Answer:使用社区摘要生成局部答案,然后汇总这些局部答案以生成全局答案。

本项目为demo示例,仅用于学习GraphRAG思路。

出于方便,LLM接口目前只兼容了openai的规范,其他大模型可以考虑使用one-api类的集成产品

 "OpenAI": {
   "Key": "sk-xxx",
   "Endpoint": "https://api.antsk.cn/",
   "ChatModel": "gpt-4o-mini",
   "EmbeddingModel": "text-embedding-ada-002"
 },
"TextChunker": {
    "LinesToken": 100,
    "ParagraphsToken": 1000
},
"GraphDBConnection": {
    "DbType": "Sqlite", //PostgreSQL
    "DBConnection": "Data Source=graph.db",
    "GraphDBConnection": "graphmem.db",
    "VectorSize": 1536 //DbType=PostgreSQL时需要设置,sqlite可以不设置
}

启动项目

dotnet run --project GraphRag.Net.Web.csproj

启动项目后可以通过

http://localhost:5000/swagger

打开swagger查看接口

Graoh

也可以使用界面

http://localhost:5000/

打开blazor的UI界面,页面提供了文本导入、文件导入,和问答对话,查看知识图谱等功能

Graoh

Nuget包使用

dotnet add package GraphRag.Net

添加包以后,需要进行配置文件的设置以及依赖注入

//OpenAI配置
builder.Configuration.GetSection("OpenAI").Get<OpenAIOption>();
//文档切片配置
builder.Configuration.GetSection("TextChunker").Get<TextChunkerOption>();
//配置数据库链接
builder.Configuration.GetSection("GraphDBConnection").Get<GraphDBConnectionOption>();

//注入AddGraphRagNet,注意,需要先注入配置文件,然后再注入GraphRagNet
builder.Services.AddGraphRagNet();

使用时注入 IGraphService 服务,以下为参考示例代码

namespace GraphRag.Net.Api.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class GraphDemoController(IGraphService _graphService) : ControllerBase
    {
        /// <summary>
        /// 获取所有的索引数据
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetAllIndex()
        {
            var graphModel = _graphService.GetAllIndex();
            return Ok(graphModel);
        }


        /// <summary>
        /// 获取所有的图谱数据
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetAllGraphs(string index)
        {
            if (string.IsNullOrEmpty(index))
            {
                return Ok(new GraphViewModel());
            }
            var graphModel = _graphService.GetAllGraphs(index);
            return Ok(graphModel);
        }


        /// <summary>
        /// 插入文本数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> InsertGraphData(InputModel model)
        {
            await _graphService.InsertGraphDataAsync(model.Index, model.Input);
            return Ok();
        }

        /// <summary>
        /// 搜索递归获取节点相关的所有边和节点进行图谱对话
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> SearchGraph(InputModel model)
        {
            var result = await _graphService.SearchGraphAsync(model.Index, model.Input);
            return Ok(result);
        }

        /// <summary>
        /// 通过社区算法检索社区节点进行对话
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> SearchGraphCommunity(InputModel model)
        {
            var result = await _graphService.SearchGraphCommunityAsync(model.Index, model.Input);
            return Ok(result);
        }

        /// <summary>
        /// 导入txt文档
        /// </summary>
        /// <param name="index"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> ImportTxt(string index,IFormFile file)
        {
            var forms = await Request.ReadFormAsync();
            using (var stream = new StreamReader(file.OpenReadStream()))
            {
                var txt = await stream.ReadToEndAsync();
                await _graphService.InsertTextChunkAsync(index,txt);
                return Ok();
            }
        }

        /// <summary>
        /// 通过社区检测生成社区和摘要
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GraphCommunities(string index)
        {
            await _graphService.GraphCommunitiesAsync(index);
            return Ok();
        }      
        
        /// <summary>
        /// 通过社区摘要生成全局摘要
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GraphGlobal(string index)
        {
            await _graphService.GraphGlobalAsync(index);
            return Ok();
        }
    }

    public class InputModel
    {
        public string Index { get; set; }
        public string Input { get; set; }
    }
}