Defining indexes
Register named knowledge indexes with sources, embedding models, and vector stores.
A named index is the application's definition of a searchable knowledge collection. Keep its name stable so ingestion jobs and queries refer to the same collection.
Install the host and provider dependencies
For this OpenAI agent example, add the RAG, agent, and hosting packages:
The typed embedding helpers in Runiq.AI.Agents.Providers.OpenAI are included in the Runiq.AI.Agents package.
Supply OpenAI:ApiKey with .NET user-secrets, the OpenAI__ApiKey environment variable, or your host's secret provider. Do not put real credentials in source-controlled appsettings.json or appsettings.Development.json files.
Register the index and its agent
This startup example selects Markdown company policies and a disposable in-memory store, then explicitly connects an agent to that index. Create the document directory and supply the API key before starting the host:
There are three separate registrations here: AddIndex defines the collection, .UseRag(...) connects the agent to it, and AddRuniqServer(...) registers the agent runtime. Defining the index alone never enables agent retrieval.
Keep this order: the current OpenAI host integration inspects already registered indexes when AddRuniqServer(...) adds RAG-enabled OpenAI agents. It registers the matching OpenAI embedding client using the agent's API key. UseOpenAiEmbeddingModel(...) alone only selects the model reference; it does not perform that client registration. For custom providers or retrieval-only hosts, register an IEmbeddingClient through AddRagEmbeddingClient(...) explicitly.
OnStartup rebuilds this disposable index on every process start and blocks host startup while ingestion runs. It is appropriate here for a small local collection; choose a persistent store and a deliberate ingestion strategy for production.
Hybrid needs both semantic and lexical retrieval support. The acceptance settings control candidate evaluation in the agent runtime; the example threshold should be tuned with representative policy questions. Required with ReturnNotFound skips model invocation when successful retrieval leaves no accepted context.
The example resolves documents from AppContext.BaseDirectory, independent of the process working directory. Keep the corpus under documents/company-policies in the project and copy it to build and publish output. Add this item to the application's project file:
Understand the registration
| Setting | Responsibility |
|---|---|
AddIndex("company-policies", ...) | Give ingestion and retrieval a shared logical name. |
UseDirectory(...) | Describe which files discovery should read when ingestion runs. |
UseOpenAiEmbeddingModel(...) | Select the typed provider/model reference. |
UseInMemoryVectorStore() | Select disposable local storage. |
ConfigureIngestion(...) | Decide when ingestion starts automatically, if at all. |
Registration does not scan the directory, call the embedding service, ingest documents, or open a database connection. It stores the configuration for later runtime execution.
Indexes cannot be created from Dashboard > RAG Management. Register them in application startup code; RAG Management shows those registrations and lets you inspect or start/cancel ingestion.
Configure chunk boundaries
The index builder can override chunk size and overlap. These values are character counts:
This is an example configuration to evaluate with your documents. Test whether retrieved chunks contain enough surrounding text to answer real questions before choosing production values.
Select a persistent store
For PostgreSQL, replace the index's in-memory selection with:
Import Runiq.AI.Rag.PostgreSql.DependencyInjection and register the provider as shown in PostgreSQL. A store selection identifies the provider; the provider registration supplies its connection configuration.
Continue with Ingestion to make the collection searchable.
Reference: RAG package guide.