Skip to main content

Embedding Workflow

AveniECA supports vector embeddings for both ESS records and documents, enabling semantic search across your state history and knowledge base. The typical workflow is:
  1. Create an embedding input with unique text/data
  2. Link the embedding input to ESS records
  3. AveniECA generates vector embeddings automatically
  4. Use vector search to find similar states or documents

Creating Embedding Inputs

Embedding inputs are unique text representations that get vectorized:
import os
import avenieca
from avenieca.api.model import Config, EmbeddingInputInsert
from avenieca.api.eca import ECA

config = Config(
    uri="http://localhost:2580/v1",
    username=os.getenv("USERNAME"),
    password=os.getenv("PASSWORD")
)
eca = ECA(config)

# Create unique hash for the input
input_text = "the inputs"
input_hash = avenieca.encode("my_secret", input_text)

# Create embedding input
embedding = EmbeddingInputInsert(
    module_id="air_conditioner",
    input=input_text,
    hash=input_hash
)

res, status = eca.embedding.create(data=embedding)
if status == 201:
    embedding_id = res.id
    print(f"Created embedding input {embedding_id}")

Hash Generation

The hash field ensures uniqueness and prevents duplicate embeddings:
import avenieca

# Use a secret key and input text to generate hash
secret = "my_secret_key"
input1 = "temperature is high"
input2 = "temperature is low"

hash1 = avenieca.encode(secret, input1)
hash2 = avenieca.encode(secret, input2)

# Same input always produces same hash
print(hash1 == avenieca.encode(secret, input1))  # True

# Different inputs produce different hashes
print(hash1 == hash2)  # False

Linking ESS to Embeddings

Connect ESS records to embedding inputs using the embedding_input field:
from avenieca.api.model import ESSInsert

# Create ESS with embedding reference
ess = ESSInsert(
    module_id="air_conditioner",
    state=[18],
    valence=10.0,
    score=4,
    embedding_input=1,  # References embedding input ID
    context=None,
)

res, status = eca.ess.create(data=ess)
if status == 201:
    print(f"ESS {res.id} linked to embedding {res.embedding_input}")

Vector Search with ESS

The search() method finds ESS with similar state vectors using cosine similarity:
from avenieca.api.model import Search

# Search for similar states
search_query = Search(
    module_id="air_conditioner",
    state=[18],  # Query state vector
    limit=1      # Return top match
)

res, status = eca.ess.search(data=search_query)

if status == 200:
    for result in res:
        print(f"Similarity score: {result.score}")
        print(f"Matched ESS ID: {result.ess.id}")
        print(f"Matched state: {result.ess.state}")
        print(f"Valence: {result.ess.valence}")
        if result.ess.embedding_input:
            print(f"Embedding: {result.ess.embedding_input}")

Search Method Parameters

module_id
str
required
Module to search within. Only searches ESS from this module.
state
List[float]
required
Query state vector to find similar states. Should match the dimensionality of states in the module.
limit
int
default:1
Maximum number of results to return. Results are ranked by similarity.

Understanding Search Results

The search returns SearchResult objects with two fields:
# SearchResult structure
for result in res:
    # Similarity score (0.0 to 1.0, higher is more similar)
    print(result.score)  # e.g., 0.95
    
    # Full ESS record that matched
    print(result.ess)    # ESSResponse object
    print(result.ess.id)
    print(result.ess.state)
    print(result.ess.module_id)

Retrieving ESS by Embedding

Get ESS records associated with a specific embedding input:
# Get ESS by embedding input ID
res, status = eca.ess.get_one_with_embedding(
    module_id="air_conditioner",
    emb_input=1
)

if status == 200:
    print(f"ESS {res.id} has state {res.state}")
    print(f"Linked to embedding input {res.embedding_input}")

Document Embeddings

Documents can also be embedded for semantic search:
from avenieca.api.model import DocumentInsert

# Create document with automatic embedding
document = DocumentInsert(
    doc_id="001",
    text="testing 123",
    embed=True  # Automatically generate embedding
)

res, status = eca.document.create(data=document)
if status == 201:
    print(f"Document {res.id} created and embedded")
    print(f"Status: {res.status}")  # Check embedding status

Embedding Existing Documents

