Hướng dẫn mô hình và phương thức10 tháng 11, 2026Flatkey Team

API OpenAI Embeddings: Xây dựng và kiểm chứng tìm kiếm ngữ nghĩa

Xây dựng ví dụ tìm kiếm ngữ nghĩa nhỏ với embeddings OpenAI, sau đó kiểm chứng ánh xạ vector, giới hạn token, thay đổi chỉ mục và chất lượng truy xuất.

API OpenAI Embeddings: Xây dựng và kiểm chứng tìm kiếm ngữ nghĩa

Đang tìm kiếm API embeddings của OpenAI? Điểm cuối embeddings của OpenAI chuyển đổi văn bản thành các vector số để ứng dụng có thể truy xuất các đoạn văn liên quan. Yêu cầu chỉ là bước đầu tiên: một tính năng tìm kiếm hữu ích cũng cần ID tài liệu ổn định, không gian vector nhất quán và một phép kiểm thử cho biết liệu việc truy xuất có được cải thiện hay không.

Hướng dẫn này xây dựng một ví dụ tìm kiếm nhỏ bằng Python, cho thấy cần lưu trữ những gì cùng với mỗi vector và cung cấp danh sách kiểm tra để đưa thử nghiệm vào sản phẩm. Hướng dẫn sử dụng trực tiếp OpenAI. Khả năng tương thích của gateway và tính khả dụng của mô hình phải được xác minh riêng cho từng nhà cung cấp.

API embeddings của OpenAI: yêu cầu bạn cần

Gửi văn bản đến POST https://api.openai.com/v1/embeddings cùng với một mô hình embedding và khóa API. Chọn encoding_format="float" khi ứng dụng của bạn cần các mảng số. Với một lô, hãy dùng index của từng mục phản hồi để liên kết lại vector với dữ liệu đầu vào của nó. Phản hồi cũng bao gồm mức sử dụng token. Tùy chọn dimensions được các mô hình embedding thế hệ thứ ba hỗ trợ. Tài liệu tham khảo API OpenAI.

Embedding không phải là câu trả lời được tạo ra. Trong một ứng dụng tăng cường truy xuất, bước tìm kiếm trước tiên sẽ chọn các đoạn nguồn; sau đó một lệnh gọi tạo sinh riêng biệt có thể trả lời dựa trên các đoạn đó. Việc tách riêng các giai đoạn giúp bạn chẩn đoán kết quả kém: tìm kiếm đã truy xuất sai bằng chứng, hay mô hình trả lời đã sử dụng sai bằng chứng tốt?

Chọn một mô hình và giữ cố định cấu hình của nó

Độ dài vector mặc định được tài liệu hóa là 1.536 cho text-embedding-3-small và 3.072 cho text-embedding-3-large. Các mô hình này hỗ trợ vector đầu ra ngắn hơn thông qua dimensions. Vector ngắn hơn thay đổi các đánh đổi về lưu trữ và truy xuất; đó không phải là lý do để bỏ qua việc đánh giá. Hướng dẫn embeddings của OpenAI.

Hãy bắt đầu với một cấu hình và một tập nhỏ các truy vấn mang tính đại diện. Ghi lại mô hình, số chiều được yêu cầu và phiên bản xử lý văn bản cùng với chỉ mục. Hai vector có cùng độ dài không chứng minh rằng chúng đến từ một mô hình tương thích. Khi thay đổi mô hình hoặc quy tắc xử lý, hãy xây dựng một chỉ mục riêng và so sánh trước khi chuyển lưu lượng production.

Một ví dụ tìm kiếm ngữ nghĩa Python tối giản

Cài đặt openai trong môi trường Python của bạn và cung cấp OPENAI_API_KEY thông qua trình quản lý bí mật hoặc cấu hình môi trường thông thường. Không đưa khóa vào mã nguồn được quản lý phiên bản và mã chạy trên trình duyệt. SDK Python chính thức đọc biến đó khi khởi tạo OpenAI().

Lưu nội dung sau dưới tên search_demo.py. Ví dụ sử dụng ba tài liệu hỗ trợ giả định, tạo embedding cho kho tài liệu và một truy vấn, rồi xếp hạng tài liệu bằng độ tương đồng cosine. Việc chạy chương trình sẽ tạo các yêu cầu API có tính phí. Đầu ra phụ thuộc vào phản hồi của dịch vụ; ví dụ không cam kết một điểm số hoặc thứ hạng cụ thể.

