ดูวิธีสร้างและทำให้แอป LangChain ใช้งานได้บน Cloud Run

1. ภาพรวม

ใน Code Lab นี้ คุณจะได้เรียนรู้วิธีทำให้แอป LangChain ที่ใช้ Gemini ใช้งานได้ เพื่อให้คุณถามคำถามผ่านบันทึกประจำรุ่นของ Cloud Run ได้

ตัวอย่างวิธีการทำงานของแอป ได้แก่ หากคุณถามว่า "ฉันจะต่อเชื่อมที่เก็บข้อมูล Cloud Storage เป็นวอลุ่มใน Cloud Run ได้ไหม" แอปจะตอบว่า "ใช่ ตั้งแต่วันที่ 19 มกราคม 2024" หรือคำอื่นที่คล้ายกัน

หากต้องการแสดงคำตอบที่ถูกต้อง แอปจะเรียกบันทึกประจำรุ่นของ 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
    • บทกวีสำหรับการจัดการทรัพยากร Dependency
    • pipx เพื่อติดตั้งและเรียกใช้ LangChain CLI และบทกวีในสภาพแวดล้อมเสมือนจริงที่แยกไว้

นี่คือบล็อกที่จะช่วยให้คุณเริ่มต้นติดตั้งเครื่องมือที่จำเป็นสำหรับคำแนะนำแบบทีละขั้นนี้

Cloud Workstations

คุณยังใช้ Cloud Workstations บน Google Cloud แทนเครื่องภายในได้อีกด้วย โปรดทราบว่าตั้งแต่เดือนเมษายน 2024 เป็นต้นไป ไลบรารีจะทำงานด้วย Python เวอร์ชันที่ต่ำกว่า 3.11 ดังนั้นคุณอาจต้องอัปเกรด Python ก่อนเริ่มต้นใช้งาน

เปิดใช้ Cloud APIs

ก่อนอื่นให้เรียกใช้คำสั่งต่อไปนี้เพื่อให้แน่ใจว่าคุณได้กำหนดค่าโปรเจ็กต์ 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 มีให้บริการในหลายแห่งทั่วโลก และคุณต้องเลือก 1 แห่งเพื่อทำให้ทรัพยากรที่จะใช้สำหรับห้องทดลองนี้ ตั้งค่าภูมิภาคเป็นตัวแปรสภาพแวดล้อมใน Shell (คำสั่งหลังจากนี้จะใช้ตัวแปรนี้) ดังนี้

export REGION=us-central1

3. สร้างอินสแตนซ์ฐานข้อมูลเวกเตอร์

ส่วนสำคัญของแอปนี้คือการเรียกบันทึกประจำรุ่นที่เกี่ยวข้องกับคำถามของผู้ใช้ เพื่อให้เห็นภาพชัดเจนยิ่งขึ้น หากคุณกำลังถามคำถามเกี่ยวกับ Cloud Storage คุณต้องการให้เพิ่มบันทึกประจำรุ่นต่อไปนี้ในข้อความแจ้ง

คุณสามารถใช้การฝังข้อความและฐานข้อมูลเวกเตอร์เพื่อค้นหาบันทึกประจำรุ่นที่คล้ายคลึงกันเชิงความหมาย

ผมจะสาธิตวิธีใช้ PostgreSQL บน Cloud SQL เป็นฐานข้อมูลเวกเตอร์ การสร้างอินสแตนซ์ Cloud SQL ใหม่ต้องใช้เวลาสักครู่ มาดำเนินการดังกล่าวกันเลย

gcloud sql instances create sql-instance \
  --database-version POSTGRES_14 \
  --tier db-f1-micro \
  --region $REGION

โดยคุณจะอนุญาตให้คำสั่งนี้ทำงานและดำเนินการตามขั้นตอนถัดไปได้ เมื่อถึงเวลาหนึ่ง คุณจะต้องสร้างฐานข้อมูลและเพิ่มผู้ใช้ แต่อย่าเสียเวลาดูไอคอนหมุนในตอนนี้

PostgreSQL เป็นเซิร์ฟเวอร์ฐานข้อมูลเชิงสัมพันธ์ และอินสแตนซ์ใหม่ทุกรายการของ Cloud SQL จะติดตั้งส่วนขยาย pgvector อยู่โดยค่าเริ่มต้น ซึ่งหมายความว่าคุณสามารถใช้ส่วนขยายดังกล่าวเป็นฐานข้อมูลเวกเตอร์ได้

