1. 概览
在此 Codelab 中,您将学习如何部署使用 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 和诗歌
以下博文可帮助您开始安装此演示文稿所需的工具。
Cloud Workstations
您还可以使用 Google Cloud 上的 Cloud Workstations,而不是本地机器。请注意,自 2024 年 4 月起,该服务将运行低于 3.11 的 Python 版本,因此您可能需要先升级 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. 为 LangChain 应用搭建框架
如需继续,您需要安装 LangChain CLI 并使用 poetry 来管理依赖项。以下是使用 pipx 安装这些软件的方法:
pipx install langchain-cli poetry
使用以下命令为 LangChain 应用创建框架。当系统询问时,将文件夹命名为 run-rag
,并按 Enter 键跳过安装软件包:
langchain app new
切换到 run-rag
目录并安装依赖项
poetry install
您刚刚创建了一个 LangServe 应用。LangServe 会将 FastAPI 封装在 LangChain 链中。它内置了一个 Playground,可让您轻松发送提示并检查结果,包括所有中间步骤。建议您在编辑器中打开文件夹 run-rag
,然后浏览其中的内容。
5. 创建索引编制作业
在开始组合 Web 应用之前,我们先确保 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 在作业部署后立即启动作业。
如需验证作业是否已成功完成,您可以执行以下操作:
- 通过 Web 控制台读取作业执行日志。它应报告“已保存:xxx 个版本说明”(其中 xxx 是已保存的版本说明数量)。
- 您还可以在 Web 控制台中前往 Cloud SQL 实例,然后使用 Cloud SQL Studio 查询
langchain_pg_embedding
表中的记录数量。
6. 编写 Web 应用
在编辑器中打开 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. 将 Web 应用部署到 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 build。
- 将生成的容器映像推送到 Artifact Registry。
- 使用容器映像创建 Cloud Run 服务。
命令运行完毕后,系统会列出 run.app 网域中的 HTTPS 网址。这是新 Cloud Run 服务的公开网址
8. 探索 Playground
打开 Cloud Run 服务网址并导航到 /playground
。它会调出一个文本字段。您可以使用它就 Cloud Run 版本说明提出问题,如下所示:
9. 恭喜
您已在 Cloud Run 上成功构建并部署了 LangChain 应用。非常棒!
以下是关键概念:
- 使用 LangChain 框架构建检索增强生成 (RAG) 应用。
- 在 Cloud SQL 上使用 PostgreSQL 作为矢量数据库,并搭配使用 Cloud SQL 上默认安装的 pgvector。
- 将运行时间较长的索引编制作业作为 Cloud Run 作业运行,并将 Web 应用作为 Cloud Run 服务运行。
- 使用 LangServe 将 LangChain 链封装在 FastAPI 应用程序中,提供与您的 RAG 应用程序进行交互的便捷接口。
清理
为避免因本教程中使用的资源导致您的 Google Cloud Platform 账号产生费用,请执行以下操作:
- 在 Cloud Console 中,转到“管理资源”页面。
- 在项目列表中,选择您的项目,然后点击“删除”。
- 在对话框中输入项目 ID,然后点击“关停”以删除项目。
如果您想保留该项目,请务必删除以下资源:
- Cloud SQL 实例
- Cloud Run 服务
- Cloud Run 作业