生成 Cypher 能力:GPT3.5 VS ChatGLM


Here’s the table of contents:

生成 Cypher 能力:GPT3.5 VS ChatGLM

  在之前的文章中已经测试过GPT3.5GPT4生成Cypher的能力:

  1. 大语言模型Prompt工程之使用GPT4生成图数据库Cypher
  2. 大语言模型Prompt工程之使用GPT3.5生成图数据库Cypher
  3. GPT-3.5 生成 Fabric Cypher

  这次测试的模型是ChatGLM,测试过程中使用的Prompt和之前的测试过程中使用的是一样。总体来说,未微调的ChatGLM结果差于GPT3.5

  下面是展示的一部分内容,测试结果为GPT3.5和未微调的ChatGLM两个大语言模型生成Cypher的展示。

一、 测试结果

  1. QA:你好

  该问题GPT3.5ChatGLM都无法生成Cypher,是正确的。但是ChatGLM的回复显得有些冗长。

RE-GPT3.5:

无法根据示例Cypher查询推断出生成Cypher查询的特定上下文。请提供更具体的问题或信息。
RE-ChatGLM:

欢迎,有什么需要帮助的吗?

# 查询用户信息
user_id:int(什么是用户ID?), name:text(用户姓名), email:text(用户邮箱), password:text(用户密码)
        
# 查询订单信息
order_id:int(订单ID), customer_id:int(客户ID), product_id:int(产品ID), total:float(总价), status:text(状态:完成/未支付/取消)
        
# 查询用户订单
user_order:list(用户订单列表)
        
# 查询商品订单
product_order:list(商品订单列表)

请提供您的查询需求,我会尽力生成正确的Cypher语句。
  1. QA:最近半导体上涨的原因是什么?

  该问题GPT3.5ChatGLM都无法生成正确的Cypher,是正确的。
但是ChatGLM确回复了一个SQL,确实没有明白我在Prompt中定义的想生成Cypher的意图。

RE-GPT3.5:

MATCH (c:Company)-[r:CAUSED]->(p:Price)
    WHERE c.name = '半导体' AND r.reason = '上涨'
RETURN r.reason, p.reason
RE-ChatGLM:

SELECT 
    CASE 
        WHEN A.column_name = 'reason' THEN 'reason' 
        WHEN A.column_name = 'bubble_up' THEN 'bubble_up' 
        WHEN A.column_name = 'bubble_down' THEN 'bubble_down' 
        WHEN A.column_name = 'stock_price' THEN 'stock_price' 
        WHEN A.column_name = 'future_price' THEN 'future_price' 
        ELSE 'default' 
        END AS reason 
     FROM 
        columns A 
     WHERE 
     A.table_name = 'stock' 
     ORDER BY 
     stock_price DESC 
LIMIT 1;
  1. QA:海南有哪些上市公司?

  该问题GPT3.5生成了完全正确的Cypher,ChatGLM没有生成正确的Cypher。
ChatGLM回复了一个看似正确的Cypher但是语法有错误,单独复制粘贴后Cypher无法运行,另外结果中还多了一些废话。

RE-GPT3.5:

MATCH p0=(n0:股票)-[r0:地域]->(n1:地域) WHERE n1.value='海南'
RETURN DISTINCT n0 AS n4 LIMIT 10;
RE-ChatGLM:

match (n0:股票)-[r0:地域]->(n1:地域) WHERE n1.value='海南' return distinct n0 as n4 limit 10;

这是一条简单的Cypher查询,它匹配了一个股票向一个地域的反向匹配,并返回该股票的所有地区名称。请注意,此查询可能无法完全准确地返回所有海南上市公司的详细信息,因为它只返回了海南的股票。如果您需要更详细的信息,请提供更多上下文。
  1. QA:电气设备行业有多少家上市公司?

  该问题GPT3.5生成了完全正确的Cypher,ChatGLM没有生成正确的Cypher。
ChatGLM也是回复了一个看似正确的Cypher但是语法有错误,单独复制粘贴后Cypher无法运行,另外结果中还多了一些废话。

RE-GPT3.5:

MATCH p0=(n0:股票)-[r0:所属行业]->(n1:行业)
WHERE n1.value='电气设备'
RETURN COUNT(DISTINCT n0) AS n4;
RE-ChatGLM:


match p0=(n0:股票)-[r0:所属行业]->(n1:行业) 
WHERE n1.value='电气设备'
RETURN COUNT(DISTINCT n0) AS n4;


该查询将返回电气设备行业中上市公司的总数量。请注意,该查询将返回所有股票,无论它们属于哪个行业。如果您只需要返回特定行业的数量,请在WHERE子句中更改该条件。
  1. QA:水泥行业博士学历的男性高管有多少位?

  该问题GPT3.5生成了完全正确的Cypher,ChatGLM没有生成正确的Cypher。
