Chuyển đến nội dung chính

Hướng dẫn Oracle AI Vector Search: Lưu trữ và truy vấn Embeddings với Python

Hướng dẫn này giới thiệu Oracle AI Vector Search, giải thích các tính năng cốt lõi và hướng dẫn qua một dự án cục bộ thực tế. Nội dung cũng bao gồm yêu cầu thiết lập, tìm kiếm ngữ nghĩa, lập chỉ mục vector và các bước khắc phục sự cố thường gặp.
· 15 phút đọc

Khám phá cùng AI

Trong hướng dẫn này, chúng ta sẽ dựng một bản demo tìm kiếm ngữ nghĩa cục bộ với Oracle AI Vector Search, Python và Oracle Database Free 26ai. 

Chúng ta sẽ bắt đầu với các vector ba chiều viết tay để có thể nhìn thấy phép tính khoảng cách, sau đó tạo embeddings văn bản và truy vấn chúng từ Oracle Database bằng SQL. 

Hướng dẫn này dành cho các lập trình viên Python và SQL mới làm quen với tìm kiếm vector, đồng thời thoải mái sử dụng Docker, biến môi trường, gói Python và thiết lập cơ sở dữ liệu cục bộ.

Các ứng dụng dùng AI cần khả năng tìm kiếm hiểu ý nghĩa, không chỉ từ khớp chính xác. Một ứng dụng hỗ trợ, cổng tài liệu hay công cụ tri thức nội bộ nên có thể tìm thấy “lưu trữ cơ sở dữ liệu cho tìm kiếm AI” ngay cả khi tài liệu khớp nhất viết rằng “lưu vector embeddings trong các cột native”.

Vector embeddings giúp điều đó khả thi bằng cách biểu diễn văn bản dưới dạng vector số. Oracle AI Vector Search cho phép chúng ta lưu trữ các vector đó trực tiếp trong Oracle Database, truy vấn bằng SQL và giữ embeddings ngay cạnh dữ liệu ứng dụng quan hệ. 

Với quy trình cục bộ này, chúng ta không cần một cơ sở dữ liệu vector riêng biệt.

Chúng ta sẽ chạy Oracle Database Free 26ai cục bộ, kết nối từ Python bằng oracledb Thin mode, lưu vector thủ công trước, tiếp theo lưu embeddings của OpenAI, chạy tìm kiếm ngữ nghĩa, so sánh truy xuất ngữ nghĩa với một điều kiện cụm từ chính xác đơn giản, và tạo một chỉ mục vector được xác thực qua USER_INDEXES.

Kết thúc, chúng ta sẽ có một quy trình tìm kiếm ngữ nghĩa vận hành bằng Python, lưu embeddings trong Oracle Database và truy xuất các documents tương tự nhất ngay trên máy.

Oracle AI Vector Search là gì?

Oracle AI Vector Search là tập hợp các khả năng trong Oracle Database để lưu trữ, lập chỉ mục và truy vấn vector embeddings. Một vector embedding là danh sách cố định số lượng các con số, đại diện cho ý nghĩa của văn bản, hình ảnh hoặc dữ liệu khác dưới dạng mà cơ sở dữ liệu có thể so sánh bằng toán học.

Một mô hình embedding tạo ra các vector số. Nó nhận đầu vào như câu, đoạn văn, mô tả hình ảnh hoặc đoạn mã và trả về một vector với số chiều cố định.

Các đầu vào tương tự sẽ tạo ra các vector gần nhau, trong khi đầu vào không liên quan sẽ cách xa nhau. Do đó, chúng ta phải dùng cùng một mô hình embedding cho các documents đã lưu và các truy vấn đến, vì khoảng cách chỉ có ý nghĩa khi các vector cùng hệ tọa độ.

Trong hướng dẫn này, các vector thủ công được cố tình để nhỏ để chúng ta có thể kiểm tra toán học. Các embeddings văn bản thực tế lớn hơn nhiều vì mô hình cần đủ số chiều để mã hóa các mối quan hệ tinh tế hơn giữa từ, cụm từ và chủ đề.

Tìm kiếm vector xếp hạng các hàng theo khoảng cách giữa các vector. Với truy vấn khoảng cách Euclid và cosine, giá trị khoảng cách nhỏ hơn nghĩa là khớp gần hơn. Trong hướng dẫn này, chúng ta sẽ bắt đầu với một cột VECTOR(3, FLOAT32) nhỏ để có thể thấy trực tiếp hành vi của khoảng cách, sau đó chuyển sang embeddings VECTOR(1536, FLOAT32) được tạo từ văn bản.

Oracle AI Vector Search flow

Hình 1. Quy trình Oracle AI Vector Search

Oracle AI Vector Search lưu embeddings trong một cột VECTOR native và xếp hạng kết quả theo khoảng cách vector.

Oracle Database hữu ích khi embeddings cần nằm cạnh dữ liệu ứng dụng quan hệ như ID tài liệu, tiêu đề, nội dung, người dùng, sản phẩm, phiếu hỗ trợ hoặc metadata. 

Một số ứng dụng dùng cơ sở dữ liệu vector hoặc công cụ tìm kiếm riêng cho khối lượng truy xuất chuyên biệt, nhưng với quy trình tìm kiếm ngữ nghĩa cục bộ trong hướng dẫn này, Oracle Database cung cấp các tính năng lưu trữ và tìm kiếm vector mà chúng ta cần.

Các tính năng chính của Oracle AI Vector Search

Chúng ta sẽ dùng bốn tính năng Oracle AI Vector Search trong demo: lưu trữ vector native, hàm khoảng cách, chỉ mục vector, và tích hợp quan hệ.

Kiểu dữ liệu vector native

Oracle Database hỗ trợ các cột VECTOR native với số chiều và định dạng phần tử rõ ràng. Trong demo, chúng ta sẽ dùng VECTOR(3, FLOAT32) cho vector thủ công và VECTOR(1536, FLOAT32) cho mô hình embedding mặc định text-embedding-3-small.

Hàm và toán tử khoảng cách

Các ví dụ có thể chạy dùng VECTOR_DISTANCE() vì nó giữ cho thước đo khoảng cách được nêu rõ trong SQL. 

Chúng ta sẽ dùng khoảng cách Euclid cho ví dụ vector thủ công và khoảng cách cosine cho embeddings văn bản. 

Oracle Database cũng có các toán tử viết tắt cho khoảng cách vector và hành vi khoảng cách liên quan đến tích vô hướng, nhưng hướng dẫn này giữ SQL có thể chạy theo hướng tường minh với VECTOR_DISTANCE().

