1. 개요
이 Codelab에서는 Gemini를 사용하여 Cloud Run 출시 노트에 관해 질문할 수 있는 LangChain 앱을 배포하는 방법을 알아봅니다.
다음은 앱이 작동하는 방식의 예입니다. '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월부터 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는 전 세계 여러 위치에서 사용할 수 있으며, 이 실습에 사용할 리소스를 배포할 위치를 선택해야 합니다. 셸에서 지역을 환경 변수로 설정합니다 (이후 명령어에서는 이 변수를 사용).
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는 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에 작업이 배포된 후 즉시 작업을 시작하도록 지시합니다.
작업이 성공적으로 완료되었는지 확인하려면 다음을 실행합니다.
- 웹 콘솔을 통해 작업 실행 로그를 읽습니다. '저장 완료: xxx 출시 노트'(여기서 xxx는 저장된 출시 노트 수)가 표시됩니다.
- 웹 콘솔에서 Cloud SQL 인스턴스로 이동하여 Cloud SQL 스튜디오를 사용하여
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 build를 실행합니다.
- 결과 컨테이너 이미지를 Artifact Registry에 푸시합니다.
- 컨테이너 이미지를 사용하여 Cloud Run 서비스를 만듭니다.
명령어가 완료되면 run.app 도메인의 HTTPS URL이 나열됩니다. 새 Cloud Run 서비스의 공개 URL입니다.
8. 플레이그라운드 살펴보기
Cloud Run 서비스 URL을 열고 /playground
로 이동합니다. 텍스트 필드가 표시됩니다. 다음과 같이 Cloud Run 출시 노트에 관해 질문하는 데 사용하세요.
9. 축하합니다
Cloud Run에서 LangChain 앱을 빌드하고 배포했습니다. 잘하셨습니다.
다음은 주요 개념입니다.
- LangChain 프레임워크를 사용하여 검색 증강 생성(RAG) 애플리케이션을 빌드합니다.
- Cloud SQL에 기본적으로 설치된 pgvector를 사용하여 Cloud SQL의 PostgreSQL을 벡터 데이터베이스로 사용합니다.
- 실행 시간이 긴 색인 생성 작업을 Cloud Run 작업으로, 웹 애플리케이션을 Cloud Run 서비스로 실행합니다.
- LangServe를 사용하여 FastAPI 애플리케이션에서 LangChain 체인을 래핑하여 RAG 앱과 상호작용할 수 있는 편리한 인터페이스를 제공합니다.
삭제
이 튜토리얼에서 사용한 리소스 비용이 Google Cloud Platform 계정에 청구되지 않도록 하는 방법은 다음과 같습니다.
- Cloud Console에서 리소스 관리 페이지로 이동합니다.
- 프로젝트 목록에서 해당 프로젝트를 선택한 후 삭제를 클릭합니다.
- 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.
프로젝트를 유지하려면 다음 리소스를 삭제해야 합니다.
- Cloud SQL 인스턴스
- Cloud Run 서비스
- Cloud Run 작업