Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ add_or_replace_documents_1: |-
"release_date": "2019-03-23"
}
]'
add_or_replace_documents_csv_1: |-
curl \
-X POST 'MEILISEARCH_URL/indexes/movies/documents' \
-H 'Content-Type: text/csv' \
--data-binary @movies.csv
add_or_replace_documents_ndjson_1: |-
curl \
-X POST 'MEILISEARCH_URL/indexes/movies/documents' \
-H 'Content-Type: application/x-ndjson' \
--data-binary @movies.ndjson
# put_indexes_indexUid_documents
add_or_update_documents_1: |-
curl \
Expand Down Expand Up @@ -431,6 +441,13 @@ update_faceting_settings_1: |-
"genres": "count"
}
}'
update_faceting_settings_max_values_per_facet_1: |-
curl \
-X PATCH 'MEILISEARCH_URL/indexes/books/settings/faceting' \
-H 'Content-Type: application/json' \
--data-binary '{
"maxValuesPerFacet": 20
}'
# delete_indexes_indexUid_settings_faceting
reset_faceting_settings_1: |-
curl \
Expand Down Expand Up @@ -578,6 +595,23 @@ update_embedders_1: |-
"documentTemplate": "A document titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}"
}
}'
update_embedders_distribution_1: |-
curl \
-X PATCH 'MEILISEARCH_URL/indexes/INDEX_NAME/settings' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer MEILISEARCH_KEY' \
--data-binary '{
"embedders": {
"default": {
"source": "openAi",
"model": "text-embedding-3-small",
"distribution": {
"mean": 0.7,
"sigma": 0.3
}
}
}
}'
# delete_indexes_indexUid_settings_embedders
reset_embedders_1: |-
curl \
Expand Down Expand Up @@ -665,6 +699,13 @@ get_documents_post_1: |-
"fields": ["title", "genres", "rating", "language"],
"limit": 3
}'
get_documents_post_with_filter_1: |-
curl \
-X POST 'MEILISEARCH_URL/indexes/movies/documents/fetch' \
-H 'Content-Type: application/json' \
--data-binary '{
"filter": "genres = Action AND rating > 8"
}'
# post_indexes_indexUid_documents_delete
delete_documents_by_filter_1: |-
curl \
Expand Down Expand Up @@ -1186,6 +1227,15 @@ facet_search_3: |-
"facetQuery": "c",
"facetName": "genres"
}'
facet_search_exhaustive_1: |-
curl \
-X POST 'MEILISEARCH_URL/indexes/books/facet-search' \
-H 'Content-Type: application/json' \
--data-binary '{
"facetName": "genres",
"facetQuery": "c",
"exhaustiveFacetCount": true
}'
analytics_event_click_1: |-
curl \
-X POST 'https://PROJECT_URL/events' \
Expand Down Expand Up @@ -1434,6 +1484,18 @@ chat_patch_settings_1: |-
-H "Authorization: Bearer MEILISEARCH_KEY" \
-H "Content-Type: application/json" \
--data-binary '{ "apiKey": "your-valid-api-key" }'
chat_patch_settings_prompts_1: |-
curl \
-X PATCH 'MEILISEARCH_URL/chats/WORKSPACE_NAME/settings' \
-H 'Authorization: Bearer MEILISEARCH_KEY' \
-H 'Content-Type: application/json' \
--data-binary '{
"prompts": {
"searchDescription": "Search the outdoor gear catalog whenever the user asks about products, prices, availability, or specifications. Do not use it for generic small talk.",
"searchQParam": "A short natural-language query capturing the user intent. Rewrite long questions into 3 to 8 keywords. Preserve product names and brand names verbatim.",
"searchIndexUidParam": "Choose between: \"products\" for physical gear, accessories, and apparel; \"guides\" for how-to articles and buying guides; \"reviews\" for customer reviews and ratings. Use \"products\" by default."
}
}'
# delete_chats_workspaceUid_settings
reset_chat_workspace_settings_1: |-
curl \
Expand Down
12 changes: 12 additions & 0 deletions capabilities/conversational_search/getting_started/chat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ In code examples, replace `WORKSPACE_NAME` with the name of your workspace. On M

All requests to the chat completions endpoint must include `"stream": true`. Non-streaming (`stream: false`) is not yet supported and returns a `501 Not Implemented` error.

## Message roles

Every entry in the `messages` array carries a `role` that tells the LLM who authored it. The chat completions endpoint uses three roles, each with a distinct origin:

| Role | Origin | Typical content |
|------|--------|-----------------|
| `system` | Meilisearch | Workspace-level instructions (the `prompts.system` string) plus internal tool descriptions injected by Meilisearch. You do not need to send this role yourself; Meilisearch prepends it. |
| `assistant` | LLM provider | Responses generated by the configured model, including tool calls. Push these back into `messages` to preserve context on follow-up turns. |
| `user` | User input | Questions and follow-ups coming from the end user of your application. This is what you add to `messages` before each request. |

