<?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: jinho von choi</title>
    <description>The latest articles on DEV Community by jinho von choi (@yurgenschmidt).</description>
    <link>https://dev.to/yurgenschmidt</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%2F3810774%2F08bf9c41-12fd-4e7e-bfa9-d4e63037c1d6.jpg</url>
      <title>DEV Community: jinho von choi</title>
      <link>https://dev.to/yurgenschmidt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yurgenschmidt"/>
    <language>en</language>
    <item>
      <title>A Three-Layer Memory Architecture for LLMs (Redis + Postgres + Vector) MCP</title>
      <dc:creator>jinho von choi</dc:creator>
      <pubDate>Fri, 27 Mar 2026 17:57:29 +0000</pubDate>
      <link>https://dev.to/yurgenschmidt/a-three-layer-memory-architecture-for-llms-redis-postgres-vector-mcp-19b1</link>
      <guid>https://dev.to/yurgenschmidt/a-three-layer-memory-architecture-for-llms-redis-postgres-vector-mcp-19b1</guid>
      <description>&lt;p&gt;GitHub : &lt;a href="https://github.com/JinHo-von-Choi/memento-mcp/blob/main/README.en.md" rel="noopener noreferrer"&gt;https://github.com/JinHo-von-Choi/memento-mcp/blob/main/README.en.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I posted v1 about a month ago. The architecture has been significantly reworked since then.&lt;/p&gt;

&lt;p&gt;The premise: We've been optimizing the wrong variable. The next leap isn't a better prompt. It's an AI that actually knows you, your project, and your mistakes.&lt;/p&gt;

&lt;p&gt;Your AI knows every Redis command ever documented. It doesn't know that your Redis threw NOAUTH last Tuesday because someone forgot the env var. Knowledge without experience. Close the session, and it all evaporates. Goldfish remember for months. Our AIs remember for zero seconds.&lt;/p&gt;

&lt;p&gt;RAG builds a library. Memento builds experience.&lt;/p&gt;

&lt;p&gt;RAG dumps docs into a vector store and retrieves chunks. That's a library. A library treats every page as equally relevant. It doesn't know which chapter saved your production server at 2 AM.&lt;/p&gt;

&lt;p&gt;Memento works differently.&lt;/p&gt;

&lt;p&gt;Say someone suddenly asks me out of nowhere: "Hey, do you remember Mijeong?"&lt;/p&gt;

&lt;p&gt;I'd draw a blank. "Who?" Then they say: "Your desk partner in first grade."&lt;/p&gt;

&lt;p&gt;That single hint is enough. A vague face surfaces. "Oh... right."&lt;/p&gt;

&lt;p&gt;Then more comes flooding back: drawing a line down the middle of the desk and pinching each other if someone crossed it, lending an eraser and never getting it back.&lt;/p&gt;

&lt;p&gt;That's what Memento does. Memory as atomic fragments (1–3 sentences each), reconstructed through association, not retrieved as document dumps.&lt;/p&gt;

&lt;p&gt;How it works:&lt;/p&gt;

&lt;p&gt;Three-layer cascade search. L1 (Redis keyword index, microseconds) → L2 (Postgres metadata, milliseconds) → L3 (pgvector semantic search, deepest). Fast layers answer first; slow layers are skipped. Redis and OpenAI are both optional. Postgres alone is a fully functional baseline.&lt;/p&gt;

&lt;p&gt;Memories have temperature. Hot → warm → cold → expired. But recalled once, and they snap back to hot. Just like human long-term memory.&lt;/p&gt;

&lt;p&gt;Some things never decay. Preferences (who you are) and error patterns (what can always return) are permanent.&lt;/p&gt;

&lt;p&gt;Experience compounds. reflect() at session end distills decisions/errors/procedures into fragments. context() at session start loads them. Over time, the AI genuinely gets better at working with you specifically.&lt;/p&gt;