import math
from openai import OpenAI

client = OpenAI(timeout=30.0, max_retries=2)
model = "text-embedding-3-small"
dimensions = 1536

documents = [
    {"id": "key-rotation", "text": "Replace an exposed API key and revoke the old credential."},
    {"id": "invoice-export", "text": "Download a monthly invoice from the billing workspace."},
    {"id": "request-timeout", "text": "Record the request ID and retry temporary upstream timeouts."},
]
query = "What should I do after accidentally sharing a secret key?"


def embed(texts):
    response = client.embeddings.create(
        model=model, input=texts,
        dimensions=dimensions, encoding_format="float",
    )
    ordered = sorted(response.data, key=lambda item: item.index)
    if [item.index for item in ordered] != list(range(len(texts))):
        raise ValueError("Unexpected embedding response indices")
    vectors = [item.embedding for item in ordered]
    if any(len(vector) != dimensions for vector in vectors):
        raise ValueError("Unexpected vector dimensions")
    print("Input tokens:", response.usage.prompt_tokens)
    return vectors


def cosine(a, b):
    if len(a) != len(b):
        raise ValueError("Vector dimensions do not match")
    denominator = math.sqrt(sum(x*x for x in a) * sum(y*y for y in b))
    if not denominator:
        raise ValueError("Cannot compare a zero vector")
    return sum(x*y for x, y in zip(a, b)) / denominator


vectors = embed([document["text"] for document in documents])
query_vector = embed([query])[0]
ranked = sorted(
    ((cosine(query_vector, vector), document["id"])
     for document, vector in zip(documents, vectors)),
    reverse=True,
)
for score, document_id in ranked:
    print(document_id, round(score, 4))

Chạy python search_demo.py. Xác nhận rằng cả ba ID đều xuất hiện đúng một lần và mỗi embedding có độ dài đã cấu hình. Sau đó thay đổi truy vấn để hỏi về hóa đơn. Đây là phép kiểm tra nhanh cho luồng dữ liệu, không phải bằng chứng rằng hệ thống đã sẵn sàng cho lưu lượng hỗ trợ thực tế. Để rõ ràng, ví dụ tạo embedding lại cho kho tài liệu ở mỗi lần thực thi; một dịch vụ được triển khai thông thường nên lưu trữ các vector tài liệu và chỉ tạo embedding cho nội dung mới hoặc đã thay đổi.

Chuyển bản demo thành một chỉ mục tài liệu đáng tin cậy

Bố cục bản ghi sau đây là một điểm khởi đầu thực tế. Đây là ví dụ về thiết kế ứng dụng, không phải lược đồ trường bắt buộc của OpenAI.

Lưu cùng mỗi chunkVì sao điều này quan trọng
document_id và chunk_idCập nhật hoặc xóa đúng nội dung mà không phụ thuộc vào thứ tự mảng.
URL nguồn, tiêu đề mục và bản sửa đổi nguồnHiển thị trích dẫn hữu ích và truy vết các câu trả lời lỗi thời.
Hash nội dung và phiên bản xử lýXác định những chunk nào thực sự cần được tạo embedding lại.
Mô hình và số chiềuNgăn việc vô tình trộn lẫn các cấu hình vector không tương thích.
Siêu dữ liệu tenant và kiểm soát truy cậpLọc truy xuất thành các tài liệu mà người dùng yêu cầu được phép truy cập.
Văn bản và embeddingTrả về đoạn nguồn sau khi chọn vector của đoạn đó.

Chia tài liệu tại các ranh giới có ý nghĩa, rồi kiểm tra độ dài token. Một mục chứa câu trả lời cho câu hỏi phải vẫn dễ hiểu khi được truy xuất riêng lẻ. Đánh giá phần chồng lấp một cách có chủ đích: chồng lấp quá mức có thể lấp đầy tập kết quả bằng các phiên bản lặp lại của cùng một đoạn.

