Context-aware knowledge engine for AI — memory, graph, intelligent routing
Kairn defines 3 tools with mixed quality. All three have reasonable names following verb_noun convention (kn_add, kn_connect, kn_judge) and explicit descriptions. However, descriptions lack LLM-optimization depth (averaging ~100-150 chars vs. 194-char baseline for A+ tools), and parameter descriptions are present but generic. Schema structure is visible and properly typed, but parameter constraints are minimal. The semantic domain is coherent (graph operations: add node, connect nodes, judge relationships), but the tools lack output schema documentation and error recovery guidance, critical for a knowledge graph system where operations have cascading effects. No tool annotations (destructiveHint, readOnlyHint) are present despite all three being write operations.
Add node to knowledge graph. Auto-links via FTS5.
Create typed, weighted edge between nodes.
Record a typed relationship judgment between two nodes. Strict-mode wrapper around kn_connect: only the 5 canonical relation verbs (conflicts_with, supersedes, compatible, scoped, related) are accepted. Use after kn_learn returns a non-empty candidates[] list to assert how the new node relates to an existing one. For legacy or system-generated edges, use kn_connect (lax mode).
All three tools are write operations (WRITE risk) but lack tool annotations (destructiveHint, idempotentHint). LLMs cannot determine safety/idempotency without explicit hints. kn_judge modifies state via edge creation; kn_add inserts nodes; kn_connect creates edges. None declare idempotency or retry semantics.
No output schemas documented. Tools return structured data (node IDs, edge objects, candidates list for kn_learn) but descriptions do not specify what fields the LLM receives. For a knowledge graph system where downstream operations depend on IDs and edge weights, missing output schemas force agents to guess field names and types.
Descriptions lack LLM-optimized depth. kn_add: 'Add node to knowledge graph. Auto-links via FTS5.' (54 chars), does not explain when to use it vs. kn_connect, what auto-linking means, or what the LLM receives back. kn_connect: 'Create typed, weighted edge between nodes.' (43 chars), omits relationship types, weight semantics, or use cases. Baseline A+ descriptions: 194 chars average. These are 70% shorter.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
Parameter 'weight' in kn_connect and 'confidence' in kn_judge accept floats 0.0-1.0 but descriptions do not explain semantic meaning or default behavior. Does weight=0 delete the edge? Does confidence affect query results? LLMs need actionable constraints, not just type signatures.
kn_judge enforces 5 canonical verbs (conflicts_with, supersedes, compatible, scoped, related) but parameter description does not declare this as an enum. Free-form string invites hallucinated values outside the 5. Schema should use 'enum': ["conflicts_with", "supersedes", "compatible", "scoped", "related"].
No error handling guidance. If kn_add receives a duplicate node name, what happens? Does it return an error, merge with existing node, or create a variant? If kn_connect receives invalid node IDs, what recovery steps should the LLM take? Missing recovery guidance per pattern:recovery-guide.
Parameter descriptions are present but generic. 'Node name' does not explain length limits, character restrictions, or naming conventions. 'Namespace' has a default but no explanation of what namespaces are or when to override. 'Tags for categorization' does not indicate format (array of strings? comma-separated? structured objects?).