KnowledgeBase API
KnowledgeBase, in package com.tnsai.knowledge, is a programmatic document store that your own code fills and searches. InMemoryKnowledgeBase is the only implementation TnsAI ships; you can write your own.
It is not how agents are grounded. Agent chat and actions retrieve through declared @Knowledge sources and ChatKnowledgeBinding (see RAG), and nothing in the orchestrator calls KnowledgeBase.search. Role and action indexes are VectorMemoryStore instances, optionally in remote vector stores. WeaviateTools and QdrantTools in tnsai-tools are LLM-callable HTTP helpers, not KnowledgeBase backends.
Methods
| Method | Description |
|---|---|
void addDocument(Document document) | Adds one document. Throws KnowledgeBaseException on failure. |
default void addDocuments(List<Document> documents) | Adds several. The default calls addDocument for each. |
Optional<Document> getDocument(String id) | The document with that ID, or empty |
boolean removeDocument(String id) | true if a document was removed |
default void replaceDocuments(Collection<String> removeIds, List<Document> add) | Removes, then adds, as one generation. The default runs the steps in order. InMemoryKnowledgeBase holds its write lock throughout and undoes both steps if an add fails, so readers never see a mix. |
List<SearchResult> search(String query, int topK) | Text search, highest score first |
List<SearchResult> search(String query, int topK, Map<String, Object> filters) | Text search over documents whose metadata matches every filter entry |
List<SearchResult> searchByEmbedding(float[] embedding, int topK) | Similarity search with a vector you computed |
int size(), default boolean isEmpty() | Document count |
void clear() | Removes every document |
default boolean contains(String id) | getDocument(id).isPresent() |
Document
Document is immutable. It has an ID (a UUID when you don't set one), non-empty content, a metadata map and an optional embedding. Two documents are equal when their IDs are equal.
Document simple = Document.of("This is the document content");
Document tagged = Document.of("Product docs...", "source", "docs/product.md");
Document full = Document.builder()
.id("doc-001")
.content("Product documentation...")
.metadata("source", "docs/product.md")
.metadata(Map.of("category", "documentation"))
.embedding(embeddingVector)
.build();
Document withVector = simple.withEmbedding(embeddingVector); // a new Documentcontent(null) throws NullPointerException, and build() throws IllegalStateException when the content is null or empty.
| Accessor | Returns |
|---|---|
getId(), getContent() | The ID and the text |
getSpec() | The metadata as an unmodifiable map |
getSpec(key), getSpec(key, type) | One metadata value, or null when it is missing or, for the typed form, of another type |
hasEmbedding(), getEmbedding(), getEmbeddingDimension() | Whether there is an embedding, a copy of it (or null), and its length (or 0) |
SearchResult
new SearchResult(document, score) pairs a document with a score; the document must not be null. Results sort by score, highest first. getDocument(), getScore(), getContent() and getDocumentId() read it.
InMemoryKnowledgeBase
InMemoryKnowledgeBase keeps documents in a concurrent map behind a read-write lock:
searchscores documents by TF-IDF cosine similarity after removing stop words, and leaves out documents that score 0.searchByEmbeddingscores only documents that have an embedding.- Filters compare metadata values for equality; every entry must match.
KnowledgeBase kb = new InMemoryKnowledgeBase();
kb.addDocument(Document.of("Java is a programming language"));
kb.addDocument(Document.builder()
.content("Rust is a systems programming language")
.metadata("category", "systems")
.build());
List<SearchResult> results = kb.search("programming language", 5);
List<SearchResult> filtered = kb.search("programming", 5, Map.of("category", "systems"));
List<SearchResult> similar = kb.searchByEmbedding(queryEmbedding, 3);FileIndexer in tnsai-server uses replaceDocuments to swap in a new generation of a file's chunks. See Pipeline: incremental indexing.
Related
- RAG: declared
@Knowledgesources, which ground agents. - Pipeline:
RagServiceandFileIndexer, which build on aKnowledgeBase. - Embeddings: embedding functions for vector search.
- File formats: what file ingestion reads.