Các thước đo khoảng cách khác nhau trả lời hơi khác nhau cho câu hỏi về “độ gần”. 

Với một hướng dẫn nhỏ, khoảng cách cosine là lựa chọn mặc định tốt cho embeddings văn bản vì nó tập trung vào hướng, thường ánh xạ tốt tới độ tương đồng ngữ nghĩa. 

Khoảng cách Euclid dễ hình dung hơn với các vector viết tay, và so sánh kiểu tích vô hướng hữu ích trong một số hệ thống truy xuất khi độ lớn vector hoặc vector chuẩn hóa là một phần thiết kế mô hình.

Thước đo

So sánh điều gì

Phù hợp cho

Lưu ý

Cosine

Hướng của vector

Embeddings văn bản và độ tương đồng ngữ nghĩa

Kết quả phụ thuộc vào việc dùng cùng mô hình embedding và tiền xử lý nhất quán

Euclid

Khoảng cách đường thẳng

Ví dụ nhỏ, trực giác hình học, một số vector đặc trưng số

Độ lớn ảnh hưởng đến khoảng cách, nên việc scale có thể quan trọng

Tích vô hướng

Kết hợp hướng và độ lớn

Quy trình xoay quanh vector chuẩn hóa hoặc chấm điểm inner-product

Cần hiểu hướng điểm số và quy tắc chuẩn hóa trước khi so sánh kết quả

Chỉ mục vector

Tìm kiếm vector chính xác hữu ích cho tính đúng đắn và tập dữ liệu nhỏ. Khi dữ liệu lớn dần, chỉ mục vector hỗ trợ các quy trình tìm lân cận gần nhất xấp xỉ.

Oracle AI Vector Search bao gồm chỉ mục đồ thị hàng xóm trong bộ nhớ, thường gắn với tìm kiếm kiểu HNSW, và chỉ mục phân vùng hàng xóm, thường gắn với phân vùng kiểu IVF. 

Trong demo cục bộ này, chúng ta dùng ORGANIZATION NEIGHBOR PARTITIONS và xác thực chỉ mục bằng USER_INDEXES.

Các chỉ mục xấp xỉ đánh đổi một chút tính chắc chắn của tìm kiếm toàn diện để đổi lấy truy xuất nhanh hơn ở quy mô lớn. 

Nhóm chỉ mục phù hợp phụ thuộc vào khối lượng công việc, dữ liệu, mẫu cập nhật và mục tiêu recall.

Hướng dẫn này dùng chỉ mục phân vùng hàng xóm kiểu IVF vì nó giữ thiết lập cục bộ đơn giản và cung cấp một bước tạo chỉ mục cụ thể mà không biến hướng dẫn thành tài liệu tinh chỉnh chỉ mục.

Nhóm chỉ mục

Ý tưởng cơ bản

Thế mạnh

Đánh đổi

Khi nào dùng

IVF / phân vùng hàng xóm

Phân vùng không gian vector, sau đó tìm trong các phân vùng có khả năng

Mô hình tinh thần đơn giản, thực tiễn cho nhiều bộ dữ liệu nạp theo lô

Recall và tốc độ phụ thuộc vào phân vùng và thiết lập tìm kiếm

Chúng ta muốn đường đi tìm kiếm xấp xỉ đơn giản cho bộ dữ liệu đang tăng trưởng

HNSW / đồ thị hàng xóm

Xây đồ thị liên kết các vector gần nhau để duyệt nhanh

Hồ sơ recall và độ trễ mạnh cho nhiều khối lượng công việc lân cận gần nhất

Thiên về bộ nhớ hơn, và cấu hình có thể quan trọng hơn

Chúng ta cần độ trễ thấp và có thể dự trù bộ nhớ cùng công sức tinh chỉnh

Tích hợp với truy vấn quan hệ

Một cột vector có thể nằm cạnh các cột quan hệ thông thường. Bảng documents của chúng ta sẽ lưu tiêu đề, nội dung và embedding cùng nhau, để SQL có thể trả về cả điểm tương tự và văn bản gốc của tài liệu.

Bắt đầu với Oracle AI Vector Search

Chúng ta sẽ dùng một đường thiết lập cục bộ: Oracle Database Free 26ai trong Docker, dịch vụ FREEPDB1, và một người dùng ứng dụng riêng vector_demo. 

Các khái niệm tìm kiếm vector khá dễ tiếp cận, nhưng phần thiết lập ở mức trung cấp vì chúng ta dùng Docker, một schema cơ sở dữ liệu, các gói Python, biến môi trường và một khóa API embedding.

Yêu cầu tiên quyết

Chúng ta sẽ cần:

  • Docker Desktop hoặc Docker Engine.
  • Quyền truy cập Oracle Container Registry.
  • Các cổng cục bộ 1521 và 5500 còn trống.
  • Python 3.10 trở lên.
  • Kiến thức cơ bản về Python và SQL.
  • Hiểu biết cơ bản về Docker và biến môi trường.
  • Một khóa API OpenAI cho các bước embedding.

Bản demo này yêu cầu phiên bản hoặc môi trường Oracle Database bao gồm các tính năng vector dùng ở đây, gồm các cột VECTOR native, VECTOR_DISTANCE() và CREATE VECTOR INDEX. 

Đường cục bộ dùng Oracle Database Free 26ai với thẻ ảnh hiển thị bên dưới, và DSN dùng dịch vụ pluggable database FREEPDB1.

Các bước vector thủ công không yêu cầu khóa API OpenAI. Các bước ngữ nghĩa sẽ gửi văn bản tài liệu mẫu và văn bản truy vấn tới nhà cung cấp embedding đã cấu hình, vì vậy chúng ta chỉ dùng văn bản mẫu hoặc không nhạy cảm.

Hướng dẫn này dùng oracledb, driver Python hiện tại cho Oracle Database. python-oracledb chạy ở Thin mode theo mặc định, vì vậy demo cục bộ này không yêu cầu thư viện Oracle Client. Thick mode hữu ích trong các triển khai Oracle Database khác, nhưng chúng ta sẽ không gọi oracledb.init_oracle_client() ở đây.

Khởi chạy Oracle Database Free 26ai trên máy

Tạo thư mục dự án cho các script chúng ta sẽ xây dựng.

mkdir oracle-ai-vector-search-python
 cd oracle-ai-vector-search-python

Khởi chạy Oracle Database Free 26ai với ảnh container cục bộ.

docker run --name oracle-free-26ai-vector \
   --detach \
   --publish 1521:1521 \
   --publish 5500:5500 \
   --shm-size=1g \
   --env ORACLE_PWD="replace-with-a-strong-password" \
   container-registry.oracle.com/database/free:23.26.1.0-lite-amd64

