Relationships
Cross-memory connections that link memories to each other, entities to events, and events into temporal chains. Relationships give your agent's memory structure and context.
Overview
Memories in Rekall do not exist in isolation. They form a connected web through several types of relationships:
- •Semantic relationships connect entities in the knowledge graph (e.g., "Sarah knows Python").
- •Episodic references link events to the entities they mention (e.g., a meeting memory referencing participant entities).
- •Temporal chains connect events in chronological sequences (e.g., a series of related conversations).
- •Cross-type links connect memories of different types (e.g., a procedure referencing execution history).
These connections enable rich queries like "show me all meetings about ProjectX in chronological order" or "what does the agent know about this entity from both events and structured knowledge?"
Semantic Relationships
Semantic relationships are the typed, directed edges in the knowledge graph. They connect entities with labeled relationships and optional metadata.
import Rekall from '@rekall/sdk';const rekall = new Rekall({ apiKey: 'rk_your_api_key' });// Create relationships between entitiesawait rekall.semantic.relationships.create({source: 'ent_sarah',target: 'ent_python',type: 'knows',metadata: { proficiency: 'expert', years: 8 },});await rekall.semantic.relationships.create({source: 'ent_project_alpha',target: 'ent_react',type: 'depends_on',metadata: { version: '18.x', critical: true },});await rekall.semantic.relationships.create({source: 'ent_sarah',target: 'ent_project_alpha',type: 'leads',metadata: { since: '2024-06-01' },});// Traverse: find all technologies ProjectAlpha depends onconst deps = await rekall.semantic.traverse({entityId: 'ent_project_alpha',relationshipTypes: ['depends_on'],direction: 'outgoing',depth: 1,});
Episodic References
Episodic memories can reference semantic entities, creating links between events and structured knowledge. When an episodic memory mentions a person, project, or technology, you can explicitly link them.
// Create an episodic memory with entity referencesconst meeting = await rekall.episodic.create({content: 'Sarah presented the ProjectAlpha roadmap. Team agreed to adopt React 18 and deprecate the legacy Vue components.',importance: 0.85,participants: ['user:sarah', 'user:bob', 'user:carol'],// Link to relevant entitiesentityRefs: [{ entityId: 'ent_sarah', role: 'presenter' },{ entityId: 'ent_project_alpha', role: 'subject' },{ entityId: 'ent_react', role: 'mentioned' },],});// Find all episodic memories referencing an entityconst sarahMentions = await rekall.episodic.search({entityRef: 'ent_sarah',limit: 20,});// Find memories about a project with a specific roleconst projectDecisions = await rekall.episodic.search({entityRef: { entityId: 'ent_project_alpha', role: 'subject' },minImportance: 0.7,});
Automatic entity detection
Rekall can optionally auto-detect entity mentions in episodic memory content and create references automatically. Enable this withautoLinkEntities: truein your SDK configuration.
Temporal Chains
Temporal chains connect episodic memories in chronological order, creating a timeline of related events. This is useful for tracking conversations, project progress, or any sequence of related interactions.
// Create a chain of related eventsconst chain = await rekall.temporal.createChain({name: 'project-alpha-standup',description: 'Daily standup meetings for ProjectAlpha',});// Add memories to the chain (they are automatically ordered by timestamp)await rekall.temporal.addToChain({chainId: chain.id,memoryId: 'mem_monday_standup',});await rekall.temporal.addToChain({chainId: chain.id,memoryId: 'mem_tuesday_standup',});await rekall.temporal.addToChain({chainId: chain.id,memoryId: 'mem_wednesday_standup',});// Get the full chain in chronological orderconst timeline = await rekall.temporal.getChain(chain.id);for (const event of timeline.memories) {console.log(event.timestamp, event.content);}// Link two memories as "follows" (ad-hoc temporal link)await rekall.temporal.link({from: 'mem_initial_bug_report',to: 'mem_bug_investigation',type: 'followed_by',});
Cross-Type Links
Memories of different types can reference each other. These cross-type links connect the different memory systems into a unified knowledge structure.
| From | To | Link Type | Example |
|---|---|---|---|
| Episodic | Semantic entity | entity_ref | Meeting mentions Sarah |
| Episodic | Long-term | consolidated_from | Long-term memory sourced from episodes |
| Procedural | Execution | executed_by | Procedure being tracked by execution task |
| Preferences | Episodic | evidence | Preference backed by specific interactions |
| Long-term | Semantic entity | about | Consolidated knowledge about an entity |
// Link a procedure to its execution taskawait rekall.links.create({source: { type: 'procedural', id: 'proc_deploy_checklist' },target: { type: 'execution', id: 'exec_deploy_20250115' },linkType: 'executed_by',});// Link a long-term memory to its source episodesawait rekall.links.create({source: { type: 'long-term', id: 'lt_sarah_prefers_python' },target: { type: 'episodic', id: 'mem_convo_20250110' },linkType: 'consolidated_from',});// Query all links for a memoryconst links = await rekall.links.list({source: { type: 'episodic', id: 'mem_meeting_20250115' },});for (const link of links) {console.log(link.linkType, '->', link.target.type, link.target.id);}
Querying Relationships
Rekall provides several ways to query across relationships, enabling powerful multi-hop questions.
// Multi-hop query: "What technologies does ProjectAlpha use,// and who on the team knows them?"const techStack = await rekall.semantic.traverse({entityId: 'ent_project_alpha',relationshipTypes: ['depends_on'],direction: 'outgoing',depth: 1,});for (const tech of techStack.nodes) {const experts = await rekall.semantic.traverse({entityId: tech.id,relationshipTypes: ['knows'],direction: 'incoming',depth: 1,});console.log(`${tech.name}: known by ${experts.nodes.map(n => n.name).join(', ')}`);}// Combined query: find memories about an entity with temporal contextconst entityTimeline = await rekall.query({entity: 'ent_project_alpha',includeEpisodic: true,includeLongTerm: true,includeRelationships: true,orderBy: 'timestamp',limit: 20,});
Use Cases
Impact Analysis
When a library has a vulnerability, traverse relationships to find all projects that depend on it, then find all team members who work on those projects to notify.
Knowledge Provenance
Trace a long-term memory back to the episodic memories it was consolidated from. Verify that consolidated knowledge is still accurate by reviewing source events.
Conversation Threading
Use temporal chains to track multi-session conversations. When a user says "remember what we discussed last week?", follow the chain to find the relevant context.
Workflow Audit Trail
Link procedural memories to their execution tasks. Track which procedures have been run, when, and with what results. Build an audit trail of agent actions.
Best Practices
- 1.Link entities when creating episodic memories. The more entity references you include, the richer the relationship graph becomes.
- 2.Use consistent relationship type names. Standardize on a vocabulary like "knows", "depends_on", "leads", "works_at" and document it for your team.
- 3.Use temporal chains for recurring events. Standups, weekly reviews, sprint retrospectives are natural candidates for temporal chains.
- 4.Keep traversal depth reasonable. Most useful queries require depth 1-2. Depth 3+ can return large result sets and should be filtered.
- 5.Enable auto-linking. Turn on automatic entity detection to build relationships without manual effort. Review and correct as needed.
Related
Relationships connect all memory types. See semantic memory for entity and graph details, episodic memory for events, and decay & consolidation for how knowledge evolves.
