1. 總覽
在本程式碼研究室中,您將瞭解如何部署使用 Gemini 的 LangChain 應用程式,以便您透過 Cloud Run 發布說明詢問問題。
以下舉例說明應用程式的運作方式:如果詢問「我可以在 Cloud Run 中將 Cloud Storage 值區做為磁碟區嗎?」這個問題,應用程式會傳回「是,自 2024 年 1 月 19 日以來」或類似回應。
為了傳回具體回應,應用程式會先擷取與問題相似的 Cloud Run 發布說明,然後向 Gemini 提示問題和發布說明。(這就是通常稱為 RAG 的模式)。以下是應用程式架構的圖表:
2. 設定和需求
首先,請確認您的開發環境設定正確無誤。
- 您需要建立 Google Cloud 專案,才能部署應用程式所需的資源。
- 如要部署應用程式,您的本機電腦需要安裝 gcloud、經過驗證,並設定為使用專案。
gcloud auth login
gcloud config set project
- 如果您想在本機上執行應用程式 (這是我建議的做法),請務必正確設定應用程式預設憑證,包括設定配額專案。
gcloud auth application-default login
gcloud auth application-default set-quota-project
- 您也必須安裝下列軟體:
- Python (需要 3.11 以上版本)
- LangChain CLI
- poetry 可用於依附元件管理
- pipx:在隔離的虛擬環境中安裝及執行 LangChain CLI 和 poetry
以下說明如何安裝本教學課程所需的工具。
Cloud Workstations
您也可以在 Google Cloud 上使用 Cloud Workstations,而非本機電腦。請注意,截至 2024 年 4 月,該服務執行的 Python 版本低於 3.11,因此您可能需要先升級 Python,再開始使用。
啟用 Cloud API
首先,請執行下列指令,確認已設定要使用的正確 Google Cloud 專案:
gcloud config list project
如果未顯示正確的專案,請輸入下列指令設定專案:
gcloud config set project <PROJECT_ID>
現在啟用下列 API:
gcloud services enable \ bigquery.googleapis.com \ sqladmin.googleapis.com \ aiplatform.googleapis.com \ cloudresourcemanager.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ run.googleapis.com \ secretmanager.googleapis.com
選擇一個區域
Google Cloud 在全球多個地區提供服務,您必須選擇其中一個地區來部署本實驗室的資源。在 Shell 中將區域設為環境變數 (後續指令會使用這個變數):
export REGION=us-central1
3. 建立向量資料庫例項
這款應用程式的主要功能是擷取與使用者問題相關的發布說明。舉例來說,如果您想詢問 Cloud Storage 相關問題,請在提示中加入下列版本說明:
您可以使用文字嵌入和向量資料庫,找出語意相似的版本資訊。
我將示範如何在 Cloud SQL 上使用 PostgreSQL 做為向量資料庫。建立新的 Cloud SQL 執行個體需要一些時間,因此我們現在就來建立。
gcloud sql instances create sql-instance \ --database-version POSTGRES_14 \ --tier db-f1-micro \ --region $REGION
您可以讓這項指令執行,並繼續執行後續步驟。您必須在某個時間點建立資料庫並新增使用者,但現在請不要浪費時間等待旋轉圖示。
PostgreSQL 是關聯資料庫伺服器,每個新的 Cloud SQL 執行個體都會預設安裝 pgvector 擴充功能,也就是說,您也可以將其用作向量資料庫。
4. Scaffold the LangChain 應用程式
如要繼續操作,您必須先安裝 LangChain CLI,並使用 Poetry 管理依附元件。以下說明如何使用 pipx 安裝:
pipx install langchain-cli poetry
請使用下列指令建立 LangChain 應用程式的專案架構。系統提示時,請將資料夾命名為 run-rag
,然後按下 Enter 鍵略過安裝套件:
langchain app new
切換至 run-rag
目錄並安裝依附元件
poetry install
您剛剛建立了 LangServe 應用程式。LangServe 會在 LangChain 鏈結中包裝 FastAPI。內建的遊樂場可讓您輕鬆傳送提示並檢查結果,包括所有中介步驟。建議您開啟編輯器中的 run-rag
資料夾,並瀏覽當中的內容。
5. 建立索引工作
開始整合網頁應用程式之前,請先確認 Cloud Run 發布說明已在 Cloud SQL 資料庫中建立索引。在本節中,您將建立索引工作,執行以下操作:
索引工作會擷取發布說明,並使用文字嵌入模型將其轉換為向量,然後儲存在向量資料庫中。這可讓您根據語意意義,快速搜尋類似的發布說明。
在 run-rag/app
資料夾中,建立含有下列內容的 indexer.py
檔案:
import os
from google.cloud.sql.connector import Connector
import pg8000
from langchain_community.vectorstores.pgvector import PGVector
from langchain_google_vertexai import VertexAIEmbeddings
from google.cloud import bigquery
# Retrieve all Cloud Run release notes from BigQuery
client = bigquery.Client()
query = """
SELECT
CONCAT(FORMAT_DATE("%B %d, %Y", published_at), ": ", description) AS release_note
FROM `bigquery-public-data.google_cloud_release_notes.release_notes`
WHERE product_name= "Cloud Run"
ORDER BY published_at DESC
"""
rows = client.query(query)
print(f"Number of release notes retrieved: {rows.result().total_rows}")
# Set up a PGVector instance
connector = Connector()
def getconn() -> pg8000.dbapi.Connection:
conn: pg8000.dbapi.Connection = connector.connect(
os.getenv("DB_INSTANCE_NAME", ""),
"pg8000",
user=os.getenv("DB_USER", ""),
password=os.getenv("DB_PASS", ""),
db=os.getenv("DB_NAME", ""),
)
return conn
store = PGVector(
connection_string="postgresql+pg8000://",
use_jsonb=True,
engine_args=dict(
creator=getconn,
),
embedding_function=VertexAIEmbeddings(
model_name="textembedding-gecko@003"
),
pre_delete_collection=True
)
# Save all release notes into the Cloud SQL database
texts = list(row["release_note"] for row in rows)
ids = store.add_texts(texts)
print(f"Done saving: {len(ids)} release notes")
新增必要的依附元件:
poetry add \ "cloud-sql-python-connector[pg8000]" \ langchain-google-vertexai==1.0.5 \ langchain-community==0.2.5 \ pgvector
建立資料庫和使用者
在 Cloud SQL 執行個體 sql-instance
上建立資料庫 release-notes
:
gcloud sql databases create release-notes --instance sql-instance
建立名為 app
的資料庫使用者:
gcloud sql users create app --instance sql-instance --password "myprecious"
部署及執行索引工作
接著部署及執行工作:
DB_INSTANCE_NAME=$(gcloud sql instances describe sql-instance --format="value(connectionName)") gcloud run jobs deploy indexer \ --source . \ --command python \ --args app/indexer.py \ --set-env-vars=DB_INSTANCE_NAME=$DB_INSTANCE_NAME \ --set-env-vars=DB_USER=app \ --set-env-vars=DB_NAME=release-notes \ --set-env-vars=DB_PASS=myprecious \ --region=$REGION \ --execute-now
這是一條長指令,讓我們來看看發生了什麼事:
第一個指令會擷取連線名稱 (格式為 project:region:instance
的不重複 ID),並將其設為環境變數 DB_INSTANCE_NAME
。
第二個指令會部署 Cloud Run 工作。旗標的作用如下:
--source .
:指定工作原始碼位於目前工作目錄 (您執行指令的目錄)。--command python
:設定要在容器中執行的指令。在本例中,我們要執行 Python。--args app/indexer.py
:提供 Python 指令的引數。這會指示它在應用程式目錄中執行指令碼 indexer.py。--set-env-vars
:設定 Python 指令碼在執行期間可存取的環境變數。--region=$REGION
:指定要部署工作所在的區域。--execute-now
:指示 Cloud Run 在工作部署後立即啟動。
如要確認工作是否順利完成,您可以執行下列操作:
- 透過網頁控制台讀取工作執行記錄。系統應會回報「Done saving: xxx release notes」(xxx 是已儲存的版本資訊數量)。
- 您也可以前往網路控制台的 Cloud SQL 執行個體,並使用 Cloud SQL Studio 查詢
langchain_pg_embedding
資料表中的記錄數量。
6. 編寫網頁應用程式
在編輯器中開啟 app/server.py
檔案。您會看到一行內容如下:
# Edit this to add the chain you want to add
將該註解替換為下列程式碼片段:
# (1) Initialize VectorStore
connector = Connector()
def getconn() -> pg8000.dbapi.Connection:
conn: pg8000.dbapi.Connection = connector.connect(
os.getenv("DB_INSTANCE_NAME", ""),
"pg8000",
user=os.getenv("DB_USER", ""),
password=os.getenv("DB_PASS", ""),
db=os.getenv("DB_NAME", ""),
)
return conn
vectorstore = PGVector(
connection_string="postgresql+pg8000://",
use_jsonb=True,
engine_args=dict(
creator=getconn,
),
embedding_function=VertexAIEmbeddings(
model_name="textembedding-gecko@003"
)
)
# (2) Build retriever
def concatenate_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
notes_retriever = vectorstore.as_retriever() | concatenate_docs
# (3) Create prompt template
prompt_template = PromptTemplate.from_template(
"""You are a Cloud Run expert answering questions.
Use the retrieved release notes to answer questions
Give a concise answer, and if you are unsure of the answer, just say so.
Release notes: {notes}
Here is your question: {query}
Your answer: """)
# (4) Initialize LLM
llm = VertexAI(
model_name="gemini-1.0-pro-001",
temperature=0.2,
max_output_tokens=100,
top_k=40,
top_p=0.95
)
# (5) Chain everything together
chain = (
RunnableParallel({
"notes": notes_retriever,
"query": RunnablePassthrough()
})
| prompt_template
| llm
| StrOutputParser()
)
您也需要新增下列匯入項目:
import pg8000
import os
from google.cloud.sql.connector import Connector
from langchain_google_vertexai import VertexAI
from langchain_google_vertexai import VertexAIEmbeddings
from langchain_core.runnables import RunnablePassthrough, RunnableParallel
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_community.vectorstores.pgvector import PGVector
最後,將「NotImplemented」這一行改為:
# add_routes(app, NotImplemented)
add_routes(app, chain)
7. 將網頁應用程式部署至 Cloud Run
在 run-rag
目錄中,使用下列指令將應用程式部署至 Cloud Run:
DB_INSTANCE_NAME=$(gcloud sql instances describe sql-instance --format="value(connectionName)") gcloud run deploy run-rag \ --source . \ --set-env-vars=DB_INSTANCE_NAME=$DB_INSTANCE_NAME \ --set-env-vars=DB_USER=app \ --set-env-vars=DB_NAME=release-notes \ --set-env-vars=DB_PASS=myprecious \ --region=$REGION \ --allow-unauthenticated
這個指令會執行以下操作:
- 將原始碼上傳至 Cloud Build
- 執行 docker 建構作業。
- 將產生的容器映像檔推送至 Artifact Registry。
- 使用容器映像檔建立 Cloud Run 服務。
指令執行完成後,系統會在 run.app 網域上列出 HTTPS 網址。這是新 Cloud Run 服務的公開網址
8. 探索遊樂場
開啟 Cloud Run 服務網址,然後前往 /playground
。這會產生文字欄位您可以使用這項功能,針對 Cloud Run 版本資訊提出問題,例如:
9. 恭喜
您已成功在 Cloud Run 上建構及部署 LangChain 應用程式。非常好!
以下是關鍵概念:
- 使用 LangChain 架構建構檢索增強生成 (RAG) 應用程式。
- 使用 Cloud SQL 上的 PostgreSQL 做為向量資料庫,搭配 Cloud SQL 預設安裝的 pgvector。
- 以 Cloud Run 工作形式執行較長時間的索引工作,並以 Cloud Run 服務形式執行網頁應用程式。
- 使用 LangServe 在 FastAPI 應用程式中包裝 LangChain 鏈結,提供方便的介面,以便與 RAG 應用程式互動。
清除所用資源
如要避免系統向您的 Google Cloud Platform 帳戶收取在本教學課程中使用資源的相關費用:
- 前往 Cloud Console 中的「管理資源」頁面。
- 在專案清單中選取專案,然後按一下「刪除」。
- 在對話方塊中輸入專案 ID,然後按一下「Shut down」(關閉) 即可刪除專案。
如果您想保留專案,請務必刪除下列資源:
- Cloud SQL 執行個體
- Cloud Run 服務
- Cloud Run 工作