Skip to main content

Use with agents

Agents get long-term memory powered by the same vector-search engine as VectorDB. This page explains how that memory bank works, how it relates to the VectorDB indexes you create yourself, and which one to use for what.

Two different things, one engine

Two separate things run on that engine, and telling them apart saves confusion later:

  • VectorDB indexes are resources you create and manage. You bring your own vectors, choose dimensions and distance, and query them however you like. Internally they get collection names like p_<project-short>_<index-name>, where <project-short> is your project short id.
  • The agent memory bank is storage the platform creates and manages for each deployed agent. You never write vectors into it directly; the platform turns conversation text into vectors for you. Internally each agent gets a collection named mem_<project-short>_<agent-name>. Agents deployed before project scoping use the older mem_<agent-name> form.

Memory-bank collections never appear in your VectorDB index list, and in normal use you never look at their internals. Both run on the same engine, though, so everything in the overview about vectors and similarity search explains how agent memory behaves.

CRUSOE_VECTORDB_URL is not your VectorDB

Every agent and serverless workload runs with an environment variable named CRUSOE_VECTORDB_URL. Its older alias QDRANT_URL is set to the same value.

The name is misleading. It points at the low-level storage behind the agent memory bank, not at the VectorDB API that serves your own indexes. Point your retrieval code at it and your project's indexes are not what you get back.

To use your own indexes from inside a workload, call the VectorDB REST API. The platform injects its private address for you as CAI_VECTORDB_URL, alongside CAI_PROJECT_ID — read the variable rather than writing the address down, because the value is ours to change:

import json, os, urllib.request

import crusoe_adk as crusoe # crusoe_langchain / crusoe_crewai / crusoe_mcp expose the same secret()

VDB = os.environ["CAI_VECTORDB_URL"].rstrip("/")
PROJECT = os.environ["CAI_PROJECT_ID"]

req = urllib.request.Request(
"%s/v1/projects/%s/indexes/docs:query" % (VDB, PROJECT),
data=json.dumps({"vector": query_vector, "top_k": 5}).encode("utf-8"),
headers={"Content-Type": "application/json",
# NOT CAI_PROJECT_KEY - see below. A service-account key, bound as a secret.
"Authorization": "Bearer " + crusoe.secret("vector-search-key")},
method="POST")
with urllib.request.urlopen(req, timeout=45) as resp:
hits = json.loads(resp.read().decode("utf-8"))["results"]

The bearer token has to be a real credential. A workload's own identity, CAI_PROJECT_KEY, is deliberately refused by project APIs like VectorDB — it holds no authority in the tenancy model and 404s on every project route, the same as a stranger. Its one power is minting the short-lived token crusoe.secret() reads through. So mint a service-account key, store it as a project secret, bind that secret to the workload, and read it per call. Agent with vectors and secrets walks the whole setup.

Do not hardcode the public https://api.codyhill.dev address into a workload. It resolves to the platform's public front door, which a workload running inside your project has no route to: the connection is dropped rather than refused, so your code hangs until its request timeout and reports nothing useful. CAI_VECTORDB_URL is platform-owned and cannot be overridden — deliberately, since repointing it would address another project's data. Try to set it and the env write is refused, naming the reason.

One exception: a container deploy — your own Dockerfile image rather than the platform harness — gets none of this wiring, by design. It receives only CRUSOE_REQUEST_TIMEOUT_SECONDS, CAI_API_URL, CAI_PROJECT_ID, and CAI_PROJECT_KEY.

The same trap applies to CRUSOE_MEMORYSTORE_ADDR and the session store. See MemoryStore with agents.

How memories get written: memorize

An agent's conversation history lives in a session. A session is short-term memory: it ends. Memorize is the step that turns one into long-term memory:

  1. The platform flattens the session's turns into a single block of text, as user: ... and assistant: ... lines.
  2. It runs that text through the platform's embedding model to get a vector. You never generate vectors yourself here.
  3. It writes the vector into the agent's mem_ collection. The original text and the session id go in as the payload.

You trigger it explicitly, either per session:

platformctl memorize research-buddy --session S1

You should see:

memorized session S1 for research-buddy

Or inline at invoke time with the --memorize flag, which memorizes the exchange immediately:

platformctl invoke research-buddy "My boat is a Mastercraft Maristar 245." --session S1 --memorize

Nothing is memorized automatically. If you never call memorize, the agent's long-term memory stays empty. Sessions do not leak into it on their own.

How memories get read: search_memory

Agents built with the platform's toolset get a search_memory(query) tool. When the agent calls it:

  1. The query goes through the same embedding model that was used at memorize time, producing a query vector.
  2. The memory bank returns the closest stored snippets (top 5), joined together as the tool's text result.
  3. If nothing relevant is stored, the tool returns the literal string No relevant memories found.

Because this is vector search, recall works by meaning. Memorize a session that says "My boat is a Mastercraft Maristar 245". A later question — "what do you know about my boat?" — finds it, even from a brand-new session. The question shares no words with "Mastercraft", and the two sessions are unrelated. Neither matters.

The end-to-end flow looks like this:

# Session 1: tell the agent something, then memorize it
platformctl invoke research-buddy "My boat is a Mastercraft Maristar 245." --session S1
platformctl memorize research-buddy --session S1

# Session 2 (fresh session): the agent recalls it via search_memory
platformctl invoke research-buddy "What do you know about my boat?" --session S2

The second response draws on the memorized snippet. To confirm that is what happened, look for a search_memory entry in the response's tool calls. The research agent tutorial walks this exact scenario step by step.

Memory bank vs. your own VectorDB index

You want to...Use
Have an agent remember what users told it across sessionsMemory bank (memorize + search_memory) — zero setup
Ground an agent or app in your documents (RAG)Your own VectorDB index — you control chunking, embeddings, payloads, filters
Filter search by metadata (tags, dates, sources)Your own VectorDB index — the memory bank has no filter interface
Choose the embedding model, dimensions, or distance metricYour own VectorDB index — the memory bank's embedding setup is platform-managed
Inspect, edit, or bulk-delete stored entries in a console UIYour own VectorDB index — it has a data browser and query panel

Most real agents use both. A research agent leans on the memory bank for "what has this user told me", and on a VectorDB index for "what do my documents say". The RAG chatbot tutorial builds the second half.

Memory Bank Management

The memory bank has no management surface of its own yet — no listing, browsing, or selective deletion of memories through the console or CLI. What you can do today is write (memorize) and read (search_memory). If you need managed, inspectable semantic storage now, use a VectorDB index directly.

Next steps