ObjectStackObjectStack

Knowledge & RAG

The Knowledge Protocol — permission-aware RAG for agents via pluggable adapter plugins (memory, RAGFlow, custom)

Knowledge & RAG

Part of the AI module — how agents retrieve knowledge through the Knowledge Protocol and its adapter plugins.

ObjectStack ships a Knowledge Protocol that lets you retrieve from pluggable backends (RAGFlow, LlamaIndex, Dify, custom pgvector, …) with one call: KnowledgeService.search(query, { sourceIds?, topK? }). The framework defines the contract and runs permission-aware filtering; the adapter plugin does the actual retrieval. See the protocol design for the rationale.

This whole stack is open. The @objectstack/service-knowledge service, the adapter plugins (@objectstack/knowledge-memory, @objectstack/knowledge-ragflow), the @objectstack/embedder-openai embedder, and the permission-aware retrieval + event sync below all ship in the open-source framework. The workflow is: declare your knowledge sources, pick an adapter, and call search — retrieval respects the same row-level security as any ObjectQL query. Only the in-product chat runtime that consumes retrieval ships in ObjectOS; see the callout under Retrieving knowledge.

Wiring

import { ObjectKernel } from '@objectstack/core';
import { KnowledgeServicePlugin } from '@objectstack/service-knowledge';
import { KnowledgeMemoryPlugin } from '@objectstack/knowledge-memory';
// or, for prod:
// import { KnowledgeRagflowPlugin } from '@objectstack/knowledge-ragflow';

const kernel = new ObjectKernel();
kernel.use(new KnowledgeServicePlugin({
  sources: [
    {
      id: 'task_notes',
      label: 'Task notes',
      adapter: 'memory',
      source: { kind: 'object', object: 'task', contentFields: ['title', 'notes'] },
    },
    {
      id: 'product_docs',
      label: 'Product docs',
      adapter: 'ragflow',
      source: { kind: 'http', urls: ['https://docs.example.com/sitemap.xml'] },
      options: { datasetId: 'rgf_doc_dataset' },
    },
  ],
}));
kernel.use(new KnowledgeMemoryPlugin());
// kernel.use(new KnowledgeRagflowPlugin({ endpoint, apiKey }));

Retrieving knowledge

Retrieval is a plain service call — no AI runtime required. Resolve the knowledge service and call search. Hits are re-checked against the caller's ExecutionContext (RLS), sorted by score, and capped at topK before they come back.

const knowledge = ctx.getService('knowledge');

const hits = await knowledge.search('proposals about ACME', {
  sourceIds: ['task_notes', 'product_docs'], // optional — defaults to every source the caller may see
  topK: 5,
  executionContext,  // the caller's context — retrieval drops any hit RLS would hide
});
// hits: KnowledgeHit[] — each { chunkId, documentId, sourceId, sourceRecordId?, score, snippet, title? }

In-product chat ships in ObjectOS. Exposing this retrieval to a chat UI as the search_knowledge tool — the ask / build personas, the /api/v1/ai/* endpoints, and aiService.chatWithTools — is provided by the ObjectOS in-product runtime. The open-source framework has no built-in in-product chat, but everything else here — the Knowledge Protocol, adapters, embedder, and KnowledgeService.search — is open, so you can call search directly from your own code, agent, or MCP tool.

What you get for free

  • Permission-aware retrieval. Every hit with a sourceRecordId is re-checked against the caller's ExecutionContext via IDataEngine — the same RLS that gates plain ObjectQL queries. A salesperson asking "find proposals about ACME" only sees the proposals they could already read directly. File / HTTP hits pass through (ACL is the adapter's problem).
  • Inline event sync. When records on indexed objects change, the kernel's IRealtimeService events drive KnowledgeService.handleRecordUpsert/Delete automatically. No cron, no queue (yet — Phase 2).
  • Adapter swap, zero caller changes. Move from memory to ragflow to a custom adapter without touching your search calls, the search_knowledge tool, or any agent prompt.

Why we did not build a vector DB

Mature OSS (RAGFlow, LlamaIndex, Dify) already nail chunking, embedding, hybrid retrieval, rerank, and OCR. ObjectStack's value is the metadata-native source declaration + the permission-aware filter on top of those engines — not yet-another-RAG-stack. Customers pick the retrieval engine that matches their data; we make sure it talks to ObjectStack the same way every time.


See also

On this page