如何使用Elasticsearch以自然語言提示ChatGPT

如何使用Elasticsearch以自然語言提示ChatGPT (1200 x 630 像素)

最近大家都在談論ChatGPT。這個大型語言模型(LLM)的一項很酷的功能是有產生程式碼的能力。我們可以使用它來在 Elasticsearch DSL 查詢。像是在 Elasticsearch 中搜尋使用「給我2017年股票指數的前10個文件」這樣的句子在Elasticsearch®中進行搜索。這個實驗顯示了這是可能的,但有一些限制。在這篇文章中,我們描述了這個實驗以及我們為這個案例發布的開源庫。

ChatGPT能夠生成Elasticsearch DSL嗎?

我們開始了一些測試,專注於ChatGPT生成Elasticsearch DSL查詢的能力。為此,您需要向ChatGPT提供一些有關您想搜索的數據結構的上下文。

 

在Elasticsearch中,數據儲存在索引中,這類似於關係數據庫中的「表」。它有一個對映,定義了多個字段及其類型。因此我們需要提供想要查詢的索引對映資訊。透過這樣做,ChatGPT就有了將查詢轉換為Elasticsearch DSL的必要上下文。

 

Elasticsearch提供了一個get mapping API來檢索索引的對映。在我們的實驗中,我們使用了一個這裡提供的股票指數數據集。這個數據集包含了五年的500家財富公司的股票價格,從2013年2月到2018年2月。

這裡我們報告了包含數據集的CSV文件的前五行:

date,open,high,low,close,volume,name
2013-02-08,15.07,15.12,14.63,14.75,8407500,AAL
2013-02-11,14.89,15.01,14.26,14.46,8882000,AAL
2013-02-12,14.45,14.51,14.1,14.27,8126000,AAL
2013-02-13,14.3,14.94,14.25,14.66,10259500,AAL

每一行包含股票的日期、當日開盤價、最高和最低價值、收盤價、交易量,最後是股票名稱,例如美國航空集團股份有限公司(AAL)。

與股票指數相關聯的對應如下所示:

{
  "stocks": {
    "mappings": {
      "properties": {
        "close": {"type":"float"},
        "date" : {"type":"date"},
        "high" : {"type":"float"},
        "low"  : {"type":"float"},
        "name" : {
          "type": "text",
          "fields": {
            "keyword":{"type":"keyword", "ignore_above":256}
          }
        },
        "open"  : {"type":"float"},
        "volume": {"type":"long"}
      }
    }
  }
}

我們可以使用 GET /stocks/_mapping API 從 Elasticsearch 中檢索對映。

讓我們建立一個提示來找出答案

為了將以人類語言表達的查詢轉換為 Elasticsearch DSL,我們需要找到合適的提示來提供給 ChatGPT。這是整個過程中最困難的部分:實際上使用正確的問題格式(正確的提示)來編程 ChatGPT。

在經過一些迭代後,我們最終得到了以下看似效果良好的提示:

Given the mapping delimited by triple backticks ```{mapping}``` translate the text delimited by triple quotes in a valid Elasticsearch DSL query """{query}""". Give me only the json code part of the answer. Compress the json output removing spaces.

在提示中,{mapping} 和 {query} 是兩個佔位符,需要用對映的 JSON 字符串(例如,前面示例中使用 GET /stocks/_mapping 返回的)和以人類語言表達的查詢(例如:返回 2017 年的前 10 個文件)替換。

當然,ChatGPT 有其限制,在某些情況下可能無法回答問題。我們發現,大多數情況下,這是因為提示中使用的句子過於一般或含糊不清。為了解決這種情況,我們需要加強提示的細節。這個過程稱為迭代,需要多個步驟來定義要使用的正確句子。

如果您想要試試 ChatGPT 如何將搜索句子翻譯為 Elasticsearch DSL 查詢(甚至是 SQL),您可以使用 dsltranslate.com

將所有內容整合起來

我們將 OpenAI 提供的 ChatGPT API 與 Elasticsearch API(用於對映和搜索)結合在一起,開發了一個用於 PHP 的實驗庫

該庫提供了一個具有以下 API 的 search() 函數:

search(string $index, string $prompt, bool $cache = true)

其中,$index 是要使用的索引名稱,$prompt 是以人類語言表達的查詢,而 $bool 是一個可選參數,用於使用緩存(默認情況下啟用)。

 

該函數的運行過程如下圖所示:

輸入為索引和提示(位於左側)。索引用於從Elasticsearch檢索對映(使用get mapping API)。結果是一個JSON格式的對映,用於構建要發送到ChatGPT的查詢字符串,使用以下API代碼。我們使用的是OpenAI的gpt-3.5-turbo模型,它能夠將文本翻譯成程式碼。

從ChatGPT得到的結果包含一個Elasticsearch DSL查詢,我們用它來查詢Elasticsearch。然後將結果返回給用戶。為了查詢Elasticsearch,我們使用了官方的elastic/elasticsearch-php客戶端。

為了優化回應時間並降低使用ChatGPT API的成本,我們使用了一個基於文件的簡單緩存系統。我們使用緩存來:

 

  • 儲存Elasticsearch返回的對映JSON:我們將這個JSON儲存在以索引命名的文件中。這樣可以讓我們在不需要向Elasticsearch進行額外調用的情況下檢索對映資訊。
  • 儲存由ChatGPT生成的Elasticsearch DSL:為了緩存生成的Elasticsearch DSL,我們使用提示的哈希(MD5)來命名緩存文件。這種方法使我們能夠重用先前為相同查詢生成的Elasticsearch DSL,消除了再次調用ChatGPT API的需求。

 

