Trực quan hoá bộ nhớ của trợ lý AI bằng Gemini và Cloud SQL pgvector

1. Giới thiệu

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách tạo Bản minh hoạ về Ký ức sống, một trợ lý dựa trên AI có thể theo dõi "Bộ nhớ" về cuộc trò chuyện của bạn để mang đến trải nghiệm được cá nhân hoá.

Giao diện người dùng của tính năng Kỷ niệm

Ứng dụng này sử dụng Gemini để hiểu ngôn ngữ tự nhiên và Cloud SQL cho PostgreSQL với tiện ích pgvector để lưu trữ và truy xuất những ký ức này dựa trên mức độ tương đồng về ngữ nghĩa.

Lớp học lập trình này dành cho nhà phát triển ở mọi cấp độ kỹ năng quan tâm đến AI và cơ sở dữ liệu. Bạn sẽ mất khoảng 60 phút để hoàn thành lớp học lập trình này. Các tài nguyên được tạo phải có chi phí dưới 5 USD.

Bạn sẽ thực hiện

  • Cách thiết lập một phiên bản Cloud SQL cho PostgreSQL có hỗ trợ pgvector.
  • Cách dùng Gemini để trích xuất "kỷ niệm" một cách tương tác từ tin nhắn của người dùng.
  • Cách thực hiện tìm kiếm vectơ trong PostgreSQL để truy xuất ngữ cảnh có liên quan cho câu trả lời của AI.

Kiến trúc bộ nhớ trực tiếp

Bạn cần có

  • Một dự án trên Google Cloud đã bật tính năng thanh toán.
  • Kiến thức cơ bản về dòng lệnh và Node.js.

2. Trước khi bắt đầu

Thiết lập dự án

Tạo một dự án trên Google Cloud

  1. Trong Google Cloud Console, trên trang chọn dự án, hãy chọn hoặc tạo một dự án trên Google Cloud.
  2. Đảm bảo bạn đã bật tính năng thanh toán cho dự án trên Cloud. Tìm hiểu cách kiểm tra xem tính năng thanh toán có được bật trên một dự án hay không.

Khởi động Cloud Shell

Cloud Shell là một môi trường dòng lệnh chạy trong Google Cloud và được tải sẵn các công cụ cần thiết.

  1. Nhấp vào Kích hoạt Cloud Shell ở đầu bảng điều khiển Cloud.
  2. Sau khi kết nối với Cloud Shell, hãy xác minh thông tin xác thực của bạn:
    gcloud auth list
    
  3. Xác nhận rằng dự án của bạn đã được định cấu hình:
    gcloud config get project
    
  4. Nếu dự án của bạn không được thiết lập như mong đợi, hãy thiết lập dự án:
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

Bật API

Chạy lệnh sau trong Cloud Shell để bật các API bắt buộc:

gcloud services enable sqladmin.googleapis.com \
                       aiplatform.googleapis.com

3. Sao chép kho lưu trữ bản minh hoạ

Bây giờ, hãy lấy mã cho bản minh hoạ Kỷ niệm sống.

  1. Sao chép kho lưu trữ vào môi trường Cloud Shell:
    git clone https://github.com/GoogleCloudPlatform/devrel-demos.git
    cd devrel-demos/codelabs/visual-memory-postgres-demo
    
  2. Cài đặt các phần phụ thuộc:
    npm install
    

4. Tạo và định cấu hình cơ sở dữ liệu Cloud SQL