Đối với thử nghiệm đầu tiên, vòng lặp trong bộ nhớ ở trên là đủ. Khi kho ngữ liệu phát triển, hãy dùng một chỉ mục hoặc kho vector hỗ trợ hành vi lọc, xóa và truy xuất mà bạn cần. Hãy kiểm tra các thao tác đó trước khi dựa vào điểm tương đồng. Một đoạn có độ tương đồng cao từ khách hàng không đúng tuyệt đối không được trả về chỉ vì nó xếp hạng đầu tiên.

Kiểm tra riêng các giới hạn đầu vào và batch

Tài liệu tham chiếu endpoint hiện tại của OpenAI quy định tối đa 8.192 token cho mỗi đầu vào và tổng cộng tối đa 300.000 token trên các đầu vào trong một yêu cầu; tài liệu này cũng nêu tối đa 2.048 đầu vào batch. Văn bản rỗng là không hợp lệ. Hãy đếm token thay vì ký tự và chừa khoảng cách dưới các giới hạn khi xây dựng batch. Các ràng buộc của endpoint.

Nếu bạn sử dụng Azure OpenAI, cấu hình endpoint, xác thực và cách đặt tên deployment có thiết lập riêng. Hãy làm theo hướng dẫn về embeddings của Azure cho dịch vụ đó thay vì cho rằng có thể sao chép nguyên trạng một yêu cầu OpenAI trực tiếp. Áp dụng sự tách biệt tương tự khi dùng gateway: trước tiên hãy kiểm tra endpoint, quyền truy cập mô hình, tham số được hỗ trợ và tài khoản thanh toán của gateway.

Ước tính chi phí mà không che giấu việc xây dựng lại chỉ mục

Chi phí embedding phụ thuộc vào token đầu vào, vì vậy hãy đếm riêng việc nạp tài liệu, các chunk đã thay đổi và embedding cho truy vấn. Sử dụng mức giá hiện tại từ trang mô hình liên quan, chẳng hạn text-embedding-3-small, và xác nhận liệu mức giá được nêu có áp dụng cho chế độ yêu cầu của bạn hay không.

Đối với một ví dụ lập kế hoạch, đặt P là mức giá đã xác minh của bạn cho một triệu token đầu vào:

Nạp ban đầu: 50.000 chunk × 400 token = 20 triệu token
Thay đổi hằng tháng:    5.000 chunk × 400 token =  2 triệu token
Truy vấn hằng tháng:  200.000 truy vấn × 20 token =  4 triệu token

Chi phí embedding ban đầu = 20 × P
Chi phí embedding định kỳ = (2 + 4) × P = 6 × P

Đây là các giả định về khối lượng công việc mang tính minh họa, không phải giá của Flatkey hoặc OpenAI. Hãy cộng riêng chi phí lưu trữ vector, hạ tầng tìm kiếm và mọi lệnh gọi tạo câu trả lời. Nếu thay đổi mô hình embedding, hãy bao gồm một lượt tạo embedding lại toàn bộ trong ngân sách di chuyển. Một pipeline tạo embedding lại cho các tài liệu không thay đổi có thể tốn nhiều hơn cùng khối lượng công việc với một mô hình lớn hơn nhưng được lưu cache đúng cách.

Chẩn đoán lỗi trước khi thêm retry

Triệu chứngKiểm tra hữu ích đầu tiên
Lỗi xác thựcXác nhận khóa hợp lệ cho endpoint và tài khoản mà bạn đang gọi.
Yêu cầu không hợp lệKiểm tra nội dung lỗi, chuỗi rỗng, số lượng token và các tham số được hỗ trợ.
Lỗi giới hạn tốc độ hoặc hạn ngạchPhân biệt áp lực về tốc độ yêu cầu với việc cạn hạn ngạch tài khoản.
Lỗi máy chủ tạm thời hoặc hết thời gian chờLưu lại mã định danh yêu cầu và sử dụng hành vi retry có giới hạn.
Lỗi số chiều của kho vectorSo sánh cấu hình collection với độ dài vector thực tế được trả về.
Kết quả có vẻ hợp lý nhưng không liên quanKiểm tra văn bản chunk, tính nhất quán của mô hình và các ví dụ truy vấn trước khi đổ lỗi cho mạng.