ChatGLM回复了一个看似正确的Cypher但是语法有错误,单独复制粘贴后Cypher无法运行,但这次好一些废话没有了。

# RE-GPT3.5:

MATCH
    p0=(n1:行业)<-[r0:所属行业]-(n0:股票)<-[r1:任职于]-(n2:高管)-[r2:性别]->(n3:性别)-[r4:别名]->(n5:性别_别名),
    p1=(n2)-[r3:学历]->(n4:学历)
    WHERE n1.value='水泥' AND n5.value='男性' AND n4.value='博士'
RETURN COUNT(DISTINCT n2) AS n3;
RE-ChatGLM:

MATCH 
    p0=(n1:行业)<-[r0:所属行业]-(n0:股票)<-[r1:任职于]-(n2:高管)-[r2:性别]->(n3:性别)-[r4:别名]->(n5:性别_别名),
    p1=(n2)-[r3:学历]->(n4:学历) 
WHERE n1.value='水泥' AND n5.value='男性' AND n4.value='博士'
RETURN COUNT(DISTINCT n2) AS n3;
  1. QA:在北京由硕士学历的女性高管任职的上市公司,都属于哪些行业?

  该问题GPT3.5生成了完全正确的Cypher,ChatGLM没有生成正确的Cypher。
ChatGLM也是回复了一个看似正确的Cypher但是语法有错误,单独复制粘贴后Cypher无法运行,另外结果中仍然多了一些废话。

RE-GPT3.5:

MATCH
    p1=(n1:`地域`)<-[:`地域`]-(n2:`股票`)<-[:`任职于`]-(n3:`高管`)-[:`性别`]->(n4:`性别`),
    p2=(n3)-[:`学历`]->(n5:学历),
    p3=(n2)-[:`所属行业`]->(n6:行业)
WHERE n1.value='北京' AND n5.value='硕士' AND n4.value='F'
RETURN DISTINCT n6.value AS hy;
RE-ChatGLM:

match p1=(n1:`地域`)<-[:`地域`]-(n2:`股票`)<-[:`任职于`]-(n3:`高管`)-[:`性别`]->(n4:`性别`),
    p2=(n3)-[:`学历`]->(n5:学历),
    p3=(n2)-[:`所属行业`]->(n6:行业)
WHERE n1.value='北京' AND n5.value='硕士' AND n4.value='F'
RETURN DISTINCT n6.value AShy;

这是一个匹配“在北京由硕士学历的女性高管任职的上市公司”的三元组Cypher查询,使用了以下语法:

- `match`:匹配三元组中的元素。
- `p1`:匹配`n1`中的`地域`元素。
- `p2`:匹配`n3`中的`学历`元素。
- `p3`:匹配`n2`中的`所属行业`元素。
- `WHERE`:在查询条件中添加过滤条件。
- `n1.value='北京' AND n5.value='硕士' AND n4.value='F'`:过滤条件,只有“北京”和“硕士”且“女性”的高管才能任职上市公司。
- `RETURN DISTINCT n6.value AShy`:返回每个行业的代码值。

请注意,这个查询只匹配了北京的数据,并且只使用了硕士和女性这两个条件。如果有更多的条件,可能需要在查询条件中包含它们。

二、 测试代码(包含Prompt)

import requests
import Levenshtein
import json


# 使用HTTP封装的ChatGLM接口,请根据具体接口情况替换
def chatglm(msg):
    url = "https://localhost:8080/llm/chatglm/chat"
    payload = json.dumps({
    
    
        "query": msg,
        "history": [],
        "max_length": 2048,
        "temperature": 0.95
    })
    headers = {
    
    
        'Content-Type': 'application/json'
    }

    response = requests.request("POST", url, headers=headers, data=payload)
    return response.json()['response']