Trong phần này, bạn sẽ tạo một phiên bản Cloud SQL, khởi động cơ sở dữ liệu và thiết lập giản đồ.

  1. Ứng dụng này sử dụng các biến môi trường để định cấu hình. Chạy khối sau trong thiết bị đầu cuối Cloud Shell để đặt các biến bắt buộc cho phiên này:
    export REGION="us-central1"
    export INSTANCE_NAME="living-memory-db"
    export DB_HOST=127.0.0.1
    export DB_PORT=5432
    export DB_USER=memory_app
    export DB_PASS=memory_app_password
    export DB_NAME=living_memory
    export PGPASSWORD=$DB_PASS
    
  2. Tạo phiên bản. Bước này thường mất từ 5 đến 10 phút.
    gcloud sql instances create $INSTANCE_NAME \
        --database-version=POSTGRES_16 \
        --cpu=1 \
        --memory=3840MB \
        --region=$REGION \
        --root-password=$DB_PASS \
        --edition=ENTERPRISE
    
    Trong khi phiên bản đang được tạo, hãy dành chút thời gian để tìm hiểu giản đồ cơ sở dữ liệu mà bạn sẽ sử dụng. Tập lệnh này cho phép tiện ích vector và tạo một số bảng để hỗ trợ ứng dụng:Sơ đồ giản đồ bộ nhớ trực quan
    • users, conversations, messages: Các bảng tiêu chuẩn để lưu trữ hồ sơ người dùng và nhật ký trò chuyện.
    • memories: Đây là bảng cốt lõi cho tính năng Tạo nội dung dựa trên thông tin truy xuất (RAG). Mỗi hàng đại diện cho một thông tin được trích xuất từ cuộc trò chuyện (ví dụ: "Người dùng thích đi bộ đường dài"). Nhật ký này lưu trữ:
      • content: Văn bản của bộ nhớ.
      • memory_type: Loại kỷ niệm (FACT, PREF hoặc IMPLICIT).
      • embedding: Cột vector gồm 768 chiều chứa biểu diễn ngữ nghĩa của nội dung, do Gemini tạo.
    • pgvector Chỉ mục: Một chỉ mục HNSW (Hierarchical Navigable Small World) được tạo trên cột embedding. Điều này rất quan trọng để tối ưu hoá các lượt tìm kiếm k-Lân cận (k-NN), cho phép pgvector nhanh chóng tìm thấy những kỷ niệm tương tự nhất về mặt ngữ nghĩa bằng cách sử dụng toán tử khoảng cách cosine (<=>).
  3. Tạo Database
    gcloud sql databases create $DB_NAME --instance=$INSTANCE_NAME
    
  4. Tạo người dùng ứng dụng
    gcloud sql users create $DB_USER --instance=$INSTANCE_NAME --password=$DB_PASS
    
  5. Khởi động Cloud SQL Auth Proxy. Proxy này cung cấp quyền truy cập an toàn vào phiên bản của bạn mà không cần định cấu hình danh sách cho phép IP.
    (cloud-sql-proxy ${GOOGLE_CLOUD_PROJECT}:us-central1:living-memory-db &) && sleep 2 && echo ""
    
    Bạn sẽ thấy một thông báo như: The proxy has started successfully and is ready for new connections!.
  6. Áp dụng schema.sql để bật tiện ích vector và tạo các bảng cần thiết. Vì proxy đang chạy, nên giờ đây, bạn có thể kết nối với phiên bản của mình tại 127.0.0.1.
    psql -h 127.0.0.1 -U $DB_USER -d $DB_NAME < schema.sql
    
  7. Xác minh rằng bạn đã tạo giản đồ thành công.
    psql -h 127.0.0.1 -U $DB_USER -d $DB_NAME -c "\dt"
    
    Bạn sẽ thấy đầu ra liệt kê các bảng conversations, memories, messagesusers.
                      List of relations
    Schema |     Name      | Type  |   Owner    
    --------+---------------+-------+------------
    public | conversations | table | memory_app
    public | memories      | table | memory_app
    public | messages      | table | memory_app
    public | queries_log   | table | memory_app
    public | users         | table | memory_app
    (5 rows)
    

5. Tìm hiểu về tính năng truy xuất ngữ nghĩa bằng pgvector

Trong phần này, bạn sẽ xem xét cách ứng dụng truy xuất ngữ cảnh có liên quan cho AI trước khi tạo câu trả lời. Đoạn mã sau đây từ server.js cho thấy mã chịu trách nhiệm về việc này trong điểm cuối /api/chat:

// Retrieve Similar Memories for Context (Using pgvector)
const promptEmbeddingRes = await ai.models.embedContent({
  model: 'gemini-embedding-001',
  contents: message,
  config: { outputDimensionality: 768 },
});

const promptEmbedding = promptEmbeddingRes.embeddings[0].values;
const embeddingStr = `[${promptEmbedding.join(',')}]`;

