Quickstart: Ahnlich AI
Send plain text (or images) and let Ahnlich do the vector math for you — this is the gentlest way in, with no need to understand embeddings or dimensions. Pick your language — or the CLI for a no-code path — once below, and every sample on this page follows your choice.
Bringing your own vectors instead? Use the Ahnlich DB quickstart — same flow, but you supply the vectors.
You need the Ahnlich AI proxy running (it embeds text for you automatically). The fastest way is Docker:
docker run -d --name ahnlich-ai -p 1370:1370 ghcr.io/deven96/ahnlich-ai:latestSee Installation for binaries and other options.
Install the client
- Python
- Rust
- Node
- Go
- CLI
pip install ahnlich-client-pycargo add ahnlich_client_rsnpm install ahnlich-client-nodego get github.com/deven96/ahnlich/sdk/ahnlich-client-go# Download the ahnlich-cli binary (see Installation for all platforms/options)wget -L https://github.com/deven96/ahnlich/releases/download/bin%2Fcli%2F0.2.1/x86_64-unknown-linux-gnu-ahnlich-cli.tar.gztar -xvzf x86_64-unknown-linux-gnu-ahnlich-cli.tar.gz && chmod +x ahnlich-cli1. Connect
Open a client against the AI proxy. No boilerplate, no config.
- Python
- Rust
- Node
- Go
- CLI
import asyncio
from grpclib.client import Channel
from ahnlich_client_py.grpc.services.ai_service import AiServiceStub
async def main():
# Open a gRPC channel to the AI proxy (default port 1370).
# `async with` closes the connection automatically when you're done.
async with Channel(host="127.0.0.1", port=1370) as channel:
# The stub is your typed client — every Ahnlich call goes through it.
client = AiServiceStub(channel)
# ready to talk to Ahnlich
use ahnlich_client_rs::ai::AiClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connect to the AI proxy (host:port). The client is cheap to clone
// and safe to share across tasks.
let client = AiClient::new("127.0.0.1:1370".to_string()).await?;
// ready to talk to Ahnlich
Ok(())
}
import { createAiClient } from "ahnlich-client-node";
// Connect to the AI proxy (host:port). Reuse this client for every call.
const client = createAiClient("127.0.0.1:1370");
// ready to talk to Ahnlich
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
aisvc "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/services/ai_service"
)
// Dial the AI proxy (host:port). Use insecure credentials for local dev.
conn, err := grpc.DialContext(ctx, "127.0.0.1:1370",
grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
if err != nil {
log.Fatalf("failed to connect: %v", err)
}
defer conn.Close() // close the connection when main returns
// The typed client — every Ahnlich call goes through it.
client := aisvc.NewAIServiceClient(conn)
Open the interactive shell against the AI proxy — every command in the following steps runs inside it.
ahnlich-cli ahnlich --agent ai --host 127.0.0.1 --port 13702. Create a store
Pick an embedding model and let Ahnlich handle the vectors for you.
- Python
- Rust
- Node
- Go
- CLI
from ahnlich_client_py.grpc.ai import query as ai_query
from ahnlich_client_py.grpc.ai.models import AiModel
await client.create_store(ai_query.CreateStore(
store="books", # name of the store
index_model=AiModel.ALL_MINI_LM_L6_V2, # model used to embed stored data
query_model=AiModel.ALL_MINI_LM_L6_V2, # model used to embed search queries
predicates=["author", "genre"], # metadata fields you can filter on
store_original=True, # keep the raw text alongside vectors
error_if_exists=True, # fail if a store with this name exists
))
use ahnlich_types::ai::query::CreateStore;
use ahnlich_types::ai::models::AiModel;
client.create_store(CreateStore {
store: "books".to_string(),
schema: None,
index_model: AiModel::AllMiniLmL6V2 as i32, // embeds stored data
query_model: AiModel::AllMiniLmL6V2 as i32, // embeds search queries
predicates: vec!["author".into(), "genre".into()], // filterable metadata fields
non_linear_indices: vec![], // optional ANN indexes (e.g. hnsw)
error_if_exists: true, // fail if the store already exists
store_original: true, // keep the raw text alongside vectors
}, None).await?;
import { CreateStore } from "ahnlich-client-node/grpc/ai/query_pb";
import { AIModel } from "ahnlich-client-node/grpc/ai/models_pb";
await client.createStore(
new CreateStore({
store: "books",
queryModel: AIModel.ALL_MINI_LM_L6_V2, // embeds search queries
indexModel: AIModel.ALL_MINI_LM_L6_V2, // embeds stored data
predicates: ["author", "genre"], // filterable metadata fields
errorIfExists: true, // fail if the store already exists
storeOriginal: true, // keep the raw text alongside vectors
})
);
import (
aiquery "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/ai/query"
aimodel "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/ai/models"
)
_, err = client.CreateStore(ctx, &aiquery.CreateStore{
Store: "books",
QueryModel: aimodel.AIModel_ALL_MINI_LM_L6_V2, // embeds search queries
IndexModel: aimodel.AIModel_ALL_MINI_LM_L6_V2, // embeds stored data
Predicates: []string{"author", "genre"}, // filterable metadata fields
ErrorIfExists: true, // fail if the store exists
StoreOriginal: true, // keep the raw text too
})
CREATESTORE books QUERYMODEL all-minilm-l6-v2 INDEXMODEL all-minilm-l6-v2 PREDICATES (author, genre)predicates are metadata fields you can later filter on (e.g. author, genre).
Field names must match exactly between insert and query.
3. Insert data
Send raw text with metadata. Embeddings are generated automatically.
- Python
- Rust
- Node
- Go
- CLI
from ahnlich_client_py.grpc import keyval, metadata
from ahnlich_client_py.grpc.ai import preprocess
await client.set(ai_query.Set(
store="books",
inputs=[
# Each entry = the text to embed (key) + its metadata (value).
keyval.AiStoreEntry(
key=keyval.StoreInput(raw_string="A galactic empire in decline..."),
value=keyval.StoreValue(value={
# These keys must match the store's `predicates` to be filterable.
"genre": metadata.MetadataValue(raw_string="SciFi"),
"author": metadata.MetadataValue(raw_string="Asimov"),
}),
)
],
# ModelPreprocessing lets the proxy tokenize/normalize the text before embedding.
preprocess_action=preprocess.PreprocessAction.ModelPreprocessing,
))
use ahnlich_types::ai::query::Set;
use ahnlich_types::ai::preprocess::PreprocessAction;
use ahnlich_types::keyval::{AiStoreEntry, StoreInput, StoreValue};
use ahnlich_types::keyval::store_input::Value;
use ahnlich_types::metadata::{MetadataValue, metadata_value::Value as MValue};
use std::collections::HashMap;
// Metadata keys must match the store's `predicates` to be filterable later.
let mut metadata = HashMap::new();
metadata.insert("genre".to_string(),
MetadataValue { value: Some(MValue::RawString("SciFi".into())) });
client.set(Set {
store: "books".to_string(),
schema: None,
execution_provider: None,
// Let the proxy preprocess the text before embedding.
preprocess_action: PreprocessAction::ModelPreprocessing as i32,
inputs: vec![AiStoreEntry {
// key = the text to embed, value = its metadata.
key: Some(StoreInput { value: Some(Value::RawString("A galactic empire in decline...".into())) }),
value: Some(StoreValue { value: metadata }),
}],
model_params: HashMap::new(),
}, None).await?;
import { Set } from "ahnlich-client-node/grpc/ai/query_pb";
import { AiStoreEntry, StoreInput, StoreValue } from "ahnlich-client-node/grpc/keyval_pb";
import { MetadataValue } from "ahnlich-client-node/grpc/metadata_pb";
import { PreprocessAction } from "ahnlich-client-node/grpc/ai/preprocess_pb";
await client.set(
new Set({
store: "books",
inputs: [
new AiStoreEntry({
// key = the text to embed, value = its metadata.
key: new StoreInput({ value: { case: "rawString", value: "A galactic empire in decline..." } }),
value: new StoreValue({
value: {
// These keys must match the store's predicates to be filterable.
genre: new MetadataValue({ value: { case: "rawString", value: "SciFi" } }),
author: new MetadataValue({ value: { case: "rawString", value: "Asimov" } }),
},
}),
}),
],
// Let the proxy preprocess the text before embedding.
preprocessAction: PreprocessAction.MODEL_PREPROCESSING,
})
);
import (
keyval "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/keyval"
metadata "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/metadata"
preprocess "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/ai/preprocess"
)
_, err = client.Set(ctx, &aiquery.Set{
Store: "books",
Inputs: []*keyval.AiStoreEntry{{
// Key = the text to embed.
Key: &keyval.StoreInput{Value: &keyval.StoreInput_RawString{
RawString: "A galactic empire in decline..."}},
// Value = metadata; keys must match the store's predicates to filter on.
Value: &keyval.StoreValue{Value: map[string]*metadata.MetadataValue{
"genre": {Value: &metadata.MetadataValue_RawString{RawString: "SciFi"}},
"author": {Value: &metadata.MetadataValue_RawString{RawString: "Asimov"}},
}},
}},
// Let the proxy preprocess the text before embedding.
PreprocessAction: preprocess.PreprocessAction_ModelPreprocessing,
})
SET (([A galactic empire in decline...], {genre: SciFi, author: Asimov})) IN books PREPROCESSACTION modelpreprocessing4. Update data
UPSERT finds a single matching entry using a predicate condition and updates its raw input or metadata.
- Python
- Rust
- Node
- Go
- CLI
from ahnlich_client_py.grpc import ai_query, keyval, metadata, predicates
from ahnlich_client_py.grpc.ai import preprocess
# Update the book with genre "SciFi" - change its author metadata
await client.upsert(ai_query.Upsert(
store="books",
# New text to embed (replaces the old key)
new_input=keyval.StoreInput(raw_string="The Foundation trilogy explores psychohistory"),
# New metadata (merges with existing by default in AI)
new_value=keyval.StoreValue(value={
"author": metadata.MetadataValue(raw_string="Isaac Asimov"),
}),
# Find the entry to update using a predicate
condition=predicates.PredicateCondition(predicates=[
predicates.Predicate(key="genre", value=metadata.MetadataValue(raw_string="SciFi"))
]),
preprocess_action=preprocess.PreprocessAction.ModelPreprocessing,
))
use ahnlich_types::ai::query::Upsert;
use ahnlich_types::ai::preprocess::PreprocessAction;
use ahnlich_types::keyval::{StoreInput, StoreValue};
use ahnlich_types::keyval::store_input::Value;
use ahnlich_types::metadata::{MetadataValue, metadata_value::Value as MValue};
use ahnlich_types::predicate::{Predicate, PredicateCondition};
use std::collections::HashMap;
let mut new_metadata = HashMap::new();
new_metadata.insert("author".to_string(),
MetadataValue { value: Some(MValue::RawString("Isaac Asimov".into())) });
client.upsert(Upsert {
store: "books".to_string(),
schema: None,
execution_provider: None,
// New text to embed
new_input: Some(StoreInput { value: Some(Value::RawString("The Foundation trilogy explores psychohistory".into())) }),
// New metadata (merges automatically in AI)
new_value: Some(StoreValue { value: new_metadata }),
// Predicate to find entry
condition: Some(PredicateCondition {
predicates: vec![Predicate {
key: "genre".to_string(),
value: Some(MetadataValue { value: Some(MValue::RawString("SciFi".into())) }),
}],
}),
preprocess_action: PreprocessAction::ModelPreprocessing as i32,
model_params: HashMap::new(),
}, None).await?;
import { Upsert } from "ahnlich-client-node/grpc/ai/query_pb";
import { StoreInput, StoreValue } from "ahnlich-client-node/grpc/keyval_pb";
import { MetadataValue } from "ahnlich-client-node/grpc/metadata_pb";
import { PreprocessAction } from "ahnlich-client-node/grpc/ai/preprocess_pb";
import { Predicate, PredicateCondition } from "ahnlich-client-node/grpc/predicate_pb";
await client.upsert(
new Upsert({
store: "books",
// New text to embed
newInput: new StoreInput({ value: { case: "rawString", value: "The Foundation trilogy explores psychohistory" } }),
// New metadata (merges automatically in AI)
newValue: new StoreValue({
value: {
author: new MetadataValue({ value: { case: "rawString", value: "Isaac Asimov" } }),
},
}),
// Find entry by predicate
condition: new PredicateCondition({
predicates: [
new Predicate({
key: "genre",
value: new MetadataValue({ value: { case: "rawString", value: "SciFi" } }),
}),
],
}),
preprocessAction: PreprocessAction.MODEL_PREPROCESSING,
})
);
import (
keyval "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/keyval"
metadata "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/metadata"
predicates "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/predicate"
preprocess "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/ai/preprocess"
)
_, err = client.Upsert(ctx, &aiquery.Upsert{
Store: "books",
// New text to embed
NewInput: &keyval.StoreInput{Value: &keyval.StoreInput_RawString{
RawString: "The Foundation trilogy explores psychohistory"}},
// New metadata (merges automatically in AI)
NewValue: &keyval.StoreValue{Value: map[string]*metadata.MetadataValue{
"author": {Value: &metadata.MetadataValue_RawString{RawString: "Isaac Asimov"}},
}},
// Find entry by predicate
Condition: &predicates.PredicateCondition{Predicates: []*predicates.Predicate{{
Key: "genre",
Value: &metadata.MetadataValue{Value: &metadata.MetadataValue_RawString{RawString: "SciFi"}},
}}},
PreprocessAction: preprocess.PreprocessAction_ModelPreprocessing,
})
UPSERT NEWINPUT [The Foundation trilogy explores psychohistory] NEWVALUE {author: Isaac Asimov} WHERE (genre = SciFi) IN books5. Search
Query by meaning, with results ranked by similarity.
- Python
- Rust
- Node
- Go
- CLI
from ahnlich_client_py.grpc.algorithm import algorithms
from ahnlich_client_py.grpc.ai.preprocess import PreprocessAction
# Search by meaning — the query text is embedded with the store's query_model.
response = await client.get_sim_n(ai_query.GetSimN(
store="books",
search_input=keyval.StoreInput(raw_string="space opera classics"),
closest_n=3, # return the 3 nearest matches
algorithm=algorithms.Algorithm.CosineSimilarity, # distance metric
preprocess_action=PreprocessAction.ModelPreprocessing,
))
# Results are ranked most-similar first.
for entry in response.entries:
print(entry.key.raw_string, entry.similarity.value)
use ahnlich_types::ai::query::GetSimN;
use ahnlich_types::algorithm::algorithms::Algorithm;
let res = client.get_sim_n(GetSimN {
store: "books".to_string(),
schema: None,
// The query text is embedded with the store's query_model.
search_input: Some(StoreInput {
value: Some(Value::RawString("space opera classics".into())),
}),
closest_n: 3, // return the 3 nearest matches
algorithm: Algorithm::CosineSimilarity as i32, // distance metric
execution_provider: None,
preprocess_action: PreprocessAction::ModelPreprocessing as i32,
condition: None, // optional metadata filter (WHERE)
model_params: HashMap::new(),
}, None).await?;
// Results are ranked most-similar first.
println!("{:?}", res.entries);
import { GetSimN } from "ahnlich-client-node/grpc/ai/query_pb";
import { Algorithm } from "ahnlich-client-node/grpc/algorithm/algorithm_pb";
// Search by meaning — the query text is embedded with the store's query model.
const response = await client.getSimN(
new GetSimN({
store: "books",
searchInput: new StoreInput({ value: { case: "rawString", value: "space opera classics" } }),
closestN: 3, // return the 3 nearest matches
algorithm: Algorithm.COSINE_SIMILARITY, // distance metric
})
);
// Results are ranked most-similar first.
for (const entry of response.entries) {
console.log(entry.input?.value, entry.similarity);
}
import (
algorithms "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/algorithm/algorithms"
)
// Search by meaning — the query text is embedded with the store's query model.
resp, err := client.GetSimN(ctx, &aiquery.GetSimN{
Store: "books",
SearchInput: &keyval.StoreInput{Value: &keyval.StoreInput_RawString{RawString: "space opera classics"}},
ClosestN: 3, // return the 3 nearest matches
Algorithm: algorithms.Algorithm_CosineSimilarity, // distance metric
PreprocessAction: preprocess.PreprocessAction_ModelPreprocessing,
})
// Results are ranked most-similar first.
for _, entry := range resp.Entries {
fmt.Println(entry.Key, entry.Similarity)
}
GETSIMN 3 WITH [space opera classics] USING cosinesimilarity IN books WHERE (genre = SciFi)You now have semantic search working end to end. The sections below cover the rest of the everyday operations.
6. Filter your search
Combine similarity with a metadata condition — only return matches where a
predicate holds (e.g. genre = SciFi).
- Python
- Rust
- Node
- Go
- CLI
from ahnlich_client_py.grpc import predicates
# genre = "SciFi"
condition = predicates.PredicateCondition(
value=predicates.Predicate(
equals=predicates.Equals(
key="genre",
value=metadata.MetadataValue(raw_string="SciFi"),
)
)
)
response = await client.get_sim_n(ai_query.GetSimN(
store="books",
search_input=keyval.StoreInput(raw_string="space opera classics"),
closest_n=3,
algorithm=algorithms.Algorithm.CosineSimilarity,
condition=condition, # only entries where genre = SciFi
preprocess_action=PreprocessAction.ModelPreprocessing,
))
use ahnlich_types::predicates::{
Predicate, PredicateCondition, Equals, predicate, predicate_condition,
};
// genre = "SciFi"
let condition = PredicateCondition {
kind: Some(predicate_condition::Kind::Value(Predicate {
kind: Some(predicate::Kind::Equals(Equals {
key: "genre".to_string(),
value: Some(MetadataValue { value: Some(MValue::RawString("SciFi".into())) }),
})),
})),
};
let res = client.get_sim_n(GetSimN {
store: "books".to_string(),
search_input: Some(StoreInput {
value: Some(Value::RawString("space opera classics".into())),
}),
closest_n: 3,
algorithm: Algorithm::CosineSimilarity as i32,
condition: Some(condition), // only entries where genre = SciFi
preprocess_action: PreprocessAction::ModelPreprocessing as i32,
schema: None,
execution_provider: None,
model_params: HashMap::new(),
}, None).await?;
import { PredicateCondition, Predicate, Equals } from "ahnlich-client-node/grpc/predicates_pb";
// genre = "SciFi"
const condition = new PredicateCondition({
kind: {
case: "value",
value: new Predicate({
kind: {
case: "equals",
value: new Equals({
key: "genre",
value: new MetadataValue({ value: { case: "rawString", value: "SciFi" } }),
}),
},
}),
},
});
const response = await client.getSimN(
new GetSimN({
store: "books",
searchInput: new StoreInput({ value: { case: "rawString", value: "space opera classics" } }),
closestN: 3,
algorithm: Algorithm.COSINE_SIMILARITY,
condition, // only entries where genre = SciFi
})
);
import (
predicates "github.com/deven96/ahnlich/sdk/ahnlich-client-go/grpc/predicates"
)
// genre = "SciFi"
condition := &predicates.PredicateCondition{Kind: &predicates.PredicateCondition_Value{
Value: &predicates.Predicate{Kind: &predicates.Predicate_Equals{
Equals: &predicates.Equals{
Key: "genre",
Value: &metadata.MetadataValue{Value: &metadata.MetadataValue_RawString{RawString: "SciFi"}},
}}}}}
resp, err := client.GetSimN(ctx, &aiquery.GetSimN{
Store: "books",
SearchInput: &keyval.StoreInput{Value: &keyval.StoreInput_RawString{RawString: "space opera classics"}},
ClosestN: 3,
Algorithm: algorithms.Algorithm_CosineSimilarity,
Condition: condition, // only entries where genre = SciFi
PreprocessAction: preprocess.PreprocessAction_ModelPreprocessing,
})
GETSIMN 3 WITH [space opera classics] USING cosinesimilarity IN books WHERE (genre = SciFi)A metadata field must be declared as a predicate on the store (or indexed
with CREATEPREDINDEX) before you can filter on it. See step 8.
7. Retrieve by key
Fetch entries by their original input — handy when you already know the exact
text. Requires the store to have been created with store_original = true.
- Python
- Rust
- Node
- Go
- CLI
response = await client.get_key(ai_query.GetKey(
store="books",
keys=[keyval.StoreInput(raw_string="A galactic empire in decline...")],
))
for entry in response.entries:
print(entry.key.raw_string, entry.value.value)
use ahnlich_types::ai::query::GetKey;
let res = client.get_key(GetKey {
store: "books".to_string(),
keys: vec![StoreInput {
value: Some(Value::RawString("A galactic empire in decline...".into())),
}],
schema: None,
}, None).await?;
println!("{:?}", res.entries);
import { GetKey } from "ahnlich-client-node/grpc/ai/query_pb";
const response = await client.getKey(
new GetKey({
store: "books",
keys: [new StoreInput({ value: { case: "rawString", value: "A galactic empire in decline..." } })],
})
);
resp, err := client.GetKey(ctx, &aiquery.GetKey{
Store: "books",
Keys: []*keyval.StoreInput{
{Value: &keyval.StoreInput_RawString{RawString: "A galactic empire in decline..."}},
},
})
GETKEY ([A galactic empire in decline...]) IN books8. Speed up filters with an index
Create a predicate index so metadata filters (step 6) stay fast as your store grows. You can add predicates that weren't declared at creation time.
- Python
- Rust
- Node
- Go
- CLI
await client.create_pred_index(ai_query.CreatePredIndex(
store="books",
predicates=["author", "genre"],
))
use ahnlich_types::ai::query::CreatePredIndex;
client.create_pred_index(CreatePredIndex {
store: "books".to_string(),
predicates: vec!["author".into(), "genre".into()],
schema: None,
}, None).await?;
import { CreatePredIndex } from "ahnlich-client-node/grpc/ai/query_pb";
await client.createPredIndex(
new CreatePredIndex({ store: "books", predicates: ["author", "genre"] })
);
_, err = client.CreatePredIndex(ctx, &aiquery.CreatePredIndex{
Store: "books",
Predicates: []string{"author", "genre"},
})
CREATEPREDINDEX (author, genre) IN books9. Inspect your stores
List every store on the server, along with its size, dimensions, and models.
- Python
- Rust
- Node
- Go
- CLI
stores = await client.list_stores(ai_query.ListStores())
for store in stores.stores:
print(store.name, store.size_in_bytes)
use ahnlich_types::ai::query::ListStores;
let stores = client.list_stores(ListStores { schema: None }, None).await?;
println!("{:?}", stores.stores);
import { ListStores } from "ahnlich-client-node/grpc/ai/query_pb";
const stores = await client.listStores(new ListStores({}));
console.log(stores.stores);
stores, err := client.ListStores(ctx, &aiquery.ListStores{})
fmt.Println(stores.Stores)
LISTSTORES10. Clean up
Delete individual entries with del key, or remove the whole store with drop store.
- Python
- Rust
- Node
- Go
- CLI
# delete a single entry by its key
await client.del_key(ai_query.DelKey(
store="books",
keys=[keyval.StoreInput(raw_string="A galactic empire in decline...")],
))
# or drop the entire store
await client.drop_store(ai_query.DropStore(store="books", error_if_not_exists=True))
use ahnlich_types::ai::query::{DelKey, DropStore};
client.del_key(DelKey {
store: "books".to_string(),
keys: vec![StoreInput { value: Some(Value::RawString("A galactic empire in decline...".into())) }],
schema: None,
}, None).await?;
client.drop_store(DropStore {
store: "books".to_string(),
error_if_not_exists: true,
schema: None,
}, None).await?;
import { DelKey, DropStore } from "ahnlich-client-node/grpc/ai/query_pb";
await client.delKey(
new DelKey({
store: "books",
keys: [new StoreInput({ value: { case: "rawString", value: "A galactic empire in decline..." } })],
})
);
await client.dropStore(new DropStore({ store: "books", errorIfNotExists: true }));
_, err = client.DelKey(ctx, &aiquery.DelKey{
Store: "books",
Keys: []*keyval.StoreInput{{Value: &keyval.StoreInput_RawString{RawString: "A galactic empire in decline..."}}},
})
_, err = client.DropStore(ctx, &aiquery.DropStore{Store: "books", ErrorIfNotExists: true})
DELKEY ([A galactic empire in decline...]) IN booksDROPSTORE books IF EXISTSThat's the full lifecycle — create, populate, search, filter, and clean up.
Where to next?
- Usage — drive Ahnlich from the CLI, plus the full command reference.
- Client Libraries — deeper SDK docs for each language.
- Components — how the DB, AI proxy, and CLI fit together.
Found a bug or something unclear? Open an issue.