Kiểm tra nhật ký container và chờ đến khi cơ sở dữ liệu báo đã khởi động xong.

docker logs oracle-free-26ai-vector

FREEPDB1 là dịch vụ pluggable database được dùng bởi đường dẫn container Oracle Database Free cục bộ này. DSN Python của chúng ta sẽ là localhost:1521/FREEPDB1.

Tạo schema vector_demo trong FREEPDB1

Chỉ dùng SYS cho bước thiết lập schema. Mật khẩu trong lệnh sqlplus là giá trị ORACLE_PWD từ lệnh docker run; mật khẩu trong CREATE USER là mật khẩu ứng dụng chúng ta sẽ export dưới dạng DB_PASSWORD.

Chạy thiết lập bên trong container cơ sở dữ liệu.

# Create the application user and grant the privileges needed for the demo.
 docker exec -i oracle-free-26ai-vector \
   sqlplus -s 'sys/"replace-with-oracle-pwd"@FREEPDB1 as sysdba' <<'SQL'
 WHENEVER SQLERROR EXIT SQL.SQLCODE

 CREATE USER vector_demo IDENTIFIED BY "replace-with-vector-demo-password";

 GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, UNLIMITED TABLESPACE TO vector_demo;

 EXIT
 SQL

Đây là lối tắt phát triển cục bộ cho container demo. CREATE SEQUENCE là cần thiết vì các bảng dùng cột identity. 

Với môi trường sản xuất, chúng ta sẽ rà soát đặc quyền với quản trị viên cơ sở dữ liệu và áp dụng nguyên tắc tối thiểu đặc quyền phù hợp khối lượng công việc ứng dụng.

Cài đặt phụ thuộc Python

Tạo và kích hoạt môi trường ảo.

python -m venv .venv
 source .venv/bin/activate
 python -m pip install --upgrade pip

Cài đặt các gói Python dùng trong demo.

python -m pip install oracledb openai

Đặt biến môi trường

Lưu thông tin xác thực cơ sở dữ liệu và thiết lập embedding trong biến môi trường thay vì ghi cứng trong các tệp Python.

export DB_USER="vector_demo"
 export DB_PASSWORD="replace-with-vector-demo-password"
 export DB_DSN="localhost:1521/FREEPDB1"
 export OPENAI_API_KEY="replace-with-your-api-key"
 export EMBEDDING_MODEL="text-embedding-3-small"
 export EMBEDDING_DIM="1536"

OPENAI_API_KEY chỉ cần cho các bước embedding và tìm kiếm ngữ nghĩa. EMBEDDING_DIM phải khớp với số chiều do mô hình embedding đã chọn trả về.

Dự án demo Oracle AI Vector Search

Chúng ta sẽ xây demo qua tám điểm kiểm tra. Mỗi script bổ sung một khái niệm và tạo ra đầu ra để xác minh trước khi tiếp tục.

Phần chỉ cơ sở dữ liệu hoàn tất sau Bước 1–3. Ở thời điểm đó, chúng ta đã kết nối tới Oracle Database, lưu vector thủ công, truy vấn chúng theo khoảng cách và tạo bảng ngữ nghĩa. Khóa API OpenAI bắt đầu cần từ Bước 4.

Bước 1: Kết nối đến cơ sở dữ liệu cục bộ

Trước tiên, chúng ta sẽ xác minh rằng Python có thể kết nối đến Oracle Database bằng người dùng ứng dụng vector_demo. Script này đọc DB_USER, DB_PASSWORD và DB_DSN từ môi trường và in ra chế độ driver cùng phiên bản cơ sở dữ liệu.

Tạo script

Lưu đoạn mã sau với tên 01_check_connection.py.

import os

 import oracledb

 ADMIN_USERS = {"SYS", "SYSTEM", "PDBADMIN"}


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def main():
 	# Load required database settings from environment variables.
 	user = required_env("DB_USER")
     password = required_env("DB_PASSWORD")
 	dsn = required_env("DB_DSN")

 	if user.upper() in ADMIN_USERS:
         raise SystemExit(
             "Use the vector_demo application user, not an admin user."
     	)

 	# Open a Thin-mode connection with the application user.
 	with oracledb.connect(user=user, password=password, dsn=dsn) as connection:
         mode = "thin" if oracledb.is_thin_mode() else "thick"
         print("Connected to Oracle Database.")
         print(f"Driver mode: {mode}")
         print(f"Database version: {connection.version}")


 if __name__ == "__main__":
 	main()

Chạy script

Chạy kiểm tra kết nối.

python 01_check_connection.py

Kết quả mong đợi

Đầu ra sẽ xác nhận kết nối hoạt động và driver ở Thin mode.

Connected to Oracle Database.
 Driver mode: thin
 Database version: 23.26.1.0.0

Giờ chúng ta biết cơ sở dữ liệu cục bộ, tên dịch vụ, thông tin xác thực và driver Python đang hoạt động trước khi tạo bất kỳ bảng vector nào.

Bước 2: Xây trực giác với các vector thủ công

Trước khi giới thiệu mô hình embedding, hãy lưu ba vector nhỏ dễ suy luận. Lời gọi array.array("f", values) tạo một mảng số thực 32-bit mà python-oracledb có thể bind vào cột VECTOR(..., FLOAT32).

Three-dimensional apple, banana, and car vectors showing Euclidean distance from the apple query vector.

Hình 2. Vector thủ công và khoảng cách Euclid.

Ví dụ thủ công dùng khoảng cách Euclid. Vector apple có khoảng cách 0.0000 vì trùng với vector truy vấn. Vector banana xếp thứ hai vì sqrt((1.0 - 0.9)^2 + (0.0 - 0.1)^2 + (0.0 - 0.0)^2) = 0.1414.

Tạo script

Lưu đoạn mã sau với tên 02_manual_vectors.py.

