Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 10 additions & 29 deletions src/contents/posts/en/building-agent-memory-free-vendor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ In the initial architecture, semantic search directly targeted the flat `MEMORY_
![Architecture Before](/media/blog/membangun-agent-memory-bebas-vendor/architecture-before.png)

#### 2. New Architecture
In the new architecture, we introduce a **Hybrid Scoring** layer (Semantic + Importance + Recency) and **Graph Link Validation** (BFS with a depth limit) to filter candidate dates before fetching raw transcripts from the NAS. The synchronization process is also enhanced with a **Reconciliation Pass** and **Daily Summary Generation**.
In the new architecture, we introduce a **Hybrid Scoring** layer (Semantic + Importance + Recency) to filter candidate dates before fetching raw transcripts from the NAS. The synchronization process is also enhanced with a **Reconciliation Pass** and **Daily Summary Generation** to keep everything tidy and indexed.

![Architecture After](/media/blog/membangun-agent-memory-bebas-vendor/architecture-after.png)

Expand All @@ -56,8 +56,6 @@ projects: [Nouverse Core, Homelab]
tags: [Kubernetes, Docker, RAG]
importance: 7
mood: excited
continue_of: 2026-07-05
related_dates: [2026-07-01]
uncategorized:
technologies: []
libraries: [Pydantic]
Expand Down Expand Up @@ -92,32 +90,15 @@ With this math, a critical system design discussion from 3 months ago (high impo

---

### 3. BFS Graph Traversal with Depth Limit

To ensure the agent can pull context that continues across days, we parse the `continue_of` and `related_dates` fields from the YAML header. But to prevent performance degradation (pulling too many markdown files from the NAS), I implemented a **Breadth-First Search (BFS)** traversal with a strict depth limit:

```python
# Queue: (date, current_depth, current_semantic_score)
queue = deque([(d, 0, date_scores[d]) for d in date_scores])
visited_dates = {}

while queue:
d, depth, score = queue.popleft()
if d in visited_dates:
continue

final_score, metadata = calculate_hybrid_score(score, d, config)
visited_dates[d] = (final_score, metadata)

if depth < max_depth:
linked_dates = ([metadata.get("continue_of")] if metadata.get("continue_of") else []) + metadata.get("related_dates", [])
for linked in linked_dates:
if linked and linked not in visited_dates:
# Decay the semantic score by 20% per graph level
queue.append((linked, depth + 1, score * 0.8))
```
### 3. Keep it Simple: Dropping Graph Traversal & BFS

Initially, when designing this system, I went all-in on writing a graph traversal algorithm using **Breadth-First Search (BFS)** with a strict depth limit (`max_depth = 2`) to crawl the `continue_of` and `related_dates` fields in the YAML header. The goal was to automatically pull threaded daily notes.

However, after testing it in production, I realized this approach was *overkill* and highly prone to **date hallucination** by the LLM (the LLM frequently hallucinated past dates that didn't actually have logs).

Ultimately, I decided to **completely drop the graph traversal logic**. Why? Because the task of connecting related topics is **already handled naturally and automatically by Semantic RAG (pgvector/AnythingLLM)**.

The `max_graph_depth` is capped at `2`. This ensures we only fetch up to a 2-hop relationship, keeping context window size and Disk I/O safe and fast.
If I ask *"How was the Docker setup yesterday?"*, the RAG automatically retrieves all daily summaries relevant to the keyword "Docker" without requiring manual wikilinks inside the markdown files. We don't need a complex graph database traversal for a personal assistant. *Keep it simple!*

---

Expand All @@ -135,7 +116,7 @@ I just added a quick instruction to the summary generator prompt to append wikil
- [Point 1]

---
**🔗 Links:** [[2026-07-05]] · [[Gading]] · [[Nouverse Core]]
**🔗 Links:** [[Gading]] · [[Nouverse Core]] · [[2026-07-06]]
```

