我自己构建了一个小型的古籍知识库,想接入ChatGPT,来实现更精准的古籍知识问答。实现的方式应该有很多,但我目前只会最简单的,即:调用chat-gpt的api,通过prompt生成Cypher查询语句进行查询,然后chat-gpt根据查询的结果生成回答。
我主要是根据B站视频 GPT接入Neo4j知识图谱,实现精准知识问答 修改的代码,看见CSDN上也有类似代码,但需要付费订阅才能看。我暂将这个免费的demo记载这里。后续还会采用更智能的方法。
- 导入相关第三方库
import openai
from neo4j import GraphDatabase
from docx import Document
- 调用chat-gpt的api,通过Prompt生成Cypher查询语句
openai.api_base = "url" # 换成代理url
openai.api_key = "sk-xxxxxxxx" #your api_key
#api_key = "sk-xxxxx"
#client = OpenAI(api_key = api_key)start_sequence = "\nA:"
restart_sequence = "\n\nQ:"# 图谱结构:(杜仲)-[杜仲_又名]->(又名); (杜仲)-[杜仲_功用]->(功用);(杜仲)-[杜仲_地域]->(地域)
system1 = "这是我的neo4j知识图谱结构,根据问题,写一个Cypher查询语句,我希望返回完整的节点,而不只是节点的名字。图谱结构:MATCH(p1:` 矿类 `{name:' 铁 '})<-[r:` 多 `]-(p2)。问题:"
question1 = "《山经》中富含铁矿的山有哪些?"#client.chat.completions.create
#openai.ChatCompletion.create
response1 = openai.ChatCompletion.create(model = 'gpt-3.5-turbo',messages = [{"role": "user","content": system1 + question1,}],# prompt = system1 + question1,temperature = 0,max_tokens = 100,top_p = 1,frequency_penalty = 0,presence_penalty = 0,stop = None
)#answer1 = response1.choices[0].text.strip()
answer1 = response1.choices[0].message['content'].strip()print("问题:", question1)
print("查询语句:", answer1)
输出结果如下,可知根据Prompt中的提示生成了对应的Cypher查询语句:
- 登录neo4j,并使用上一步生成的查询语句进行查询
class Neo4jService(object):def __init__(self, uri, auth):self._driver = GraphDatabase.driver(uri, auth = auth)def close(self):self._driver.close()def run_query(self, query):with self._driver.session() as session:result = session.run(query)return result.values()# 将GPT-3的回答当做一个Neo4j查询
username = 'neo4j'
password = 'xxxxx' # your password
auth = (username, password)
neo4j = Neo4jService("bolt://localhost:7687", auth)
result = neo4j.run_query(answer1)
neo4j.close()
- 根据Neo4j的查询结果,使用chat-gpt生成报告
result2 = str(result)result2 = result2.replace("Node element_id", "")
result2 = result2.replace("labels=frozenset", "")
result2 = result2.replace("Relationship element_id", "")system2 = "这是基于我的neo4j的查询结果,根据结果写一个报告。"response2 = openai.ChatCompletion.create(model = 'gpt-3.5-turbo',messages = [{"role": "user","content": system2 + result2,}],#prompt = system2 + result2,temperature = 0,max_tokens = 1000,top_p = 1,frequency_penalty = 0,presence_penalty = 0,stop = None
)# answer2 = response2.choices[0].text.strip()
answer2 = response2.choices[0].message['content'].strip()print("查询结果:", result2)
print("摘要:", answer2)
输出如下:
- 将结果保存至.docx文档
doc = Document()
doc.add_heading('问题:', level=1)
doc.add_paragraph(question1)
doc.add_heading('cypher查询语句:', level=1)
doc.add_paragraph(answer1)
doc.add_heading('cypher查询结果:', level=1)
doc.add_paragraph(result2)
doc.add_heading('结果描述:', level=1)
doc.add_paragraph(answer2)
doc.save('report.docx') # 保存为docx文件
下图是最终生成的结果中的描述,结合之前创建的知识图谱,或者《山海经》原文,可知这个答案是很准确的。
而下图是GPT-3.5-Turbo的原始回答,可知其对领域知识知之甚少。