This guide covers the full local development loop: create a schema, deploy locally, feed and query documents, then iterate with new migrations. See Manage Schema to learn how to manage schemas and the CLI reference for the full set of flags.
Prerequisites
- Search Toolkit Vespa Plugin installed (Installation)
- Docker installed and running
Step 1: Create Your First Migration
uv run mistral-vespa generate-migration --app-dir ./vespa_app initial_schemaFill in the generated file:
from mistralai.search.toolkit.plugins.vespa.app.schemas.app import (
FieldDefinition,
SearchMode,
)
from mistralai.search.toolkit.plugins.vespa.migration import VespaMigration, create_default_schema, set_app_name
class InitialSchema(VespaMigration):
def migrate(self) -> None:
set_app_name("mynewproject")
create_default_schema(
name="articles",
mode=SearchMode.INDEX,
embedding_dimensions=1024,
schema_version=1,
default_query_profile_name="hybrid-profile",
additional_fields=[
FieldDefinition.TextField(name="title"),
],
)create_default_schema() includes all required fields for VespaSearchIndex by default. Use additional_fields to add custom fields for your use case. For full control over the field set, use create_schema() with explicit fields.
Chunk functions are generated automatically when chunk fields are present. If a schema includes both a multi-dimensional embedding field and a multi-dimensional text field, the plugin generates best_chunks, chunk_scores, and related helpers automatically.
Step 2: Start a Local Vespa Instance
uv run mistral-vespa local up --query-port 18080 --config-port 19171 --name vespa-dev| Port | Service | Use |
|---|---|---|
| 18080 | Container HTTP | Query and document feed |
| 19171 | Config server | Application deploys |
Step 3: Deploy From Migrations
uv run mistral-vespa migrate \
--app-dir ./vespa_app \
--config-server http://localhost:19171 \
--query-port 18080mistral-vespa migrate builds the application package from migrations in memory, deploys it, and polls the query endpoint until the app is up.
Step 4: Feed and Query Documents
Feed a document:
curl -X POST \
-H "Content-Type: application/json" \
--data '{
"fields": {
"title": "Document 1"
}
}' \
"http://localhost:18080/document/v1/articles/articles/docid/doc1"Run a search:
curl -H "Content-Type: application/json" \
--data '{"yql": "select * from sources * where true"}' \
"http://localhost:18080/search/"Step 5: Modify the Schema
Create a new migration to evolve the schema:
uv run mistral-vespa generate-migration \
--app-dir ./vespa_app \
add_view_countUpdate the generated file:
from mistralai.search.toolkit.plugins.vespa.app.schemas.app import FieldDefinition
from mistralai.search.toolkit.plugins.vespa.migration import VespaMigration, add_field
class AddViewCount(VespaMigration):
def migrate(self) -> None:
add_field("articles", FieldDefinition.CountField(name="view_count"))Preview the change:
uv run mistral-vespa migrate \
--app-dir ./vespa_app \
--config-server http://localhost:19171 \
--query-port 18080 \
--dry-runApply it (remove --dry-run):
uv run mistral-vespa migrate \
--app-dir ./vespa_app \
--config-server http://localhost:19171 \
--query-port 18080Understanding Schema Changes
What happens when you change the schema of a running application:
| Change | Behavior |
|---|---|
| Adding new fields | No problem. The new field has no value until documents write to it. |
| Changing how a field is indexed | Vespa triggers background reindexing. Temporary inconsistency possible. |
| Removing a field | All data and indexes for that field are removed. |
| Changing the type of a field | Data loss. Prefer adding a new field, migrating data, then removing the old one. |
For more details, see Vespa's documentation on modifying schemas.
Custom Ranking Profiles and Extra Assets
Add custom rank profiles or model files from a migration:
from pathlib import Path
from mistralai.search.toolkit.plugins.vespa.migration import VespaMigration, add_schema_rank_profiles
class AddCustomRankingProfile(VespaMigration):
def migrate(self) -> None:
add_schema_rank_profiles(
"articles",
[Path(__file__).parent.parent / "vespa-extra" / "custom.profile"],
)You can use the same pattern for add_schema_model_files, add_schema_custom_document_summary, and add_query_profiles.
vespa.lock SnapshotOptional: Generate a vespa.lock Snapshot
If your repo keeps a generated reference package for CI or review:
uv run mistral-vespa generate \
--app-dir ./vespa_app \
--path ./vespa.lockRegenerate after every schema change. Deployment should still happen from migrations via mistral-vespa migrate.
IDE Support
Use an IDE with the Vespa plugin for syntax highlighting, code completion, navigation between functions and profiles, and error detection. See Vespa IDE support documentation.
See Also
- Deploy and Operate — Production deployment and health checks