def example_list():
    ex_list = [{
    
    
        'qa': '火力发电行业博士学历的男性高管有多少位?',
        'cypher': '''
            MATCH 
                p0=(n1:行业)<-[r0:所属行业]-(n0:股票)<-[r1:任职于]-(n2:高管)-[r2:性别]->(n3:性别)-[r4:别名]->(n5:性别_别名),
                p1=(n2)-[r3:学历]->(n4:学历) 
            WHERE n1.value='火力发电' AND n5.value='男性' AND n4.value='博士'
            RETURN COUNT(DISTINCT n2) AS n3;
            '''
    }, {
    
    
        'qa': '山西都有哪些上市公司?',
        'cypher': '''
            MATCH p0=(n0:股票)-[r0:地域]->(n1:地域) WHERE n1.value='山西' 
            RETURN DISTINCT n0 AS n4 LIMIT 10;
               '''
    }, {
    
    
        'qa': '富奥股份的高管都是什么学历?',
        'cypher': '''
                 MATCH p0=(n1:股票名称)<-[r0:股票名称]-(n0:股票)<-[r1:任职于]-(n2:高管)-[r2:学历]->(n3:学历) 
            WHERE n1.value='富奥股份'
            RETURN DISTINCT n3 AS n2 LIMIT 10;
                   '''
    }, {
    
    
        'qa': '中国宝安属于什么行业?',
        'cypher': '''
                MATCH p0=(n1:股票名称)<-[r0:股票名称]-(n0:股票)-[r1:所属行业]->(n2:行业) 
            WHERE n1.value='中国宝安'
            RETURN DISTINCT n2 AS n5 LIMIT 10;
                       '''
    }, {
    
    
        'qa': '建筑工程行业有多少家上市公司?',
        'cypher': '''
                MATCH p0=(n0:股票)-[r0:所属行业]->(n1:行业) 
            WHERE n1.value='建筑工程'
            RETURN COUNT(DISTINCT n0) AS n4;
                           '''
    }, {
    
    
        'qa': '刘卫国是哪个公司的高管?',
        'cypher': '''
             MATCH p0=(n0:股票)<-[r0:任职于]-(n1:高管) 
            WHERE n1.value='刘卫国'
            RETURN DISTINCT n0 AS n4 LIMIT 10;
                            '''
    }, {
    
    
        'qa': '美丽生态上市时间是什么时候?',
        'cypher': '''
                MATCH p0=(n1:股票名称)<-[r0:股票名称]-(n0:股票)-[r1:上市日期]->(n2:上市日期) 
            WHERE n1.value='美丽生态'
            RETURN DISTINCT n2 AS n1 LIMIT 10;
                                '''
    }, {
    
    
        'qa': '山西的上市公司有多少家?',
        'cypher': '''
                MATCH p0=(n0:股票)-[r0:地域]->(n1:地域) 
            WHERE n1.value='山西'
            RETURN COUNT(DISTINCT n0) AS n4;
                                    '''
    }, {
    
    
        'qa': '博士学历的高管都有哪些?',
        'cypher': '''
                MATCH p0=(n0:高管)-[r0:学历]->(n1:学历) 
            WHERE n1.value='博士' 
            RETURN DISTINCT n0 AS n3 LIMIT 10;
                                        '''
    }, {
    
    
        'qa': '上市公司是博士学历的高管有多少个?',
        'cypher': '''
               MATCH p0=(n0:高管)-[r0:学历]->(n1:学历) 
            WHERE n1.value='博士'
            RETURN COUNT(DISTINCT n0) AS n3;
                                            '''
    }, {
    
    
        'qa': '刘卫国是什么学历?',
        'cypher': '''
                MATCH p0=(n0:高管)-[r0:学历]->(n1:学历) 
            WHERE n0.value='刘卫国'
            RETURN DISTINCT n1 AS n2 LIMIT 10;
                                                '''
    }, {
    
    
        'qa': '富奥股份的男性高管有多少个?',
        'cypher': '''
               MATCH p0=(n1:股票名称)<-[r0:股票名称]-(n0:股票)<-[r1:任职于]-(n2:高管)-[r2:性别]->(n3:性别)-[r3:别名]->(n4:性别_别名) 
            WHERE n1.value='富奥股份' AND n4.value='男性'
            RETURN COUNT(DISTINCT n2) AS n3;
                                                    '''
    }, {
    
    
        'qa': '同在火力发电行业的上市公司有哪些?',
        'cypher': '''
                MATCH p0=(n0:股票)-[r0:所属行业]->(n1:行业) 
            WHERE n1.value='火力发电' 
            RETURN DISTINCT n0 AS n4 LIMIT 10;
                                                        '''
    }, {
    
    
        'qa': '同在火力发电行业的上市公司有多少家?',
        'cypher': '''
                MATCH p0=(n0:股票)-[r0:所属行业]->(n1:行业) 
            WHERE n1.value='火力发电'
            RETURN COUNT(DISTINCT n0) AS n4;
                                                            '''
    }, {
    
    
        'qa': '大悦城和荣盛发展是同一个行业嘛?',
        'cypher': '''
                MATCH p0=(n1:股票名称)<-[r0:股票名称]-(n0:股票)-[r1:所属行业]->(n2:行业) 
            WHERE n1.value IN ['大悦城','荣盛发展']
            RETURN DISTINCT n2 AS n5 LIMIT 10;
                                                                '''
    }, {
    
    
        'qa': '同在河北的上市公司有哪些?',
        'cypher': '''
                MATCH p0=(n0:股票)-[r0:地域]->(n1:地域) 
            WHERE n1.value='河北' 
            RETURN DISTINCT n0 AS n4 LIMIT 10;
                                                                    '''
    }, {
    
    
        'qa': '神州高铁是什么时候上市的?',
        'cypher': '''
               MATCH p0=(n1:股票名称)<-[r0:股票名称]-(n0:股票)-[r1:上市日期]->(n2:上市日期) 
            WHERE n1.value='神州高铁' 
            RETURN DISTINCT n2 AS n1 LIMIT 10;
                                                                       '''
    }, {
    
    
        'qa': '火力发电行业男性高管有多少个?',
        'cypher': '''
               MATCH p0=(n1:行业)<-[r0:所属行业]-(n0:股票)<-[r1:任职于]-(n2:高管)-[r2:性别]->(n3:性别)-[r3:别名]->(n4:性别_别名) 
            WHERE n1.value='火力发电' AND n4.value='男性'
            RETURN COUNT(DISTINCT n2) AS n3;
                                                                          '''
    }, {
    
    
        'qa': '2023年三月六日上市的股票代码?',
        'cypher': '''
               MATCH p0=(n0:股票)-[r0:上市日期]->(n1:上市日期) 
            WHERE (n1.value>=20230306 AND n1.value<=20230306) 
            RETURN DISTINCT n0 AS n4 LIMIT 10;
                                                                             '''
    }, {
    
    
        'qa': '2023年三月六日上市的股票有哪些?',
        'cypher': '''
               MATCH p0=(n0:股票)-[r0:上市日期]->(n1:上市日期) 
            WHERE (n1.value>=20230306 AND n1.value<=20230306) 
            RETURN DISTINCT n0 AS n4 LIMIT 10;
                                                                                 '''
    }, {
    
    
        'qa': '2023年三月六日上市的股票有多少个?',
        'cypher': '''
                MATCH p0=(n0:股票)-[r0:上市日期]->(n1:上市日期) 
            WHERE (n1.value>=20230306 AND n1.value<=20230306) 
            RETURN COUNT(DISTINCT n0) AS n4;
                                                                                     '''
    }, {
    
    
        'qa': '胡永乐是什么性别?',
        'cypher': '''
                 MATCH p0=(n0:高管)-[r0:性别]->(n1:性别) 
            WHERE n0.value='胡永乐' 
            RETURN DISTINCT n1 AS n7 LIMIT 10;
                                                                                         '''
    }, {
    
    
        'qa': '在山东由硕士学历的男性高管任职的上市公司,都属于哪些行业?',
        'cypher': '''
               MATCH 
    	        p1=(n1:`地域`)<-[:`地域`]-(n2:`股票`)<-[:`任职于`]-(n3:`高管`)-[:`性别`]->(n4:`性别`),
                p2=(n3)-[:`学历`]->(n5:学历),
                p3=(n2)-[:`所属行业`]->(n6:行业)
            WHERE n1.value='山东' AND n5.value='硕士' AND n4.value='M'
            RETURN DISTINCT n6.value AS hy;
                                                                                            '''
    }]
    return ex_list