Understanding the origin matters when debugging: unexpected `system` content usually means the workspace system prompt needs tuning, wrong answers are an `assistant` problem, and malformed input is a `user` problem.

## Send a streaming request

Send a `POST` request to `/chats/{workspace}/chat/completions` with `stream: true`:
Expand Down
20 changes: 18 additions & 2 deletions capabilities/conversational_search/getting_started/setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ description: Enable the chat completions feature, configure your indexes, and cr

import CodeSamplesAuthorizationHeader1 from '/snippets/generated-code-samples/code_samples_authorization_header_1.mdx';
import CodeSamplesChatCreateKey1 from '/snippets/generated-code-samples/code_samples_chat_create_key_1.mdx';
import CodeSamplesUpdateExperimentalFeaturesChat1 from '/snippets/generated-code-samples/code_samples_update_experimental_features_chat_1.mdx';

Before building a chat interface or generating summarized answers, you need to enable the feature, configure your indexes, and create a workspace. This setup is shared across all conversational search use cases.

Expand All @@ -17,17 +18,32 @@ Enable chat completions from your Meilisearch Cloud project in one of two ways:
- Or open the **Chat** tab in your project and activate the feature directly from there

<Note>
For self-hosted instances, enable the feature through the [experimental features API](/reference/api/experimental-features/configure-experimental-features).
For self-hosted instances, enable the feature through the [experimental features API](/reference/api/experimental-features/configure-experimental-features) by sending a `PATCH` request with `chatCompletions` set to `true`:

<CodeSamplesUpdateExperimentalFeaturesChat1 />
</Note>

## Find your chat API key

Meilisearch automatically generates a "Default Chat API Key" with `chatCompletions` and `search` permissions on all indexes. Check if you have the key using:
Meilisearch automatically generates a "Default Chat API Key" that combines `chatCompletions` and `search` permissions on all indexes. Conversational search requires both actions: `chatCompletions` authorises the LLM call, and `search` authorises the retrieval step that feeds documents to the model. Any key you use with the `/chats` routes must carry both actions, so prefer the default chat API key unless you have a specific reason to create a custom one.
Comment thread
qdequele marked this conversation as resolved.

Check if you have the key using:

<CodeSamplesAuthorizationHeader1 />

Look for the key with the description "Default Chat API Key".

### Restrict chat access to specific indexes

Chat queries only search the indexes that the API key can access. The default chat API key is scoped to all indexes. To limit which indexes a chat client can reach, you have two options:

- Create a new API key with both `chatCompletions` and `search` actions, scoped to the exact indexes you want exposed. See [manage API keys](/capabilities/security/how_to/manage_api_keys) for the full workflow.
- Generate a [tenant token](/capabilities/security/how_to/generate_token_from_scratch) from the default chat API key. Tenant tokens inherit both the `chatCompletions` and `search` actions from their parent key and let you narrow index access or attach search rules per user.

<Note>
A tenant token cannot grant access to an index its parent API key does not already cover. Make sure the parent key is scoped to every index the token should be allowed to reach.
</Note>

### Troubleshooting: Missing default chat API key

If your instance does not have a Default Chat API Key, create one manually:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: Set up a chat workspace with a system prompt, tools, and connected
import CodeSamplesChatPatchSettings1 from '/snippets/generated-code-samples/code_samples_chat_patch_settings_1.mdx';
import CodeSamplesChatGetSettings1 from '/snippets/generated-code-samples/code_samples_chat_get_settings_1.mdx';

A chat workspace defines the configuration for a conversational search session, including the LLM provider, system prompt, and search behavior. You can create multiple workspaces targeting different use cases, such as a public-facing knowledge base and an internal support tool.
A chat workspace groups the chat settings tailored to a specific use case: the LLM provider credentials, the system prompt, and the search behavior. Workspaces are the entry point for conversational search. You must configure at least one workspace before the chat completions endpoint can serve requests. You can also create multiple workspaces targeting different use cases, such as a public-facing knowledge base and an internal support tool.

<Note>
On Meilisearch Cloud, the default workspace name is `cloud`. Replace `WORKSPACE_NAME` with `cloud` in all API calls. If you need additional workspaces, contact us.
Expand Down Expand Up @@ -42,12 +42,20 @@ The `source` field determines which LLM provider Meilisearch uses. Each provider

