examples/rag/README.md
Two library-mode walk-throughs of agentscope.rag — no FastAPI service, no manager, no message bus. Each script wires the building blocks (parser, chunker, embedding model, vector store, KnowledgeBase handle) by hand so the data flow is visible end-to-end.
| Script | What it shows |
|---|---|
index_and_search.py | The minimal pipeline: parse → chunk → embed → insert, then KnowledgeBase.search. Start here. |
integrate_with_agent.py | Attaches the same KnowledgeBase to an Agent via RAGMiddleware, in both static (auto-inject) and agentic (tool-driven) modes. |
Both examples use an in-memory Qdrant store (location=":memory:") and the DashScope text-embedding-v4 model, so no external services are required. The sections below show how to swap in Milvus Lite, MongoDB, or Elasticsearch instead; those backends need additional setup.
# From PyPI
uv pip install "agentscope[rag]"
# Or from source (repo root)
uv pip install -e ".[rag]"
To use a local persistent Milvus Lite vector store instead of the in-memory Qdrant store, install the optional extra:
uv pip install "agentscope[vdb-milvus]"
# Or from source (repo root)
uv pip install -e ".[vdb-milvus]"
Then replace the vector store construction in index_and_search.py
and/or integrate_with_agent.py:
from agentscope.rag import MilvusLiteStore
store = MilvusLiteStore(uri="./rag_demo.db")
To use MongoDB as the vector backend instead of the in-memory Qdrant store — useful when your team already runs MongoDB as the primary data store and wants to avoid maintaining a separate vector database — install the optional extra:
uv pip install "agentscope[vdb-mongodb]"
# Or from source (repo root)
uv pip install -e ".[vdb-mongodb]"
Prerequisites
export MONGODB_URI="mongodb+srv://user:[email protected]/?retryWrites=true&w=majority"
# Self-hosted example:
# export MONGODB_URI="mongodb://localhost:27017"
Then replace the vector store construction in index_and_search.py
and/or integrate_with_agent.py:
import os
from agentscope.rag import MongoDBStore
store = MongoDBStore(
uri=os.environ["MONGODB_URI"],
database="agentscope_rag",
# Declare every field you plan to filter on in search().
# Required for metadata_filter; defaults to ["document_id"] only.
filter_fields=[
"document_id",
# "chunk.metadata.tenant_id", # uncomment if you use metadata_filter
],
)
# MongoDBStore is also an async context manager — same as QdrantStore.
async with store:
knowledge = KnowledgeBase(
name="demo-kb",
description="A toy corpus on cats and AgentScope.",
embedding_model=embedding_model,
vector_store=store,
collection=COLLECTION,
)
...
Notes
text-embedding-v4 with dimensions=1024.
MongoDBStore.create_collection is called automatically on the first
index operation with that dimension — keep the embedding model and
index dimensions aligned.:memory: or Milvus Lite (local .db file), MongoDB is
an external service; you must have a reachable cluster before running
the scripts.search(..., metadata_filter={...}) returns no results or errors,
ensure each metadata key is listed in filter_fields as
chunk.metadata.<key> when constructing MongoDBStore.MongoDBStore instance
to CollectionPerKbManager(storage=..., vector_store=...) in
examples/agent_service/main.py (the default there uses in-memory Qdrant
for zero-setup demos).To use Elasticsearch as the vector backend, install the optional async client extra:
uv pip install "agentscope[vdb-elasticsearch]"
# Or from source (repo root)
uv pip install -e ".[vdb-elasticsearch]"
Prerequisites
For local development, the following starts a single-node Elasticsearch instance with security disabled:
docker run --rm --name agentscope-elasticsearch \
-p 9200:9200 \
-e discovery.type=single-node \
-e xpack.security.enabled=false \
docker.elastic.co/elasticsearch/elasticsearch:8.19.3
export ELASTICSEARCH_URL="http://localhost:9200"
Do not disable security in shared or production environments. For an
authenticated HTTPS deployment, also export credentials and the CA
certificate path, then pass them through client_kwargs as shown below.
Replace the vector store construction in index_and_search.py and/or
integrate_with_agent.py:
import os
from agentscope.rag import ElasticsearchStore
client_kwargs = {}
if os.getenv("ELASTICSEARCH_API_KEY"):
client_kwargs["api_key"] = os.environ["ELASTICSEARCH_API_KEY"]
if os.getenv("ELASTICSEARCH_CA_CERTS"):
client_kwargs["ca_certs"] = os.environ["ELASTICSEARCH_CA_CERTS"]
store = ElasticsearchStore(
hosts=os.environ["ELASTICSEARCH_URL"],
# Number of HNSW candidates considered per shard. Higher values can
# improve recall at the cost of additional search work.
num_candidates=100,
# Use False for higher write throughput during large imports when
# immediate search visibility is not required.
refresh="wait_for",
client_kwargs=client_kwargs,
)
# ElasticsearchStore implements the same async context-manager and
# VectorStoreBase contracts as QdrantStore.
async with store:
knowledge = KnowledgeBase(
name="demo-kb",
description="A toy corpus on cats and AgentScope.",
embedding_model=embedding_model,
vector_store=store,
collection=COLLECTION,
)
...
For username/password authentication, configure basic_auth instead of an
API key:
store = ElasticsearchStore(
hosts=os.environ["ELASTICSEARCH_URL"],
client_kwargs={
"basic_auth": (
os.environ["ELASTICSEARCH_USERNAME"],
os.environ["ELASTICSEARCH_PASSWORD"],
),
"ca_certs": os.environ["ELASTICSEARCH_CA_CERTS"],
},
)
Notes
dense_vector field with cosine similarity.
Keep the embedding model dimensions unchanged after an index is created.flattened field. Any
top-level metadata key can therefore be used with
search(..., metadata_filter={"tenant_id": "bank-a"}); no filter-field
declaration is required.document_id and chunk_index, so
retrying the same indexing operation replaces existing chunks instead of
creating duplicates.refresh="wait_for", making indexed chunks searchable
before the operation returns. For large imports, set refresh=False and
allow Elasticsearch's normal refresh interval (or an explicit index
refresh) to make changes visible with higher throughput._score.
ElasticsearchStore converts it back to raw cosine similarity so score
thresholds behave consistently with the other vector backends.CollectionPerKbManager(storage=storage, vector_store=store) and pass it
to create_app(knowledge_base_manager=...).| Qdrant (default) | Milvus Lite | MongoDB | Elasticsearch | |
|---|---|---|---|---|
| Install extra | agentscope[rag] | agentscope[vdb-milvus] | agentscope[vdb-mongodb] | agentscope[vdb-elasticsearch] |
| External service | No | No | Yes | Yes |
| Persistence | No (:memory:) | Yes (local .db) | Yes (server) | Yes (server) |
| Best for | Quick start / tests | Local dev with persistence | Teams already on MongoDB | Teams already on Elastic or needing distributed kNN search |
integrate_with_agent.py additionally uses DashScopeChatModel, which is already in the base agentscope dependencies.
export DASHSCOPE_API_KEY=sk-...
python examples/rag/index_and_search.py
python examples/rag/integrate_with_agent.py
When using MongoDB, also export MONGODB_URI before running. When using
Elasticsearch, export ELASTICSEARCH_URL and any required authentication or
TLS environment variables.
The two scripts above are library-mode — you drive the pipeline yourself in a single process. For the full service-mode experience (FastAPI endpoints for knowledge base CRUD, document upload, indexing workers, and search), see examples/agent_service for the backend and examples/web_ui for the chat-style UI.