import array
 import os

 import oracledb

 ADMIN_USERS = {"SYS", "SYSTEM", "PDBADMIN"}


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def main():
 	user = required_env("DB_USER")
 	if user.upper() in ADMIN_USERS:
         raise SystemExit(
             "Use the vector_demo application user, not an admin user."
     	)

 	# Define three small vectors so the distance calculation is easy to inspect.
 	rows = [
         ("apple", array.array("f", [1.0, 0.0, 0.0])),
         ("banana", array.array("f", [0.9, 0.1, 0.0])),
         ("car", array.array("f", [0.0, 1.0, 0.0])),
 	]

 	with oracledb.connect(
         user=user,
         password=required_env("DB_PASSWORD"),
         dsn=required_env("DB_DSN"),
 	) as connection:
         with connection.cursor() as cursor:
             # Recreate the table so the script can be run repeatedly.
             cursor.execute(
                 """
                 BEGIN
                 	EXECUTE IMMEDIATE 'DROP TABLE manual_vectors PURGE';
                 EXCEPTION
                 	WHEN OTHERS THEN
                     	IF SQLCODE <> -942 THEN
                         	RAISE;
                     	END IF;
                 END;
                 """
             )
             cursor.execute(
                 """
                 CREATE TABLE manual_vectors (
                 	id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
                 	label VARCHAR2(100),
                 	embedding VECTOR(3, FLOAT32)
                 )
                 """
             )
             # Bind each vector as a 32-bit floating-point array.
             cursor.executemany(
                 """
                 INSERT INTO manual_vectors (label, embedding)
                 VALUES (:1, :2)
                 """,
                 rows,
             )
             connection.commit()

             # Rank rows by Euclidean distance from the query vector.
             cursor.execute(
                 """
                 SELECT label,
                    	VECTOR_DISTANCE(
                        	embedding,
                        	:query_vector,
                        	EUCLIDEAN
                    	) AS distance
                 FROM manual_vectors
                 ORDER BY distance
                 FETCH EXACT FIRST 2 ROWS ONLY
                 """,
                 query_vector=array.array("f", [1.0, 0.0, 0.0]),
             )

             print("Created manual_vectors.")
             print("Inserted 3 manual vectors.")
             print("\nNearest manual vectors:")
             for rank, (label, distance) in enumerate(cursor, start=1):
                 print(f"{rank}. {label:<6} distance={float(distance):.4f}")


 if __name__ == "__main__":
 	main()

Chạy script

Chạy script vector thủ công.

python 02_manual_vectors.py

Kết quả mong đợi

Vector giống hệt sẽ xuất hiện đầu tiên với khoảng cách 0.0000, và vector banana gần kề xuất hiện thứ hai.

Created manual_vectors.
 Inserted 3 manual vectors.

 Nearest manual vectors:
 1. apple  distance=0.0000
 2. banana distance=0.1414

Đây là ý tưởng cốt lõi của tìm kiếm vector: các hàng được xếp hạng theo độ gần gũi toán học với vector truy vấn. Các mô hình embedding sẽ tạo ra vector lớn hơn, nhưng hành vi của cơ sở dữ liệu vẫn như vậy.

Bước 3: Tạo bảng tài liệu ngữ nghĩa

Giờ khi chúng ta biết vector hoạt động, hãy tạo một bảng theo phong cách ứng dụng thực. Chi tiết quan trọng là số chiều của cột vector phải khớp với số chiều đầu ra của mô hình embedding.

Số chiều là một phần hợp đồng của bảng. Nếu một mô hình embedding trả về 1.536 số, cột phải được khai báo là VECTOR(1536, FLOAT32). 

Nếu sau này chúng ta chuyển sang mô hình có độ dài đầu ra khác, cần tạo lại hoặc di chuyển cột vector để các thao tác chèn và truy vấn tiếp tục dùng vector tương thích.

Vì DDL không thể bind số chiều vector như bind variable SQL thông thường, script sẽ chuyển EMBEDDING_DIM sang số nguyên trước khi dùng trong câu lệnh CREATE TABLE.

Tạo script

Lưu đoạn mã sau với tên 03_create_documents_table.py.

import os

 import oracledb

 ADMIN_USERS = {"SYS", "SYSTEM", "PDBADMIN"}


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def configured_dimension():
 	try:
         dimension = int(required_env("EMBEDDING_DIM"))
 	except ValueError as exc:
         raise SystemExit("EMBEDDING_DIM must be an integer.") from exc

 	if dimension <= 0:
         raise SystemExit("EMBEDDING_DIM must be a positive integer.")

 	return dimension


 def main():
 	user = required_env("DB_USER")
 	if user.upper() in ADMIN_USERS:
         raise SystemExit(
             "Use the vector_demo application user, not an admin user."
     	)

 	# Validate the configured model name and vector dimension.
     model_name = required_env("EMBEDDING_MODEL")
     dimension = configured_dimension()

 	with oracledb.connect(
         user=user,
         password=required_env("DB_PASSWORD"),
         dsn=required_env("DB_DSN"),
 	) as connection:
         with connection.cursor() as cursor:
             # Recreate the documents table so the script is repeatable.
             cursor.execute(
                 """
                 BEGIN
                 	EXECUTE IMMEDIATE 'DROP TABLE documents PURGE';
                 EXCEPTION
                 	WHEN OTHERS THEN
                     	IF SQLCODE <> -942 THEN
                         	RAISE;
                     	END IF;
                 END;
                 """
             )
             cursor.execute(
                 f"""
                 CREATE TABLE documents (
                 	id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
                 	title VARCHAR2(200) NOT NULL,
                 	content VARCHAR2(1000) NOT NULL,
                 	embedding VECTOR({dimension}, FLOAT32)
                 )
                 """
             )

     print(f"Embedding model: {model_name}")
     print(f"Embedding dimension: {dimension}")
     print("Recreated documents table.")


 if __name__ == "__main__":
 	main()

Chạy script

Chạy script tạo bảng.

python 03_create_documents_table.py

Kết quả mong đợi

Đầu ra sẽ hiển thị mô hình embedding và số chiều vector đã cấu hình.

Embedding model: text-embedding-3-small
 Embedding dimension: 1536
 Recreated documents table.

Chúng ta đã hoàn tất phần chỉ có cơ sở dữ liệu. Oracle Database có thể lưu trữ và so sánh vector cục bộ; tiếp theo, chúng ta sẽ thay các vector viết tay bằng embeddings tạo từ văn bản.

Bước 4: Xác minh số chiều của mô hình embedding

Trước khi chèn embeddings, chúng ta sẽ yêu cầu mô hình embedding trả về một vector và xác minh độ dài của nó. Điều này ngăn lỗi bảng vector phổ biến nhất: chèn một vector có độ dài không khớp với số chiều cột VECTOR.

Một mô hình embedding không chỉ là bộ chuyển văn bản thành số; nó định nghĩa không gian ý nghĩa cho ứng dụng. Mọi embedding tài liệu và truy vấn trong demo này phải đến từ cùng một mô hình.

Dùng một mô hình đảm bảo rằng khoảng cách nhỏ biểu thị ý nghĩa tương tự, thay vì hai vector không liên quan tình cờ có hình dạng giống nhau. Mô hình cũng quyết định độ dài vector, đó là lý do chúng ta kiểm tra số chiều trả về trước khi nạp dữ liệu.

