1. 개요
이 Codelab에서는 Gemini를 사용하여 Cloud Run 출시 노트에서 질문할 수 있는 LangChain 앱을 배포하는 방법을 알아봅니다.
다음은 앱이 작동하는 방식의 예입니다. 'Cloud Storage 버킷을 Cloud Run에서 볼륨으로 마운트할 수 있나요?'라고 물으면 앱은 '예, 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
- 격리된 가상 환경에서 LangChain CLI 및 시를 설치하고 실행하는 pipx
다음은 이 둘러보기에 필요한 도구 설치를 시작하는 데 도움이 되는 블로그입니다.
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는 전 세계 여러 위치에서 사용할 수 있으며 이 실습에 사용할 리소스를 배포하려면 한 곳을 선택해야 합니다. 셸에서 지역을 환경 변수로 설정합니다 (이후 명령어에서는 이 변수를 사용).
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를 설치하고 종속 항목을 관리하는 시를 실행해야 합니다. 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 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 URL이 나열됩니다. 새 Cloud Run 서비스의 공개 URL입니다.
8. 놀이터 살펴보기
Cloud Run 서비스 URL을 열고 /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를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.
프로젝트를 유지하려면 다음 리소스를 삭제해야 합니다.
- Cloud SQL 인스턴스
- Cloud Run 서비스
- Cloud Run 작업