def examples(ask):
    examples_str = ''
    examples_list = []
    for index, map in enumerate(example_list()):
        qa = map['qa']
        cypher = map['cypher']
        dis = Levenshtein.distance(ask, qa)
        examples_list.append({
    
    'qa': qa, 'cypher': cypher, 'dis': dis})

    sorted_list = sorted(examples_list, key=lambda map: map['dis'])

    for map in sorted_list:
        qa = map['qa']
        cypher = map['cypher']
        dis = map['dis']
        ex = f'''
          # {
      
      qa}
          {
      
      cypher}
          '''
        # `prompt(ask)` Prompt Length 300
        if dis < 6 and len(examples_str + ex) + 300 <= 2048:
            examples_str += ex

    return examples_str


def prompt(ask):
    return f"""
        您是一名助手,能够根据示例Cypher查询生成Cypher查询。
        示例Cypher查询有:\n {
      
      examples(ask)} \n
        除了Cypher查询之外,不要回复任何解释或任何其他信息。
        您永远不要为你的不准确回复感到抱歉,并严格根据提供的cypher示例生成cypher语句。
        不要提供任何无法从Cypher示例中推断出的Cypher语句。
        当由于缺少对话上下文而无法推断密码语句时,通知用户,并说明缺少的上下文是什么。
        现在请为这个查询生成Cypher:
        # {
      
      ask}
        """


if __name__ == '__main__':
    # 输入问题
    ask = '在北京由硕士学历的女性高管任职的上市公司,都属于哪些行业?'

    print(chatglm(prompt(ask)))

猜你喜欢

转载自blog.csdn.net/superman_xxx/article/details/130435718