<?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: Radu C.</title>
    <description>The latest articles on DEV Community by Radu C. (@eyepaq).</description>
    <link>https://dev.to/eyepaq</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%2F3818489%2Fb7e22e28-9bf0-4835-876c-72adbd08b7e2.png</url>
      <title>DEV Community: Radu C.</title>
      <link>https://dev.to/eyepaq</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eyepaq"/>
    <language>en</language>
    <item>
      <title>Your AI Memory System Can't Tell a River Bank from a Savings Account</title>
      <dc:creator>Radu C.</dc:creator>
      <pubDate>Wed, 15 Apr 2026 00:49:38 +0000</pubDate>
      <link>https://dev.to/eyepaq/your-ai-memory-system-cant-tell-a-river-bank-from-a-savings-account-34j</link>
      <guid>https://dev.to/eyepaq/your-ai-memory-system-cant-tell-a-river-bank-from-a-savings-account-34j</guid>
      <description>&lt;p&gt;Regex-based safety classification fails in both directions. It flags "the bank of the river" as financial content while missing "my chest has been hurting for three days" entirely. We fixed this in widemem with a two-stage classification pipeline that catches implied safety-critical content and ignores metaphors, at zero additional API cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with keyword matching
&lt;/h2&gt;

&lt;p&gt;YMYL (Your Money or Your Life) classification protects facts that could cause real harm if lost or corrupted. A patient's medication. A legal custody arrangement. An outstanding debt. These memories need higher importance scores, immunity from time decay, and forced contradiction detection.&lt;/p&gt;

&lt;p&gt;Most memory systems (including widemem until this week) rely on regex patterns to identify YMYL content. Strong patterns like "blood pressure" or "401k" work well. But single-keyword weak patterns create two failure modes that undermine the entire safety premise.&lt;/p&gt;

&lt;h3&gt;
  
  
  False positives: flagging content that isn't safety-critical
&lt;/h3&gt;

&lt;p&gt;We tested 12 common phrases against widemem's previous regex classifier. Six triggered false YMYL flags:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Regex result&lt;/th&gt;
&lt;th&gt;Actual YMYL?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"I walked by the &lt;strong&gt;bank&lt;/strong&gt; of the river"&lt;/td&gt;
&lt;td&gt;financial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"The &lt;strong&gt;doctor&lt;/strong&gt; is a good TV show"&lt;/td&gt;
&lt;td&gt;health&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"My &lt;strong&gt;investment&lt;/strong&gt; of time in learning Python paid off"&lt;/td&gt;
&lt;td&gt;financial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"The &lt;strong&gt;court&lt;/strong&gt; at the tennis club"&lt;/td&gt;
&lt;td&gt;legal&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Take this with a grain of salt, not a &lt;strong&gt;prescription&lt;/strong&gt;"&lt;/td&gt;
&lt;td&gt;pharmaceutical&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"&lt;strong&gt;Fire alarm&lt;/strong&gt; went off during cooking"&lt;/td&gt;
&lt;td&gt;safety&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every one of these would get elevated importance, decay immunity, and forced contradiction detection. A cooking incident treated like a medical emergency. A TV recommendation sitting next to actual diagnoses.&lt;/p&gt;

&lt;p&gt;The noise drowns out real signal.&lt;/p&gt;

&lt;h3&gt;
  
  
  False negatives: missing content that IS safety-critical
&lt;/h3&gt;

&lt;p&gt;Worse, the regex approach misses implied YMYL content entirely. No keyword, no classification.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Regex result&lt;/th&gt;
&lt;th&gt;Actual YMYL?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"My chest has been hurting for three days"&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;health&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I can't breathe when I lie down"&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;health&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I owe $40,000 and can't make payments"&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;financial&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"The judge ruled against me in the custody hearing"&lt;/td&gt;
&lt;td&gt;weak (custody)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;legal&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I stopped taking my pills two weeks ago"&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;medical&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"My ex is threatening to take the kids"&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;legal&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;"I stopped taking my pills" contains no medical keyword in the strong pattern list. No "medication," no "prescription," no "drug interaction." The regex sees ordinary English. The meaning is invisible to it.&lt;/p&gt;