Tạo script

Lưu đoạn mã sau với tên 04_check_embedding_dimension.py.

import os

 from openai import OpenAI


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def configured_dimension():
 	try:
         return int(required_env("EMBEDDING_DIM"))
 	except ValueError as exc:
         raise SystemExit("EMBEDDING_DIM must be an integer.") from exc


 def main():
     required_env("OPENAI_API_KEY")

     model_name = required_env("EMBEDDING_MODEL")
     expected_dimension = configured_dimension()

 	# Request one embedding to confirm the model output dimension.
 	client = OpenAI()
     response = client.embeddings.create(
         model=model_name,
         input="Oracle AI Vector Search dimension check",
 	)

     returned_dimension = len(response.data[0].embedding)

     print(f"Embedding model: {model_name}")
     print(f"Returned embedding length: {returned_dimension}")
     print(f"Configured EMBEDDING_DIM: {expected_dimension}")

 	# Stop before loading data if the table dimension is incompatible.
 	if returned_dimension != expected_dimension:
         raise SystemExit(
             "Dimension check failed. Update EMBEDDING_DIM, rerun "
             "03_create_documents_table.py, and try again."
     	)

     print("Dimension check passed.")


 if __name__ == "__main__":
 	main()

Chạy script

Chạy kiểm tra số chiều.

python 04_check_embedding_dimension.py

Kết quả mong đợi

Với mô hình và số chiều mặc định, đầu ra sẽ như sau.

Embedding model: text-embedding-3-small
 Returned embedding length: 1536
 Configured EMBEDDING_DIM: 1536
 Dimension check passed.

Nếu sau này chọn mô hình embedding khác, chúng ta nên cập nhật EMBEDDING_MODEL, đặt EMBEDDING_DIM bằng độ dài vector trả về, và tạo lại bảng documents.

Bước 5: Tạo và chèn embeddings tài liệu

Giờ chúng ta sẽ tạo embeddings cho một bộ dữ liệu nhỏ, độc lập và chèn chúng vào Oracle Database. 

Mỗi embedding được chuyển thành array.array("f", embedding) trước khi bind để khớp với cột vector FLOAT32.

Tạo script

Lưu đoạn mã sau với tên 05_insert_embeddings.py.

import array
 import os

 import oracledb
 from openai import OpenAI

 DOCUMENTS = [
 	(
         "Oracle AI Vector Search",
         "Oracle Database can store vector embeddings in native VECTOR "
         "columns and query them with SQL similarity search.",
 	),
 	(
         "Semantic Search for Applications",
         "Semantic search ranks results by meaning, helping applications "
         "find related content even when exact words differ.",
 	),
 	(
         "Vector Index Workflow",
         "Vector indexes help approximate nearest-neighbor search scale "
         "when datasets grow beyond small examples.",
 	),
 	(
         "Local Docker Development",
         "Docker containers make it practical to run a local database for "
         "development and repeatable tutorials.",
 	),
 	(
         "Python Database Code",
         "Python applications can connect to Oracle Database with the "
         "oracledb driver and use environment variables for credentials.",
 	),
 	(
         "Acoustic Guitar Practice",
         "Daily guitar practice improves timing, chord transitions, and "
         "confidence when learning new songs.",
 	),
 	(
         "Weeknight Vegetable Soup",
         "A simple soup can combine onions, carrots, beans, herbs, and "
         "broth for an easy weeknight meal.",
 	),
 ]

 ADMIN_USERS = {"SYS", "SYSTEM", "PDBADMIN"}


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def configured_dimension():
 	try:
         return int(required_env("EMBEDDING_DIM"))
 	except ValueError as exc:
         raise SystemExit("EMBEDDING_DIM must be an integer.") from exc


 def main():
 	user = required_env("DB_USER")
 	if user.upper() in ADMIN_USERS:
         raise SystemExit(
             "Use the vector_demo application user, not an admin user."
     	)

     required_env("OPENAI_API_KEY")
     model_name = required_env("EMBEDDING_MODEL")
     expected_dimension = configured_dimension()

 	# Generate embeddings for all sample documents in one API request.
 	client = OpenAI()
     response = client.embeddings.create(
         model=model_name,
         input=[content for _, content in DOCUMENTS],
 	)

 	# Restore the response order using each item's index.
     embeddings = [
         item.embedding
     	for item in sorted(
             response.data,
             key=lambda item: item.index,
     	)
 	]

 	if any(len(embedding) != expected_dimension for embedding in embeddings):
         raise SystemExit(
             "An embedding length did not match EMBEDDING_DIM. "
             "Rerun 04_check_embedding_dimension.py."
     	)

 	# Bind each embedding as a 32-bit floating-point array.
 	rows = [
         (title, content, array.array("f", embedding))
     	for (title, content), embedding in zip(DOCUMENTS, embeddings)
 	]

 	# Replace the sample rows and commit the transaction.
 	with oracledb.connect(
         user=user,
         password=required_env("DB_PASSWORD"),
         dsn=required_env("DB_DSN"),
 	) as connection:
         with connection.cursor() as cursor:
             cursor.execute("DELETE FROM documents")
             cursor.executemany(
                 """
                 INSERT INTO documents (title, content, embedding)
                 VALUES (:1, :2, :3)
                 """,
                 rows,
             )
             cursor.execute("SELECT COUNT(*) FROM documents")
             row_count = cursor.fetchone()[0]
             connection.commit()

     print(f"Embedding model: {model_name}")
     print(f"Generated embeddings for {len(DOCUMENTS)} documents.")
     print(f"Inserted {len(DOCUMENTS)} documents.")
     print(f"documents row count: {row_count}")


 if __name__ == "__main__":
 	main()

Chạy script

Chạy script chèn dữ liệu.

python 05_insert_embeddings.py

Kết quả mong đợi

Số hàng phải khớp với bảy documents nội tuyến.

Embedding model: text-embedding-3-small
 Generated embeddings for 7 documents.
 Inserted 7 documents.
 documents row count: 7

Giờ chúng ta đã lưu văn bản và embeddings cùng nhau trong Oracle Database. Các documents không liên quan về guitar và súp được đưa vào để kết quả tìm kiếm có những khớp gần và xa rõ rệt.

Bước 6: Chạy truy vấn tìm kiếm ngữ nghĩa

Tiếp theo, chúng ta sẽ embedding một truy vấn ngôn ngữ tự nhiên và so sánh với embeddings tài liệu đã lưu. Script này dùng khoảng cách cosine, thường dùng cho embeddings văn bản vì nó tập trung vào hướng vector hơn là độ lớn thô.

