検索拡張生成:Apifyでウェブサイトをクロールし、Milvusにデータを保存して質問に答える
このチュートリアルでは、ApifyのWebサイトコンテンツクローラを使ってWebサイトをクロールし、Milvus/Zillizベクトルデータベースにデータを保存して、後で質問回答に使用する方法を説明します。
ApifyはWebスクレイピングとデータ抽出のプラットフォームで、アクターと呼ばれる2000以上の既製のクラウドツールを備えたアプリマーケットプレイスを提供しています。これらのツールは、eコマースサイト、ソーシャルメディア、検索エンジン、オンラインマップなどから構造化データを抽出するようなユースケースに最適である。
例えば、ウェブサイトコンテンツクローラアクターは、ウェブサイトを深くクロールし、クッキーモーダル、フッター、またはナビゲーションを削除することによって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、トークン、コレクション名の設定
クライアントのセットアップには、Milvus/ZillizのURIとTokenが必要です。
- DockerやKubernetes上にMilvusサーバを自前でデプロイしている場合は、サーバのアドレスとポートをURIとして使用します(例:
http://localhost:19530
)。Milvusで認証機能を有効にしている場合は、トークンに"<your_username>:<your_password>"を、そうでない場合は空文字列としてください。 - MilvusのフルマネージドクラウドサービスであるZilliz Cloudをご利用の場合は、Zilliz CloudのPublic EndpointとAPI keyに対応する
uri
とtoken
を調整してください。
コレクションは事前に存在する必要はありません。データベースにデータがアップロードされると自動的に作成されます。
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を定義し、vectorデータベースに保存される情報を指定します。
actor_id="apify/website-content-crawler"
は Website Content Crawler の識別子です。クローラーの動作は、run_input パラメータで完全に制御できます(詳細はinput ページを参照)。この例では、JavaScriptのレンダリングを必要としないMilvusのドキュメントをクローリングします。そのため、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
で設定された事前定義された制限に達するまで、サイトを徹底的にクロールします。スクレイピングされたデータは、アピファイ・プラットフォームのDataset
に保存されます。このデータにアクセスして分析するにはdefaultDatasetId
dataset_id = actor_call["defaultDatasetId"]
dataset_id
'P9dLFfeJAljlePWnz'
以下のコードは、アピファイDataset
からスクレイピングされたデータをフェッチし、最初にスクレイピングされたウェブサイトを表示します。
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
)
全てのスクレイピングされたデータはMilvusデータベースに保存され、検索と質問応答の準備が整いました。
検索とLLM生成パイプライン
次に、Langchainを使った検索支援パイプラインを定義する。パイプラインは2つのステージで動作する:
- ベクターストア(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を使用してWebサイトのコンテンツをクロールし、milvusベクトルデータベースにデータを保存し、検索補強パイプラインを使用して質問応答タスクを実行する方法を示しました。ApifyのWebスクレイピング機能とベクトルストレージのMilvus/Zilliz、言語モデルのLangchainを組み合わせることで、非常に効果的な情報検索システムを構築することができます。
データベースのデータ収集と更新を改善するために、Apifyの統合はインクリメンタルアップデートを提供し、チェックサムに基づいて新しいデータや変更されたデータのみを更新します。さらに、指定された時間内にクロールされなかった古いデータを自動的に削除することもできます。これらの機能により、ベクターデータベースを最適化し、検索で補強されたパイプラインを最小限の手作業で効率的かつ最新の状態に保つことができます。
ApifyとMilvusの統合の詳細については、Apify Milvusのドキュメントと 統合のREADMEファイルを参照してください。