Bốn kiểm tra đầu tiên tuân theo hướng dẫn lỗi của OpenAI. Hai kiểm tra cuối liên quan đến ứng dụng và chỉ mục của bạn. Tôn trọng hướng dẫn retry của máy chủ và tính đến các lần retry của SDK trước khi thêm một vòng lặp retry khác. Ghi log siêu dữ liệu vận hành mà không ghi lại thông tin xác thực hoặc văn bản tài liệu riêng tư không cần thiết.

Đánh giá truy xuất trước khi chọn mô hình trả lời

Tạo một tập có nhãn nhỏ từ các câu hỏi thực của người dùng, bao gồm các cách diễn đạt lại, tên sản phẩm chính xác, câu hỏi mơ hồ và những câu hỏi mà kho ngữ liệu của bạn không thể trả lời. Ghi lại tài liệu nguồn dự kiến cho từng truy vấn có thể trả lời trước khi tinh chỉnh hệ thống.

Với mỗi cấu hình ứng viên, hãy ghi nhận liệu một nguồn chấp nhận được có xuất hiện trong vài kết quả đầu tiên hay không, lượng tài liệu trùng lặp được trả về, độ trễ truy xuất và chi phí trên mỗi truy vấn. Xem xét từng lỗi riêng lẻ. Nếu truy vấn hỏi một mã lỗi chính xác, đối sánh từ khóa có thể bổ sung cho độ tương đồng ngữ nghĩa. Nếu thiếu nguồn, việc thay đổi số chiều embedding không thể tạo ra nguồn đó.

Giữ lại một phần câu hỏi chưa được dùng để đánh giá cho lần so sánh cuối cùng. Đừng chọn ngưỡng tương đồng từ bản demo ba tài liệu rồi coi đó là điểm tin cậy phổ quát. Một bài kiểm tra chấp nhận hữu ích phản ánh hậu quả của việc truy xuất sai trong chính ứng dụng của bạn.

Flatkey phù hợp ở đâu trong ứng dụng

Flatkey cung cấp bộ định tuyến mô hình tương thích với OpenAI và một danh mục mô hình hiện tại. Hãy sử dụng tài liệu tích hợp Flatkey để đánh giá phía tạo sinh mô hình của ứng dụng. Các ví dụ ở trên gọi trực tiếp OpenAI; chúng không khẳng định rằng một mô hình embedding hoặc mọi tham số embeddings đều khả dụng thông qua Flatkey.

Đối với ứng dụng đa nhà cung cấp, hãy giữ cấu hình truy xuất độc lập với cấu hình mô hình trả lời. Điều đó cho phép bạn so sánh các mô hình trả lời mà không cần xây dựng lại chỉ mục tài liệu cho mọi thử nghiệm. Hãy tham khảo các hướng dẫn về kiến trúc API của Flatkey khi lập kế hoạch định tuyến, kiểm soát tài khoản và kiểm tra vận hành.

Câu hỏi thường gặp

API embeddings có tự trả lời câu hỏi không?

Nó trả về các vector. Ứng dụng của bạn sử dụng chúng để chọn nội dung liên quan; mô hình trả lời là một thành phần riêng biệt nếu bạn cần phản hồi bằng văn bản.

Tôi có thể so sánh vector từ các mô hình embedding khác nhau không?

Đừng giả định rằng chúng chia sẻ một không gian tọa độ có ý nghĩa, ngay cả khi số chiều của chúng khớp nhau. Hãy duy trì các chỉ mục riêng theo từng mô hình và đánh giá việc chuyển đổi bằng cùng các câu hỏi và tài liệu nguồn.

Tôi có nên chọn ngay mô hình embedding lớn nhất không?

Hãy bắt đầu với một cấu hình mà bạn có thể đo lường. So sánh chất lượng truy xuất, độ trễ, dung lượng lưu trữ và chi phí trên các truy vấn của riêng bạn trước khi chấp nhận một chỉ mục lớn hơn hoặc một mô hình khác.

Tôi nên xây dựng gì trước?

Hãy sử dụng API embeddings của Open AI để nhúng một kho ngữ liệu nhỏ, an toàn về quyền truy cập, xác minh ánh xạ tài liệu sang vector và kiểm thử truy xuất bằng các câu hỏi đã gán nhãn. Mở rộng kho ngữ liệu sau khi vòng lặp đó tạo ra bằng chứng đáng tin cậy.