| Provider | `source` value | Required fields | Optional fields |
|----------|---------------|-----------------|-----------------|
| OpenAI | `openAi` | `apiKey` | `baseUrl`, `orgId`, `projectId` |
| Azure OpenAI | `azureOpenAi` | `apiKey`, `baseUrl` | `deploymentId`, `apiVersion` |
| OpenAI | `openAi` | `apiKey` | `baseUrl` |
| Azure OpenAI | `azureOpenAi` | `apiKey`, `baseUrl`, `orgId`, `projectId`, `apiVersion` | `deploymentId` |
| Mistral | `mistral` | `apiKey`, `baseUrl` | |
| vLLM | `vLlm` | `baseUrl` | |
| vLLM | `vLlm` | `baseUrl` | `apiKey` |

`baseUrl` is required for all providers except OpenAI. For OpenAI, it is optional and only needed when using a custom endpoint.
A few provider-specific rules to keep in mind:

- `orgId`, `projectId`, and `apiVersion` are required for Azure OpenAI and are incompatible with every other `source`. Sending them with `openAi`, `mistral`, or `vLlm` is rejected.
- `baseUrl` is required for Azure OpenAI and vLLM. For Mistral it points to the Mistral API endpoint. For OpenAI it is optional and only needed when routing through a custom endpoint.
- `apiKey` is optional for vLLM (self-hosted deployments often run without authentication) and mandatory for every other provider.

<Warning>
The `apiKey` field is write-only. Meilisearch stores it for outbound LLM calls but redacts it in every response from the workspace settings endpoint. Retrieving the settings will show an obfuscated placeholder rather than the real secret, so keep your own copy in a secure location. To rotate the key, `PATCH` the workspace with the new value.
</Warning>

### Azure OpenAI example

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ description: Control how each index is described to the LLM and how it is search

Each index you want to make available to conversational search must have its chat settings configured. These settings tell the LLM what the index contains, how to format document data, and what search parameters to use.

<Note>
`chat` is an **index-level** setting, distinct from the workspace-level configuration that connects Meilisearch to an LLM provider. Workspace settings define the model, API key, and global prompts; index chat settings describe each individual index to the LLM and control how it is queried. Both must be configured: first set up a workspace, then configure chat settings on every index you want the agent to access.
</Note>

## Update chat settings

Use the `/indexes/{index_uid}/settings/chat` endpoint to configure chat settings for an index:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: Optimize chat prompts
description: Improve conversational search response quality by tuning system prompts, document templates, and index chat settings.
---

import CodeSamplesChatPatchSettingsPrompts1 from '/snippets/generated-code-samples/code_samples_chat_patch_settings_prompts_1.mdx';

The quality of conversational search responses depends on three layers of configuration: the system prompt, the document template, and the index-level chat settings. Each layer shapes what the LLM receives and how it responds. This guide covers how to tune each one for better results.

## System prompt strategies
Expand Down Expand Up @@ -68,6 +70,22 @@ a detailed explanation.

</CodeGroup>

## Tune the tool prompts

Beyond `prompts.system`, the workspace `prompts` object exposes three tool-facing prompts that Meilisearch injects into the function-calling schema the agent sees. They do not talk to the end user: they talk to the LLM about how to drive the Meilisearch search tool. Small edits here shift which index the agent picks, how it rewrites the query, and whether it decides to search at all.

| Field | What it configures |
|-------|--------------------|
| `prompts.searchDescription` | Internal description of the Meilisearch chat tools. Use it to instruct the agent on how and when to use the configured tools, for example encouraging it to search for any factual question or to skip the search for greetings. |
| `prompts.searchQParam` | Describes the expected user input and the desired query shape. Use it to tell the agent how to reformulate user messages into effective search queries and what output to expect back. |
| `prompts.searchIndexUidParam` | Describes each index the agent has access to and explains how to pick between them. This is the main lever when you have multiple indexes and want the agent to route queries correctly. |

<CodeSamplesChatPatchSettingsPrompts1 />

<Tip>
Change one prompt at a time and re-run your evaluation queries. Tool prompts compound: a change in `searchIndexUidParam` can make earlier `searchQParam` wording look wrong even though it hasn't changed.
</Tip>

## Configure index chat settings

Each index has chat-specific settings that control how documents are prepared for the LLM. Configure these through the [index chat settings](/capabilities/conversational_search/how_to/configure_index_chat_settings) endpoint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,15 @@ The `-N` flag in the cURL example disables output buffering, so you see each chu

## Understand the SSE response format

