


























大家好!
在这个全民 RAG 的时代,人们似乎找到了一条蹭 AI 的捷径。大模型加上领域知识分分钟包装成知识库,智能体,垂直大模型?但在实际应用中,传统 RAG 并不能解决所有问题,尤其是需要复杂推理和关系分析的场景。知识图谱(Knowledge Graph)作为结构化语义网络,能更好地表达实体及其关系,补足 RAG 的不足。
本文将结合 Neo4j 图数据库和大语言模型(LLM),介绍如何实现一个简单的问答系统。当然我也还在学习跟尝试当中,如有不当的地方请友好探讨。
知识图谱(Knowledge Graph)是一种通过节点和关系来表达知识的结构化方式。
节点(Node):节点代表知识图谱中的实体,可以是人、地点、事物、事件等。例如,“张三”、“北京”、“苹果公司”都可以作为节点。
边(Edge):边用于连接两个节点,表示它们之间存在某种关系。每条边都有方向和类型。例如,“张三”——[居住于]——>“北京”,“苹果公司”——[创始人]——>“乔布斯”。
关系(Relationship):关系是边的具体类型,描述节点之间的语义联系。关系可以是“属于”、“包含”、“朋友”、“创始人”等。关系通常带有属性,比如时间、权重等。
通过节点和边的组合,知识图谱能够以图结构的方式表达复杂的现实世界知识,实现语义理解和推理。
RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合检索与生成的AI问答技术。它通常通过向量数据库检索相关文档片段,然后用大模型进行生成式回答。
对比点:
实际应用中,知识图谱和RAG可以结合使用,既利用结构化知识进行推理,又用检索增强生成提升问答的广度和灵活性。
本次试验我们使用 Neo4j 作为图数据库。
Neo4j 是一个高性能的开源图数据库,专门用于存储和管理图结构数据。它以节点、关系和属性为核心,能够高效地处理复杂的连接和关系查询。
Neo4j 的主要特点:
Neo4j 广泛应用于社交网络、推荐系统、知识图谱、风控反欺诈等领域,能够帮助企业高效地挖掘和分析数据中的关联关系。
安装的话使用 docker 非常的方便,不多说。
docker run \
--restart always \
--publish=7474:7474 --publish=7687:7687 \
neo4j:2025.06.2
在我们进行试验前,需要先准备一些数据到 neo4j 的数据库里。这里采用 Neo4j 安装向导自带的一个关于演员与电影之间的知识库。包含 38 部电影与 133 个演员的信息。
CREATE CONSTRAINT movie_title IF NOT EXISTS FOR (m:Movie) REQUIRE m.title IS UNIQUE;
CREATE CONSTRAINT person_name IF NOT EXISTS FOR (p:Person) REQUIRE p.name IS UNIQUE;
MERGE (TheMatrix:Movie {title:'The Matrix'}) ON CREATE SET TheMatrix.released=1999, TheMatrix.tagline='Welcome to the Real World'
MERGE (Keanu:Person {name:'Keanu Reeves'}) ON CREATE SET Keanu.born=1964
MERGE (Carrie:Person {name:'Carrie-Anne Moss'}) ON CREATE SET Carrie.born=1967
MERGE (Laurence:Person {name:'Laurence Fishburne'}) ON CREATE SET Laurence.born=1961
MERGE (Hugo:Person {name:'Hugo Weaving'}) ON CREATE SET Hugo.born=1960
MERGE (LillyW:Person {name:'Lilly Wachowski'}) ON CREATE SET LillyW.born=1967
MERGE (LanaW:Person {name:'Lana Wachowski'}) ON CREATE SET LanaW.born=1965
MERGE (JoelS:Person {name:'Joel Silver'}) ON CREATE SET JoelS.born=1952
...