&lt;p&gt;Appropriate forgetting. Periodic consolidation decays unused memories, merges duplicates, and detects contradictions. The store gets denser, not just bigger.&lt;/p&gt;

&lt;p&gt;What's new since v1: Cascade search (L1/L2/L3), fragment linking with causal graph exploration, TTL tier system, automatic duplicate merging, LLM-based contradiction detection, Streamable HTTP (MCP 2025-11-25), Claude Code hook support, RBAC (read/write/admin), knowledge graph visualization, fragment import/export, sentiment-aware decay, closed learning loop, temperature-weighted context, admin module split with cookie auth, DB migration runner.&lt;/p&gt;

&lt;p&gt;Stack: Node.js 20+ / PostgreSQL 14+ (pgvector) / Redis 6+ (optional) / OpenAI Embeddings (optional) / Gemini Flash (optional)&lt;/p&gt;

&lt;p&gt;Feedback, issues, and PRs welcome.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>llm</category>
      <category>rag</category>
    </item>
    <item>
      <title>This MCP Makes Your AI Smarter: Parism — A Terminal Output Parser for AI Agents</title>
      <dc:creator>jinho von choi</dc:creator>
      <pubDate>Sat, 07 Mar 2026 14:13:33 +0000</pubDate>
      <link>https://dev.to/yurgenschmidt/this-mcp-makes-your-ai-smarter-parism-a-terminal-output-parser-for-ai-agents-5bao</link>
      <guid>https://dev.to/yurgenschmidt/this-mcp-makes-your-ai-smarter-parism-a-terminal-output-parser-for-ai-agents-5bao</guid>
      <description>&lt;p&gt;Have you ever watched your AI agent fumble a simple directory listing — retrying three times for no obvious reason — and wondered what went wrong?&lt;/p&gt;

&lt;p&gt;The answer, more often than not, is &lt;strong&gt;misreading&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: AI Can't Really Read Terminal Output
&lt;/h2&gt;

&lt;p&gt;Terminal output is designed for &lt;em&gt;human&lt;/em&gt; eyes. When you run &lt;code&gt;ls -la&lt;/code&gt;, you instantly understand which column is the filename, which is the size, and which is the timestamp. To an AI, it's just a blob of characters with no clear structure.&lt;/p&gt;

&lt;p&gt;Here's what that means in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain text misread rate: ~4%&lt;/strong&gt; on average&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;With spaces or special characters in filenames: up to 30%&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Overall task reliability: ~85%&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That 15% failure rate sounds small — until one wrong read cascades into minutes (or hours) of the agent spinning its wheels, misinterpreting data, and making things worse.&lt;/p&gt;

&lt;p&gt;It gets messier when you factor in OS differences. &lt;code&gt;stat&lt;/code&gt; on macOS outputs something completely different from Linux. Windows is a different universe altogether. AI models frequently get confused trying to parse these inconsistencies on the fly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea Behind Parism
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/JinHo-von-Choi/parism" rel="noopener noreferrer"&gt;Parism&lt;/a&gt; is an MCP (Model Context Protocol) server that acts as a translator between your terminal and your AI agent.&lt;/p&gt;

&lt;p&gt;Instead of letting the AI parse raw text output directly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without Parism:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI → Terminal → "figure it out yourself" → ~85% accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With Parism:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI → Parism → Terminal → clean JSON → AI → 100% accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI no longer needs to &lt;em&gt;guess&lt;/em&gt; where the filename ends and the size begins. It just reads a key-value pair from structured JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my file (final).zip"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"size_bytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2147483648&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"modified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-03-06T22:14:00"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Does This Actually Buy You?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Token savings on repeated data use:&lt;/strong&gt; If you're doing a one-off lookup, Parism actually increases token usage (the JSON overhead). But the moment you reference that data more than once in a long task, it reverses — the AI no longer needs to re-explain the format to itself, and the 67% reduction in "explanation tokens" compounds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed:&lt;/strong&gt; When the AI doesn't need to reason about data format, it skips an entire inference step. Tasks complete faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reliability:&lt;/strong&gt; The &lt;code&gt;stat&lt;/code&gt; command scenario was telling — without Parism, accuracy on macOS was literally &lt;strong&gt;0%&lt;/strong&gt; because the output format is incompatible with what models trained on Linux examples expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Mental Model
&lt;/h2&gt;