Meilisearch streams responses as Server-Sent Events. Each event is a line prefixed with `data: ` followed by a JSON object. The stream ends with a `data: [DONE]` message.
Meilisearch streams responses as [Server-Sent Events (SSE)](https://developer.mozilla.org/docs/Web/API/Server-sent_events) over a persistent HTTP connection. The wire format is deliberately OpenAI-compatible so you can point the official OpenAI SDKs, the Vercel AI SDK, or any other SSE-aware client at the endpoint without custom parsing.

Concretely, each event on the wire follows three rules:

- Every event is a line that begins with the literal prefix `data: `.
- The payload after `data: ` is a single JSON object shaped like an OpenAI `chat.completion.chunk` (same `id`, `object`, `choices[].delta` structure as `/v1/chat/completions`).
- The stream terminates with the sentinel line `data: [DONE]`. The `[DONE]` marker is a literal string, not JSON, so parsers must check for it before calling `JSON.parse`.

Events are separated by blank lines. After consuming `[DONE]`, close the reader and treat the connection as complete.

### Content chunks

Expand Down
8 changes: 4 additions & 4 deletions capabilities/conversational_search/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ sidebarTitle: Overview
description: Conversational search allows people to make search queries using natural languages and receive AI-generated answers grounded in your data.
---

<Warning>
**Conversational search is still in early development and conversational agents can hallucinate.** LLMs may occasionally produce inaccurate or misleading answers even when the retrieved source documents are correct. Monitor responses closely in production, follow the [hallucination reduction guide](/capabilities/conversational_search/advanced/reduce_hallucination), and configure [guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to minimise this risk.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use American English spelling: "minimize".

Suggested fix
-**Conversational search is still in early development and conversational agents can hallucinate.** LLMs may occasionally produce inaccurate or misleading answers even when the retrieved source documents are correct. Monitor responses closely in production, follow the [hallucination reduction guide](/capabilities/conversational_search/advanced/reduce_hallucination), and configure [guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to minimise this risk.
+**Conversational search is still in early development and conversational agents can hallucinate.** LLMs may occasionally produce inaccurate or misleading answers even when the retrieved source documents are correct. Monitor responses closely in production, follow the [hallucination reduction guide](/capabilities/conversational_search/advanced/reduce_hallucination), and configure [guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to minimize this risk.

As per coding guidelines: "Use American English spelling (e.g., analyze, behavior, color, center, license, canceled, cancelation, program, labeling, initialed, favorite, dependent)".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Conversational search is still in early development and conversational agents can hallucinate.** LLMs may occasionally produce inaccurate or misleading answers even when the retrieved source documents are correct. Monitor responses closely in production, follow the [hallucination reduction guide](/capabilities/conversational_search/advanced/reduce_hallucination), and configure [guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to minimise this risk.
**Conversational search is still in early development and conversational agents can hallucinate.** LLMs may occasionally produce inaccurate or misleading answers even when the retrieved source documents are correct. Monitor responses closely in production, follow the [hallucination reduction guide](/capabilities/conversational_search/advanced/reduce_hallucination), and configure [guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to minimize this risk.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@capabilities/conversational_search/overview.mdx` at line 8, Update the
American English spelling in the sentence that currently reads "...and configure
[guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to
minimise this risk." Replace "minimise" with "minimize" in the content of
capabilities/conversational_search/overview.mdx so the line reads "...and
configure
[guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to
minimize this risk."

</Warning>

Conversational search is an AI-powered feature built on top of Meilisearch's search engine. It works as a built-in Retrieval Augmented Generation (RAG) system: when a user asks a question, Meilisearch retrieves relevant documents from its indexes, then uses an LLM to generate a response grounded in those results.

With proper configuration, such as [system prompt engineering](/capabilities/conversational_search/advanced/reduce_hallucination#system-prompt-engineering) and [guardrails](/capabilities/conversational_search/how_to/configure_guardrails), you can ensure that responses are based on your indexed data rather than the LLM's general knowledge.

This is similar to how [Perplexity](https://www.perplexity.ai/) works: every answer comes with source documents so users can verify the information. Meilisearch brings the same pattern to your own data.

<Warning>
Conversational search relies on large language models (LLMs) to generate responses. LLMs may occasionally hallucinate inaccurate or misleading information, even when provided with correct source documents. Follow the [hallucination reduction guide](/capabilities/conversational_search/advanced/reduce_hallucination) and configure [guardrails](/capabilities/conversational_search/how_to/configure_guardrails) to minimize this risk in production environments.
</Warning>

## Use cases

Conversational search supports three main use cases, all powered by the same `/chats` API route:
Expand Down
4 changes: 4 additions & 0 deletions capabilities/filtering_sorting_faceting/getting_started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ If you want to filter results based on an attribute, you must first add it to th
By default, `filterableAttributes` is empty. Filters do not work without first explicitly adding attributes to the `filterableAttributes` list.
</Note>

<Tip>
Calculating `comparison` filters (such as `<`, `>`, or `TO`) is a resource-intensive operation. Disabling them may lead to better search and indexing performance. `equality` filters use fewer resources and have limited impact on performance. Use [granular filterable attributes](/capabilities/filtering_sorting_faceting/how_to/configure_granular_filters) to enable only the filter operations you actually need for each attribute.
</Tip>

## Use `filter` when searching

After updating the [`filterableAttributes` index setting](/reference/api/settings/get-filterableattributes), you can use `filter` to fine-tune your search results.
Expand Down
Loading
Loading