Embed a document after creation:
# Create document without embedding
doc = DocumentInsert(
    doc_id="002",
    text="important information",
    embed=False
)
res, status = eca.document.create(data=doc)

# Embed it later
if status == 201:
    embed_res, embed_status = eca.document.embed(db_id=res.id)
    if embed_status == 200:
        print(f"Document {res.id} embedded successfully")

Combining Documents and ESS Embeddings

You can create documents directly from ESS or sequences, linking state history to textual descriptions:

Creating Documents from ESS

# Create document from existing ESS
res, status = eca.document.create_from_ess(
    module_id="air_conditioner",
    ess_id=8
)

if status == 201:
    print(f"Document {res.id} created from ESS 8")
    print(f"Text: {res.text}")

Creating Documents from Sequences

# Create document from sequence (entire state trajectory)
res, status = eca.document.create_from_sequence(
    module_id="air_conditioner",
    sequence_id=3
)

if status == 201:
    print(f"Document {res.id} created from sequence 3")
    print(f"Contains all ESS from sequence")

Retrieval with Combined Context

Query across both documents and ESS embeddings:
from avenieca.api.model import RetrievalRequest

# Natural language query
retrieval = RetrievalRequest(
    query="what is the temperature on 3rd of may at around 1pm?"
)

res, status = eca.retrieval.query(data=retrieval)

if status == 200:
    print("Retrieved answer:")
    print(res.response)
The retrieval system searches across:
  • Document embeddings (text descriptions)
  • ESS embeddings (state vectors with embedding inputs)
  • Historical sequences
Here’s a full example combining all concepts:
import os
import avenieca
from avenieca.api.model import (
    Config, EmbeddingInputInsert, ESSInsert, Search
)
from avenieca.api.eca import ECA

config = Config(
    uri="http://localhost:2580/v1",
    username=os.getenv("USERNAME"),
    password=os.getenv("PASSWORD")
)
eca = ECA(config)

# Step 1: Create embedding inputs for different states
states = [
    ("very cold", [15.0]),
    ("cold", [18.0]),
    ("comfortable", [22.0]),
    ("warm", [26.0]),
    ("very warm", [30.0]),
]

embedding_map = {}
for label, state_vec in states:
    # Create embedding
    emb_hash = avenieca.encode("temp_secret", label)
    emb = EmbeddingInputInsert(
        module_id="temperature",
        input=label,
        hash=emb_hash
    )
    emb_res, emb_status = eca.embedding.create(data=emb)
    
    if emb_status == 201:
        embedding_map[label] = emb_res.id
        
        # Create ESS with embedding
        ess = ESSInsert(
            module_id="temperature",
            state=state_vec,
            valence=50.0,
            score=10,
            embedding_input=emb_res.id,
            context=label
        )
        ess_res, ess_status = eca.ess.create(data=ess)
        print(f"Created ESS {ess_res.id} for '{label}': {state_vec}")

# Step 2: Search for similar temperature
query_temp = [23.5]  # Between comfortable and warm
search = Search(
    module_id="temperature",
    state=query_temp,
    limit=3
)

results, search_status = eca.ess.search(data=search)

if search_status == 200:
    print(f"\nSearching for states similar to {query_temp}:")
    for i, result in enumerate(results, 1):
        print(f"\n{i}. Similarity: {result.score:.3f}")
        print(f"   State: {result.ess.state}")
        print(f"   Context: {result.ess.context}")
        print(f"   ESS ID: {result.ess.id}")

Managing Embeddings

List All Embeddings

res, status = eca.embedding.get_all(module_id="temperature")

if status == 200:
    for emb in res:
        print(f"ID {emb.id}: {emb.input} (hash: {emb.hash})")

Update Embedding

updated = EmbeddingInputInsert(
    module_id="temperature",
    input="updated description",
    hash=avenieca.encode("temp_secret", "updated description")
)

res, status = eca.embedding.update(
    module_id="temperature",
    db_id=1,
    data=updated
)

Delete Embedding

res, status = eca.embedding.delete(
    module_id="temperature",
    db_id=1
)

if status == 200:
    print("Embedding deleted")
Deleting an embedding input doesn’t delete associated ESS records, but they will lose their semantic labels.

Next Steps

Aggregates

Combine multiple modules with embeddings for rich semantic search

Best Practices

Learn production patterns for embedding workflows

Build docs developers (and LLMs) love