【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统
【Langchain系列二】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统
- 测试数据:https://docs.nebula-graph.io/2.0/basketballplayer-2.X.ngql
- 具体Nebula环境(本地/在线试用)可参考适合小白的Nebula图数据库教程(部署安装、常用命令、数据迁移全系列教程)
- 本文基于glm模型进行技术路线说明,可根据需要自行更换为其他模型
1. 安装依赖
pip install langchain langchain_community nebula3-python pandas pyjwt
2. 核心代码
2.1. 连接LLM与Nebula
- 申请智谱清言的key:https://bigmodel.cn/usercenter/proj-mgmt/apikeys
- GLM-4-Flash模型为免费模型,不消耗token,适合用于技术路线验证,正式试用中可按需更换为ollama本地模型或者其他在线模型
from langchain_community.chat_models.zhipuai import ChatZhipuAI
from langchain_community.graphs import NebulaGraph
os.environ["ZHIPUAI_API_KEY"] = "自己的key"
llm = ChatZhipuAI(model="GLM-4-Flash")
# ollama—glm4的效果也不错
# llm = ChatOllama(base_url="http://{ip}:{端口}", model="glm4:latest", temperature=0.5)
graph = NebulaGraph(space="工作空间名称",username="用户名",password="密码",address="ip地址",port=9669
)
2.2. 提示词
# 尝试在提示词加上“最后返回ngql语句,并用中文总结最终答案”,但效果不太稳定,因此ngql改成自己提取
answer_prompt = '''
You are an assistant that helps to form nice and human understandable answers.用中文做最后回答
The information part contains the provided information that you must use to construct an answer.
The provided information is authoritative, you must never doubt it or try to use your internal knowledge to correct it.
Make the answer sound as a response to the question. Do not mention that you based the result on the given information.
Here is an example:Question: Which managers own Neo4j stocks?
Context:[manager:CTL LLC, manager:JANE STREET GROUP LLC]
Helpful Answer: CTL LLC, JANE STREET GROUP LLC owns Neo4j stocks.Follow this example when generating answers.
If the provided information is empty, say that you don't know the answer.
Information:
{context}Question: {question}
Helpful Answer:
'''
# 注意特殊字符的转义,如{{、\"
prompt = '''Task: Generate NebulaGraph Cypher statement to query a graph database.
Instructions:
First, generate Cypher then convert it to NebulaGraph Cypher dialect (rather than standard):
1. note explicit label specification is not needed for edge properties, so it's e.name instead of e.`Bar`.name.But it requires explicit label specification only when referring to node properties: v.`Foo`.name instead of v.name.
2. it uses double equals sign for comparison: `==` rather than `=`
3. You should try translating Chinese to English, for instance, if