作者:來自 Elastic?Michael Supangkat
了解如何在 Elastic Cloud 中,通過使用 LLM 生成的詞匯,為搜索應用增強自動補全功能,實現更智能、更動態的搜索建議。
自動補全是搜索應用中的一項關鍵功能,它通過在用戶輸入時實時提供建議,顯著提升用戶體驗。傳統上,Elasticsearch 的自動補全功能是通過補全建議器(completion suggester)實現的,它依賴于預定義的詞匯。這種方式需要人工整理建議詞匯,且往往缺乏上下文的相關性。通過調用 OpenAI 的 completion 接口生成 LLM 詞匯,我們可以構建一個更加智能、可擴展且自動化的自動補全功能。
用 LLM 強化你的搜索自動補全功能
在本文中,我們將探討:
- 在 Elasticsearch 中實現自動補全的傳統方法
- 如何通過集成 OpenAI 的 LLM 提升補全建議的質量
- 如何結合 Elastic Cloud 的 Ingest Pipeline 和 Inference Endpoint 實現可擴展的方案
Elasticsearch 傳統的自動補全方式
在 Elasticsearch 中構建自動補全的常見做法是,在索引映射中定義一個補全字段(completion field)。這樣 Elasticsearch 就可以基于預定義的詞匯提供建議。
這種方法實現起來非常直接,尤其是當你的數據集相對靜態,并且已經準備好了完整的建議詞列表時。
實現步驟
- 創建一個包含 completion 字段的索引。
- 手動整理并維護建議詞列表,并將其存儲到索引中。
- 使用補全建議器(completion suggester)查詢,獲取相關建議。
示例:傳統自動補全設置
首先,創建一個名為 products_test 的索引。在這個索引中,我們定義一個名為 suggest 的字段,類型為 completion,該字段專門用于快速自動補全建議。
PUT /products_test
{"mappings": {"properties": {"suggest": { "type": "completion" }}}
}
向 products_test 索引中插入一個測試文檔。suggest 字段存儲多個補全建議詞。
PUT /products_test/_doc/1
{"suggest": ["MacBook Air M2", "Apple Laptop", "Lightweight Laptop"]
}
最后,我們使用?completion suggester?查詢來搜索以 “MacB” 開頭的建議詞。
前綴 “MacB” 將匹配到 “MacBook Air M2”。
POST /products_test/_search
{"suggest": {"search-suggestion": {"prefix": "MacB","completion": { "field": "suggest" }}}
}
suggest
部分包含匹配到的建議詞。
options
包含一個匹配建議的數組,其中 "text": "MacBook Air M2"
是最優先的建議結果。
"took": 2,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 0,"relation": "eq"},"max_score": null,"hits": []},"suggest": {"search-suggestion": [{"text": "MacB","offset": 0,"length": 4,"options": [{"text": "MacBook Air M2","_index": "products_test","_id": "1","_score": 1,"_source": {"suggest": ["MacBook Air M2","Apple Laptop","Lightweight Laptop"]}}]}]}
}
雖然這種方法有效,但它依賴于手動整理和不斷更新建議詞匯,且無法動態適應新產品或描述的變化。
更多有個 autocomplete 的文章,請在 “Elastic:開發者上手指南”?里查找 “autocomplete"。
用 OpenAI LLM 增強自動補全功能
在某些場景中,數據集會頻繁變化,這就需要你不斷更新有效的建議詞列表。當出現新的產品、名稱或術語時,你必須手動將它們添加到建議列表中。
這正是 LLM 發揮作用的地方 —— 它可以基于真實世界的知識和最新數據,動態生成相關補全詞匯。
通過調用 OpenAI 的?completion?接口,我們可以基于產品名稱和描述動態生成自動補全建議。這帶來的好處包括:
- 自動生成同義詞和相關術語
- 基于產品描述的上下文感知建議
- 無需手動維護詞表,系統更加可擴展
基于 LLM 的自動補全實現步驟
- 使用 OpenAI 的 completion API 創建一個推理端點(Inference Endpoint)。
- 配置一個 Elasticsearch ingest pipeline,在 pipeline 中使用腳本處理器(script processor),調用 OpenAI 接口并使用預定義 prompt 獲取補全建議。
- 將生成的建議詞存儲到帶有?completion?字段的 Elasticsearch 索引中。
- 使用搜索請求獲取動態補全結果。
以上所有步驟都可以通過在?Kibana Dev Tools?中逐步復制粘貼 API 請求完成。
在本示例中,我們使用的是?gpt-4o-mini?模型。你需要提前獲取你的 OpenAI API 密鑰。登錄你的 OpenAI 賬號,然后訪問 https://platform.openai.com/api-keys,創建一個新的密鑰或使用已有密鑰。
創建推理端點(Inference Endpoint)
首先,我們需要創建一個推理端點。
這個端點讓我們可以通過 API 與機器學習模型(這里是 OpenAI)無縫交互,同時還能保持在 Elastic 的界面中進行操作。
PUT _inference/completion/openai-completion
{"service": "openai","service_settings": {"api_key": "<insert_your_api_key>","model_id": "gpt-4o-mini"}
}
設置 Elasticsearch Ingest Pipeline
通過設置一個 ingest pipeline,我們可以在數據索引時進行處理。在這個案例中,pipeline 被命名為 autocomplete-LLM-pipeline,并包含以下內容:
- 腳本處理器(script processor):定義我們發送給 OpenAI 的 prompt,以獲取建議詞列表。產品名稱和產品描述作為動態值包含在 prompt 中。
- 推理處理器(inference processor):引用我們之前創建的 OpenAI 推理端點。該處理器接收來自腳本處理器的 prompt 作為輸入,將其發送到 LLM 模型,并將結果存儲在一個名為 results 的輸出字段中。
- 分割處理器(split processor):將 LLM 輸出的文本結果分割成逗號分隔的數組,以適應 suggest 類型字段的格式。
- 2 個刪除處理器(remove processors):在填充 suggest 字段后,刪除 prompt 和 results 字段。
PUT _ingest/pipeline/autocomplete-LLM-pipeline
{"processors": [{"script": {"source": "\n ctx.prompt = 'Based on the following product name and product description, create relevant autocomplete suggestion terms from the following product, including the exact product name itself as the first term, synonyms of the product category, and keywords which might commonly be used when searching the following product:' + '\\\\n Product Name:\\\\n' + ctx.ProductName + '\\\\nProduct Description:\\\\n' + ctx.Description + '\\\\nJust include the suggestion terms in the response, as an array encapsulated in double quotes and separated by commas without any prefix or numbering'\n "}},{"inference": {"model_id": "openai-completion","input_output": {"input_field": "prompt","output_field": "results"}}},{"split": {"field": "results","separator": ",","target_field": "suggest"}},{"remove": {"field": "prompt"}},{"remove": {"field": "results"}}]
}
為了能讓讓大家把上面的 prompt 看得更清楚,我們在下面重新粘貼:
ctx.prompt = 'Based on the following product name and product description, create relevant autocomplete suggestion terms from the following product, including the exact product name itself as the first term, synonyms of the product category, and keywords which might commonly be used when searching the following product:' + '\\\\n Product Name:\\\\n' + ctx.ProductName + '\\\\nProduct Description:\\\\n' + ctx.Description + '\\\\nJust include the suggestion terms in the response, as an array encapsulated in double quotes and separated by commas without any prefix or numbering'\n
更多有關在 ingest pipeline 里調用 LLM 的示例,我們可以閱讀 “分面搜索:利用人工智能改善搜索范圍和結果”。
索引示例文檔
在這個示例中,我們使用 documents API 通過開發工具手動將文檔索引到一個臨時索引中,名為 'products'。
需要注意的是,這并不是我們最終用于自動補全的索引。
PUT products/_doc/1
{"ProductName": "MacBook Air M2","Description": "The MacBook Air M2 is a powerful, ultra-portable laptop designed to deliver exceptional performance, all while maintaining an ultra-slim profile. Powered by Apple’s latest M2 chip, this lightweight machine is perfect for both work and play, combining top-tier performance with impressive battery life"
}
創建帶有 Completion 類型映射的索引
現在,我們將創建實際用于自動補全的索引,該索引包含一個名為 suggest 的 completion 類型字段。
PUT products_with_suggestion
{"mappings": {"properties": {"suggest": { "type": "completion" } }}
}
通過 Ingest Pipeline 重新索引文檔到指定索引
在這一步中,我們將之前創建的 products 索引中的數據重新索引到實際的自動補全索引 products_with_suggestion,并通過 autocomplete-LLM-pipeline 進行處理。
該 pipeline 將處理來自原始索引的示例文檔,并將結果填充到目標索引中的 suggest 自動補全字段。
POST _reindex?slices=auto&wait_for_completion=false
{"source": {"index": "products"},"dest": {"index": "products_with_suggestion","pipeline": "autocomplete-LLM-pipeline"}
}
展示自動補全建議
如下所示,新的索引 products_with_suggestion 現在包含一個名為 suggest 的新字段,該字段包含由 OpenAI LLM 生成的詞匯或同義詞數組。
你可以運行以下請求來檢查:
GET products_with_suggestion/_search
結果:
{"hits": [{"ProductName": "MacBook Air M2","Description": "The MacBook Air M2 is a powerful, ultra-portable laptop designed to deliver exceptional performance, all while maintaining an ultra-slim profile. Powered by Apple’s latest M2 chip, this lightweight machine is perfect for both work and play, combining top-tier performance with impressive battery life","suggest": ["MacBook Air M2","ultra-portable laptop","lightweight laptop","performance laptop","Apple laptop","M2 chip laptop","thin laptop","best laptop for work","laptop with long battery life","powerful lightweight laptop","Apple MacBook","MacBook Air","laptop for students","portable computer","laptop for professionals"]},{"ProductName": "DKNY Unisex Black & Grey Printed Medium Trolley Bag","Description": "Black and grey printed medium trolley bag, secured with a TSA lockOne handle on the top and one on the side, has a trolley with a retractable handle on the top and four corner mounted inline skate wheelsOne main zip compartment, zip lining, two compression straps with click clasps, one zip compartment on the flap with three zip pocketsWarranty: 5 yearsWarranty provided by Brand Owner / Manufacturer","suggest": ["DKNY Unisex Black & Grey Printed Medium Trolley Bag","medium trolley bag","travel bag","luggage","roller bag","printed suitcase","black and grey suitcase","trolley luggage","travel trolley","carry-on trolley","retractable handle bag","inline skate wheels bag","TSA lock luggage","zip compartment suitcase","compression straps bag","soft sided luggage","durable travel bag","wheeled duffel bag","luggage with warranty","brand name luggage"]}]
}
請注意,即使使用相同的 prompt,LLM 生成的詞匯也不總是相同的。你可以檢查生成的詞匯,看看它們是否適合你的搜索用例。如果不符合需求,你可以選擇修改腳本處理器中的 prompt,以獲得更可預測和一致的建議詞匯。
測試自動補全搜索
現在,我們可以使用 completion suggester 查詢來測試自動補全功能。下面的示例還包括一個 fuzzy 參數,通過處理搜索查詢中的小拼寫錯誤來提升用戶體驗。你可以在開發工具中執行以下查詢,并查看建議結果。
POST /products_with_suggestion/_search
{"suggest": {"search-suggestion": {"prefix": "lugg","completion": {"field": "suggest","fuzzy": { "fuzziness": 1 }}}}
}
為了可視化自動補全結果,我實現了一個簡單的搜索欄,它通過客戶端在 Elastic Cloud 中針對自動補全索引執行查詢。隨著用戶輸入,搜索會基于 LLM 生成的建議列表中的詞匯返回結果。
通過 OpenAI 推理集成進行擴展
通過在 Elastic Cloud 中將 OpenAI 的 completion API 作為推理端點,我們可以高效地擴展這個解決方案:
- 推理端點 允許自動化和可擴展的 LLM 建議生成,而無需手動創建和維護建議詞匯列表。
- Ingest Pipeline 確保在索引過程中實時豐富數據。
- 腳本處理器(Script Processor)在 ingest pipeline 中允許輕松編輯 prompt,以便在需要時更具體地定制建議列表的內容。
- Pipeline 執行 還可以直接配置為索引模板,以進一步實現自動化。這使得隨著新產品的添加,建議列表可以動態生成。
在成本效率方面,模型只在索引過程中調用,這意味著它的使用隨著處理的文檔數量而擴展,而不是搜索量。因此,預計用戶增長或搜索活動增加時,這種方法比在搜索時運行模型節省更多的成本。
結論
傳統的自動補全依賴于手動定義的詞匯,這既有限制又勞動密集。通過利用 OpenAI 生成的 LLM 建議,我們可以選擇自動化并增強自動補全功能,提升搜索相關性和用戶體驗。此外,使用 Elastic 的 ingest pipeline 和推理端點集成,確保了自動化和可擴展的自動補全系統。
總的來說,如果你的搜索用例需要一套非常具體的建議,且是從一個經過精心維護和整理的列表中提取的,按照本文第一部分的描述,通過 API 批量導入建議詞匯仍然是一個很好的高效選擇。如果管理和更新建議列表是一個痛點,那么基于 LLM 的補全系統通過自動生成上下文相關的建議,省去了手動輸入的麻煩。
Elasticsearch 提供了與行業領先的生成 AI 工具和供應商的本地集成。可以查看我們的網絡研討會,了解如何超越 RAG 基礎,或構建適合生產的 Elastic 向量數據庫應用。
為了為你的用例構建最佳的搜索解決方案,立即開始免費云試用,或嘗試在本地機器上運行 Elastic。
原文:How to build autocomplete feature on search application automatically using LLM generated terms - Elasticsearch Labs