使用 C# 去访问 Neo4j 呢也相当简单。安装相关的驱动把 cypher 发过去就行了。
<ItemGroup>
<PackageReference Include="Neo4j.Driver" Version="5.28.2" />
</ItemGroup>
代码:
const string dbUri = "neo4j://125.gen8.com:7687";
const string dbUser = "neo4j";
const string dbPassword = "neo4j@123";
await using var driver = GraphDatabase.Driver(dbUri, AuthTokens.Basic(dbUser, dbPassword));
await driver.VerifyConnectivityAsync();
Console.WriteLine("Connection established.");
var query = "MATCH (n)-[r]-(m) RETURN *";
var result = await driver.ExecutableQuery(query)
.WithConfig(new QueryConfig(database: "neo4j"))
.ExecuteAsync();
要实现这个 chatbot 呢,首先让我们来理一下整个流程:
graph TD A[用户输入问题] --> B[LLM 生成 Cypher 查询语句] B --> C[C# 代码访问 Neo4j 数据库] C --> D[Neo4j 返回查询结果] D --> E[LLM 总结并生成回答] E --> F[返回给用户]
流程说明:
直接看完整代码吧,测试模型试验 gpt-4.1,SK 什么的背景知识就不解释了,可以翻以前的文章。
// Populate values from your OpenAI deployment
var modelId = "gpt-4.1";
var endpoint = "https://kklldog-openai.openai.azure.com/";
var apiKey = "";
// Create a kernel with Azure OpenAI chat completion
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);
var sk = builder.Build();
var chatCompletionService = sk.GetRequiredService<IChatCompletionService>();
//var q = "Who is Tom Cruise ?";
var q = Console.ReadLine();
// round1 => get cypher query
ChatHistory chatHistory = [
new() {
Role = AuthorRole.System,
Content = "你是一个neo4j的专家,当收到问题后,请尝试给出可以帮助回答问题的 cypher 查询语句。" +
"你可以使用以下标签:" +
"Movie,Person " +
"你可以使用以下关系:" +
"ACTED_IN,DIRECTED,FOLLOWS,PRODUCED,REVIEWED,WROTE " +
"请直接返回cypher语句,不需要多余的内容"
},
new() {
Role = AuthorRole.User,
Content = q
}
];
var chatResponse = await chatCompletionService.GetChatMessageContentAsync(
chatHistory
);
string query = chatResponse.ToString();
Console.WriteLine(query);
const string dbUri = "neo4j://125.gen8.com:7687";
const string dbUser = "neo4j";
const string dbPassword = "neo4j@123";
await using var driver = GraphDatabase.Driver(dbUri, AuthTokens.Basic(dbUser, dbPassword));
await driver.VerifyConnectivityAsync();
Console.WriteLine("Connection established.");
var result = await driver.ExecutableQuery(query)
.WithConfig(new QueryConfig(database: "neo4j"))
.ExecuteAsync();
var answerTxt = JsonConvert.SerializeObject(result.Result);
Console.WriteLine(answerTxt);
// round2 => get answer
ChatHistory chatHistory_1 = [
new() {
Role = AuthorRole.System,
Content = "我会给你一段 cypher 语句,以及它的查询结果。请根据这些内容对问题进行回答,如果无法回答就说不知道。" +
"query:" + query +
"answer:" + answerTxt
},
new() {
Role = AuthorRole.User,
Content = q
}
];
var chatResponse_1 = await chatCompletionService.GetChatMessageContentAsync(
chatHistory_1
);
Console.WriteLine(chatResponse_1);
让我们试跑一下,输入问题:How many movies does tom cruise acted in?
Hello, World!
How many movies does tom cruise acted in?
MATCH (p:Person {name: "Tom Cruise"})-[:ACTED_IN]->(m:Movie)
RETURN count(m) AS num_movies
Connection established.
[{"num_movies":3}]
Tom Cruise has acted in 3 movies.
本文介绍了如何结合 Neo4j 图数据库与大语言模型(LLM)实现一个简单的问答系统。通过知识图谱结构化存储信息,利用 LLM 自动生成 Cypher 查询语句,并用 C# 代码访问 Neo4j 获取结果,最后由 LLM 进行答案总结,实现了从自然语言到结构化知识的闭环。
这种方案的优势在于:
未来可以进一步扩展:
总之,Neo4j + LLM 的结合为智能问答和知识管理提供了强大的技术基础,值得在更多场景中探索和应用。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。