擷取增強世代:使用 Apify 抓取網站,並將資料儲存至 Milvus 作為問題回答之用
本教學說明如何使用 Apify 的網站內容抓取器抓取網站,並將資料儲存至 Milvus/Zilliz 向量資料庫,以後用於問題回答。
Apify是一個網路搜刮與資料擷取平台,提供一個應用程式市場,其中有超過兩千種現成的雲端工具,稱為 Actors。這些工具是從電子商務網站、社群媒體、搜尋引擎、線上地圖等抽取結構化資料等使用個案的理想選擇。
例如,Website Content CrawlerActor 可以深入抓取網站,透過移除 cookies 模組、頁尾或導覽來清理 HTML,然後將 HTML 轉換成 Markdown。
適用於 Milvus/Zilliz 的 Apify 整合可輕鬆地將資料從網路上傳至向量資料庫。
開始之前
在執行本筆記型電腦之前,請確定您已具備下列條件:
一個 Apify 帳戶和APIFY_API_TOKEN。
一個 OpenAI 帳戶和OPENAI_API_KEY
一個Zilliz Cloud 帳戶(Milvus 的完全管理雲端服務)。
Zilliz 資料庫 URI 和令牌
安裝相依性
$ pip install --upgrade --quiet apify==1.7.2 langchain-core==0.3.5 langchain-milvus==0.1.5 langchain-openai==0.2.0
設定 Apify 和 Open API 金鑰
import os
from getpass import getpass
os.environ["APIFY_API_TOKEN"] = getpass("Enter YOUR APIFY_API_TOKEN")
os.environ["OPENAI_API_KEY"] = getpass("Enter YOUR OPENAI_API_KEY")
Enter YOUR APIFY_API_TOKEN··········
Enter YOUR OPENAI_API_KEY··········
設定 Milvus/Zilliz URI、Token 和集合名稱
您需要 Milvus/Zilliz 的 URI 和 Token 來設定用戶端。
- 如果您有在Docker 或 Kubernetes 上自行部署 Milvus 伺服器,請使用伺服器位址和連接埠作為您的 URI,例如
http://localhost:19530
。如果您啟用 Milvus 上的驗證功能,請使用「<your_username>:<your_password>」作為令牌,否則令牌保留為空字串。 - 如果您使用Zilliz Cloud(Milvus 的完全管理雲端服務),請調整
uri
和token
,它們對應於 Zilliz Cloud 中的Public Endpoint 和 API key。
請注意,集合不需要事先存在。當資料上傳到資料庫時,它會自動建立。
os.environ["MILVUS_URI"] = getpass("Enter YOUR MILVUS_URI")
os.environ["MILVUS_TOKEN"] = getpass("Enter YOUR MILVUS_TOKEN")
MILVUS_COLLECTION_NAME = "apify"
Enter YOUR MILVUS_URI··········
Enter YOUR MILVUS_TOKEN··········
使用網站內容抓取器從 Milvus.io 抓取文字內容
接下來,我們將使用 Apify Python SDK 來使用網站內容爬蟲。我們先定義 actor_id 和 run_input,然後再指定要儲存到向量資料庫的資訊。
actor_id="apify/website-content-crawler"
是網站內容爬蟲的識別碼。爬蟲的行為可透過 run_input 參數完全控制(詳情請參閱輸入頁面)。在這個範例中,我們要抓取的是 Milvus 文件,不需要 JavaScript 渲染。因此,我們設定crawlerType=cheerio
, 定義startUrls
, 並透過設定maxCrawlPages=10
來限制爬取的頁面數量。
from apify_client import ApifyClient
client = ApifyClient(os.getenv("APIFY_API_TOKEN"))
actor_id = "apify/website-content-crawler"
run_input = {
"crawlerType": "cheerio",
"maxCrawlPages": 10,
"startUrls": [{"url": "https://milvus.io/"}, {"url": "https://zilliz.com/"}],
}
actor_call = client.actor(actor_id).call(run_input=run_input)
網站內容抓取程式會徹底抓取網站,直到達到maxCrawlPages
所設定的預定限制。抓取的資料會儲存在 Apify 平台上的Dataset
。要存取及分析這些資料,您可以使用defaultDatasetId
dataset_id = actor_call["defaultDatasetId"]
dataset_id
'P9dLFfeJAljlePWnz'
以下程式碼從 ApifyDataset
取得 scraped 資料,並顯示第一個 scraped 網站
item = client.dataset(dataset_id).list_items(limit=1).items
item[0].get("text")
'The High-Performance Vector Database Built for Scale\nStart running Milvus in seconds\nfrom pymilvus import MilvusClient client = MilvusClient("milvus_demo.db") client.create_collection( collection_name="demo_collection", dimension=5 )\nDeployment Options to Match Your Unique Journey\nMilvus Lite\nLightweight, easy to start\nVectorDB-as-a-library runs in notebooks/ laptops with a pip install\nBest for learning and prototyping\nMilvus Standalone\nRobust, single-machine deployment\nComplete vector database for production or testing\nIdeal for datasets with up to millions of vectors\nMilvus Distributed\nScalable, enterprise-grade solution\nHighly reliable and distributed vector database with comprehensive toolkit\nScale horizontally to handle billions of vectors\nZilliz Cloud\nFully managed with minimal operations\nAvailable in both serverless and dedicated cluster\nSaaS and BYOC options for different security and compliance requirements\nTry Free\nLearn more about different Milvus deployment models\nLoved by GenAI developers\nBased on our research, Milvus was selected as the vector database of choice (over Chroma and Pinecone). Milvus is an open-source vector database designed specifically for similarity search on massive datasets of high-dimensional vectors.\nWith its focus on efficient vector similarity search, Milvus empowers you to build robust and scalable image retrieval systems. Whether you’re managing a personal photo library or developing a commercial image search application, Milvus offers a powerful foundation for unlocking the hidden potential within your image collections.\nBhargav Mankad\nSenior Solution Architect\nMilvus is a powerful vector database tailored for processing and searching extensive vector data. It stands out for its high performance and scalability, rendering it perfect for machine learning, deep learning, similarity search tasks, and recommendation systems.\nIgor Gorbenko\nBig Data Architect\nStart building your GenAI app now\nGuided with notebooks developed by us and our community\nRAG\nTry Now\nImage Search\nTry Now\nMultimodal Search\nTry Now\nUnstructured Data Meetups\nJoin a Community of Passionate Developers and Engineers Dedicated to Gen AI.\nRSVP now\nWhy Developers Prefer Milvus for Vector Databases\nScale as needed\nElastic scaling to tens of billions of vectors with distributed architecture.\nBlazing fast\nRetrieve data quickly and accurately with Global Index, regardless of scale.\nReusable Code\nWrite once, and deploy with one line of code into the production environment.\nFeature-rich\nMetadata filtering, hybrid search, multi-vector and more.\nWant to learn more about Milvus? View our documentation\nJoin the community of developers building GenAI apps with Milvus, now with over 25 million downloads\nGet Milvus Updates\nSubscribe to get updates on the latest Milvus releases, tutorials and training from Zilliz, the creator and key maintainer of Milvus.'
要上傳資料到 Milvus 資料庫,我們使用Apify Milvus 整合。首先,我們需要設定 Milvus 資料庫的參數。接下來,我們選擇要儲存到資料庫的欄位 (datasetFields
)。在下面的範例中,我們要儲存text
欄位和metadata.title
。
milvus_integration_inputs = {
"milvusUri": os.getenv("MILVUS_URI"),
"milvusToken": os.getenv("MILVUS_TOKEN"),
"milvusCollectionName": MILVUS_COLLECTION_NAME,
"datasetFields": ["text", "metadata.title"],
"datasetId": actor_call["defaultDatasetId"],
"performChunking": True,
"embeddingsApiKey": os.getenv("OPENAI_API_KEY"),
"embeddingsProvider": "OpenAI",
}
現在,我們呼叫apify/milvus-integration
來儲存資料
actor_call = client.actor("apify/milvus-integration").call(
run_input=milvus_integration_inputs
)
現在所有的 scraped 資料都儲存在 Milvus 資料庫中,可以進行擷取和問題回答了
檢索與 LLM 產生管道
接下來,我們將使用 Langchain 定義檢索增強管道。管道分兩個階段運作:
- 向量倉庫 (Milvus):Langchain 透過將查詢嵌入與儲存的文件嵌入進行匹配,從 Milvus 擷取相關文件。
- LLM 回應:擷取的文件為 LLM (例如 GPT-4)提供上下文,以產生有根據的答案。
有關 RAG 鏈的詳細資訊,請參閱Langchain 文件。
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_milvus.vectorstores import Milvus
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Milvus(
connection_args={
"uri": os.getenv("MILVUS_URI"),
"token": os.getenv("MILVUS_TOKEN"),
},
embedding_function=embeddings,
collection_name=MILVUS_COLLECTION_NAME,
)
prompt = PromptTemplate(
input_variables=["context", "question"],
template="Use the following pieces of retrieved context to answer the question. If you don't know the answer, "
"just say that you don't know. \nQuestion: {question} \nContext: {context} \nAnswer:",
)
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{
"context": vectorstore.as_retriever() | format_docs,
"question": RunnablePassthrough(),
}
| prompt
| ChatOpenAI(model="gpt-4o-mini")
| StrOutputParser()
)
一旦資料庫中有了資料,我們就可以開始發問了
question = "What is Milvus database?"
rag_chain.invoke(question)
'Milvus is an open-source vector database specifically designed for billion-scale vector similarity search. It facilitates efficient management and querying of vector data, which is essential for applications involving unstructured data, such as AI and machine learning. Milvus allows users to perform operations like CRUD (Create, Read, Update, Delete) and vector searches, making it a powerful tool for handling large datasets.'
總結
在本教程中,我們示範了如何使用 Apify 抓取網站內容、將資料儲存在 Milvus 向量資料庫,並使用檢索增強管道來執行問題解答任務。透過結合 Apify 的網頁抓取功能與向量儲存的 Milvus/Zilliz 以及語言模型的 Langchain,您可以建立高效能的資訊檢索系統。
為了改善資料庫中的資料蒐集與更新,Apify 整合提供增量更新功能,僅根據校驗和更新新的或修改過的資料。此外,它還可以自動移除在指定時間內未被抓取的過期資料。這些功能有助於保持您的向量資料庫最佳化,並確保您的檢索增強管道以最少的手動工作保持高效率與最新。
有關 Apify-Milvus 整合的更多詳細資訊,請參閱Apify Milvus 文件及整合 README 檔案。