When opened in Obsidian on my laptop, I instantly get **Graph View**, **Backlinks**, and a **Calendar Heatmap** out-of-the-box, without writing a single line of visualization code. The RAG benefits from clean metadata, and I get a gorgeous UI to browse Nouva's memory history.
Expand Down
39 changes: 10 additions & 29 deletions src/contents/posts/id/membangun-agent-memory-bebas-vendor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Di arsitektur awal, pencarian semantik langsung mengarah ke index flat `MEMORY_I
![Arsitektur Sebelum](/media/blog/membangun-agent-memory-bebas-vendor/architecture-before.png)

#### 2. Arsitektur Baru
Di arsitektur baru, kita menyisipkan layer **Hybrid Scoring** (Semantic + Importance + Recency) dan **Graph Link Validation** (BFS dengan depth limit) untuk menyaring kandidat tanggal sebelum mengambil data dari NAS. Proses sinkronisasi juga disisipi dengan **Reconciliation Pass** dan **Daily Summary Generation**.
Di arsitektur baru, kita menyisipkan layer **Hybrid Scoring** (Semantic + Importance + Recency) untuk menyaring kandidat tanggal sebelum mengambil data dari NAS. Proses sinkronisasi juga disisipi dengan **Reconciliation Pass** dan **Daily Summary Generation** agar data tetap rapi dan terindeks dengan baik.

![Arsitektur Sesudah](/media/blog/membangun-agent-memory-bebas-vendor/architecture-after.png)

Expand All @@ -56,8 +56,6 @@ projects: [Nouverse Core, Homelab]
tags: [Kubernetes, Docker, RAG]
importance: 7
mood: excited
continue_of: 2026-07-05
related_dates: [2026-07-01]
uncategorized:
technologies: []
libraries: [Pydantic]
Expand Down Expand Up @@ -92,32 +90,15 @@ Dengan skema ini, diskusi penting 3 bulan lalu (importance tinggi) gak akan kala

---

### 3. BFS Graph Traversal dengan Depth Limit

Untuk menjaga agar agen bisa menarik konteks yang bersambung dari hari sebelumnya, kita membaca field `continue_of` dan `related_dates` di YAML metadata. Tapi biar gak kena masalah performa (narik puluhan file markdown sekaligus dari NAS), gw nerapin traversal menggunakan algoritma **Breadth-First Search (BFS)** dengan batas kedalaman (`max_graph_depth`):

```python
# Queue: (date, current_depth, current_semantic_score)
queue = deque([(d, 0, date_scores[d]) for d in date_scores])
visited_dates = {}

while queue:
d, depth, score = queue.popleft()
if d in visited_dates:
continue

final_score, metadata = calculate_hybrid_score(score, d, config)
visited_dates[d] = (final_score, metadata)

if depth < max_depth:
linked_dates = ([metadata.get("continue_of")] if metadata.get("continue_of") else []) + metadata.get("related_dates", [])
for linked in linked_dates:
if linked and linked not in visited_dates:
# Skor semantik didecay 20% per level kedalaman graf
queue.append((linked, depth + 1, score * 0.8))
```
### 3. Keep it Simple: Membuang Graph Traversal & BFS

Awalnya, pas merancang sistem ini, gw sempat all-in menulis kode traversal graf menggunakan algoritma **Breadth-First Search (BFS)** dengan batas kedalaman (`max_depth = 2`) untuk menelusuri field `continue_of` dan `related_dates` di YAML metadata. Idenya biar asisten AI bisa narik riwayat chat yang nyambung secara otomatis.

Tapi setelah diuji coba, gw sadar kalau pendekatan ini *overkill* dan rawan **halusinasi tanggal** dari LLM (LLM sering ngasal nebak tanggal masa lalu yang gak beneran ada lognya).

Akhirnya, gw ambil keputusan buat **ngebuang seluruh logika graph traversal tersebut**. Kenapa? Karena fungsi menghubungkan topik yang sama itu **sudah ditangani secara alami dan otomatis oleh RAG Semantik (pgvector/AnythingLLM)**.

Batas `max_graph_depth` ini gw set di angka `2`. Jadi maksimal kita cuma menarik relasi sejauh 2 langkah, sangat aman dari context window bloating dan disk I/O yang lemot.
Kalau gw nanya *"Setup Docker kemarin gimana?"*, RAG bakal otomatis narik semua tanggal summary yang relevan dengan keyword "Docker" tanpa perlu kita link secara manual di file markdown. Kita gak butuh traversal graph database yang kompleks cuma buat asisten personal. *Keep it simple!*

---

Expand All @@ -135,7 +116,7 @@ Gw tinggal nambahin sebaris instruksi di prompt generator summary untuk nge-appe
- [Point 1]

---
**🔗 Links:** [[2026-07-05]] · [[Gading]] · [[Nouverse Core]]
**🔗 Links:** [[Gading]] · [[Nouverse Core]] · [[2026-07-06]]
```

Begitu di-mount ke Obsidian di laptop gw, gw langsung dapet **Graph View**, **Backlinks**, dan **Calendar Heatmap** secara gratis tanpa perlu nulis kode visualisasi satu baris pun. RAG-nya seneng karena dapet metadata bersih, gwnya juga seneng karena bisa browsing riwayat chat Nouva dengan visualisasi grafis yang estetik.
Expand Down
Loading