Skip to main content
SONZAI

Knowledge Analytics

Turn the Knowledge Base graph into a recommendation engine — rules rank nodes by user affinity, trend velocity, or conversion rate, all readable through a simple query-time API.

Knowledge Analytics layers a ranking system on top of the Knowledge Base. Rules define scoring signals — per-user affinity for recommendations, aggregate velocity for trends — and readers fetch ranked results at query time with a single call. The graph backbone supplies the nodes and edges; analytics rules decide how to score and order them. The result is a reusable ranking layer that powers product recommendations, trending dashboards, and conversion tracking without building a separate data pipeline.

What you can build with it

  • Product recommendations — "top-N products for this user" based on user affinity signals
  • Trending topics — "what's rising this week across all users" via aggregate velocity scoring
  • Conversion dashboards — which KB nodes convert (browse to engage to buy) and at what rate
  • Per-segment ranking — different recommendation models for different user segments
  • Feedback loops — record converted recommendations to continuously sharpen scoring over time

Quickstart

Create a recommendation rule, fetch ranked results for a user, then record whether the user acted on a recommendation.

import { Sonzai } from "@sonzai-labs/agents";

const client = new Sonzai({ apiKey: process.env.SONZAI_API_KEY! });
const projectId = "proj_abc123";

// 1. Create a recommendation rule
const rule = await client.knowledge.createAnalyticsRule(projectId, {
rule_type: "recommendation",
name:      "product-affinity",
config:    { target_entity_type: "product", scoring: "affinity" },
enabled:   true,
schedule:  "0 * * * *",  // recompute hourly
});

// 2. Fetch top-5 recommendations for a user
const recs = await client.knowledge.getRecommendations(
projectId,
rule.rule_id,
"user_123",   // source_id — the user whose affinity to score against
5,
);

for (const rec of recs.recommendations) {
console.log(rec.target_id, rec.score);
}

// 3. Record that the user converted on the top result
await client.knowledge.recordFeedback(projectId, {
source_node_id: "user_123",
target_node_id: recs.recommendations[0].target_id,
rule_id:        rule.rule_id,
converted:      true,
score_at_time:  recs.recommendations[0].score,
});

Core concepts

  • Rule types"recommendation" scores nodes per source (e.g. per user), returning a personalised top-N list. "trend" aggregates signals across all sources, returning global velocity rankings.
  • Config is rule-specific — the config object is a passthrough shape; its fields depend on the rule type and your scoring model. There is no fixed schema enforced by the SDK — pass whatever your rule implementation expects (e.g. target_entity_type, scoring, decay_factor).
  • Source and target semantics — recommendations take a source_id (typically a user node ID) and return ranked nodes of the target entity type. The source must exist as a node in the Knowledge Base graph.
  • Scheduled vs manual — rules can carry an optional cron schedule for batch recomputation (e.g. "0 * * * *" for hourly). Call RunAnalyticsRule at any time to trigger a manual run outside the schedule.
  • Feedback closes the loopRecordFeedback writes a signal back against the source, target, and rule. Subsequent recomputation can weight nodes that historically converted higher, sharpening ranking over time. Use the action field to record fine-grained user intent: "converted" (user completed the action), "clicked" (user opened the recommendation), "dismissed" (user explicitly rejected it), or "ignored" (recommendation was shown but user did not interact). action: "converted" sets converted: true automatically so existing aggregate conversion queries continue to work without changes.

Full API