// Query DB for top 5 closest memories
const relevantMemories = await pool.query(
  `SELECT id, content, memory_type, category 
   FROM memories 
   WHERE user_id = $1 
   ORDER BY embedding <=> $2::vector 
   LIMIT 5`,
  [userId, embeddingStr]
);

Cách hoạt động

  • AI tạo sinh (Nhúng): Ứng dụng này lấy tin nhắn đến của người dùng và sử dụng mô hình gemini-embedding-001 để chuyển đổi văn bản thành một vectơ 768 chiều. Vectơ này biểu thị ý nghĩa ngữ nghĩa của thông báo.
  • Cloud SQL (pgvector): Ứng dụng sẽ truyền vectơ đó đến Cloud SQL. Bằng cách sử dụng toán tử <=> (khoảng cách cosine) do tiện ích pgvector cung cấp, Cloud SQL sẽ tìm ra 5 kỷ niệm có ngữ nghĩa tương tự nhất với câu lệnh.
  • Kết quả: Đây là tính năng Tạo sinh tăng cường khả năng truy xuất (RAG). AI có quyền truy cập vào những thông tin cụ thể, phù hợp trong cơ sở dữ liệu để cá nhân hoá câu trả lời mà không cần tải toàn bộ nhật ký.

6. Tìm hiểu về tính năng trích xuất kỷ niệm

Tiếp theo, hãy xem cách ứng dụng học hỏi từ cuộc trò chuyện. Đoạn mã sau đây là từ hàm extractMemoriesAsync trong server.js:

// MEMORY EXTRACTION LOGIC
async function extractMemoriesAsync(userMessage, userId, messageId) {
  const extractionPrompt = `
    Analyze the following user message. A memory profile is being built for this user.
    Extract ANY explicit facts (Facts), preferences (Pref), or implicit behavioral traits/styles (Implicit).
    Return the result as a raw JSON array of objects (NO Markdown blocks, just the JSON array).
    Format: [{"content": "string fact/sentence", "type": "FACT|PREF|IMPLICIT", "category": "General|Travel|Hobby|Persona"}]
    If nothing is found, return [].
    Message: "${userMessage}"
    `;

  const result = await ai.models.generateContent({
    model: 'gemini-2.5-flash',
    contents: extractionPrompt
  });
  let rawJson = result.text.replace(/^```json/g, '').replace(/```$/g, '').trim();

  let extracted;
  try {
    extracted = JSON.parse(rawJson);
  } catch (e) {
    console.warn("Could not parse extracted JSON:", rawJson);
    return;
  }

  if (Array.isArray(extracted) && extracted.length > 0) {
    // Compute embeddings and save each to the DB
    for (const memory of extracted) {
      const embedRes = await ai.models.embedContent({
        model: 'gemini-embedding-001',
        contents: memory.content,
        config: { outputDimensionality: 768 },
      });
      const vectorData = `[${embedRes.embeddings[0].values.join(',')}]`;

      await pool.query(
        `INSERT INTO memories (user_id, content, memory_type, category, embedding, source_message_id)
                 VALUES ($1, $2, $3, $4, $5, $6)`,
        [userId, memory.content, memory.type.toUpperCase(), memory.category, vectorData, messageId]
      );
      console.log(`Saved new memory: ${memory.content}`);
    }
  }
}

Cách hoạt động

  • AI tạo sinh (Đầu ra có cấu trúc): Ứng dụng này sử dụng mô hình gemini-2.5-flash siêu nhanh để phân tích thông báo của người dùng và trích xuất các thông tin thực tế và lựa chọn ưu tiên có cấu trúc dưới dạng một mảng JSON.
  • Cloud SQL (Bộ nhớ kết hợp): Sau khi tạo các vectơ nhúng cho những thông tin mới này, chúng sẽ được lưu trữ trong Cloud SQL. Xin lưu ý rằng dữ liệu quan hệ tiêu chuẩn (Mã nhận dạng người dùng, nội dung văn bản, danh mục) được lưu trữ ngay bên cạnh dữ liệu vectơ nhiều chiều trong một hàng duy nhất.
  • Kết quả: Ứng dụng này tạo một hồ sơ bộ nhớ tự động cập nhật theo thời gian thực, tận dụng cả sức mạnh phân tích của Gemini và khả năng lưu trữ của Cloud SQL.