Với tìm kiếm ngữ nghĩa, truy vấn đi qua cùng một mô hình embedding như các documents. Chúng ta không yêu cầu SQL hiểu trực tiếp câu tiếng Anh. 

Chúng ta yêu cầu mô hình embedding biến câu thành vector, sau đó yêu cầu Oracle Database xếp hạng các vector đã lưu theo khoảng cách với vector truy vấn đó.

Tạo script

Lưu đoạn mã sau với tên 06_semantic_search.py.

import array
 import os

 import oracledb
 from openai import OpenAI

 QUERY_TEXT = "Where should an AI app keep meaning-based search data?"
 ADMIN_USERS = {"SYS", "SYSTEM", "PDBADMIN"}


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def main():
 	user = required_env("DB_USER")
 	if user.upper() in ADMIN_USERS:
         raise SystemExit(
             "Use the vector_demo application user, not an admin user."
     	)

     required_env("OPENAI_API_KEY")

 	# Generate an embedding for the natural-language query.
 	client = OpenAI()
     response = client.embeddings.create(
         model=required_env("EMBEDDING_MODEL"),
         input=QUERY_TEXT,
 	)
     query_vector = array.array("f", response.data[0].embedding)

 	with oracledb.connect(
         user=user,
         password=required_env("DB_PASSWORD"),
         dsn=required_env("DB_DSN"),
 	) as connection:
         with connection.cursor() as cursor:
             # Rank stored documents by cosine distance from the query vector.
             cursor.execute(
                 """
                 SELECT title,
                    	content,
                    	VECTOR_DISTANCE(
                        	embedding,
                        	:query_vector,
                        	COSINE
                    	) AS distance
                 FROM documents
                 ORDER BY distance
                 FETCH EXACT FIRST 5 ROWS ONLY
                 """,
                 query_vector=query_vector,
             )
             rows = cursor.fetchall()

 	if not rows:
         raise SystemExit("No documents found. Run 05_insert_embeddings.py first.")

     print(f"Query: {QUERY_TEXT}")
     print("\nTop 5 results:")

 	for rank, (title, content, distance) in enumerate(rows, start=1):
         print(f"{rank}. {title}")
         print(f"   distance: {float(distance):.6f}")
         print(f"   {content[:90]}...")


 if __name__ == "__main__":
 	main()

Chạy script

Chạy script tìm kiếm ngữ nghĩa.

python 06_semantic_search.py

Kết quả mong đợi

Thứ hạng và khoảng cách chính xác có thể thay đổi khi mô hình embedding thay đổi. Tuy nhiên, các documents về Oracle AI Vector Search, tìm kiếm ngữ nghĩa, mã Python kết nối cơ sở dữ liệu và lập chỉ mục vector nên xếp gần đầu.

Query: Where should an AI app keep meaning-based search data?

 Top 5 results:
 1. Oracle AI Vector Search
    distance: <cosine distance from your run>
    Oracle Database can store vector embeddings in native VECTOR columns and query them with SQL...

 2. Semantic Search for Applications
    distance: <cosine distance from your run>
    Semantic search ranks results by meaning, helping applications find related content even when...

 3. Python Database Code
    distance: <cosine distance from your run>
    Python applications can connect to Oracle Database with the oracledb driver and use environment...

 4. Vector Index Workflow
    distance: <cosine distance from your run>
    Vector indexes help approximate nearest-neighbor search scale when datasets grow beyond small...

 5. Local Docker Development
    distance: <cosine distance from your run>
    Docker containers make it practical to run a local database for development and repeatable...

Với các truy vấn khoảng cách Euclid và cosine trong hướng dẫn này, giá trị nhỏ hơn thể hiện khớp gần hơn. 

Tích vô hướng là một cách so sánh vector hữu ích khác trong nhiều quy trình tìm kiếm vector, đặc biệt khi độ lớn hoặc vector chuẩn hóa quan trọng, nhưng hướng điểm số và chuẩn hóa cần được xử lý cẩn thận. 

Chúng ta sẽ giữ mã có thể chạy ở khoảng cách Euclid và cosine để việc diễn giải kết quả đơn giản.

Nếu tự chuẩn hóa embeddings trong ứng dụng tương lai, chúng ta cần chuẩn hóa nhất quán cả embeddings tài liệu đã lưu và embeddings truy vấn; nếu không, khoảng cách và xếp hạng có thể thay đổi.

Bước 7: So sánh tìm kiếm ngữ nghĩa với khớp cụm từ

Tìm kiếm ngữ nghĩa hữu ích vì không yêu cầu cụm từ chính xác phải xuất hiện trong tài liệu.

Hãy so sánh truy vấn ngữ nghĩa với một điều kiện cụm từ chính xác đơn giản.

Đây không phải bản demo máy tìm kiếm toàn văn; đây là một phép so sánh SQL nhỏ để làm rõ khác biệt giữa khớp chữ nghĩa đen và xếp hạng dựa trên ý nghĩa.

Tạo script

Lưu đoạn mã sau với tên 07_semantic_vs_keyword.py.

import array
 import os

 import oracledb
 from openai import OpenAI

 SEMANTIC_QUERY = "Where should an AI app keep meaning-based search data?"
 KEYWORD_PHRASE = "meaning-based search data"
 ADMIN_USERS = {"SYS", "SYSTEM", "PDBADMIN"}


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def main():
 	user = required_env("DB_USER")
 	if user.upper() in ADMIN_USERS:
         raise SystemExit(
             "Use the vector_demo application user, not an admin user."
     	)

     required_env("OPENAI_API_KEY")

 	# Generate an embedding for the semantic query.
 	client = OpenAI()
     response = client.embeddings.create(
         model=required_env("EMBEDDING_MODEL"),
         input=SEMANTIC_QUERY,
 	)
     query_vector = array.array("f", response.data[0].embedding)

 	with oracledb.connect(
         user=user,
         password=required_env("DB_PASSWORD"),
         dsn=required_env("DB_DSN"),
 	) as connection:
         with connection.cursor() as cursor:
             # Rank documents by semantic similarity.
             cursor.execute(
                 """
                 SELECT title,
                        VECTOR_DISTANCE(embedding, :query_vector, COSINE)
                 FROM documents
                 ORDER BY VECTOR_DISTANCE(embedding, :query_vector, COSINE)
                 FETCH EXACT FIRST 3 ROWS ONLY
                 """,
                 query_vector=query_vector,
             )
             semantic_rows = cursor.fetchall()

             # Compare semantic results with an exact phrase predicate.
             cursor.execute(
                 """
                 SELECT title
                 FROM documents
                 WHERE LOWER(title || ' ' || content)
                   	LIKE '%' || :phrase || '%'
                 ORDER BY title
                 FETCH FIRST 3 ROWS ONLY
                 """,
                 phrase=KEYWORD_PHRASE.lower(),
             )
             keyword_rows = cursor.fetchall()

     print(f"Semantic query: {SEMANTIC_QUERY}")
     print(f"Keyword phrase: {KEYWORD_PHRASE}")

     print("\nSemantic results:")
 	for rank, (title, distance) in enumerate(semantic_rows, start=1):
         print(f"{rank}. {title}")
         print(f"   distance: {float(distance):.6f}")

     print("\nKeyword results:")
 	if keyword_rows:
     	for rank, (title,) in enumerate(keyword_rows, start=1):
             print(f"{rank}. {title}")
 	else:
         print("0 exact phrase matches")


 if __name__ == "__main__":
 	main()

