Skip to content

Commit be04135

Browse files
committed
blog: add metadata search, schema workflows, and agent knowledge architecture posts
1 parent 62f7c77 commit be04135

File tree

3 files changed

+472
-0
lines changed

3 files changed

+472
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
title: "Stop Grepping Your Frontmatter"
3+
description: "Search notes by status, priority, tags, or any custom field — structured queries instead of text-string guessing."
4+
---
5+
6+
You've been searching for notes like this:
7+
8+
```
9+
search_notes("status: active")
10+
```
11+
12+
And sometimes it works. And sometimes it returns notes that mention the word "active" in a completely different context. And sometimes it misses notes where the frontmatter says `status: in-progress` because you searched for "active" and those are different strings.
13+
14+
This is text search doing a job that structured queries should be doing.
15+
16+
---
17+
18+
## Frontmatter Is Data. Search It Like Data.
19+
20+
Every Basic Memory note has YAML frontmatter — the metadata block at the top of the file:
21+
22+
```yaml
23+
---
24+
title: API Refactor Plan
25+
type: task
26+
status: active
27+
priority: high
28+
tags: [backend, q1-2026]
29+
assigned: paul
30+
---
31+
```
32+
33+
With v0.19.0, you can search these fields directly:
34+
35+
```
36+
search_notes(metadata_filters={"status": "active"})
37+
```
38+
39+
That returns every note where `status` is literally `active` in the frontmatter. Not notes that happen to contain the word "active" somewhere in their body. Not fuzzy matches. Exact structured queries on structured data.
40+
41+
## Building Up
42+
43+
Start simple — find all active tasks:
44+
45+
```
46+
search_notes(metadata_filters={"status": "active"})
47+
```
48+
49+
Filter by multiple fields — active tasks that are high priority:
50+
51+
```
52+
search_notes(metadata_filters={
53+
"status": "active",
54+
"priority": "high"
55+
})
56+
```
57+
58+
Use operators — find anything high or critical:
59+
60+
```
61+
search_notes(metadata_filters={
62+
"priority": {"$in": ["high", "critical"]}
63+
})
64+
```
65+
66+
Combine with text search — active tasks about authentication:
67+
68+
```
69+
search_notes(
70+
query="authentication",
71+
metadata_filters={"status": "active"}
72+
)
73+
```
74+
75+
Search by tags using the shorthand:
76+
77+
```
78+
search_notes(tags=["backend", "q1-2026"])
79+
```
80+
81+
Or the tag syntax in the query itself:
82+
83+
```
84+
search_notes("tag:backend AND tag:security")
85+
```
86+
87+
## The Operators
88+
89+
Beyond simple equality, you get range and set operations:
90+
91+
```
92+
# Notes created after a date
93+
search_notes(metadata_filters={
94+
"created": {"$gte": "2026-02-01"}
95+
})
96+
97+
# Priority in a specific set
98+
search_notes(metadata_filters={
99+
"priority": {"$in": ["high", "critical"]}
100+
})
101+
102+
# Sprint number between 10 and 15
103+
search_notes(metadata_filters={
104+
"sprint": {"$between": [10, 15]}
105+
})
106+
107+
# Notes with a specific tag (array contains)
108+
search_notes(metadata_filters={
109+
"tags": "security"
110+
})
111+
```
112+
113+
Available operators: `$in`, `$gt`, `$gte`, `$lt`, `$lte`, `$between`. They work on strings, numbers, and dates.
114+
115+
## Why This Matters
116+
117+
Metadata search turns your knowledge base into something closer to a database — without giving up the plain-text format that makes it readable and editable.
118+
119+
Your notes are still markdown files. You can open them in any editor. But when your AI agent needs to find "all active high-priority tasks tagged backend," it doesn't have to guess at text patterns. It queries the frontmatter directly and gets precise results.
120+
121+
This is especially powerful combined with the [schema system](/blog/schema-workflows). Define what fields a task note should have, validate that they're consistent, then query them with confidence. The schema ensures the data is there. Metadata search makes it findable.
122+
123+
## The Practical Pattern
124+
125+
Here's how this changes daily workflow:
126+
127+
**Morning standup:** "What tasks are active and high priority?"
128+
```
129+
search_notes(metadata_filters={"status": "active", "priority": "high"}, tags=["sprint-current"])
130+
```
131+
132+
**Weekly review:** "What did we complete this week?"
133+
```
134+
search_notes(metadata_filters={"status": "done", "completed": {"$gte": "2026-02-24"}})
135+
```
136+
137+
**Project scoping:** "Show me all notes tagged for the API refactor."
138+
```
139+
search_notes(tags=["api-refactor"])
140+
```
141+
142+
No custom tooling. No project management SaaS. Just frontmatter in markdown files, queried through MCP tools that any AI assistant can call.
143+
144+
---
145+
146+
[Metadata search guide →](/concepts/semantic-search)
147+
[Schema system →](/concepts/schema-system)
148+
149+
---
150+
151+
*Basic Memory is local-first AI knowledge infrastructure. Plain text files, structured when you need it, searchable always. [Get started →](https://basicmemory.com)*
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
title: "Your Knowledge Base Grew. Here's How to Keep It Honest."
3+
description: "Using Basic Memory's schema system to bring consistency to organic knowledge bases — without migration scripts or upfront planning."
4+
---
5+
6+
You started with a few notes. Then a few dozen. Now you have hundreds, and you've noticed something: your AI writes "person" notes three different ways.
7+
8+
Some have a `[name]` observation. Some use `[full_name]`. A few skip the name entirely and put it in the title. Relations are worse — `works_at`, `employed_by`, `employer`, `company` — four ways to say the same thing.
9+
10+
This is normal. Knowledge bases grow organically. You don't sit down on day one and design a schema for every note type you'll ever write. You write what you need, when you need it, and structure emerges from use.
11+
12+
The problem is that inconsistency compounds. Your AI can't reliably query "all people and their employers" if the relation type varies across notes. Metadata search returns incomplete results when some notes use `status: active` and others use `state: in-progress`.
13+
14+
The schema system fixes this — not by forcing structure upfront, but by observing what you've already written and codifying the patterns.
15+
16+
---
17+
18+
## Step 1: Discover What You Have
19+
20+
Start by asking your AI to look at what exists:
21+
22+
```
23+
"I've been writing a lot of person notes. Can you figure out
24+
what they have in common?"
25+
```
26+
27+
Behind the scenes, the AI runs `schema_infer` on your person notes. It analyzes observation categories, relation types, and frontmatter fields across every note with `type: person`. Then it proposes a schema:
28+
29+
```
30+
Done! I analyzed 45 person notes. Here's what I found:
31+
32+
Required (in 90%+ of notes):
33+
- name: string — full name
34+
- role: string — job title or function
35+
36+
Optional (in 25-89%):
37+
- works_at: Organization — employer
38+
- expertise: string[] — areas of knowledge
39+
- email: string — contact email
40+
41+
Common relations:
42+
- works_at → Organization (37 notes)
43+
- collaborates_with → Person (12 notes)
44+
45+
Want me to create this as a schema?
46+
```
47+
48+
## Step 2: Create the Schema
49+
50+
Say yes. The AI creates a schema note — which is just a regular markdown file:
51+
52+
```yaml
53+
---
54+
title: Person
55+
type: schema
56+
entity: person
57+
version: 1
58+
schema:
59+
name: string, full name
60+
role?: string, job title
61+
works_at?: Organization, employer
62+
expertise?(array): string, areas of knowledge
63+
email?: string, contact email
64+
settings:
65+
validation: warn
66+
---
67+
```
68+
69+
This lives in your knowledge base alongside everything else. Open it in VS Code, Obsidian, any editor. It's a note about how notes should look.
70+
71+
The `?` marks optional fields. `validation: warn` means the schema advises but doesn't block. Your AI reads this schema when creating new person notes and follows it as a guide.
72+
73+
## Step 3: Validate What Exists
74+
75+
Now check your existing notes against the schema:
76+
77+
```
78+
"How do my existing person notes look against that schema?"
79+
```
80+
81+
The AI runs `schema_validate`:
82+
83+
```
84+
42 of 45 person notes pass validation.
85+
86+
3 issues found:
87+
- "John Smith" — missing [name] observation (name is in title only)
88+
- "Dr. Sarah Chen" — uses [full_name] instead of [name]
89+
- "Bob (contractor)" — missing [role] observation
90+
91+
Want me to fix these?
92+
```
93+
94+
No migration script. No database alteration. The AI reads each note, identifies what's missing or inconsistent, and offers to edit them. You approve or adjust.
95+
96+
## Step 4: Detect Drift Over Time
97+
98+
A month later, run `schema_diff`:
99+
100+
```
101+
"Has my person note format drifted from the schema?"
102+
```
103+
104+
```
105+
Drift detected in Person schema:
106+
107+
New fields found in notes (not in schema):
108+
- linkedin_url (appeared in 8 notes)
109+
- department (appeared in 15 notes)
110+
111+
Declared fields with low usage:
112+
- email (only 12% of notes — consider making optional or removing)
113+
114+
Relation type variations:
115+
- "employed_by" used 3 times (schema says "works_at")
116+
```
117+
118+
Now you decide: add `department` to the schema because it's useful? Normalize `employed_by` back to `works_at`? Drop `email` because nobody uses it? The schema evolves with your knowledge base, not against it.
119+
120+
---
121+
122+
## The Full Workflow Loop
123+
124+
This is what schema-managed knowledge looks like in practice:
125+
126+
1. **Write freely** — don't worry about structure upfront
127+
2. **Infer** — let the AI discover patterns in what you've written
128+
3. **Codify** — create a schema from those patterns
129+
4. **Validate** — check existing notes and fix outliers
130+
5. **Create** — new notes follow the schema automatically
131+
6. **Drift** — periodically check if reality has diverged from the definition
132+
7. **Evolve** — update the schema to match how your knowledge base actually works
133+
134+
It's the same cycle that good database teams follow — observe, define, validate, evolve — but applied to a plain-text knowledge base managed through conversation.
135+
136+
## Why Schemas Are Just Notes
137+
138+
This was a deliberate design decision. Schemas could have been configuration files, database tables, or API-only constructs. We made them notes because:
139+
140+
- **You can read them.** Open the file, see exactly what "Person" means in your knowledge base.
141+
- **You can edit them.** Change a field name in your editor, save, done.
142+
- **Your AI can read them.** When creating a new person note, the AI checks the schema and follows it.
143+
- **They're versioned.** Git tracks changes. You can see how your schemas evolved over time.
144+
- **They're searchable.** `search_notes(metadata_filters={"type": "schema"})` finds all your schemas.
145+
146+
Schemas aren't a separate system bolted onto your knowledge base. They're part of it.
147+
148+
## Real-World Example: Task Management
149+
150+
Schemas shine for workflow note types. Here's a task schema:
151+
152+
```yaml
153+
---
154+
title: Task
155+
type: schema
156+
entity: task
157+
version: 1
158+
schema:
159+
description: string, what needs to be done
160+
status: string, current status (active/blocked/done)
161+
priority?: string, urgency level
162+
assigned?: string, who owns this
163+
current_step?: string, where we are in the process
164+
context?: string, accumulated working state
165+
blocked_by?: string, what's preventing progress
166+
settings:
167+
validation: warn
168+
---
169+
```
170+
171+
Every task note your AI creates follows this structure. When you search for active tasks, you know `status` exists and is consistent. When your AI resumes work after a context reset, it reads `current_step` and `context` to pick up where it left off.
172+
173+
The schema didn't require upfront planning. You wrote a few task notes, noticed they had common fields, inferred a schema, and now every future task is consistent.
174+
175+
---
176+
177+
[Schema system guide →](/concepts/schema-system)
178+
[Metadata search →](/blog/metadata-search)
179+
180+
---
181+
182+
*Basic Memory is local-first AI knowledge infrastructure. Structure when you need it, plain text always. [Get started →](https://basicmemory.com)*

0 commit comments

Comments
 (0)