7. Chạy ứng dụng trò chuyện

  1. Điền sẵn một vài người dùng mẫu vào cơ sở dữ liệu
    npm run seed
    
    Bộ nhớ gốc
  2. Sau đó, hãy chạy máy chủ
    node server.js
    
  3. Trong Cloud Shell, hãy nhấp vào Xem trước trên web ở trên cùng bên phải của thanh công cụ trên thiết bị đầu cuối, rồi chọn Thay đổi cổng. Nhập 3000 cho số cổng rồi nhấp vào Thay đổi và xem trước.

Tương tác với trợ lý

Khi ứng dụng mở trong trình duyệt, bạn sẽ thấy giao diện trò chuyện của Living Memory. Ở bên phải, AI Cortex Data Visualizer (Công cụ trực quan hoá dữ liệu AI Cortex) hiển thị các thông tin đã lưu trữ dưới dạng các nút trong một không gian vectơ, được mã hoá bằng màu theo loại (Dữ kiện, Lựa chọn ưu tiên, Đặc điểm ngầm định). Văn bản trên các nút bộ nhớ có thể nhỏ tuỳ thuộc vào độ phân giải màn hình của bạn; hãy sử dụng chuột hoặc bàn di chuột để thu phóng và di chuyển nhằm xem kỹ hơn.

Giao diện người dùng của tính năng Kỷ niệm

Truy vấn kỷ niệm hiện có

Tập lệnh seed mà bạn đã chạy trước đó đã tạo ra 2 người dùng mẫu với một số kỷ niệm được điền sẵn.

  1. Chọn một người dùng trong trình đơn thả xuống người dùng ở trên cùng bên trái.
  2. Sử dụng một trong các nút trò chuyện nhanh hoặc nhập Give me restaurant recommendations in New York City vào phần nhập nội dung trò chuyện rồi nhấn Gửi.
  3. Khi Trợ lý phản hồi, bạn có thể nhấp vào tin nhắn của Trợ lý để xem Trợ lý đã dùng những kỷ niệm nào. Các phần này sẽ được đánh dấu bằng màu xanh lục và bạn có thể thu phóng để xem cách các phần này giúp tạo ra câu trả lời.

Tạo người dùng mới

Bây giờ, hãy tạo một người dùng mới.

  1. Nhấp vào nút + bên cạnh trình đơn thả xuống người dùng để bắt đầu một phiên trò chuyện mới.
  2. Sử dụng tên và nội dung mô tả được tạo hoặc chỉnh sửa để mô tả bản thân.
  3. Nhấp vào Tạo và xem ứng dụng bắt đầu trích xuất kỷ niệm. Sau khoảng 30 giây, bạn sẽ thấy các nút mới xuất hiện trong trình trực quan hoá ở bên phải. Đây là những thông tin và lựa chọn ưu tiên mà Gemini đã trích xuất từ tin nhắn của bạn và lưu trữ trong cơ sở dữ liệu Cloud SQL.
  4. Đặt một câu hỏi tiếp theo như What food do I like? để xem trợ lý sử dụng những thông tin vừa ghi nhớ trong cuộc trò chuyện.

8. Dọn dẹp

Để tránh các khoản phí liên tục cho tài khoản Google Cloud của bạn đối với các tài nguyên được dùng trong lớp học lập trình này, bạn nên xoá các tài nguyên mà bạn đã tạo.

  1. Xoá phiên bản Cloud SQL:
    gcloud sql instances delete $INSTANCE_NAME --quiet
    
  2. Xoá kho lưu trữ bản minh hoạ:
    rm -rf ~/devrel-demos
    

9. Xin chúc mừng

Bạn đã tạo và triển khai thành công một trợ lý AI "Kỷ niệm sống"!

Kiến thức bạn học được

  • Cách sử dụng Cloud SQL pgvector cho tìm kiếm ngữ nghĩa.
  • Cách sử dụng Gemini để trích xuất bộ nhớ linh động.

Các bước tiếp theo

Hãy thoả sức sáng tạo với tính năng Kỷ niệm sống!