| name | rasa-setting-up-enterprise-search |
| description | Adds knowledge base search to a Rasa CALM assistant using EnterpriseSearchPolicy, connects vector stores (Faiss, Milvus, Qdrant), and configures generative or extractive search modes. Use when setting up RAG, connecting a vector store, overriding pattern_search, or implementing a custom information retriever.
|
| license | Apache-2.0 |
| metadata | {"author":"rasa","version":"0.1.0","rasa_version":">=3.13.0","docs-url":"https://rasa.com/docs/pro/build/configuring-enterprise-search"} |
Setting Up Enterprise Search
Enterprise Search lets a Rasa assistant answer informational questions by
retrieving relevant documents from a knowledge base and generating (or
extracting) answers. It is powered by the EnterpriseSearchPolicy and
triggered via the built-in pattern_search pattern.
Workflow
- Check the existing project — does it already have
EnterpriseSearchPolicy
configured? If not, add EnterpriseSearchPolicy to policies in config.yml with
the desired vector store type and options (see "Enterprise Search Policy").
- Switch the command generator in
config.yml to
SearchReadyLLMCommandGenerator (see "Command generator").
- Add vector store connection details to
endpoints.yml if using Milvus or Qdrant
(see "Connecting vector stores").
- Add model groups for the LLM and embeddings used by the policy
(see
rasa-configuring-model-groups skill).
- Override
pattern_search in a flows file to trigger action_trigger_search
(see "Triggering Enterprise Search").
- Place documents in the knowledge base —
./docs for Faiss, or ingest into your
vector database for Milvus/Qdrant.
- Validate and train.
Command generator
Enterprise Search requires SearchReadyLLMCommandGenerator in the pipeline. This is the
search-aware variant of CompactLLMCommandGenerator — it produces SearchAndReply
commands when the LLM within the Command Generator detects an informational question.
If the project currently uses CompactLLMCommandGenerator, replace it.
pipeline:
- name: SearchReadyLLMCommandGenerator
llm:
model_group: command_generator_llm
Enterprise Search Policy
Add EnterpriseSearchPolicy to policies in config.yml. The policy
supports two modes:
- Generative (default) — uses an LLM to produce a context-aware answer from
retrieved documents. When
check_relevancy is enabled and the answer is not relevant,
the policy triggers pattern_cannot_handle.
- Extractive — set
use_generative_llm: false to return a pre-authored answer
directly with no LLM generation. Documents must be ingested in Q&A format (see example
below). Use vector_store.threshold so only high-confidence matches are returned.
The embedding model used for querying must match the model used to embed documents
during ingestion.
policies:
- name: FlowPolicy
- name: EnterpriseSearchPolicy
llm:
model_group: enterprise_search_llm
embeddings:
model_group: enterprise_search_embeddings
vector_store:
type: "faiss"
source: "./docs"
citation_enabled: true
check_relevancy: true
max_messages_in_query: 2
include_date_time: true
timezone: "UTC"
Corresponding model groups in endpoints.yml:
model_groups:
- id: enterprise_search_llm
models:
- provider: <your-provider>
model: <your-llm-model>
- id: enterprise_search_embeddings
models:
- provider: <your-provider>
model: <your-embedding-model>
Extractive search Q&A ingestion format — page_content holds the question
(vectorized for similarity), metadata.answer holds the response text:
[
{
"page_content": "What is the return policy?",
"metadata": {
"title": "return_policy",
"type": "faq",
"answer": "Items can be returned within 30 days of purchase."
}
}
]
Triggering Enterprise Search
By default, pattern_search responds with utter_no_knowledge_base (denying the
request). Override it to trigger document search instead.
Automatic triggering via pattern_search
When the command generator detects an informational question, it pushes pattern_search
onto the dialogue stack. Override this pattern to call action_trigger_search:
flows:
pattern_search:
description: handle a knowledge-based question or request
name: pattern search
steps:
- action: action_trigger_search
Triggering from within a flow
action_trigger_search is a default action that can also be used as a step in any flow.
This is useful when a specific point in a business process needs to pull knowledge base
content:
flows:
troubleshoot_device:
description: Guides users through troubleshooting their device.
steps:
- collect: device_model
- action: action_trigger_search
- action: utter_anything_else
Connecting vector stores
Rasa supports three built-in vector stores. Choose based on your environment.
Faiss (development only)
In-memory index built from .txt files during rasa train. Not meant for production.
Use Milvus or Qdrant for production workloads.
- name: EnterpriseSearchPolicy
vector_store:
type: "faiss"
source: "./docs"
No endpoints.yml configuration needed — the index is stored on disk.
Milvus
Connect to a self-hosted Milvus instance. Documents must already be ingested with the
same embedding model.
- name: EnterpriseSearchPolicy
vector_store:
type: "milvus"
threshold: 0.7
vector_store:
type: milvus
host: localhost
port: 19530
collection: rasa
Qdrant
Connect to a self-hosted or Qdrant Cloud instance.
Adjust content_payload_key and metadata_payload_key to match how documents were
ingested into Qdrant.
- name: EnterpriseSearchPolicy
vector_store:
type: "qdrant"
threshold: 0.5
vector_store:
type: qdrant
collection: rasa
host: 0.0.0.0
port: 6333
content_payload_key: page_content
metadata_payload_key: metadata
Prompt customization
Override the default prompt with a Jinja2 template file. Available variables:
docs,
slots,
current_conversation,
current_datetime.
- name: EnterpriseSearchPolicy
prompt_template: prompts/enterprise-search-template.jinja2
See the Rasa docs on
Generative Search prompts
for the default template and all available variables.
Custom information retrievers
For proprietary search engines, slot-based filtering, re-ranking, or unsupported vector
stores, implement a custom retriever class.
Subclass rasa.core.information_retrieval.InformationRetrieval and implement connect
and search:
from rasa.utils.endpoints import EndpointConfig
from rasa.core.information_retrieval import SearchResultList, InformationRetrieval
class MyRetriever(InformationRetrieval):
def connect(self, config: EndpointConfig) -> None:
pass
async def search(
self, query: str, tracker_state: dict, threshold: float = 0.0
) -> SearchResultList:
pass
Reference the class in config.yml:
- name: EnterpriseSearchPolicy
vector_store:
type: "addons.custom_retrieval.MyRetriever"
Connection parameters in endpoints.yml are passed to connect via config.kwargs:
vector_store:
api_key: ${SEARCH_API_KEY}
collection: my_collection