Chạy script

Chạy script so sánh.

python 07_semantic_vs_keyword.py

Kết quả mong đợi

Tìm kiếm ngữ nghĩa sẽ trả về các documents phù hợp dù cụm từ khóa chính xác không xuất hiện.

Semantic query: Where should an AI app keep meaning-based search data?
 Keyword phrase: meaning-based search data

 Semantic results:
 1. Oracle AI Vector Search
    distance: <cosine distance from your run>
 2. Semantic Search for Applications
    distance: <cosine distance from your run>
 3. Python Database Code
    distance: <cosine distance from your run>

 Keyword results:
 0 exact phrase matches

Các điều kiện SQL truyền thống vẫn quan trọng cho bộ lọc, join, quyền truy cập và khớp chính xác. Tìm kiếm vector bổ sung một tín hiệu xếp hạng dựa trên ý nghĩa mà chúng ta có thể kết hợp với dữ liệu quan hệ khi ứng dụng cần truy xuất ngữ nghĩa.

Bước 8: Thêm và xác thực một chỉ mục vector

Cuối cùng, chúng ta sẽ tạo một chỉ mục vector và xác thực rằng Oracle Database báo cáo nó là một chỉ mục hợp lệ thuộc schema demo. 

Bước này minh họa quy trình tạo chỉ mục; bộ dữ liệu tí hon của chúng ta không đủ lớn để rút ra kết luận hiệu năng có ý nghĩa.

Không có chỉ mục, Oracle Database có thể so sánh chính xác vector truy vấn với từng vector đã lưu. Cách này phù hợp cho bộ dữ liệu rất nhỏ và hữu ích khi học.

Với bộ dữ liệu lớn hơn, chỉ mục vector xấp xỉ giảm không gian tìm kiếm để truy vấn có thể trả về nhanh mà vẫn tìm thấy hàng xóm gần. 

Chọn nhóm chỉ mục sau khi cân nhắc kích thước dữ liệu, mục tiêu độ trễ, yêu cầu recall, ngân sách bộ nhớ và tần suất vector thay đổi.

Truy vấn ở cuối sẽ xác nhận rằng tìm kiếm ngữ nghĩa vẫn trả về kết quả sau khi tạo chỉ mục. 

Chúng ta sẽ không dùng EXPLAIN PLAN hay DBMS_XPLAN ở đây vì hướng dẫn này xác thực tạo chỉ mục bằng metadata schema, không phải hành vi kế hoạch truy vấn.

Tạo script

Lưu đoạn mã sau với tên 08_create_vector_index.py.

import array
 import os

 import oracledb
 from openai import OpenAI

 INDEX_NAME = "DOCUMENT_EMBEDDING_IDX"
 QUERY_TEXT = "Where should an AI app keep meaning-based search data?"
 ADMIN_USERS = {"SYS", "SYSTEM", "PDBADMIN"}


 def required_env(name):
 	value = os.getenv(name)
 	if not value:
         raise SystemExit(f"Set {name} before running this script.")
 	return value


 def main():
 	user = required_env("DB_USER")
 	if user.upper() in ADMIN_USERS:
         raise SystemExit(
             "Use the vector_demo application user, not an admin user."
     	)

     required_env("OPENAI_API_KEY")

 	# Generate the query vector used for the validation search.
 	client = OpenAI()
     response = client.embeddings.create(
         model=required_env("EMBEDDING_MODEL"),
         input=QUERY_TEXT,
 	)
     query_vector = array.array("f", response.data[0].embedding)

 	with oracledb.connect(
         user=user,
         password=required_env("DB_PASSWORD"),
         dsn=required_env("DB_DSN"),
 	) as connection:
         with connection.cursor() as cursor:
             # Remove a prior index so the script can be rerun safely.
             try:
                 cursor.execute(f"DROP INDEX {INDEX_NAME}")
             except oracledb.DatabaseError as exc:
                 error = exc.args[0]
                 if error.code != 1418:
                 	raise

             # Create an approximate neighbor-partitions vector index.
             cursor.execute(
                 """
                 CREATE VECTOR INDEX document_embedding_idx
                 ON documents (embedding)
                 ORGANIZATION NEIGHBOR PARTITIONS
                 DISTANCE COSINE
                 WITH TARGET ACCURACY 95
                 """
             )

             # Confirm that Oracle reports the vector index as valid.
             cursor.execute(
                 """
                 SELECT index_name, index_type, status
                 FROM user_indexes
                 WHERE index_name = :index_name
                 """,
                 index_name=INDEX_NAME,
             )
             index_row = cursor.fetchone()

             # Confirm that semantic search still returns rows after index creation.
             cursor.execute(
                 """
                 SELECT title
                 FROM documents
                 ORDER BY VECTOR_DISTANCE(embedding, :query_vector, COSINE)
                 FETCH EXACT FIRST 3 ROWS ONLY
                 """,
                 query_vector=query_vector,
             )
             rows = cursor.fetchall()

 	if not index_row:
         raise SystemExit("Vector index was not found in USER_INDEXES.")

     print("Created vector index DOCUMENT_EMBEDDING_IDX.")
     print("\nIndex validation:")
     print(f"Index name: {index_row[0]}")
     print(f"Index type: {index_row[1]}")
     print(f"Status: {index_row[2]}")
     result_count = len(rows)

 	print(
         "\nSemantic search still returns "
         f"{result_count} results after index creation."
 	)


 if __name__ == "__main__":
 	main()

Chạy script

Chạy script tạo chỉ mục.

python 08_create_vector_index.py

Kết quả mong đợi

