Website to Vector Database: Thu thập, phân đoạn, nhúng trong một luồng
TL;DR
Một pipeline từ website đến cơ sở dữ liệu vector lưu trữ các khối có thể tìm kiếm và siêu dữ liệu nguồn gốc; nó không đưa cả một website vào trong một vector.
Thu thập một tập hợp giới hạn các trang, xác thực Markdown, chia thành các khối ổn định, nhúng từng khối, sau đó thêm hoặc cập nhật nó vào một namespace Pinecone.
Chiều kích đầu ra của mô hình nhúng phải khớp với chỉ mục dày đặc của Pinecone, và việc nạp lại nên sử dụng ID có định dạng xác định thay vì tạo ra các bản sao.
Đây là một tài liệu hỗ trợ xây dựng cho cái nhìn tổng quan Crawl-to-Pinecone hiện có của Nstdata; ở đây, trọng tâm là hợp đồng dữ liệu và lộ trình làm mới an toàn.
Giới thiệu: Những gì bạn sẽ xây dựng
Nstdata Crawl là lớp thu thập trong quy trình làm việc này; tổng quan sản phẩm của nó mô tả việc lấy trang và trang web cho các pipeline dữ liệu tiếp theo.
Hướng dẫn này biến một trang tài liệu công khai thành các bản ghi có thể tìm kiếm trong Pinecone. Quy trình là URL → Crawl → Markdown → khối → nhúng → Pinecone → truy vấn. Nó dừng lại ở việc truy xuất; một UI chat, quyền người dùng, và giám sát sản xuất là các lớp ứng dụng riêng biệt.
Một cơ sở dữ liệu vector không thường lưu trữ một website như một tài liệu khổng lồ. Mỗi bản ghi là một vector cho một đoạn, cộng với một ID và siêu dữ liệu cho phép bạn tìm thấy nguồn gốc và cập nhật nó sau này. Nstdata Crawl cung cấp giai đoạn thu thập trang và chuyển đổi Markdown; Pinecone lưu trữ và truy xuất các vector. Để biết các điểm cuối Crawl hiện tại và phản hồi tác vụ, hãy sử dụng Tài liệu tham khảo API Nstdata Crawl.
Trải nghiệm Nstproxy Crawl - Bắt Đầu Dùng Thử Miễn Phí Hôm Nay
Trang
https://docs.example.com/auth
Danh tính và trích dẫn nguồn
Markdown
Tiêu đề, giải thích, mẫu mã
Nội dung nguồn có thể đọc
Khối
Một phần mạch lạc
Đơn vị truy xuất
Nhúng
Vector số
Tìm kiếm tương đồng ngữ nghĩa
Siêu dữ liệu
URL, tiêu đề, phần, phiên bản, băm
Lọc, trích dẫn, cập nhật
Bản ghi Pinecone
ID ổn định + giá trị + siêu dữ liệu
Đối tượng thêm hoặc cập nhật và truy vấn
Giữ nội dung văn bản gốc của trang trong siêu dữ liệu chỉ khi nó phù hợp với mô hình dữ liệu và yêu cầu về quyền riêng tư của bạn. Trong ví dụ này, văn bản khối được đính kèm vào siêu dữ liệu của từng vector để việc truy xuất có thể trả về một đoạn sẵn sàng trích dẫn. Đối với các thiết kế bản ghi lớn hơn, hãy đánh giá các hướng dẫn mô hình dữ liệu và thêm hoặc cập nhật của Pinecone hiện tại.
Điều kiện tiên quyết: API Crawl, nhúng và Pinecone
Tạo một mã thông báo Nstdata Crawl, một khóa API OpenAI và một dự án Pinecone. Tạo một chỉ mục dày đặc Pinecone có chiều kích khớp với đầu ra mô hình nhúng. Ví dụ dưới đây sử dụng đầu ra 1.536 chiều mặc định của text-embedding-3-small; nếu bạn đặt một chiều kích nhúng tùy chỉnh, hãy cấu hình chỉ mục với cùng một giá trị. Cài đặt các thư viện và cố định các phiên bản chính xác được giải quyết trong file khóa triển khai của bạn:
Các tên SDK và hình thức API dưới đây theo tài liệu hiện tại của nhà cung cấp. Không có thông tin xác thực API nào có sẵn trong môi trường viết, vì vậy quy trình làm việc đám mây hoàn chỉnh chưa được thực hiện từ đầu đến cuối.
Bước 1: Thu thập một trang web vào Markdown
Đối với một URL đã biết, sử dụng khách hàng Python đồng bộ được tài liệu hóa. Đối với một trang web tài liệu, gửi một cuộc thu thập trang web giới hạn với maxPages thấp trong lần chạy xác thực đầu tiên. API cấp trang web trả về một ID tác vụ; polling trạng thái và sau đó là kết quả trang. Tài liệu tham khảo Crawl ghi lại POST /api/v1/crawl, GET /api/v1/crawl/status/{crawlId}, và GET /api/v1/crawl/pages/{crawlId}.
import os
from nstdata_ai_crawl import CrawlRequestDto, Format, NstDataClient
with NstDataClient(os.environ["NSTDATA_API_TOKEN"])as client: submitted = client.submit_crawl_task(CrawlRequestDto( url="https://docs.example.com/", formats=[Format.MARKDOWN], maxDepth=2, maxPages=100, includeUrls=["*docs.example.com/*"], excludeUrls=["*docs.example.com/search*","*docs.example.com/login*"], ignoreQuery=True, onlyMainContent=True, timeout=60_000,)) crawl_id = submitted.idprint("đã gửi cuộc thu thập", crawl_id)
Ví dụ SDK xác nhận phương thức gửi và các trường yêu cầu. Đối với sản xuất, thêm polling với một thời hạn đồng bộ, backoff theo cấp số nhân, và thời gian chờ tối đa; sau đó phân trang danh sách trang trả về cho đến khi nextCursor của nó trống. Một bản ghi trang có thể mang một tham chiếu nội dung thay vì Markdown đầy đủ, vì vậy hãy truy xuất artefact được tham chiếu qua điểm cuối đọc lưu trữ đã được tài liệu hóa trước khi chia nhỏ. Kiểm tra từng trang có success, trạng thái, siêu dữ liệu và nội dung thay vì coi một cuộc thu thập cha đã hoàn thành là bằng chứng mỗi trang đều có thể sử dụng.
Hướng dẫn tham khảo phản hồi của Crawl cho đầu ra lớn sử dụng các trường như markdownRef và GET /api/v1/crawl/storage/read?st={ref} đã xác thực. Giữ lại bước lấy dữ liệu đó trong bộ chuyển đổi cho phiên bản SDK của bạn; không giả định mỗi phản hồi nhúng một thân đầy đủ. Tránh thu thập nội dung chỉ dành cho đăng nhập hoặc nội dung không được phép khác.
Bước 2: Làm sạch và chuẩn hóa trước khi nhúng
Bảo tồn các đường dẫn tiêu đề, mã biên, bảng và liên kết nguồn. Chỉ bỏ đi những chrome lặp lại rõ ràng không phải là phần của tài liệu. Một trợ giúp chuẩn hóa cơ bản cố ý bảo thủ:
Không xóa mọi liên kết hoặc bảng chỉ để giảm số lượng token. Tài liệu API thường lưu trữ câu trả lời hữu ích trong một bảng tham số hoặc một trang phiên bản liên kết. Bắt giữ URL chính thức cuối cùng, tiêu đề, ngôn ngữ và phiên bản sản phẩm như siêu dữ liệu bên cạnh thân đã chuẩn hóa.
Bước 3: Chia thành các khối nhận thức tiêu đề
Một phiên bản đầu tiên có thể chia Markdown theo tiêu đề trong khi giữ nguyên mã biên cùng nhau. Ví dụ này tạo một bản ghi cho mỗi phần tiêu đề; thêm một bước thứ hai nhận thức tokenizer khi một phần vượt quá giới hạn đầu vào của nhà cung cấp nhúng của bạn.
defsplit_sections(markdown:str): heading_path, lines, fenced =[],[],Falsefor line in markdown.splitlines():if line.strip().startswith("```"): fenced =not fenced
if line.startswith("#")andnot fenced and lines: text ="\n".join(lines).strip()if text:yield" / ".join(heading_path), text
level =len(line)-len(line.lstrip("#")) heading_path = heading_path[:level -1]+[line[level:].strip()] lines =[line]else: lines.append(line) text ="\n".join(lines).strip()if text:yield" / ".join(heading_path), text
Đây là một cấu trúc khởi đầu, không phải là một bộ phân khối phổ quát. Nó không đảm bảo một số lượng token tối đa hoặc gộp các phần nhỏ. Hướng dẫn LangChain text-splitter guide cung cấp một triển khai khung khác để so sánh. Thêm phân chia đệ quy cho các phần lớn và kiểm tra hành vi biên giới trên các khối mã và bảng. Theo dõi kích thước token với bộ phân tích liên quan đến mô hình nhúng của bạn thay vì coi số lượng ký tự là số lượng token chính xác.
Đối với các phần tiếp theo, giả định bộ chuyển đổi kết quả trang đã tạo một bản ghi đã xác nhận có tên page, với các trường url, title, markdown, crawled_at, và content_hash. Hiện thực hóa đầu ra của bộ phân tách một lần: sections = list(split_sections(page.markdown)). Bước thu thập trang trước đó gửi một tác vụ; bộ chuyển đổi của bạn phải kiểm tra nó, đọc các tác phẩm Markdown đã tham chiếu, và xây dựng bản ghi trang này trước khi nhúng.
Bước 4: Tạo nhúng
Hướng dẫn OpenAI embeddings guide tài liệu về điểm cuối nhúng. Nhúng mỗi khối sử dụng một mô hình cố định, và giữ lại tên mô hình với phiên bản chỉ số để một thay đổi mô hình sau này không thể trộn lẫn các không gian vector không tương thích một cách lén lút.
from openai import OpenAI
embedder = OpenAI()texts =[chunk_text for _, chunk_text in sections]response = embedder.embeddings.create( model="text-embedding-3-small",input=texts,)vectors =[item.embedding for item in response.data]assertlen(vectors)==len(texts)
Gộp lại giảm thiểu chi phí yêu cầu, nhưng hãy gộp kích thước theo giới hạn của nhà cung cấp và thử lại các lỗi tạm thời với backoff. Kiểm tra chiều dài vector trước khi ghi:
expected_dimension =1536ifany(len(vector)!= expected_dimension for vector in vectors):raise ValueError("Embedding dimension does not match the Pinecone index")
Bước 5: Tạo chỉ mục Pinecone
Tạo một chỉ mục dense trong bảng điều khiển Pinecone hoặc với API hiện tại của nó. Đặt chiều kích chỉ mục theo chiều kích đầu ra nhúng và chọn chỉ số tương đồng cần thiết cho thiết kế truy xuất của bạn. URL máy chủ cần thiết cho các thao tác trên dữ liệu. Sử dụng một chỉ mục phát triển trước để các thử nghiệm thất bại không làm ô nhiễm dữ liệu sản xuất.
Bước 6: Nhúng các khối với ID ổn định
Các ví dụ Python hiện tại của Pinecone chấp nhận các bản ghi dày đặc với id, values, và metadata tùy chọn. Sử dụng một không gian tên để tách biệt một bộ sưu tập tài liệu hoặc người thuê. Một tiền tố ổn định làm cho việc xóa tất cả các khối cho một trang nguồn đã thay đổi trở nên khả thi trước khi thay thế chúng.
Upsert ghi đè một bản ghi hiện có với cùng một ID. Nó không tự động xóa các ID chunk cũ đã biến mất sau khi chỉnh sửa trang. Duy trì danh sách ID trang đến ID trước đó và xóa các ID cũ sau khi bộ thay thế đã được xác minh. Tài liệu về xử lý nhóm và không gian tên của Pinecone có trong hướng dẫn upsert.
Bước 7: Truy vấn chỉ mục trang web
Nhúng câu hỏi với cùng một mô hình và truy vấn Pinecone. Trả về siêu dữ liệu để ứng dụng có thể hiển thị liên kết nguồn và tiêu đề thay vì phát ra một câu trả lời trần trụi.
question ="API xác thực yêu cầu như thế nào?"query_vector = embedder.embeddings.create( model="text-embedding-3-small",input=question,).data[0].embedding
matches = index.query( vector=query_vector, top_k=5, include_metadata=True, namespace=namespace,)formatchin matches.matches:print(match.metadata["source_url"],match.metadata["heading_path"])print(match.metadata["text"])
Xem xét top_k như một tham số truy xuất có thể điều chỉnh, không phải là bảo đảm chất lượng. Đánh giá với một tập hợp nhỏ các câu hỏi thực tế và kiểm tra rằng mỗi đoạn văn trả về hỗ trợ câu trả lời. Đối với các trang web có kiểm soát truy cập, cũng áp dụng quyền thuê và tài liệu trước khi trả lại ngữ cảnh cho mô hình.
Bước 8: Xử lý cập nhật và xóa
Lưu trữ một mã băm của nội dung trang đã chuẩn hóa. Khi lần thu thập chấp nhận tiếp theo trả về cùng một mã băm, hãy bỏ qua việc nhúng. Khi mã băm thay đổi, tạo danh sách chunk mới, ghi đè nó, xác minh rằng nó có thể được truy vấn, và sau đó xóa các ID trước đó. Giữ một bản kê ngoài Pinecone với URL chính thức, mã băm nội dung, dấu thời gian thu thập, phiên bản mô hình, và ID chunk. Nếu một lần thu thập nguồn bị thất bại, hãy giữ lại chỉ mục tốt cuối cùng và đánh dấu trang để xem xét; một khoảng thời gian chờ không được trở thành một xóa nhầm.
Lỗi chung và mô hình chi phí
Một dimension mismatch có nghĩa là chỉ mục và đầu ra nhúng không đồng ý. Một trận lũ bản sao thường mang ý nghĩa rằng các ID đã ngẫu nhiên hoặc bao gồm dấu thời gian thu nạp. Thiếu dữ liệu trích dẫn thường có nghĩa là source_url đã bị mất trong quá trình chunking. Một truy vấn siêu dữ liệu không trả về bản ghi nào có thể chỉ ra sự không khớp không gian tên thay vì vấn đề nhúng.
Ước tính chi phí cho mỗi trang được chấp nhận với các điều khoản riêng biệt: Sử dụng URL thu thập, lưu lượng proxy khi được bật, nhúng cho văn bản mới hoặc đã thay đổi, ghi và lưu trữ Pinecone, và các cuộc gọi mô hình thời gian truy vấn. Một trang có thể tạo ra nhiều chunk, vì vậy chỉ khối lượng trang không phải là một ước tính lưu trữ đáng tin cậy. Xem chi phí Nstdata Crawl hiện tại và tài liệu thanh toán Pinecone hiện tại khi chuẩn bị ngân sách; các mức giá và giới hạn kế hoạch có thể thay đổi.
Pinecone và các kho vector khác cho quy trình làm việc này
Pinecone là một lựa chọn được quản lý khi bạn muốn có một chỉ mục vector được lưu trữ và không muốn vận hành quá trình cơ sở dữ liệu. Chroma thuận tiện cho các mẫu thử nghiệm cục bộ; Qdrant và Weaviate cung cấp các triển khai tự quản lý hoặc được quản lý khác; pgvector có thể phù hợp với một nhóm đã vận hành PostgreSQL. So sánh nhu cầu lọc, hoạt động, sao lưu, vùng, và mô hình quyền—không chỉ độ trễ tìm kiếm vector. Hướng dẫn này sử dụng Pinecone vì các từ khóa nhắm đến sự tích hợp đó, không phải vì một cơ sở dữ liệu là tốt nhất cho mọi khối lượng công việc.
Một luồng chuyển đổi từ trang web sang cơ sở dữ liệu vector đáng tin cậy phụ thuộc vào các hợp đồng giữa các giai đoạn: Thu thập tạo ra một sản phẩm trang, mã của bạn xác minh và chia nhỏ nó, mô hình nhúng tạo ra các vector có kích thước xác định, và Pinecone lưu trữ mỗi vector dưới một ID ổn định với siêu dữ liệu nguồn. Xây dựng bản kê URL và hành vi cập nhật/xóa trước khi thu nạp một trang web lớn. Một chút công việc ghi chép nhỏ này ngăn chặn các đoạn văn cũ và trích dẫn hỏng sau này.
Q: Làm thế nào để tôi thu thập một trang web vào Pinecone?
Khám phá và thu thập các trang được phép, xác nhận và phân đoạn văn bản của chúng, tạo ra các embeddings, sau đó cập nhật mỗi vector với một ID ổn định và siêu dữ liệu nguồn.
H: Pinecone có lưu trữ toàn bộ trang web không?
Pinecone lưu trữ các bản ghi vector và siêu dữ liệu liên quan; ứng dụng của bạn quyết định xem văn bản phân đoạn có được lưu trữ dưới dạng siêu dữ liệu hay trong một kho nội dung riêng biệt.
H: Kích thước phân đoạn tốt nhất cho Pinecone là gì?
Không có kích thước tốt nhất phổ quát; điều chỉnh ranh giới phân đoạn và cài đặt truy xuất theo các câu hỏi đại diện và giới hạn đầu vào của mô hình embedding.
H: Làm thế nào để tôi cập nhật embeddings của trang web?
So sánh một hash nội dung chuẩn hóa, tái nhúng các trang đã thay đổi, cập nhật các phân đoạn thay thế và xóa các ID phân đoạn trước đó sau khi xác nhận.
H: Tôi có thể lưu trữ nhiều trang web trong một chỉ mục không?
Có, nhưng hãy sử dụng không gian tên hoặc bộ lọc siêu dữ liệu một cách có chủ đích và thực thi quyền truy cập của người thuê trong ứng dụng của bạn trước khi trả lại nội dung đã truy xuất.
Hiểu bảy chiều kích của chất lượng dữ liệu RAG và cách xác thực các trang web đã được thu thập, so sánh các đầu vào sạch và thô, bảo tồn nguồn gốc và chẩn đoán các thất bại trong việc truy xuất. Nó tách biệt các lỗi trích xuất, truy xuất và tạo ra để các nhóm có thể gỡ lỗi giai đoạn đúng.
Lena Zhou
Oct. 20th 2026
Thu thập toàn bộ trang web chỉ với một yêu cầu API
Tỷ lệ thành công 99,8% với kết xuất JavaScript
Nhận dữ liệu sạch, sẵn sàng cho LLM ở nhiều định dạng
Chuyển mọi trang web thành Markdown, HTML, JSON, liên kết, PDF và hơn thế nữa mà không cần quản lý hạ tầng thu thập dữ liệu.