Workflows
Common usage patterns and workflows.
Usage Patterns and Workflows
This guide explores the powerful combinations of Fortémi's search tools, embedding sets, backup capabilities, and memory isolation features that enable sophisticated knowledge management workflows.
Prerequisites
Before diving into these patterns, ensure you have:
- A running Fortémi instance (Getting Started)
- Basic familiarity with notes, tags, and search (Getting Started)
- MCP server connected if using Claude/AI tools (MCP Guide)
These patterns progress from simple to advanced. Start with Pattern 0 if you're new to Fortémi.
Core Concepts
The Memory Model
Fortémi isn't just a note-taking system—it's a contextual memory system that:
1. Stores knowledge with full semantic understanding 2. Automatically tags with 8-15 hierarchical SKOS concepts via NLP pipeline 3. Connects related concepts automatically via tag-boosted semantic links 4. Auto-generates titles and extracts metadata (authors, DOI, language, etc.) 5. Enables focused contexts through embedding sets 6. Supports complete memory swaps via backup/restore 7. Provides multiple search modalities (FTS, semantic, hybrid)
The Automation Pipeline
When you create a note, Fortémi runs a two-phase NLP pipeline automatically:
Phase 1 (parallel): AI revision, title generation, concept tagging, metadata extraction, document type inference
Phase 2 (after tagging): Tag-enriched embedding generation (with `clustering:` concept prefixes and TF-IDF filtering), tag-boosted semantic linking
Periodic: Graph maintenance job applies the quality pipeline — normalization → SNN → PFNET sparsification → Louvain community detection → diagnostics snapshot — to the entire knowledge graph. Trigger on demand via `POST /api/v1/graph/maintenance` or the `trigger_graph_maintenance` MCP tool.
This means every note is automatically tagged, titled, embedded, and linked without any manual intervention. The SKOS tools (`manage_tags`, `manage_concepts`) exist for curation and governance — reviewing auto-tags, promoting concepts, correcting errors — not for routine tag creation.
This combination enables workflows impossible with traditional tools.
Pattern 0: Basic Note Capture
Use Case: Daily notes with automatic organization. The simplest useful workflow.
The Approach
Just create notes — the system handles tagging, title generation, and organization automatically. You can optionally add user tags for organizational purposes (project names, status markers), but content-based tags are generated by the AI pipeline.
Workflow
// Capture daily notes — AI auto-tags with SKOS concepts
await capture_knowledge({
action: "create",
content: `# 2024-01-15 Standup
- Finished API pagination implementation
- Blocked on OAuth token refresh bug
- Plan to start search optimization tomorrow
`,
tags: ["standup", "daily"], // Optional user tags for filtering
revision_mode: "none" // Preserve raw meeting notes
})
// The NLP pipeline automatically:
// - Generates a title
// - Tags with SKOS concepts (e.g., domain/software-engineering, topic/api-design)
// - Extracts metadata
// - Generates embeddings and creates semantic links
// Search by keyword
await search({
action: "text",
query: "OAuth token",
mode: "fts"
})
// Filter by user tag to see all standups
await search({
action: "text",
query: "blocked",
mode: "fts",
strict_filter: { required_tags: ["standup"] }
})
When to Upgrade
Move to Pattern 0.5 when:
- You have 50+ notes and want to discover unexpected connections
- FTS isn't finding conceptually related content
- You want to explore the auto-generated knowledge graph
Pattern 0.5: Content Discovery
Use Case: Let the system discover connections you didn't know existed.
The Problem
You have 100+ notes. FTS finds what you ask for, but you're missing connections between ideas across different topics.
The Solution: Semantic Search + Auto-Links
Once Ollama is running and embeddings are generated, two features unlock automatically:
1. Semantic search finds conceptually related content even with different words 2. Auto-linking connects notes above 70% similarity threshold
// Semantic search finds related content by meaning
await search_notes({
query: "improving team productivity",
mode: "semantic"
})
// Finds notes about "sprint velocity", "meeting efficiency",
// "developer experience" even without those exact words
// Explore auto-discovered connections
const links = await get_note_links({ id: noteId })
// Returns notes semantically linked to yours
// Traverse the knowledge graph
const graph = await explore_graph({
id: noteId,
depth: 2,
max_nodes: 20
})
// Visual map of how ideas connect
Discovery Workflow
1. Write notes naturally - Don't worry about perfect organization 2. Search semantically when exploring - Use `mode: "semantic"` or `mode: "hybrid"` 3. Follow auto-links - Check `get_note_links` for surprising connections 4. Explore the graph - Use `explore_graph` to see clusters of related ideas 5. Add tags as patterns emerge - Let understanding guide organization, not the other way around
When to Upgrade
Move to Pattern 1 when:
- You work on multiple distinct projects and need isolated search contexts
- Search results mix content from different domains
- You want focused embedding sets per project or topic
Pattern 1: Domain-Isolated Memory Contexts
Use Case: Work on multiple distinct projects without cross-contamination of search results.
The Problem
When you have notes about "React components" for both a work project and a personal learning project, searches return mixed results. You want focused context.
The Solution: Embedding Sets
Create separate embedding sets for each domain:
// Create work context
await create_embedding_set({
name: "Work: Project Alpha",
slug: "work-alpha",
purpose: "Project Alpha development notes",
keywords: ["react", "typescript", "api"],
mode: "auto",
criteria: { tags: ["work", "alpha"] }
})
// Create personal learning context
await create_embedding_set({
name: "Personal: React Learning",
slug: "personal-react",
purpose: "React tutorials and experiments",
keywords: ["react", "learning"],
criteria: { tags: ["personal", "learning"] }
})
// Search within specific context
await search_notes({
query: "component lifecycle",
mode: "semantic",
set: "work-alpha" // Only searches work notes
})
Workflow
1. Tag notes consistently when creating: `create_note({ content, tags: ["work", "alpha"] })` 2. Refresh embedding sets periodically: `refresh_embedding_set({ slug: "work-alpha" })` 3. Search within context: Always specify `set` parameter for focused results
Pattern 2: Memory Snapshots for Context Switching
Use Case: Completely switch between different "minds" or knowledge bases.
The Problem
You're an AI consultant working with multiple clients. Each client has confidential information that shouldn't mix. You need to completely swap memory contexts.
The Solution: Knowledge Shards
// Save current memory state
const clientA_backup = await knowledge_shard({
include: ["notes", "embeddings", "links", "concepts"]
})
// Store base64_data to file
// Clear current memory (dangerous!)
await purge_all_notes({ confirm: true })
// Load different client's memory
await knowledge_shard_import({
file_path: "clientB-backup.shard",
on_conflict: "replace"
})
// Now working with completely different knowledge base
await search_notes({ query: "contract terms", mode: "hybrid" })
Workflow: "Memory Profiles"
1. Create profile backups for each context (client, project, persona) 2. Use naming convention: `client-acme-2024-01-15.tar.gz` 3. Swap profiles when switching contexts 4. Keep master backup before any swap operation
Advanced: Incremental Context
Instead of full swaps, use embedding sets as "overlays":
// Keep base knowledge, add client-specific layer
await create_embedding_set({
name: "Client Overlay: ACME",
slug: "client-acme",
purpose: "ACME-specific knowledge",
criteria: { tags: ["acme", "confidential"] }
})
// Search with client context prioritized
await search_notes({
query: "api integration",
set: "client-acme"
})
// Or search general knowledge
await search_notes({
query: "api integration",
mode: "hybrid"
// No set = searches everything
})
Pattern 3: Research Mode vs. Production Mode
Use Case: Separate exploratory research from validated knowledge.
The Problem
During research, you capture lots of speculative notes. You don't want these polluting searches when you need authoritative information.
The Solution: Status-Based Sets + SKOS
// Create research set (exploratory, unvalidated)
await create_embedding_set({
name: "Research Queue",
slug: "research",
purpose: "Exploratory notes pending validation",
criteria: { tags: ["research", "unvalidated"] }
})
// Create production set (validated knowledge)
await create_embedding_set({
name: "Validated Knowledge",
slug: "production",
purpose: "Reviewed and validated information",
criteria: { tags: ["validated"] }
})
// Research workflow
await create_note({
content: "Hypothesis: X causes Y because...",
tags: ["research", "unvalidated"],
revision_mode: "light" // Don't expand speculative content
})
// After validation, promote to production
await update_note({
id: noteId,
content: updatedContent
})
await set_note_tags({
id: noteId,
tags: ["validated", "causation"]
})
SKOS Integration
Use concept status for knowledge lifecycle:
// Create candidate concept during research
await create_concept({
pref_label: "X-Y Causation Hypothesis",
status: "candidate", // Not yet validated
scope_note: "Requires experimental verification"
})
// After validation, promote to controlled
await update_concept({
id: conceptId,
status: "controlled"
})
Pattern 4: The Dual-Track Mind
Use Case: Maintain both raw observations and synthesized insights.
The Problem
You want to capture raw observations (meetings, conversations, readings) while also building synthesized insights. These serve different purposes.
The Solution: Revision Mode Strategy
// Raw observation (preserve exactly)
await create_note({
content: `
Meeting with Team Alpha 2024-01-15
- John mentioned budget concerns
- Sarah proposed timeline extension
- Decision: Revisit in Q2
`,
tags: ["meeting", "raw"],
revision_mode: "none" // Preserve exactly
})
// Synthesized insight (enhance with context)
await create_note({
content: `
Budget Management Patterns at Acme Corp
Based on recent discussions, there's a pattern emerging
around Q4 budget pressures and their impact on project timelines...
`,
tags: ["insight", "synthesis"],
revision_mode: "full" // Enrich with connections
})
Search Strategy
// Find raw data for accuracy
await search_notes({
query: "budget meeting john",
mode: "fts", // Exact keyword match
// Filter to raw notes via tags
})
// Find insights for understanding
await search_notes({
query: "budget management patterns",
mode: "semantic", // Conceptual match
set: "insights" // Pre-filtered to insights
})
Pattern 5: The Versioned Notebook
Use Case: Track evolution of ideas over time.
The Problem
Your understanding of a topic evolves. You want to see how your thinking changed while maintaining a current "best understanding."
The Solution: Version History + Periodic Snapshots
// Initial understanding
await create_note({
content: "Machine learning is about pattern recognition...",
tags: ["ml", "understanding"]
})
// Update as understanding deepens (versions auto-created)
await update_note({
id: noteId,
content: "Machine learning encompasses both supervised and unsupervised..."
})
// Later: Review evolution
const versions = await list_note_versions({ note_id: noteId })
// Compare specific versions
const diff = await diff_note_versions({
note_id: noteId,
from_version: 1,
to_version: versions.length
})
// Restore previous understanding if needed
await restore_note_version({
note_id: noteId,
version: 2
})
Milestone Snapshots
For major learning milestones, create labeled backups:
await database_snapshot({
name: `ml-understanding-${new Date().toISOString().slice(0,10)}`,
title: "ML Understanding Checkpoint",
description: "After completing Stanford ML course"
})
Pattern 6: The Personal Knowledge Graph
Use Case: Explore and curate the ontology that Fortémi builds automatically.
How It Works
The NLP pipeline automatically creates SKOS concept hierarchies as notes are ingested. Each note receives 8-15 concept tags with broader/narrower relationships. Over time, this creates a rich knowledge graph without manual effort.
Discovery Workflow
// Create notes normally — the graph builds itself
await capture_knowledge({
action: "create",
content: "Rust's ownership model prevents memory leaks at compile time...",
revision_mode: "light"
})
// Pipeline auto-tags with concepts like:
// domain/programming, topic/rust, technique/ownership-model,
// application/memory-safety, content-type/technical-note
// Explore the auto-generated knowledge graph
const graph = await explore_graph({
start_note_id: rustNoteId,
max_depth: 2,
max_results: 50
})
// Returns connected notes linked by embedding similarity + tag overlap
// Review auto-generated concept tags
const concepts = await manage_tags({
action: "get_concepts",
note_id: rustNoteId
})
// Navigate by backlinks
const links = await get_note_links({ id: rustNoteId })
// links.incoming shows which notes reference this one
// Search the concept vocabulary
const related = await manage_concepts({
action: "search",
query: "memory safety"
})
Curation Workflow
The auto-generated ontology benefits from periodic curation:
// Review candidate concepts — promote good ones
const stats = await manage_concepts({ action: "stats" })
// Shows orphan tags, candidate counts, anti-patterns
// Manually create organizational concepts the AI can't infer
// (only needed for project/client structures)
// Use REST API: POST /api/v1/concepts with broader_ids
// Correct an incorrect auto-tag
await manage_tags({
action: "untag_concept",
note_id: noteId,
concept_id: wrongConceptId
})
Pattern 7: The AI Agent Memory
Use Case: Provide an AI assistant with structured long-term memory.
The Setup
Configure the AI to use Fortémi as its knowledge store:
// Agent workflow for processing user input
async function handleUserQuery(query) {
// 1. Search existing knowledge
const relevant = await search_notes({
query: query,
mode: "semantic",
limit: 5
})
// 2. Get detailed context for top results
const context = []
for (const result of relevant.results.slice(0, 3)) {
const note = await get_note({ id: result.note_id })
const links = await get_note_links({ id: result.note_id })
context.push({ note, links })
}
// 3. Generate response using context
const response = await generateResponse(query, context)
// 4. Optionally store new insights
if (shouldRemember(response)) {
await create_note({
content: response.insight,
tags: ["agent-generated", "insight"],
revision_mode: "light"
})
}
return response
}
Agent-Specific Patterns
Learning from interactions:
// Store interaction summaries
await create_note({
content: `
User asked about: ${topic}
Key points discussed: ${summary}
User feedback: ${feedback}
`,
tags: ["interaction", "feedback"],
revision_mode: "none" // Preserve exact feedback
})
Maintaining task context:
// Create task-specific embedding set
await create_embedding_set({
name: `Task: ${taskId}`,
slug: `task-${taskId}`,
purpose: "Notes related to specific task",
criteria: { tags: [`task-${taskId}`] }
})
// All task-related notes go to this set
await create_note({
content: taskUpdate,
tags: [`task-${taskId}`]
})
// Search only task-relevant knowledge
await search_notes({
query: "implementation approach",
set: `task-${taskId}`
})
Pattern 8: Collaborative Knowledge
Use Case: Share curated knowledge between users or systems.
The Solution: Export/Import with Curation
// Curator: Export curated collection
const curatedSet = await knowledge_shard({
include: ["notes", "embeddings", "links"]
// Note: Could filter to specific tags/collections
})
// Recipient: Import into their system (preview first)
await knowledge_shard_import({
file_path: "curated-set.shard",
on_conflict: "skip", // Don't overwrite their notes
dry_run: true // Preview first
})
// Check what would be imported
// Then do actual import
await knowledge_shard_import({
file_path: "curated-set.shard",
on_conflict: "skip",
dry_run: false
})
Template-Based Collaboration
Share reusable templates:
// Create standard template
await create_template({
name: "Weekly Standup",
content: `
# Weekly Standup - {{date}}
## Accomplishments
{{accomplishments}}
## Blockers
{{blockers}}
## Next Week
{{plans}}
`,
default_tags: ["standup", "weekly"]
})
// Team members use same template
await instantiate_template({
id: templateId,
variables: {
date: "2024-01-15",
accomplishments: "Completed feature X",
blockers: "Waiting on API docs",
plans: "Start integration testing"
}
})
Design Principles
1. Let the System Tag, Add Organizational Tags Manually
Content-based tags (domain, topic, methodology, etc.) are generated automatically by the NLP pipeline. You only need to add organizational tags that can't be inferred from content:
- Project tags: `project-alpha`, `client-acme` (which project does this belong to?)
- Status tags: `draft`, `validated`, `archived` (what's its review status?)
- Scope tags: `scope/personal`, `scope/work`, `scope/public` (who should see this?)
The AI handles domain classification, topic identification, and content-type detection automatically.
2. Use Appropriate Revision Modes
| Content Type | Revision Mode | Reason |
|---|---|---|
| Raw observations | `none` | Preserve exact content |
| Personal notes | `light` | Format without expansion |
| Technical concepts | `full` | Benefit from connections |
| Quotes/citations | `none` | Must stay verbatim |
3. Leverage Embedding Sets
Think of embedding sets as "views" into your knowledge:
- Create sets for major work contexts
- Use sets to reduce search noise
- Refresh sets after bulk imports
- Delete obsolete sets when projects end
4. Backup Before Major Changes
Always snapshot before:
- Bulk imports
- Memory swaps
- Major reorganizations
- Experimental operations
5. Use Semantic Search for Discovery
- FTS: When you know exact keywords
- Semantic: When exploring concepts
- Hybrid: Best general-purpose
Quick Reference
| Need | Tool | Mode |
|---|---|---|
| Find exact phrase | `search_notes` | `fts` |
| Find related concepts | `search_notes` | `semantic` |
| Best overall search | `search_notes` | `hybrid` |
| Focus search on domain | `search_notes` | `set: "slug"` |
| Save entire memory | `knowledge_shard` | - |
| Swap memory context | `knowledge_shard_import` | - |
| Track idea evolution | `list_note_versions` | - |
| Build ontology | SKOS concept tools | - |
| Explore connections | `explore_graph` | - |
| Find what references me | `get_note_links` | `incoming` |
Related Documentation
- Getting Started - First-time setup and basics
- MCP Tools Reference - Complete tool documentation
- SKOS Tagging - Hierarchical tagging system
- Search Guide - Search modes and query optimization
- Best Practices - Research-backed usage guidance
- Chunking Strategies - How content is split for embeddings
- Backup Guide - Backup and restore procedures