Đầu ra nên bao gồm một hàng cho DOCUMENT_EMBEDDING_IDX, với INDEX_TYPE là VECTOR và STATUS là VALID.

Created vector index DOCUMENT_EMBEDDING_IDX.

 Index validation:
 Index name: DOCUMENT_EMBEDDING_IDX
 Index type: VECTOR
 Status: VALID

 Semantic search still returns 3 results after index creation.

USER_INDEXES xác nhận chỉ mục tồn tại và hợp lệ. Nó không chứng minh một truy vấn cụ thể đã dùng chỉ mục, và hướng dẫn này không dùng đầu ra kế hoạch thực thi như một phương pháp xác thực. 

Với khối lượng công việc sản xuất, chúng ta sẽ kiểm thử với dữ liệu thực tế, mẫu truy vấn và mục tiêu hiệu năng thực tế.

Mẹo và khắc phục sự cố Oracle AI Vector Search

Container cơ sở dữ liệu vẫn đang khởi động

Chờ cho đến khi khởi động hoàn tất, sau đó chạy lại docker logs oracle-free-26ai-vector. Cơ sở dữ liệu phải sẵn sàng trước khi Python có thể kết nối localhost:1521/FREEPDB1.

Cổng 1521 đã được sử dụng

Dừng dịch vụ cục bộ xung đột hoặc thay đổi ánh xạ cổng Docker. Cập nhật DB_DSN nếu cổng trên host thay đổi.

Kết nối cơ sở dữ liệu thất bại

Xác minh DB_USER, DB_PASSWORD và DB_DSN. Dùng FREEPDB1 trong DSN, và kết nối các script ứng dụng bằng vector_demo, không phải SYS, SYSTEM hay PDBADMIN.

Thiếu khóa API embedding

Bước 1-3 chỉ dùng cơ sở dữ liệu. Bước 4-8 yêu cầu OPENAI_API_KEY và có thể phát sinh chi phí API.

Số chiều vector không khớp

Chạy 04_check_embedding_dimension.py, cập nhật EMBEDDING_DIM, chạy lại 03_create_documents_table.py, và nạp lại embeddings bằng 05_insert_embeddings.py.

Bind vector thất bại

Đảm bảo mọi bind vector FLOAT32 dùng array.array("f", values). Hướng dẫn dùng định dạng này cho vector thủ công, embeddings tài liệu đã lưu và embeddings truy vấn.

Thứ hạng ngữ nghĩa khác ví dụ

Điều này là bình thường. Nhà cung cấp embedding có thể cập nhật mô hình, và khoảng cách số thực có thể thay đổi giữa các lần chạy.

Tạo chỉ mục vector thất bại

Xác nhận bảng documents tồn tại, schema vector_demo sở hữu nó, và DOCUMENT_EMBEDDING_IDX không bị sót lại từ một lần chạy dở dang.

Chuẩn bị cho sản xuất

Dùng oracledb.create_pool() để tạo pool kết nối, benchmark với khối lượng dữ liệu thực tế, rà soát bảo mật và quản lý secret, và tinh chỉnh chỉ mục theo mẫu truy vấn thực.

Dừng và xóa container

Khi hoàn tất hướng dẫn, hãy dừng và xóa container cục bộ.

docker stop oracle-free-26ai-vector
docker rm oracle-free-26ai-vector

Kết luận

Chúng ta đã xây một quy trình tìm kiếm ngữ nghĩa cục bộ với Oracle AI Vector Search, Oracle Database Free 26ai và Python. 

Chúng ta bắt đầu với các giá trị VECTOR(3, FLOAT32) viết tay, chèn embeddings do mô hình tạo bằng array.array("f", values), truy vấn các documents tương tự bằng VECTOR_DISTANCE(), so sánh truy xuất ngữ nghĩa với một điều kiện cụm từ chính xác đơn giản và xác thực một chỉ mục vector qua USER_INDEXES.

Cách tiếp cận này phù hợp khi embeddings cần nằm cạnh dữ liệu quan hệ và chúng ta muốn lưu trữ và tìm kiếm hiển thị qua SQL mà không thêm cơ sở dữ liệu vector riêng cho quy trình cục bộ. 

Demo được cố ý giữ nhỏ: nó dạy các nguyên thủy, không phải quy mô sản xuất. Ứng dụng lớn hơn nên benchmark với dữ liệu thực, rà soát bảo mật và đặc quyền, dùng pool kết nối, và xác thực lựa chọn chỉ mục theo mẫu truy vấn thực.

Tiếp theo, chúng ta có thể đào sâu triển khai với các tài nguyên sau:

FAQs

Oracle AI Vector Search là gì?

Oracle AI Vector Search là tập hợp các khả năng của Oracle Database để lưu trữ, lập chỉ mục và truy vấn vector embeddings cùng với dữ liệu quan hệ.

Tôi có cần khóa API OpenAI để hoàn thành hướng dẫn không?

Các bước vector thủ công và thiết lập cơ sở dữ liệu không yêu cầu khóa API. Bước 4-8 yêu cầu nhà cung cấp embedding và OPENAI_API_KEY đã cấu hình.

Vì sao EMBEDDING_DIM phải khớp với mô hình embedding?

Số chiều của cột VECTOR phải bằng số giá trị do mô hình embedding trả về. Không khớp sẽ khiến việc chèn vector thất bại.

Hướng dẫn dùng những thước đo khoảng cách nào?

Ví dụ vector thủ công dùng khoảng cách Euclid. Các ví dụ tìm kiếm ngữ nghĩa dùng khoảng cách cosine.

Một chỉ mục vector hợp lệ có chứng minh rằng truy vấn đã dùng chỉ mục không?

Không. USER_INDEXES xác nhận chỉ mục tồn tại và có trạng thái hợp lệ, nhưng không xác nhận rằng một truy vấn cụ thể đã dùng nó.

Mark Nelson

Tác giả

Mark Nelson

Mark Nelson là một kiến trúc sư và developer evangelist tại Oracle.  Anh làm việc ở điểm giao thoa giữa AI, microservices và các công nghệ cơ sở dữ liệu.  Anh là một blogger năng động, tác giả đã xuất bản, biên tập viên kỹ thuật tại Manning Publications, Trưởng nhóm tại Stanford Code in Place, và cố vấn tại DeepLearning.ai.  Anh thường xuyên thuyết trình tại các Java và Oracle User Group, các buổi gặp gỡ về AI và những hội thảo lớn.  Anh có niềm đam mê học hỏi và giảng dạy.  Anh có hơn ba mươi năm kinh nghiệm trong ngành, tại IBM và Oracle.

Chủ đề

Liên quan