&lt;p&gt;This is the failure mode that actually hurts people. A personal assistant that forgets "I can't breathe when I lie down" because it scored 3/10 importance and decayed after a week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: two-stage classification
&lt;/h2&gt;

&lt;p&gt;The new pipeline uses regex as a fast path and the LLM as the semantic classifier. No additional API calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1 (regex, fast):&lt;/strong&gt; Strong multi-word patterns fire immediately. "Blood pressure," "401k contribution," "DNR order" don't need an LLM to confirm. These are unambiguous. This stage runs in microseconds and catches ~30% of YMYL content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2 (LLM, semantic):&lt;/strong&gt; For everything else, the LLM classifies YMYL during the fact extraction call that already happens on every &lt;code&gt;add()&lt;/code&gt;. We added one field to the extraction output:&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;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"patient reports persistent chest pain"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"importance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ymyl_category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"health"&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;The prompt includes explicit instructions to reject metaphorical usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do NOT flag metaphorical or casual usage:
  - "walked by the bank of the river" -&amp;gt; null (not financial)
  - "The Doctor is a great TV show" -&amp;gt; null (not medical)
  - "court of public opinion" -&amp;gt; null (not legal)

DO flag genuine YMYL:
  - "my chest has been hurting for three days" -&amp;gt; "health"
  - "I owe $40,000 and can't make payments" -&amp;gt; "financial"
  - "I stopped taking my pills" -&amp;gt; "medical"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM understands context. "Bank" next to "river" is geography. "Bank" next to "$40,000" is finance. Regex can't make that distinction. The LLM already processes the text for fact extraction; the YMYL classification adds ~50 tokens to the prompt and zero latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before vs after: classification accuracy
&lt;/h2&gt;

&lt;p&gt;We ran both classifiers against 18 test phrases (6 false positives, 6 false negatives, 6 true positives that both should catch).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;                    Regex-only    Two-stage (regex + LLM)
&lt;span class="p"&gt;                    ----------    -----------------------&lt;/span&gt;
Precision              50%           100%
Recall                 17%           100%
F1 Score               0.25          1.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The regex classifier caught every strong-pattern match but failed on everything else. Half of what it flagged was wrong, and it missed 5 out of 6 implied YMYL phrases.&lt;/p&gt;

&lt;p&gt;The two-stage classifier caught all 12 YMYL phrases (strong patterns via regex, implied via LLM) and rejected all 6 false positives.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens to classified memories
&lt;/h2&gt;

&lt;p&gt;Once a fact gets a &lt;code&gt;ymyl_category&lt;/code&gt;, three things change:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Importance floor.&lt;/strong&gt; YMYL facts get bumped to at least 8/10 importance, regardless of what the LLM initially scored them. "I stopped taking my pills" won't land at importance 4 and fade into noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decay immunity.&lt;/strong&gt; YMYL facts don't lose relevance over time. A peanut allergy recorded six months ago is as critical today as when it was stored. The &lt;code&gt;ymyl_category&lt;/code&gt; field tells the scoring engine to skip the decay function entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forced contradiction detection.&lt;/strong&gt; When active retrieval is enabled, YMYL-classified facts trigger contradiction checks even if global active retrieval is off. "I moved to Boston" after "I live in San Francisco" gets flagged for resolution. For non-YMYL facts, this check is optional.&lt;/p&gt;

&lt;p&gt;The classification persists in the vector store metadata, so it survives restarts and exports. Old memories without a &lt;code&gt;ymyl_category&lt;/code&gt; fall back to regex classification at search time, so the upgrade is backward compatible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tradeoff
&lt;/h2&gt;

&lt;p&gt;This approach depends on LLM quality. GPT-4o-mini and Claude handle the classification well. Smaller local models (Ollama with llama3.2) may be less accurate on edge cases. The regex stage acts as a safety net: strong patterns always fire regardless of LLM capability.&lt;/p&gt;

&lt;p&gt;If the LLM returns an invalid category (a string not in the configured YMYL categories), the system ignores it and falls back to regex. If the LLM fails entirely, the retry and fallback mechanisms handle it gracefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; widemem-ai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;widemem&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WideMemory&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;widemem.core.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MemoryConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;YMYLConfig&lt;/span&gt;

