1. Panoramica
In questo lab di codice, imparerai a eseguire il deployment di un'app LangChain che utilizza Gemini per consentirti di porre domande sulle note di rilascio di Cloud Run.
Ecco un esempio di come funziona l'app: se chiedi "Posso montare un bucket Cloud Storage come volume in Cloud Run?", l'app risponde "Sì, dal 19 gennaio 2024" o qualcosa di simile.
Per restituire risposte fondate, l'app recupera prima le note di rilascio di Cloud Run simili alla domanda, quindi chiede a Gemini sia la domanda sia le note di rilascio. Si tratta di un pattern comunemente noto come RAG. Ecco un diagramma che mostra l'architettura dell'app:
2. Configurazione e requisiti
Innanzitutto, assicurati che l'ambiente di sviluppo sia configurato correttamente.
- Per eseguire il deployment delle risorse necessarie per l'app è necessario un progetto Google Cloud.
- Per eseguire il deployment dell'app, devi avere installato gcloud sulla tua macchina locale, autenticato e configurato per utilizzare il progetto.
gcloud auth login
gcloud config set project
- Se vuoi eseguire l'applicazione sulla tua macchina locale, cosa che consiglio, devi assicurarti che le credenziali predefinite dell'applicazione siano configurate correttamente, inclusa l'impostazione del progetto quota.
gcloud auth application-default login
gcloud auth application-default set-quota-project
- Inoltre, devi aver installato il seguente software:
- Python (è richiesta la versione 3.11 o successive)
- L'interfaccia a riga di comando LangChain
- poetry per la gestione delle dipendenze
- pipx per installare ed eseguire l'interfaccia a riga di comando LangChain e poesie in ambienti virtuali isolati
Ecco un blog che ti aiuta a iniziare a installare gli strumenti necessari per questa procedura dettagliata.
Cloud Workstations
Anziché la tua macchina locale, puoi anche utilizzare le workstation Cloud su Google Cloud. Tieni presente che da aprile 2024 viene eseguita una versione di Python precedente alla 3.11, quindi potresti dover eseguire l'upgrade di Python prima di iniziare.
Abilita le API Cloud
Innanzitutto, esegui il seguente comando per assicurarti di aver configurato il progetto Google Cloud corretto da utilizzare:
gcloud config list project
Se il progetto corretto non viene visualizzato, puoi impostarlo con questo comando:
gcloud config set project <PROJECT_ID>
Ora abilita le API seguenti:
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
Scegli una regione
Google Cloud è disponibile in molte località in tutto il mondo e devi sceglierne una per eseguire il deployment delle risorse che utilizzerai per questo lab. Imposta la regione come variabile di ambiente nella shell (i comandi successivi utilizzeranno questa variabile):
export REGION=us-central1
3. Crea l'istanza del database di vettori
Una parte fondamentale di questa app è il recupero delle note di rilascio pertinenti alla domanda dell'utente. Per essere più specifici, se fai una domanda su Cloud Storage, vuoi che la seguente nota di rilascio venga aggiunta al prompt:
Puoi utilizzare gli incorporamenti di testo e un database vettoriale per trovare note di rilascio semanticamente simili.
Ti mostrerò come utilizzare PostgreSQL su Cloud SQL come database vettoriale. La creazione di una nuova istanza Cloud SQL richiede del tempo, perciò lo facciamo ora.
gcloud sql instances create sql-instance \ --database-version POSTGRES_14 \ --tier db-f1-micro \ --region $REGION
Puoi lasciare che questo comando venga eseguito e continuare con i passaggi successivi. A un certo punto dovrai creare un database e aggiungere un utente, ma non perdiamo tempo a guardare la rotellina.
PostgreSQL è un server di database relazionale e ogni nuova istanza di Cloud SQL ha l'estensione pgvector installata per impostazione predefinita, il che significa che puoi utilizzarla anche come database vettoriale.
4. Sfrutta l'app LangChain
Per continuare, devi avere installato LangChain CLI e poetry per gestire le dipendenze. Ecco come installarli utilizzando pipx:
pipx install langchain-cli poetry
Crea lo scafo dell'app LangChain con il seguente comando. Quando richiesto, assegna alla cartella il nome run-rag
e salta l'installazione dei pacchetti premendo Invio:
langchain app new
Passa alla directory run-rag
e installa le dipendenze
poetry install
Hai appena creato un'app LangServe. LangServe avvolge FastAPI in una catena LangChain. Ha un parco giochi integrato che semplifica l'invio di prompt e l'ispezione dei risultati, inclusi tutti i passaggi intermedi. Ti suggerisco di aprire la cartella run-rag
nell'editor ed esplorare cosa c'è lì.
5. Crea il job di indicizzazione
Prima di iniziare a mettere insieme l'app web, assicurati che le note di rilascio di Cloud Run siano indicizzate nel database Cloud SQL. In questa sezione creerai un job di indicizzazione che:
Il job di indicizzazione prende note di rilascio, le converte in vettori utilizzando un modello di incorporamento del testo e le archivia in un database vettoriale. Ciò consente una ricerca efficiente di note di rilascio simili in base al loro significato semantico.
Nella cartella run-rag/app
, crea un file indexer.py
con i seguenti contenuti:
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")
Aggiungi le dipendenze richieste:
poetry add \ "cloud-sql-python-connector[pg8000]" \ langchain-google-vertexai==1.0.5 \ langchain-community==0.2.5 \ pgvector
Crea il database e un utente
Crea un database release-notes
nell'istanza Cloud SQL sql-instance
:
gcloud sql databases create release-notes --instance sql-instance
Crea un utente database denominato app
:
gcloud sql users create app --instance sql-instance --password "myprecious"
Esegui il deployment del job di indicizzazione ed eseguilo
Ora esegui il deployment ed esegui il job:
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
È un comando lungo, vediamo cosa succede:
Il primo comando recupera il nome della connessione (un ID univoco formattato come project:region:instance
) e lo imposta come variabile di ambiente DB_INSTANCE_NAME
.
Il secondo comando esegue il deployment del job Cloud Run. Ecco cosa fanno gli indicatori:
--source .
: specifica che il codice sorgente del job si trova nella directory di lavoro corrente (la directory in cui stai eseguendo il comando).--command python
: imposta il comando da eseguire all'interno del container. In questo caso, devi eseguire Python.--args app/indexer.py
: fornisce gli argomenti al comando python. Questo comando indica di eseguire lo script indexer.py nella directory dell'app.--set-env-vars
: imposta le variabili di ambiente a cui lo script Python può accedere durante l'esecuzione.--region=$REGION
: specifica la regione in cui deve essere eseguito il deployment del job.--execute-now
: indica a Cloud Run di avviare il job immediatamente dopo il deployment.
Per verificare che il job sia stato completato correttamente, puoi procedere nel seguente modo:
- Leggi i log dell'esecuzione del job tramite la console web. Dovresti visualizzare il messaggio "Salvataggio completato: xxx note di rilascio" (dove xxx è il numero di note di rilascio salvate).
- Puoi anche andare all'istanza Cloud SQL nella console web e utilizzare Cloud SQL Studio per eseguire query sul numero di record nella tabella
langchain_pg_embedding
.
6. Scrivi l'applicazione web
Apri il file app/server.py
nell'editor. Vedrai una riga con il seguente messaggio:
# Edit this to add the chain you want to add
Sostituisci il commento con il seguente snippet:
# (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()
)
Devi anche aggiungere queste importazioni:
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
Infine, modifica la riga "NotImplemented" in:
# add_routes(app, NotImplemented)
add_routes(app, chain)
7. esegui il deployment dell'applicazione web in Cloud Run
Dalla directory run-rag
, utilizza il seguente comando per eseguire il deployment dell'app in 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
Questo comando esegue le seguenti operazioni:
- Carica il codice sorgente in Cloud Build
- Esegui la build Docker.
- Esegui il push dell'immagine container risultante in Artifact Registry.
- Crea un servizio Cloud Run utilizzando l'immagine container.
Al termine del comando, viene elencato un URL HTTPS nel dominio run.app. Questo è l'URL pubblico del nuovo servizio Cloud Run
8. Esplorare il parco giochi
Apri l'URL del servizio Cloud Run e vai a /playground
. Viene visualizzato un campo di testo. Utilizzala per fare domande sulle note di rilascio di Cloud Run, come qui:
9. Complimenti
Hai creato ed eseguito correttamente il deployment di un'app LangChain su Cloud Run. Ben fatto!
Ecco i concetti chiave:
- Utilizzo del framework LangChain per creare un'applicazione RAG (Retrieval Augmented Generation).
- Utilizzo di PostgreSQL su Cloud SQL come database vettoriale con pgvector, che è installato per impostazione predefinita su Cloud SQL.
- Esegui un job di indicizzazione di durata più lunga come job Cloud Run e un'applicazione web come servizio Cloud Run.
- Includi una catena LangChain in un'applicazione FastAPI con LangServe, fornendo un'interfaccia comoda per interagire con la tua app RAG.
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial:
- In Cloud Console, vai alla pagina Gestisci risorse.
- Nell'elenco dei progetti, seleziona il progetto e fai clic su Elimina.
- Nella finestra di dialogo, digita l'ID progetto e fai clic su Chiudi per eliminare il progetto.
Se vuoi conservare il progetto, assicurati di eliminare le seguenti risorse:
- Istanza Cloud SQL
- Servizio Cloud Run
- Job Cloud Run