A blazing-fast, zero-dependency, in-memory vector database for AI Agents.
Give your AI "long-term memory" without setting up heavy infrastructure like Pinecone, Weaviate, or pgvector. agentic-memory-vector uses pure linear algebra (Cosine Similarity) with Float32Array for maximum performance across Node.js, Edge runtimes, and browsers.
- π Zero Dependencies - Pure TypeScript, no external packages
- β‘ Blazing Fast - Uses
Float32Arrayfor optimized vector operations - π Universal - Runs in Node.js, Vercel Edge, Cloudflare Workers, Deno, and browsers
- π Model Agnostic - Works with OpenAI, Cohere, HuggingFace, or custom embeddings
- πΎ Persistence - Simple JSON serialization for saving/loading memory
- π― Type-Safe - Full TypeScript support with comprehensive types
- π Semantic Search - Find relevant memories using cosine similarity
npm install agentic-memory-vectoryarn add agentic-memory-vectorpnpm add agentic-memory-vectorimport { AgenticMemory } from "agentic-memory-vector";
import OpenAI from "openai";
const openai = new OpenAI();
// 1. Define your embedder (Dependency Injection)
const embedder = async (text: string) => {
const response = await openai.embeddings.create({
model: "text-embedding-3-small",
input: text,
});
return response.data[0].embedding;
};
// 2. Initialize the memory store
const memory = new AgenticMemory(embedder);
// 3. Add memories with optional metadata
await memory.add("My favorite color is blue", {
user: "alice",
category: "preferences",
});
await memory.add("I have a dog named Rex", { user: "alice", category: "pets" });
await memory.add("I work as a software engineer", {
user: "alice",
category: "career",
});
// 4. Search semantically
const results = await memory.search("What pets do I have?");
console.log(results[0].content); // "I have a dog named Rex"
console.log(results[0].score); // 0.95 (similarity score)
console.log(results[0].metadata); // { user: "alice", category: "pets" }new AgenticMemory(embedder: EmbedderFunction)Parameters:
embedder: An async function that converts text to a vector (number array)
Example:
const memory = new AgenticMemory(async (text) => {
// Your embedding logic here
return [0.1, 0.2, 0.3, ...]; // Returns number[]
});Add a new memory to the database.
Parameters:
content: The text content to storemetadata(optional): Additional data to attach (tags, timestamps, etc.)
Returns: Promise resolving to the unique ID of the stored memory
Example:
const id = await memory.add("User prefers dark mode", {
category: "ui-preferences",
timestamp: Date.now(),
});
console.log(id); // "550e8400-e29b-41d4-a716-446655440000"Search for semantically similar memories.
Parameters:
query: The search query texttopK(default: 3): Maximum number of results to returnminScore(default: 0.7): Minimum similarity score (0.0 to 1.0)
Returns: Array of search results sorted by relevance
Example:
const results = await memory.search("food preferences", 5, 0.8);
results.forEach((result) => {
console.log(`Score: ${result.score}`);
console.log(`Content: ${result.content}`);
console.log(`Metadata:`, result.metadata);
});Serialize the entire memory store to JSON for persistence.
Returns: JSON string containing all memories
Example:
const jsonData = memory.toJSON();
await fs.writeFile("memory-backup.json", jsonData);Restore memory from a JSON string.
Parameters:
json: JSON string from a previoustoJSON()call
Example:
const jsonData = await fs.readFile("memory-backup.json", "utf-8");
memory.fromJSON(jsonData);import { AgenticMemory } from "agentic-memory-vector";
import fs from "fs/promises";
// Save memory to disk
async function saveMemory(memory: AgenticMemory, filepath: string) {
const data = memory.toJSON();
await fs.writeFile(filepath, data, "utf-8");
}
// Load memory from disk
async function loadMemory(memory: AgenticMemory, filepath: string) {
const data = await fs.readFile(filepath, "utf-8");
memory.fromJSON(data);
}
// Usage
const memory = new AgenticMemory(embedder);
await memory.add("Important information");
await saveMemory(memory, "./memory.json");
// ... later ...
await loadMemory(memory, "./memory.json");You can use any embedding model, including local ones:
import { pipeline } from "@xenova/transformers";
// Load a local transformer model
const embedder = await pipeline(
"feature-extraction",
"Xenova/all-MiniLM-L6-v2",
);
const memory = new AgenticMemory(async (text) => {
const output = await embedder(text, { pooling: "mean", normalize: true });
return Array.from(output.data);
});// Add memories for different users
await memory.add("Likes coffee", { userId: "user_1" });
await memory.add("Prefers tea", { userId: "user_2" });
await memory.add("Drinks water", { userId: "user_1" });
// Search and filter by user
const allResults = await memory.search("What does the user drink?", 10, 0.5);
const user1Results = allResults.filter((r) => r.metadata.userId === "user_1");import { AgenticMemory } from "agentic-memory-vector";
import OpenAI from "openai";
const openai = new OpenAI();
const memory = new AgenticMemory(async (text) => {
const res = await openai.embeddings.create({
model: "text-embedding-3-small",
input: text,
});
return res.data[0].embedding;
});
// Index your knowledge base
await memory.add("The company was founded in 2020");
await memory.add("We have offices in New York and London");
await memory.add("Our main product is an AI assistant");
// RAG query
async function ragQuery(question: string) {
// 1. Retrieve relevant context
const context = await memory.search(question, 3);
// 2. Build prompt with context
const prompt = `
Context:
${context.map((c) => c.content).join("\n")}
Question: ${question}
Answer:`;
// 3. Generate answer
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: prompt }],
});
return completion.choices[0].message.content;
}
const answer = await ragQuery("When was the company founded?");
console.log(answer); // "The company was founded in 2020"agentic-memory-vector implements a simple but powerful vector search algorithm:
- Embedding Generation: Text is converted to high-dimensional vectors using your provided embedder
- Storage: Vectors are stored in memory using
Float32Arrayfor optimal performance - Search: Cosine similarity is calculated between the query vector and all stored vectors
- Ranking: Results are sorted by similarity score and filtered by threshold
The library uses pure linear algebra with no external dependencies, making it:
- Fast: Direct
Float32Arrayoperations - Portable: Runs anywhere JavaScript runs
- Simple: No database setup required
interface DocumentMetadata {
[key: string]: any;
}
interface MemoryItem {
id: string;
content: string;
vector: Float32Array;
metadata: DocumentMetadata;
}
interface SearchResult {
id: string;
content: string;
metadata: DocumentMetadata;
score: number; // Cosine similarity (0.0 to 1.0)
}
type EmbedderFunction = (text: string) => Promise<number[]>;β Perfect For:
- Prototyping AI agents with memory
- Serverless/Edge deployments (Vercel, Cloudflare Workers)
- Small to medium datasets (< 100k vectors)
- Browser-based AI applications
- Quick RAG implementations
β Not Ideal For:
- Large-scale production (millions of vectors)
- Persistent storage requirements (use with companion DB)
- Distributed systems
- Advanced filtering/hybrid search
For large-scale production, consider Pinecone, Weaviate, or Qdrant. But for 90% of AI agent use cases, this is all you need!
MIT Β© Mohamed-3rafa
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Built with β€οΈ for the AI agent community.
If you find this useful, please β star the repo!