&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WideMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;MemoryConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ymyl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;YMYLConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decay_immune&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# This now gets classified as "health" by the LLM
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My chest has been hurting for three days&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# importance &amp;gt;= 8.0, immune to decay
&lt;/span&gt;
&lt;span class="c1"&gt;# This does NOT get flagged as financial
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I walked by the bank of the river&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# normal importance, normal decay
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full change is in &lt;a href="https://github.com/remete618/widemem-ai/pull/16" rel="noopener noreferrer"&gt;PR #16&lt;/a&gt;. Eight files changed, 163 tests passing, zero additional API calls.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;widemem is an open-source AI memory layer with importance scoring, time decay, hierarchical memory, and YMYL safety. &lt;a href="https://github.com/remete618/widemem-ai" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://pypi.org/project/widemem-ai/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>nlp</category>
      <category>rag</category>
    </item>
    <item>
      <title>Give Your Local LLM a Memory That Actually Works</title>
      <dc:creator>Radu C.</dc:creator>
      <pubDate>Wed, 11 Mar 2026 12:56:32 +0000</pubDate>
      <link>https://dev.to/eyepaq/give-your-local-llm-a-memory-that-actually-works-5aco</link>
      <guid>https://dev.to/eyepaq/give-your-local-llm-a-memory-that-actually-works-5aco</guid>
      <description>&lt;h1&gt;
  
  
  LLMs Remember Your Name. They Forget Everything Else.
&lt;/h1&gt;

&lt;p&gt;LLMs have conversation memory — for about 20-30 messages. Then the context window fills up and everything before that is gone. The typical fix is vector search: embed conversations, retrieve relevant chunks later.&lt;/p&gt;

&lt;p&gt;That works until facts contradict each other, critical information decays at the same rate as small talk, or the system quietly overwrites a drug allergy because the user mentioned a different medication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/remete618/widemem-ai" rel="noopener noreferrer"&gt;widemem&lt;/a&gt; is an open-source memory layer that handles the parts vector search alone can't.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Batch conflict resolution&lt;/strong&gt; — When a message has 5 new facts, most systems check each one individually. 5 facts, 5 LLM calls. widemem batches all new facts + related existing memories into one call. The model returns ADD/UPDATE/DELETE per fact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Importance-weighted scoring&lt;/strong&gt; — Every fact gets rated 1-10. Retrieval combines similarity, importance, and recency. A 9/10 fact stays relevant for months. A 2/10 fades in weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;YMYL safety&lt;/strong&gt; — Health, legal, financial facts get an importance floor of 8.0, immunity from decay, and forced contradiction detection. "Bank account" triggers it. "River bank" doesn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contradiction detection&lt;/strong&gt; — Optional callback before overwriting facts that conflict with existing memories. Useful when silent overwrites are dangerous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hierarchical memory&lt;/strong&gt; — Facts → Summaries → Themes. Broad queries get themes, specific queries get facts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Runs Fully Local
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;widemem-ai[ollama]
ollama pull llama3.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;widemem&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WideMemory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MemoryConfig&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;widemem.core.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EmbeddingConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;VectorStoreConfig&lt;/span&gt;

&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WideMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MemoryConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;LLMConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llama3.2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;EmbeddingConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sentence-transformers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;384&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;VectorStoreConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;faiss&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ollama + sentence-transformers + FAISS + SQLite. Nothing leaves the machine.&lt;/p&gt;

&lt;p&gt;Also ships as a FastAPI sidecar (&lt;code&gt;python -m widemem.server&lt;/code&gt;) and there's &lt;a href="https://github.com/remete618/ollama" rel="noopener noreferrer"&gt;Gin middleware for Ollama&lt;/a&gt; that adds memory transparently with one env var.&lt;/p&gt;




&lt;p&gt;140 tests. Apache 2.0. Python 3.10+. &lt;a href="https://github.com/remete618/widemem-ai" rel="noopener noreferrer"&gt;github.com/remete618/widemem-ai&lt;/a&gt; — &lt;code&gt;pip install widemem-ai&lt;/code&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
      <category>rag</category>
    </item>
  </channel>
</rss>
