作者:肯夢
本文將演示如何使用事件匯流排(EventBridge),向量檢索服務(DashVector),函式計算(FunctionCompute)結合靈積模型服務 [ 1] 上的 Embedding API [ 2] ,來從 0 到 1 構建基於文字索引的構建+向量檢索基礎上的語義搜尋能力。具體來說,我們將基於 OSS 文字文件動態插入資料,進行實時的文字語義搜尋,查詢最相似的相關內容。
本文中將用到事件匯流排(EventBridge),它是阿里雲提供的一款無伺服器事件匯流排服務,支援阿里雲服務、自定義應用、SaaS 應用以標準化、中心化的方式接入,並能夠以標準化的 CloudEvents 1.0 協議在這些應用之間路由事件,幫助您輕鬆構建松耦合、分散式的事件驅動架構。
RAG 背景概述
大語言模型(LLM)作為自然語言處理領域的核心技術,具有豐富的自然語言處理能力。但其訓練語料庫具有一定的侷限性,一般由普適知識、常識性知識,如維基百科、新聞、小說,和各種領域的專業知識組成。導致 LLM 在處理特定領域的知識表示和應用時存在一定的侷限性,特別對於垂直領域內,或者企業內部等私域專屬知識。
實現專屬領域的知識問答的關鍵,在於如何讓 LLM 能夠理解並獲取存在於其訓練知識範圍外的特定領域知識。同時可以透過特定 Prompt 構造,提示 LLM 在回答特定領域問題的時候,理解意圖並根據注入的領域知識來做出回答。在通常情況下,使用者的提問是完整的句子,而不像搜尋引擎只輸入幾個關鍵字。這種情況下,直接使用關鍵字與企業知識庫進行匹配的效果往往不太理想,同時長句本身還涉及分詞、權重等處理。相比之下,倘若我們把提問的文字,和知識庫的內容,都先轉化為高質量向量,再透過向量檢索將匹配過程轉化為語義搜尋,那麼提取相關知識點就會變得簡單而高效。
本文將介紹如何構建一個完全動態的 RAG 入庫方案,透過 EventBridge 拉取 OSS 非結構化資料,同時將資料投遞至 DashVector 向量資料庫,從而實現完整的 RAG Ingestion 流程。
流程概述
資料整合(Ingestion)
資料檢索(Search)
操作流程
前提條件
- DashScope 控制檯開通靈積模型服務,並獲得 API-KEY 的獲取與配置。
- 開通 DashVector 向量檢索服務,並獲得 API-KEY 的獲取與配置。
- 開通 OSS 服務。
- 開通 FC 服務。
- 開通 EventBridge 服務。
開通靈積模型服務
- 點選進入 DashScope 控制檯 [ 3] ,開通靈積相關服務
- 點選進入“API-KEY”管理,獲取相關 KEY 資訊
開通 DashVector 服務
- 若第一次配置,請點選“新建 DashVector Cluster [ 4] ”,跳轉建立新的 Cluster;點選“建立免費 Cluster”快速體驗建立向量資料庫
2. 選擇“立即購買”
3. 點選建立“Collection”
4. 填寫緯度為“1536”,距離度量方式“Cosine”,點選“確認”
5. 點選“API-KEY 管理”,獲取 DashVector 的 API KEY
建立 Ingestion 資料整合任務
1.1 進入 EventBridge 控制檯 [ 5]
1.2 配置 OSS 源
- OSS Bucket:選擇空白儲存桶實驗,若無請自行建立;
- OSS 字首:該項可根據訴求填寫,若無字首 EB 將拉取整個 Bucket 內容;本次演示不配置;
- 文件載入:目前支援解析 TextLoder 作為文件載入器;
- 載入模式:“單文件載入”單個檔案作為一條資料載入,“分塊載入”按照分隔符載入資料;本次演示使用單文件載入。
1.3 配置過濾
可根據訴求新增過濾規則,本次演示使用“匹配全部事件”。
1.4 配置轉換
轉換部分主要是將原始資料轉成向量化資料,為投遞至 DashVector 做資料準備。
函式程式碼如下,函式環境為 Python 3.10:
# -*- coding: utf-8 -*-
import os
import ast
import copy
import json
import logging
import dashscope
from dashscope import TextEmbedding
from http import HTTPStatus
logger = logging.getLogger()
logger.setLevel(level=logging.INFO)
dashscope.api_key='Your-API-KEY'
def handler(event, context):
evt = json.loads(event)
evtinput = evt['data']
resp = dashscope.TextEmbedding.call(
model=dashscope.TextEmbedding.Models.text_embedding_v1,
api_key=os.getenv('DASHSCOPE_API_KEY'),
input= evtinput )
if resp.status_code == HTTPStatus.OK:
print(resp)
else:
print(resp)
return resp
🔔 注意: 需手動安裝相關函式環境,相關文件參考《為函式安裝第三方依賴》 [ 6] 。
pip3 install dashvector dashscope -t .
返回樣例:
{
"code": "",
"message": "",
"output": {
"embeddings": [
{
"embedding": [
-2.192838430404663,
-0.703125,
... ...
-0.8980143070220947,
-0.9130208492279053,
-0.520526111125946,
-0.47154948115348816
],
"text_index": 0
}
]
},
"request_id": "e9f9a555-85f2-9d15-ada8-133af54352b8",
"status_code": 200,
"usage": {
"total_tokens": 3
}
}
1.5 配置向量資料庫 Dashvector
選擇建立好的向量資料庫。
- 資料對映:選擇 Upsert 方式插入;
- 向量:填寫上游 Dashscope 的 TextEmbedding 投遞的向量資訊 $.output. embeddings[0].embedding;
- 鑑權配置:獲取的 DashVector API-KEY 引數。
建立 Search 資料檢索任務
在進行資料檢索時,需要首先對資料進行 embedding,然後將 embedding 後的向量值與資料庫值做檢索排序。最後填寫 prompt 模版,透過自然語言理解和語義分析,理解資料檢索意圖。
該任務可以部署在雲端函式計算,或者直接在本地環境執行;首先,我們建立 embedding.py,將需要檢索的問題進行文字向量化,程式碼如下所示:
embedding.py
import os
import dashscope
from dashscope import TextEmbedding
def generate_embeddings(news):
rsp = TextEmbedding.call(
model=TextEmbedding.Models.text_embedding_v1,
input=news
)
embeddings = [record['embedding'] for record in rsp.output['embeddings']]
return embeddings if isinstance(news, list) else embeddings[0]
if __name__ == '__main__':
dashscope.api_key = '{your-dashscope-api-key}'
然後,建立 search.py 檔案,並將如下示例程式碼複製到 search.py 檔案中,透過 DashVector 的向量檢索能力來檢索相似度的最高的內容。search.py
from dashvector import Client
from embedding import generate_embeddings
def search_relevant_news(question):
# 初始化 dashvector client
client = Client(
api_key='{your-dashvector-api-key}',
endpoint='{your-dashvector-cluster-endpoint}'
)
# 獲取存入的集合
collection = client.get('news_embedings')
assert collection
# 向量檢索:指定 topk = 1
rsp = collection.query(generate_embeddings(question), output_fields=['raw'],
topk=1)
assert rsp
return rsp.output[0].fields['raw']
建立 answer.py 檔案,我們就可以按照特定的模板作為 prompt 向 LLM 發起提問了,在這裡我們選用的 LLM 是通義千問(qwen-turbo),程式碼示例如下:
answer.py
from dashscope import Generation
def answer_question(question, context):
prompt = f'''請基於```內的內容回答問題。"
```
{context}
```
我的問題是:{question}。
'''
rsp = Generation.call(model='qwen-turbo', prompt=prompt)
return rsp.output.text
最後,建立 run.py 檔案,並將如下示例程式碼複製到 run.py 檔案中,並最終執行 run.py 檔案。(驗證時,可在繫結的 OSS Bucket 上傳需要被檢索的知識庫資訊。)
import dashscope
from search import search_relevant_news
from answer import answer_question
if __name__ == '__main__':
dashscope.api_key = '{your-dashscope-api-key}'
question = 'EventBridge 是什麼,它有哪些能力?'
context = search_relevant_news(question)
answer = answer_question(question, context)
print(f'question: {question}\n' f'answer: {answer}')
總結
從本文的範例中,我們可以比較方便的使用 EventBridge 提供的 OSS To DashVector 離線資料流匯入能力,開箱即用的構建強大向量檢索服務能力,這些能力和各個 AI 模型結合,能夠衍生多樣的 AI 應用的可能。同樣,Transform 部分使用了函式計算能力,可以更靈活的制定想要的 Split 切分演算法,提供更靈活且具備生產力的 RAG 方案。
相關連結:
[1] 靈積模型服務
https://dashscope.aliyun.com/
[2] Embedding API
https://help.aliyun.com/zh/dashscope/developer-reference/text...
[3] DashScope 控制檯
https://account.aliyun.com/login/login.htm?oauth_callback=htt...
[4] 新建 DashVector Cluster
https://account.aliyun.com/login/login.htm?oauth_callback=htt...
[5] EventBridge 控制檯
https://account.aliyun.com/login/login.htm?oauth_callback=htt...
[6] 《為函式安裝第三方依賴》
https://help.aliyun.com/zh/functioncompute/fc-3-0/user-guide/...