MethodReturnsDescription
createAnalyticsRule(projectId, { rule_type, name, config, enabled, schedule? })KBAnalyticsRuleCreate a new analytics rule. rule_type is "recommendation" or "trend".
listAnalyticsRules(projectId)KBAnalyticsRuleListResponseList all analytics rules for a project.
getAnalyticsRule(projectId, ruleId)KBAnalyticsRuleFetch a single rule by ID.
updateAnalyticsRule(projectId, ruleId, { name?, config?, enabled, schedule? })KBAnalyticsRuleUpdate rule properties.
deleteAnalyticsRule(projectId, ruleId)voidDelete a rule permanently.
runAnalyticsRule(projectId, ruleId)voidTrigger an immediate manual run of the rule.
getRecommendations(projectId, ruleId, sourceId, limit?)KBRecommendationsResponseFetch ranked recommendations for a source node. Returns .recommendations array of { target_id, target_type, score }.
getTrends(projectId, nodeId)KBTrendsResponseGet trend aggregations for a specific node across all windows. Returns .trends array of { node_id, rule_id, window, value, direction }.
getTrendRankings(projectId, ruleId, rankingType, window, limit?)KBTrendRankingsResponseGet the global leaderboard for a trend rule. window is a duration string such as "7d" or "24h". Returns .rankings array with rank and score.
getConversions(projectId, ruleId, segment?)KBConversionsResponseFetch conversion statistics for a rule, optionally filtered by segment key. Returns { shown_count, conversion_count, conversion_rate } per segment.
recordFeedback(projectId, { source_node_id, target_node_id, rule_id, converted, score_at_time, action? })voidRecord whether a recommended node was acted on. converted is a boolean — true means the user engaged with the recommendation. action is an optional string enum: "converted", "dismissed", "clicked", "ignored". Passing action: "converted" also sets converted: true for backward-compatible aggregate queries.
getStats(projectId)KBStatsGeneral KB statistics (node counts, document counts, extraction tokens).

Python keyword arguments

The Python SDK exposes get_recommendations, get_trends, get_trend_rankings, get_conversions, and record_feedback using keyword-only arguments after project_id. For example: client.knowledge.get_recommendations(project_id, rule_id="...", source_id="...", limit=10).

Combines with other features

With Knowledge Base — the graph is the substrate

Analytics rules run over KB nodes and edges. Entity schemas define what types of nodes exist; rules score those nodes. The recommended pattern is to define your entity schema first, then create rules that target it.

// 1. Define a product schema in the KB
await client.knowledge.createSchema(projectId, {
entity_type: "product",
fields: [
  { name: "price",    type: "number", required: true },
  { name: "category", type: "string", required: true },
  { name: "in_stock", type: "boolean", required: true },
],
});

// 2. Push some product nodes
await client.knowledge.insertFacts(projectId, {
facts: [
  { entity_type: "product", label: "Razer Blade 16", properties: { price: 2999, category: "laptop", in_stock: true } },
  { entity_type: "product", label: "Razer DeathAdder V3", properties: { price: 79, category: "mouse", in_stock: true } },
],
});

// 3. Create a recommendation rule targeting the product entity type
const rule = await client.knowledge.createAnalyticsRule(projectId, {
rule_type: "recommendation",
name:      "product-recs",
config:    { target_entity_type: "product" },
enabled:   true,
});

With Inventory — per-user holdings drive per-user recommendations

Inventory writes create edges from a user node to the nodes they own. Those ownership edges flow into the recommendation model as affinity signals: items a user already owns inform which related nodes score highest.

// 1. User buys a product — record it in inventory
const { fact_id } = await client.agents.inventory.update("agent_abc", "user_123", {
action:      "add",
item_type:   "product",
description: "Razer DeathAdder V3",
properties:  { purchase_date: "2026-04-01" },
});

// 2. The inventory write creates a user→product edge in the KB graph.
//    The recommendation rule can now weight products related to the
//    DeathAdder higher for this user.
const recs = await client.knowledge.getRecommendations(
projectId,
rule.rule_id,
"user_123",
5,
);
// recs.recommendations may now include accessories or similar peripherals

With Agent Insights — conversation signals sharpen rankings

Agent Insights extract what users express interest in during conversations. Those interest signals can be passed into recommendation rule config as additional affinity weights, so a user who talks about budget peripherals gets different rankings than one who discusses high-end setups — without any explicit user input.

Tutorials

No dedicated Knowledge Analytics tutorial exists yet. The Knowledge Base tutorial covers schema setup and fact insertion — the prerequisite steps before creating analytics rules.

Next steps

  • Knowledge Base — the graph backbone; define schemas and push nodes before creating rules
  • Inventory — per-user holdings create user-to-node edges that feed the recommendation model
  • Organization Knowledge Base — analytics rules can also run over org-scoped KB nodes for shared ranking across all users

On this page

What you can build with itQuickstartCore conceptsFull APICombines with other featuresWith Knowledge Base — the graph is the substrateWith Inventory — per-user holdings drive per-user recommendationsWith Agent Insights — conversation signals sharpen rankingsTutorialsNext steps