我們還添加了透過getLastQuery()函數以程式化方式檢索Elasticsearch DSL的可能性。

使用金融數據運行實驗

我們使用Elastic Cloud來儲存這裡報告的股票價值。具體來說,我們使用了一個簡單的批量腳本來讀取CSV格式的股票文件,並使用批量API將其發送到Elasticsearch。

 

有關如何設置Elastic Cloud和檢索API密鑰的更多詳細資訊,請閱讀文檔。

 

一旦我們儲存了股票索引,我們就使用了一個簡單的PHP腳本來測試用英文表達的一些查詢。我們使用的腳本是examples/test.php。

 

要執行這個examples/test.php腳本,我們需要設置三個環境變量:

  • OPENAI_API_KEY:OpenAI的API密鑰
  • ELASTIC_CLOUD_ENDPOINT:Elasticsearch實例的URL
  • ELASTIC_CLOUD_API_KEY:Elastic Cloud的API密鑰

 

使用股票對映,我們測試了以下查詢,並記錄了所有的Elasticsearch DSL回應。

Query: Return the first 10 documents of 2017

Result:
{
  "query":{
    "range":{
      "date":{
        "gte":"2017-01-01",
        "lte":"2017-12-31"
      }
    }
  },
  "size":10
}
Query: Return the first 30 names of all the different stock names

Result:
{
  "size":0,
  "aggs":{
    "unique_names":{
      "terms":{
        "field":"name.keyword",
        "size":30
      }
    }
  }
}
Query: Return the max value of the field "high" for each stock in 2015

Result: 
{
  "aggs":{
    "stocks":{
      "terms":{"field":"name.keyword","size":100},
      "aggs":{
        "max_high":{"max":{"field":"high"}}
      }
    }
  },
  "query":{
    "bool":{
      "must":[{
        "range":{
          "date":{
            "gte":"2015-01-01",
            "lt":"2016-01-01"
          }
        }
      }]
    }
  }
}
Query: Return the average value of the field "high" for each stock in 2015

Result:
{
  "size":0,
  "aggs":{
    "stocks":{
      "terms":{
        "field":"name.keyword",
        "size":10000
      },
      "aggs":{
        "2015":{
          "filter":{
            "range":{
              "date":{
                "gte":"2015-01-01",
                "lt":"2016-01-01"
              }
            }
          },
          "aggs":{
            "avg_high":{
              "avg":{
                "field":"high"
              }
            }
          }
        }
      }
    }
  }
}
Query: Return the max value of the field "high" for all the documents with name MON in 2014

Result:

{
  "query":{
    "bool":{
      "must":[
        {
          "match":{
            "name.keyword":"MON"
          }
        },
        {
          "range":{
            "date":{
              "gte":"2014-01-01",
              "lt":"2015-01-01"
            }
          }
        }
      ]
    }
  },
  "size":0,
  "aggs":{
    "max_high":{
      "max":{
        "field":"high"
      }
    }
  }
}

正如您所看到的,結果非常好。最後一篇關於封閉場地和開放場地的差異令人印象深刻! 

 

所有請求均已翻譯為有效的 Elasticsearch DSL 查詢,該查詢根據以自然語言表達的問題是正確的。

 

使用您所說的語言!

ChatGPT 的一個非常好的功能是能夠用不同的語言指定問題。

這意味著您可以使用此程式庫並以不同的自然語言指定查詢,例如義大利語、西班牙語、法語、德語等。

 

這是一個例子:

# English
$result = $chatGPT->search('stocks', 'Return the first 10 documents of 2017');
# Italian
$result = $chatGPT->search('stocks', 'Restituisci i primi 10 documenti del 2017');
# Spanish
$result = $chatGPT->search('stocks', 'Devuelve los 10 primeros documentos de 2017');
# French
$result = $chatGPT->search('stocks', 'Retourner les 10 premiers documents de 2017');
# German
$result = $chatGPT->search('stocks', 'Senden Sie die ersten 10 Dokumente des Jahres 2017 zurück');

先前的所有搜尋都有相同的結果,產生以下 Elasticsearch 查詢(或多或少):

{"size":10,"query":{"range":{"date":{"gte":"2017-01-01","lt":"2018-01-01"}}}}

在這篇文章中,我們介紹了使用ChatGPT將自然語言搜索句子轉換為Elasticsearch DSL查詢的實驗案例。我們開發了一個簡單的PHP庫,使用OpenAI API在幕後進行查詢翻譯,同時提供了緩存系統。

 

實驗的結果很有前景,即使答案的正確性存在限制。儘管如此,我們肯定會進一步研究使用ChatGPT以及其他越來越受歡迎的LLM模型,以自然語言查詢Elasticsearch的可能性。

解決方案產品:

Elasticsearch

Logstash

Kibana

訂閱偉康科技洞察室部落格,掌握最新科技趨勢!

專人協助

由偉康業務人員為您詳細說明偉康的解決方案,以及相關產業經驗。

立即訂閱電子報

掌握最新科技趨勢!