///|
/// A reproducible application-level scenario result.
pub(all) struct ScenarioReport {
name : String
documents : Int
queries : Int
successful_queries : Int
average_recall : Double
context_sources : Int
passed : Bool
notes : String
}
///|
pub impl Show for ScenarioReport with fn output(self, logger) {
logger.write_string(
"ScenarioReport{name: " +
self.name +
", documents: " +
self.documents.to_string() +
", queries: " +
self.queries.to_string() +
", successful: " +
self.successful_queries.to_string() +
", recall: " +
self.average_recall.to_string() +
", context_sources: " +
self.context_sources.to_string() +
", passed: " +
self.passed.to_string() +
"}",
)
}
///|
/// Documents representing a small multi-tenant knowledge base.
pub fn knowledge_base_scenario_documents() -> Array[Document] {
[
Document::new("kb-auth", [0.98, 0.12, 0.02, 0.01], [
("tenant", "acme"),
("topic", "security"),
("title", "Authentication"),
(
"text", "Use token rotation and short session lifetimes for authentication.",
),
("source", "security-handbook"),
]),
Document::new("kb-rag", [0.94, 0.18, 0.03, 0.02], [
("tenant", "acme"),
("topic", "retrieval"),
("title", "Retrieval pipeline"),
(
"text", "Retrieve relevant chunks, rerank them, and cite the source documents.",
),
("source", "ai-playbook"),
]),
Document::new("kb-cache", [0.88, 0.22, 0.06, 0.04], [
("tenant", "acme"),
("topic", "performance"),
("title", "Embedding cache"),
(
"text", "Cache embeddings by model and document revision to reduce repeated work.",
),
("source", "platform-guide"),
]),
Document::new("kb-index", [0.82, 0.28, 0.08, 0.05], [
("tenant", "acme"),
("topic", "retrieval"),
("title", "Index selection"),
(
"text", "Use Flat for exact baselines, IVF for clustered search, and LSH for fast approximate candidates.",
),
("source", "ai-playbook"),
]),
Document::new("kb-privacy", [0.16, 0.92, 0.05, 0.03], [
("tenant", "acme"),
("topic", "security"),
("title", "Privacy review"),
(
"text", "Remove personal data from logs and enforce tenant boundaries before retrieval.",
),
("source", "security-handbook"),
]),
Document::new("kb-observe", [0.22, 0.84, 0.08, 0.04], [
("tenant", "acme"),
("topic", "operations"),
("title", "Observability"),
(
"text", "Track query counts, empty results, recall, and index rebuild revisions.",
),
("source", "platform-guide"),
]),
Document::new("kb-fallback", [0.28, 0.78, 0.11, 0.05], [
("tenant", "acme"),
("topic", "operations"),
("title", "Fallback search"),
(
"text", "Fall back to the exact index when an approximate index is empty or stale.",
),
("source", "platform-guide"),
]),
Document::new("kb-eval", [0.34, 0.72, 0.14, 0.07], [
("tenant", "acme"),
("topic", "evaluation"),
("title", "Recall evaluation"),
(
"text", "Compare approximate results with Flat using recall at several cutoffs.",
),
("source", "ai-playbook"),
]),
Document::new("kb-tenant", [0.12, 0.22, 0.95, 0.04], [
("tenant", "beta"),
("topic", "security"),
("title", "Tenant isolation"),
(
"text", "Apply tenant metadata filters before returning results to clients.",
),
("source", "beta-handbook"),
]),
Document::new("kb-schema", [0.16, 0.26, 0.88, 0.08], [
("tenant", "beta"),
("topic", "data"),
("title", "Schema validation"),
(
"text", "Reject empty vectors, duplicate ids, and inconsistent dimensions at ingestion.",
),
("source", "beta-handbook"),
]),
Document::new("kb-batch", [0.18, 0.30, 0.82, 0.10], [
("tenant", "beta"),
("topic", "performance"),
("title", "Batch retrieval"),
(
"text", "Use batch search to amortize application overhead for multiple queries.",
),
("source", "beta-handbook"),
]),
Document::new("kb-audit", [0.20, 0.34, 0.76, 0.12], [
("tenant", "beta"),
("topic", "operations"),
("title", "Audit trail"),
(
"text", "Record the index strategy, filter expression, revision, and source ids.",
),
("source", "beta-handbook"),
]),
]
}
///|
/// Product catalog documents for filtered recommendation tests.
pub fn catalog_scenario_documents() -> Array[Document] {
[
Document::new("p-laptop-1", [0.91, 0.82, 0.30, 0.10], [
("category", "laptop"),
("brand", "moon"),
("price", "premium"),
("title", "MoonBook Pro"),
("text", "portable laptop for engineering and data work"),
]),
Document::new("p-laptop-2", [0.88, 0.78, 0.34, 0.12], [
("category", "laptop"),
("brand", "orbit"),
("price", "mid"),
("title", "Orbit Air"),
("text", "lightweight laptop for travel and development"),
]),
Document::new("p-laptop-3", [0.84, 0.76, 0.28, 0.16], [
("category", "laptop"),
("brand", "moon"),
("price", "mid"),
("title", "MoonBook Studio"),
("text", "developer laptop with a bright display"),
]),
Document::new("p-laptop-4", [0.80, 0.70, 0.40, 0.18], [
("category", "laptop"),
("brand", "terra"),
("price", "budget"),
("title", "Terra Code"),
("text", "budget laptop for programming students"),
]),
Document::new("p-phone-1", [0.12, 0.24, 0.92, 0.14], [
("category", "phone"),
("brand", "moon"),
("price", "premium"),
("title", "MoonPhone X"),
("text", "secure phone with a long battery life"),
]),
Document::new("p-phone-2", [0.18, 0.28, 0.86, 0.18], [
("category", "phone"),
("brand", "orbit"),
("price", "mid"),
("title", "Orbit Note"),
("text", "phone for notes, calls, and everyday use"),
]),
Document::new("p-phone-3", [0.22, 0.30, 0.82, 0.22], [
("category", "phone"),
("brand", "terra"),
("price", "budget"),
("title", "Terra Mini"),
("text", "compact affordable phone"),
]),
Document::new("p-phone-4", [0.16, 0.20, 0.78, 0.20], [
("category", "phone"),
("brand", "moon"),
("price", "mid"),
("title", "MoonPhone S"),
("text", "balanced phone with strong privacy controls"),
]),
Document::new("p-audio-1", [0.24, 0.18, 0.42, 0.90], [
("category", "audio"),
("brand", "moon"),
("price", "premium"),
("title", "MoonPods Max"),
("text", "noise cancelling headphones for focused work"),
]),
Document::new("p-audio-2", [0.28, 0.22, 0.38, 0.84], [
("category", "audio"),
("brand", "orbit"),
("price", "mid"),
("title", "Orbit Buds"),
("text", "wireless earbuds for commuting"),
]),
Document::new("p-audio-3", [0.32, 0.26, 0.34, 0.78], [
("category", "audio"),
("brand", "terra"),
("price", "budget"),
("title", "Terra Sound"),
("text", "affordable headphones for calls"),
]),
Document::new("p-audio-4", [0.26, 0.20, 0.46, 0.74], [
("category", "audio"),
("brand", "moon"),
("price", "mid"),
("title", "MoonPods S"),
("text", "comfortable earbuds with secure fit"),
]),
]
}
///|
/// Run a retrieval regression scenario against the exact Flat baseline.
pub fn run_retrieval_scenario(
name : String,
docs : Array[Document],
queries : Array[Array[Double]],
top_k : Int,
) -> ScenarioReport raise VectorError {
validate_documents(docs)
let index = build_flat_index(docs)
let successful = []
for query in queries {
let results = index.search(query, top_k, Cosine, [])
successful.push(results.length() > 0)
}
let mut success_count = 0
for ok in successful {
if ok {
success_count = success_count + 1
}
}
let response_count = if queries.length() == 0 {
0.0
} else {
success_count.to_double() / queries.length().to_double()
}
{
name,
documents: docs.length(),
queries: queries.length(),
successful_queries: success_count,
average_recall: response_count,
context_sources: 0,
passed: success_count == queries.length(),
notes: "exact retrieval baseline",
}
}
///|
/// Exercise a tenant-aware RAG workflow with source attribution.
pub fn run_rag_scenario() -> ScenarioReport raise VectorError {
let docs = knowledge_base_scenario_documents()
let tenant_docs = filter_documents(docs, [("tenant", "acme")])
let context = build_rag_context(
tenant_docs,
[0.90, 0.20, 0.04, 0.03],
"retrieval source documents",
4,
0.75,
480,
)
{
name: "tenant-rag",
documents: tenant_docs.length(),
queries: 1,
successful_queries: if context.chunks.length() > 0 {
1
} else {
0
},
average_recall: if context.chunks.length() > 0 {
1.0
} else {
0.0
},
context_sources: context.source_ids.length(),
passed: context.chunks.length() > 0 && context.text.length() <= 600,
notes: context_citations(context),
}
}
///|
/// Exercise category and price filters in a catalog search.
pub fn run_catalog_scenario() -> ScenarioReport raise VectorError {
let docs = catalog_scenario_documents()
let laptops = filter_documents(docs, [
("category", "laptop"),
("price", "mid"),
])
let index = build_flat_index(laptops)
let results = index.search([0.88, 0.80, 0.32, 0.12], 3, Cosine, [])
{
name: "catalog-filtered-recommendation",
documents: docs.length(),
queries: 1,
successful_queries: if results.length() == 2 {
1
} else {
0
},
average_recall: if results.length() == 2 {
1.0
} else {
0.0
},
context_sources: 0,
passed: results.length() == 2,
notes: "category=laptop AND price=mid",
}
}
///|
/// Exercise batch retrieval and recall reporting for another application path.
pub fn run_batch_scenario() -> ScenarioReport raise VectorError {
let docs = knowledge_base_scenario_documents()
let index = build_flat_index(docs)
let queries = [
[0.95, 0.15, 0.03, 0.02],
[0.18, 0.28, 0.90, 0.12],
[0.20, 0.30, 0.80, 0.10],
]
let results = index.search_batch(queries, 3, Cosine, [])
let telemetry = summarize_workload(results, 3)
{
name: "batch-tenant-routing",
documents: docs.length(),
queries: queries.length(),
successful_queries: telemetry.queries - telemetry.empty_queries,
average_recall: if telemetry.queries == 0 {
0.0
} else {
1.0 - telemetry.empty_queries.to_double() / telemetry.queries.to_double()
},
context_sources: telemetry.returned,
passed: workload_is_stable(telemetry, 3),
notes: "batch search with workload telemetry",
}
}
///|
/// Run all included application scenarios.
pub fn run_all_application_scenarios() -> Array[ScenarioReport] raise VectorError {
[run_rag_scenario(), run_catalog_scenario(), run_batch_scenario()]
}