4. Scaffold แอป LangChain

หากต้องการดำเนินการต่อ คุณจะต้องติดตั้ง LangChain CLI และบทกวีเพื่อจัดการทรัพยากร Dependency วิธีติดตั้งโปรแกรมโดยใช้ pipx มีดังนี้

pipx install langchain-cli poetry

Scaffold แอป LangChain ด้วยคำสั่งต่อไปนี้ เมื่อระบบถาม ให้ตั้งชื่อโฟลเดอร์เป็น run-rag และข้ามการติดตั้งแพ็กเกจโดยกด Enter:

langchain app new

เปลี่ยนเป็นไดเรกทอรี run-rag และติดตั้งการอ้างอิง

poetry install

คุณได้สร้างแอป LangServe แล้ว LangServe จะรวม FastAPI รอบเชน LangChain โดยมาพร้อมกับสนามเด็กเล่นแบบบิวท์อินที่ทำให้ส่งข้อความแจ้งและตรวจสอบผลลัพธ์ได้ง่าย ซึ่งรวมถึงขั้นตอนตัวกลางทั้งหมด เราขอแนะนำให้คุณเปิดโฟลเดอร์ 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")

เพิ่มทรัพยากร Dependency ที่จำเป็น

poetry add \
  cloud-sql-python-connector["pg8000"] \
  langchain-google-vertexai==1.0.5 \
  langchain-community==0.2.5 \
  pgvector

สร้างฐานข้อมูลและผู้ใช้

สร้างฐานข้อมูล release-notes บนอินสแตนซ์ Cloud SQL sql-instance:

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) และตั้งค่าเป็นตัวแปรสภาพแวดล้อม DB_INSTANCE_NAME

คำสั่งที่ 2 จะทำให้งาน 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 โดยใช้อิมเมจคอนเทนเนอร์

เมื่อคำสั่งเสร็จสมบูรณ์ ระบบจะแสดง HTTPS URL ในโดเมน run.app นี่คือ URL สาธารณะของบริการ Cloud Run ใหม่ของคุณ

8. สำรวจสนามเด็กเล่น

เปิด URL ของบริการ Cloud Run แล้วไปที่ /playground เพื่อแสดงช่องข้อความ ใช้เพื่อถามคำถามในบันทึกประจำรุ่น Cloud Run ดังตัวอย่างต่อไปนี้

9. ขอแสดงความยินดี

คุณสร้างและทำให้แอป LangChain ใช้งานได้บน Cloud Run เรียบร้อยแล้ว เยี่ยมมาก!

แนวคิดหลักมีดังนี้

  • การใช้เฟรมเวิร์ก LangChain เพื่อสร้างแอปพลิเคชัน Retrieval Augmented Generation (RAG)
  • การใช้ PostgreSQL บน Cloud SQL เป็นฐานข้อมูลเวกเตอร์ที่มี pgvector ซึ่งติดตั้งบน Cloud SQL ตามค่าเริ่มต้น
  • เรียกใช้งานการจัดทำดัชนีที่นานขึ้นเป็นงาน Cloud Run และเว็บแอปพลิเคชันเป็นบริการ Cloud Run
  • รวมเชน LangChain ในแอปพลิเคชัน FastAPI ด้วย LangServe ซึ่งเป็นอินเทอร์เฟซที่สะดวกสบายในการโต้ตอบกับแอป RAG

ล้างข้อมูล

โปรดทำดังนี้เพื่อเลี่ยงไม่ให้เกิดการเรียกเก็บเงินกับบัญชี Google Cloud Platform สำหรับทรัพยากรที่ใช้ในบทแนะนำนี้

  • ใน Cloud Console ให้ไปที่หน้าจัดการทรัพยากร
  • ในรายการโปรเจ็กต์ ให้เลือกโปรเจ็กต์ของคุณ แล้วคลิกลบ
  • ในกล่องโต้ตอบ ให้พิมพ์รหัสโปรเจ็กต์แล้วคลิกปิดเครื่องเพื่อลบโปรเจ็กต์

หากต้องการเก็บโปรเจ็กต์ไว้ โปรดลบทรัพยากรต่อไปนี้

  • อินสแตนซ์ Cloud SQL
  • บริการ Cloud Run
  • งาน Cloud Run