<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: collen w</title>
    <description>The latest articles on DEV Community by collen w (@collen).</description>
    <link>https://dev.to/collen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3793086%2Fd4c285ca-eca1-4a37-acbc-6545ca28cb59.png</url>
      <title>DEV Community: collen w</title>
      <link>https://dev.to/collen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/collen"/>
    <language>en</language>
    <item>
      <title>I Built a Local AI Agent That Actually Remembers You — Here's How the River Algorithm Works</title>
      <dc:creator>collen w</dc:creator>
      <pubDate>Thu, 26 Feb 2026 00:41:20 +0000</pubDate>
      <link>https://dev.to/collen/i-built-a-local-ai-agent-that-actually-remembers-you-heres-how-the-river-algorithm-works-nc3</link>
      <guid>https://dev.to/collen/i-built-a-local-ai-agent-that-actually-remembers-you-heres-how-the-river-algorithm-works-nc3</guid>
      <description>&lt;h2&gt;
  
  
  The Vision: A Personal AI That Lives on Your Device
&lt;/h2&gt;

&lt;p&gt;I believe the future of AI isn't in the cloud — it's in your pocket. Imagine a personal AI running on your phone or watch that truly knows you: your habits, your preferences, your relationships, how your life is changing. It processes everything locally first, only reaching out to cloud models when it genuinely can't handle a task on its own. Your data never leaves your device unless absolutely necessary. It grows with you, not for a platform's benefit.&lt;/p&gt;

&lt;p&gt;That's what I'm building toward. But to get there, I needed to solve a fundamental problem first.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;You've been talking to ChatGPT for two years. Thousands of conversations. You've told it about your job, your family, your fears, your goals.&lt;/p&gt;

&lt;p&gt;Then you try Claude. Fresh start. It knows nothing.&lt;/p&gt;

&lt;p&gt;Back to ChatGPT — it "remembers" you with a flat list of bullet points: &lt;em&gt;"User is a developer. User likes coffee."&lt;/em&gt; That's it. Two years of conversations reduced to a sticky note.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Existing AI memory is fundamentally broken.&lt;/strong&gt; It's flat, it's shallow, it's owned by the platform, and it resets when you switch providers. Your digital self is scattered across clouds you don't control. None of this works for a personal AI terminal that's supposed to run on &lt;em&gt;your&lt;/em&gt; hardware and grow with &lt;em&gt;you&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So I built the foundation for that future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing the River Algorithm
&lt;/h2&gt;

&lt;p&gt;Imagine your conversations with AI as water flowing through a river. Most of the water flows past — casual talk, factual Q&amp;amp;A, small talk. But some of it carries sediment: facts about who you are, what you care about, how your life is changing.&lt;/p&gt;

&lt;p&gt;That sediment settles. Over time, it forms a riverbed — a structured, layered understanding of you.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;River Algorithm&lt;/strong&gt;, and it works through three core processes:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Flow — Every Conversation Carries Information
&lt;/h3&gt;

&lt;p&gt;Each conversation flows through the system. A cognition engine classifies every message: is this personal? Does it reveal something about the user? A preference? A life event? A relationship?&lt;/p&gt;

&lt;p&gt;Most messages flow past. But the ones that matter get caught.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Sediment — Important Information Settles into Layers
&lt;/h3&gt;

&lt;p&gt;Extracted insights don't immediately become "facts." They start as &lt;strong&gt;observations&lt;/strong&gt; — raw, unverified. Through repeated confirmation across multiple conversations, they gradually upgrade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Observation → Suspected → Confirmed → Established
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first time you mention you're a developer, it's an observation. The fifth time you discuss debugging strategies, it becomes a confirmed trait. After months of coding conversations, it's established bedrock.&lt;/p&gt;

&lt;p&gt;This is fundamentally different from ChatGPT's memory, which treats "User is a developer" the same whether you mentioned it once or demonstrated it across 500 conversations.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Purify — Sleep Cleans the River
&lt;/h3&gt;

&lt;p&gt;Here's where it gets interesting. After each conversation session ends, the system enters &lt;strong&gt;Sleep mode&lt;/strong&gt; — an offline consolidation process inspired by how human memory actually works.&lt;/p&gt;

