HazelJS KAG Package
@hazeljs/kag provides Knowledge-Augmented Generation — typed entities, relations, time-scoped facts, provenance, and explainable multi-hop reasoning.
Entities, facts, and relationships — with provenance you can audit.
KAG does not duplicate GraphRAG internals. Import document-derived graphs via importGraph(); community detection and vector search stay in @hazeljs/rag.
Use KAG for “why did X change?” over structured domain state. Use RAG for handbook passages. Use CAG for always-on policy blobs. Combine them with @hazeljs/context.
Quick Reference
- Purpose: Reason over domain knowledge (entities, facts, relationships) with evidence traces and tenant isolation.
- When to use: Settlement / chargeback causality, incident → change → outage chains, entitlement disputes — multi-hop structured “why” questions.
- Key APIs:
KnowledgeGraph,KagService,entity/relate/fact,ask({ explain: true }),traverse,resolve,promoteObservation,importGraph,COMMERCE_INDUSTRY_PROFILE,HeuristicQueryPlanner,InMemoryKnowledgeStore,createCaslKnowledgeAuthorizer. - Dependencies: Peer
@hazeljs/core. Optional: RAGKnowledgeRetrieverport, GraphRAG import adapter (no hard@hazeljs/ragcompile dependency). - Common mistakes: Treating KAG as a vector store; auto-merging uncertain entities; skipping
tenantId; using model CoT as “explanation” instead of evidence paths; treating GraphRAG as KAG.
KAG vs RAG
| KAG | RAG | |
|---|---|---|
| Question | What entities, facts, and relationships do I know? | What passages are relevant? |
| Unit | Entity / relation / fact | Document chunk |
| Strength | Multi-hop structured reasoning | Semantic similarity |
| Explain | Evidence path + provenance sources | Citations to passages |
GraphRAG (in @hazeljs/rag) extracts graphs from documents. KAG holds operational knowledge with facts, time windows, and contradictions. Full write-up: RAG vs CAG vs KAG.
Installation
npm install @hazeljs/kag @hazeljs/core
Quick Start
import { KnowledgeGraph, COMMERCE_INDUSTRY_PROFILE } from '@hazeljs/kag';
const knowledge = new KnowledgeGraph({
tenantId: 'merchant-123',
graph: 'commerce',
industry: COMMERCE_INDUSTRY_PROFILE, // opt-in; planner is generic by default
});
await knowledge.entity({
id: 'merchant-123',
type: 'merchant',
properties: { name: 'Demo Restaurant' },
});
await knowledge.entity({ id: 'refund-1', type: 'refund', properties: { amount: 1420 } });
await knowledge.relate({
from: 'merchant-123',
to: 'refund-1',
type: 'HAS_REFUND',
source: { type: 'database', id: 'refund-456', authority: 90 },
});
await knowledge.fact({
subject: 'refund-1',
predicate: 'amount',
object: 1420,
confidence: 0.98,
source: { type: 'database', id: 'refund-456', authority: 90 },
});
const result = await knowledge.ask(
'Why was yesterday’s settlement €1,420 lower?',
{ explain: true }
);
// result.answer, result.evidence, result.sources, result.confidence, result.explanation
Entities, Relations, Facts
| Primitive | Role |
|---|---|
KnowledgeEntity | Typed node (merchant, order, incident, …) |
KnowledgeRelation | Typed edge with optional provenance |
KnowledgeFact | Subject–predicate–object with confidence, validFrom / validUntil, source |
Entity Resolution
EntityResolver strategies: exact, normalized, semantic (when embed is provided), custom.
Uncertain matches stay as candidates below mergeThreshold (default 0.9) — HazelJS does not auto-merge casually.
Temporal Knowledge, Confidence, Contradictions
- Query with
asOfor helpers likecurrentFacts()/changes(from, to) - Path confidence aggregates with
min(default) orproduct - Contradictions are retained and ranked (authority → timestamp → confidence → priority)
- Policy
rejectthrowsKnowledgeConflictErrorinstead of keeping conflicts
Industry Profiles
HeuristicQueryPlanner is industry-agnostic by default (generic causal / temporal / comparison intents).
Opt into a domain vocabulary:
import { KnowledgeGraph, COMMERCE_INDUSTRY_PROFILE } from '@hazeljs/kag';
new KnowledgeGraph({
tenantId: 'merchant-123',
industry: COMMERCE_INDUSTRY_PROFILE,
});
Or pass your own IndustryProfile pack.
GraphRAG Import & Hybrid Retrieval
await kagService.importGraphRag(graphStore, { tenantId: 'merchant-123' });
Pass { rag: true } with an injected KnowledgeRetriever to fuse document passages with graph evidence — without owning embeddings inside KAG.
Memory Integration
promoteObservation({ validated: true, confidence }) is explicit. Preferences stay in @hazeljs/memory until you promote validated domain truth into the graph.
Security
- Every store call requires
KnowledgeScope.tenantId - Optional
KnowledgeAuthorizerorcreateCaslKnowledgeAuthorizer(can)for entity-level access
Agent Integration
Inject KagService as AgentRuntimeConfig.kagService. Optional DNA:
{
"context": {
"kag": { "enabled": true, "graph": "commerce" }
}
}
Prefer @hazeljs/context when the agent needs KAG alongside CAG / RAG / Memory.
Production Guide
- Start with
InMemoryKnowledgeStore; design againstKnowledgeStorefor Neo4j/Postgres later - Always set tenant scope; attach an authorizer for sensitive graphs
- Prefer
explain: truefor enterprise audit trails (evidence, not model chain-of-thought) - Keep memory promotion explicit and validated
Try it offline
# from hazeljs-meridian-ops/
npm run example:install
npm run example:kag
kag-commerce-agent builds a settlement graph, asks a causal question, and prints evidence — including a retained low-authority contradiction.
Related Resources
- RAG Package — GraphRAG + document retrieval
- CAG Package — stable cached context
- Context Package — unified planner
- Memory Package — continuity; promote explicitly into KAG
- Agent Package —
kagServiceruntime port - RAG vs CAG vs KAG — when to pick which layer
- Package README
License
Apache-2.0