&lt;p&gt;Think of it like turning down the music in your car when you're trying to read a street sign. The music and the sign are unrelated — but reducing cognitive load in one area frees up attention for another.&lt;/p&gt;

&lt;p&gt;Or, as Sun Tzu put it: &lt;em&gt;it's more valuable to make the enemy go hungry once than to feed your own troops twenty times.&lt;/em&gt; One mistake undoes twenty successes. Parism is about eliminating that one mistake.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Set It Up
&lt;/h2&gt;

&lt;p&gt;Since it's published on npm, you just add it to your MCP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parism"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@nerdvana/parism"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, the AI will automatically use it when reading terminal output.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/JinHo-von-Choi/parism" rel="noopener noreferrer"&gt;https://github.com/JinHo-von-Choi/parism&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/@nerdvana/parism##" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@nerdvana/parism##&lt;/a&gt; When Is It Worth It?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use it when you're running &lt;strong&gt;complex, multi-step agentic tasks&lt;/strong&gt; that read filesystem data multiple times. For simple one-shot queries, the JSON overhead may not pay off. But for anything involving loops, retries, or cross-platform compatibility — it's a meaningful quality-of-life upgrade for your AI workflow.&lt;/p&gt;

</description>
      <category>aimcp</category>
      <category>tooling</category>
      <category>ai</category>
    </item>
    <item>
      <title>I built a MyBatis-style SQL mapper for .NET because EF Core was eating all our memory</title>
      <dc:creator>jinho von choi</dc:creator>
      <pubDate>Sat, 07 Mar 2026 03:11:50 +0000</pubDate>
      <link>https://dev.to/yurgenschmidt/i-built-a-mybatis-style-sql-mapper-for-net-because-ef-core-was-eating-all-our-memory-146b</link>
      <guid>https://dev.to/yurgenschmidt/i-built-a-mybatis-style-sql-mapper-for-net-because-ef-core-was-eating-all-our-memory-146b</guid>
      <description>&lt;p&gt;When I inherited a .NET-based stats service, the codebase was EF Core all the way down. Query performance was the first problem — and that I solved, eventually cutting response times by 2x to 3600x depending on the query. But memory was different. EF Core's change tracking, materialization overhead, and object graph behavior imposed a ceiling I couldn't optimize past.&lt;/p&gt;

&lt;p&gt;I'd spent most of my career on Java and Spring. MyBatis was my default tool for anything SQL-heavy. I looked at Dapper — solid library, genuinely good — but I wanted SQL and code to live in separate files, not inline strings. So I built a test mapper, moved the most memory-intensive query onto it, and measured: 2–3x faster execution, 82% reduction in memory consumption.&lt;/p&gt;

&lt;p&gt;That test became NuVatis.&lt;br&gt;
What it is: a SQL mapper for .NET that generates all mapper implementation code at build time via Roslyn Source Generators. The result is zero runtime reflection, full Native AOT compatibility (.NET 8+), and an XML-to-interface mapping model that Java developers will recognize immediately.&lt;/p&gt;

&lt;p&gt;What it isn't: a full ORM. There's no change tracking, no migration system, no LINQ query builder. You write SQL. NuVatis maps it.&lt;br&gt;
Benchmark results: &lt;a href="https://jinho-von-choi.github.io/nuvatis-sample" rel="noopener noreferrer"&gt;https://jinho-von-choi.github.io/nuvatis-sample&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/JinHo-von-Choi/nuvatis" rel="noopener noreferrer"&gt;https://github.com/JinHo-von-Choi/nuvatis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