&lt;p&gt;During Sleep, the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extracts new observations and events&lt;/li&gt;
&lt;li&gt;Cross-references them against existing profile facts&lt;/li&gt;
&lt;li&gt;Detects contradictions (you said you live in Tokyo last month, but now you're talking about your new apartment in Osaka)&lt;/li&gt;
&lt;li&gt;Resolves disputes using temporal evidence (newer + more frequent = more likely current)&lt;/li&gt;
&lt;li&gt;Closes outdated facts and opens new ones&lt;/li&gt;
&lt;li&gt;Builds a trajectory of how you're changing over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result: a living, breathing profile that evolves with you. Not a sticky note. A river.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Projects
&lt;/h2&gt;

&lt;p&gt;I've open-sourced this as two complementary projects:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/wangjiake/JKRiver" rel="noopener noreferrer"&gt;Riverse&lt;/a&gt; — The Real-Time Agent
&lt;/h3&gt;

&lt;p&gt;Riverse is the main project. It's a personal AI agent you talk to through Telegram, Discord, CLI, or REST API. Every conversation shapes your profile in real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-modal input (text, voice, images, files)&lt;/li&gt;
&lt;li&gt;Pluggable tools (web search, finance tracking, health sync, smart home)&lt;/li&gt;
&lt;li&gt;YAML-based custom skills (keyword or cron triggered)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local-first architecture&lt;/strong&gt;: runs on Ollama by default. Cloud models (OpenAI / DeepSeek) are only called when the local model can't handle the task — and even then, only the specific context needed is sent, not your entire history&lt;/li&gt;
&lt;li&gt;Proactive outreach: follows up on important events, respects quiet hours&lt;/li&gt;
&lt;li&gt;Semantic search across your memory using BGE-M3 embeddings&lt;/li&gt;
&lt;li&gt;All data stored locally in PostgreSQL — you own everything&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/wangjiake/RiverHistory" rel="noopener noreferrer"&gt;RiverHistory&lt;/a&gt; — Bootstrap from Your Past
&lt;/h3&gt;

&lt;p&gt;Here's the thing: you've already had thousands of AI conversations. That data is gold. RiverHistory extracts your profile from exported &lt;strong&gt;ChatGPT, Claude, and Gemini&lt;/strong&gt; conversation histories.&lt;/p&gt;

&lt;p&gt;Export your data, run it through RiverHistory, and your Riverse agent knows you from day one. Past conversations record past you, and the past is fact.&lt;/p&gt;

&lt;p&gt;Both projects share the same database. Use RiverHistory to build your historical profile, then switch to Riverse for real-time conversations. Your AI starts with context instead of a blank slate.&lt;/p&gt;

&lt;h2&gt;
  
  
  On Accuracy — Why You Can't Edit Memories
&lt;/h2&gt;

&lt;p&gt;No LLM today is trained for personal profile extraction. Results will occasionally be wrong. When that happens, you can &lt;strong&gt;reject&lt;/strong&gt; incorrect memories or &lt;strong&gt;close&lt;/strong&gt; outdated ones in the web dashboard.&lt;/p&gt;

&lt;p&gt;But you cannot edit memory content. This is intentional.&lt;/p&gt;

&lt;p&gt;Wrong memories are sediment in a river — they should be &lt;strong&gt;washed away by the current&lt;/strong&gt;, not sculpted by hand. If you start manually editing your AI's understanding of you, you're no longer building an organic, evolving profile. You're maintaining a database. The River Algorithm is designed to self-correct through continued conversation: contradictions get detected, outdated beliefs get replaced, and the profile converges toward accuracy over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start — Docker (Recommended)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git clone https://github.com/wangjiake/JKRiver.git
  &lt;span class="nb"&gt;cd &lt;/span&gt;JKRiver/docker
  &lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
  &lt;span class="c"&gt;# Edit .env — set OPENAI_API_KEY or use LLM_PROVIDER=local for Ollama&lt;/span&gt;
  docker compose up

  Open http://localhost:2345 &lt;span class="k"&gt;for &lt;/span&gt;the profile viewer. Chat via &lt;span class="nb"&gt;command &lt;/span&gt;line:
  docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;jkriver bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd /app_work &amp;amp;&amp;amp; python -m agent.main"&lt;/span&gt;

  Process the demo to see the River Algorithm &lt;span class="k"&gt;in &lt;/span&gt;action:
  docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;riverhistory bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd /app_work &amp;amp;&amp;amp; python run.py demo max"&lt;/span&gt;

  Full Docker guide: https://wangjiake.github.io/riverse-docs/getting-started/docker/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
shell&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Riverse (Real-Time Agent)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/wangjiake/JKRiver.git
&lt;span class="nb"&gt;cd &lt;/span&gt;JKRiver

python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Edit settings.yaml with your database and LLM config&lt;/span&gt;
&lt;span class="c"&gt;# Initialize database&lt;/span&gt;
createdb &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; your_username Riverse
psql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; your_username &lt;span class="nt"&gt;-d&lt;/span&gt; Riverse &lt;span class="nt"&gt;-f&lt;/span&gt; agent/schema.sql

&lt;span class="c"&gt;# Run&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; agent.main              &lt;span class="c"&gt;# CLI&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; agent.telegram_bot      &lt;span class="c"&gt;# Telegram Bot&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; agent.discord_bot       &lt;span class="c"&gt;# Discord Bot&lt;/span&gt;
python web.py                     &lt;span class="c"&gt;# Web Dashboard (port 1234)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  RiverHistory (Import Past Conversations)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/wangjiake/RiverHistory.git
&lt;span class="nb"&gt;cd &lt;/span&gt;RiverHistory

python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Import your exported conversations&lt;/span&gt;
python import_data.py &lt;span class="nt"&gt;--chatgpt&lt;/span&gt; data/ChatGPT/conversations.json
python import_data.py &lt;span class="nt"&gt;--claude&lt;/span&gt; data/Claude/conversations.json

&lt;span class="c"&gt;# Extract profiles&lt;/span&gt;
python run.py all max

&lt;span class="c"&gt;# View results&lt;/span&gt;
python web.py &lt;span class="nt"&gt;--db&lt;/span&gt; Riverse        &lt;span class="c"&gt;# http://localhost:2345&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Python 3.10+, PostgreSQL 16+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local LLM&lt;/td&gt;
&lt;td&gt;Ollama + Qwen 2.5 14B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud LLM&lt;/td&gt;
&lt;td&gt;OpenAI GPT-4o / DeepSeek (fallback)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embeddings&lt;/td&gt;
&lt;td&gt;BGE-M3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interfaces&lt;/td&gt;
&lt;td&gt;FastAPI, Flask, Telegram, Discord, CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Local-First Matters
&lt;/h2&gt;

&lt;p&gt;Every time you talk to ChatGPT or Claude, your conversation goes to a server you don't control. The platform decides what to remember, how to use your data, and whether to keep it. You're renting your own digital identity.&lt;/p&gt;

&lt;p&gt;Riverse flips this entirely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy by architecture&lt;/strong&gt; — Your profile, your memories, your entire cognitive history lives in a local PostgreSQL database on your machine. Nothing is sent to the cloud unless the local model explicitly can't handle a task.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Growable data&lt;/strong&gt; — The more you talk, the richer your local dataset becomes. This data compounds over time. Switch AI providers? Your profile stays. Upgrade your model? Your history is already there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud as fallback, not default&lt;/strong&gt; — The local Ollama model handles most conversations. When it encounters something beyond its capability, it escalates to a cloud model — but only sends the minimum context needed for that specific task, not your life story.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the architecture you need for a personal AI terminal that will eventually run on your phone, your watch, your car. The data has to be local. The intelligence has to grow. The cloud is a tool, not a home.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This is v1.0 — the cognitive foundation running on desktop. What I'm building toward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Personal device deployment&lt;/strong&gt; — Running on phones and watches as a truly portable AI that knows you everywhere&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight local models&lt;/strong&gt; — Optimized for on-device inference, handling 90%+ of conversations without cloud&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-device sync&lt;/strong&gt; — Your profile follows you across devices while staying entirely local (no cloud intermediary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better extraction models&lt;/strong&gt; — Fine-tuned for personal profile understanding, reducing hallucinations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community-contributed skills and tools&lt;/strong&gt; — An ecosystem of capabilities that plug into your personal agent&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Riverse (main project):&lt;/strong&gt; &lt;a href="https://github.com/wangjiake/JKRiver" rel="noopener noreferrer"&gt;github.com/wangjiake/JKRiver&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RiverHistory (history import):&lt;/strong&gt; &lt;a href="https://github.com/wangjiake/RiverHistory" rel="noopener noreferrer"&gt;github.com/wangjiake/RiverHistory&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (Twitter):&lt;/strong&gt; &lt;a href="https://x.com/JKRiverse" rel="noopener noreferrer"&gt;@JKRiverse&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discord:&lt;/strong&gt; &lt;a href="https://discord.com/invite/ZnmFrPvXym" rel="noopener noreferrer"&gt;Join the community&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every AI you've ever used forgets you. This one doesn't. And one day, it'll live in your pocket.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this interesting, consider giving the repos a star — it helps more people discover the project. Questions, feedback, and contributions are always welcome.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>algorithms</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
