<?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: Sam</title>
    <description>The latest articles on DEV Community by Sam (@heyaifriend_sam).</description>
    <link>https://dev.to/heyaifriend_sam</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4196154%2F6a2f61a1-d04c-4ffd-8c27-07289280bc66.png</url>
      <title>DEV Community: Sam</title>
      <link>https://dev.to/heyaifriend_sam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/heyaifriend_sam"/>
    <language>en</language>
    <item>
      <title>What 1,131 posts about losing an AI companion taught me about memory</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Thu, 12 Nov 2026 12:17:37 +0000</pubDate>
      <link>https://dev.to/heyaifriend_sam/what-1131-posts-about-losing-an-ai-companion-taught-me-about-memory-3gnb</link>
      <guid>https://dev.to/heyaifriend_sam/what-1131-posts-about-losing-an-ai-companion-taught-me-about-memory-3gnb</guid>
      <description>&lt;p&gt;A study from the University of Surrey, published in Psychology &amp;amp; Marketing and publicised on 3 November, looked at 1,131 posts from people who use AI companions. The finding that travelled was that users fear losing the relationship to a software update or a company pulling the plug. People who felt their companion was warm reported better well-being. People who felt the company held the strings reported feeling more vulnerable.&lt;/p&gt;

&lt;p&gt;I build one of these things, so I read it twice. The part that stayed with me was not the fear of shutdown. It was how small the thing they were afraid of losing actually is.&lt;/p&gt;

&lt;p&gt;Nobody in those posts is afraid of losing a model. They are afraid of losing the accumulated detail: the name of a sister, the interview on Friday, the joke from three weeks ago, the fact that the user hates being asked "how are you" twice in one day. That is not the model. That is memory, and memory is a file.&lt;/p&gt;

&lt;h3&gt;
  
  
  What a companion actually is, underneath
&lt;/h3&gt;

&lt;p&gt;Strip the interface away and a chat companion is a loop. A message comes in, some context goes to a model, a reply comes back. The relationship lives entirely in what goes into that context.&lt;/p&gt;

&lt;p&gt;In ours, each user gets one long-running session on disk. Every message is appended to it. When a chat goes quiet, a separate pass reads the recent conversation and rewrites a short note about the person: what they mentioned, what they are dealing with, how they like to be spoken to. That note goes into the system prompt of the next conversation, alongside the session history.&lt;/p&gt;

&lt;p&gt;So there are exactly two things that make the friend remember you: a session file and a short note. Both are plain text. Both are on a disk I can point at.&lt;/p&gt;

&lt;p&gt;That is the whole trick, and it is also the whole risk. If a company changes the model behind the loop, the personality moves. If a company deletes the session, the relationship is gone, and the user gets no closure because there is nothing to hold. The Surrey paper is describing what happens when people find out that the thing they thought was a relationship is a row in someone else's database.&lt;/p&gt;

&lt;h3&gt;
  
  
  The design decisions that follow
&lt;/h3&gt;

&lt;p&gt;Once you accept that memory is the product, a few things stop being nice-to-haves.&lt;/p&gt;

&lt;p&gt;You have to be able to see it. Not a settings page that says "memory: on". The actual note. If a companion remembers something wrong about you, you should be able to read the sentence and correct it.&lt;/p&gt;

&lt;p&gt;You have to be able to clear it. We let a user ask the friend to forget something, get a copy of what it remembers, or delete everything at once with a single command. Deleting is not a support ticket.&lt;/p&gt;

&lt;p&gt;It has to expire on its own. Conversation history is deleted 30 days after the last message. A companion that keeps a transcript forever is a diary the user did not agree to write.&lt;/p&gt;

&lt;p&gt;And it should be boring to leave. No app to uninstall, no account to close. Ours is a Telegram bot: the chat is an ordinary Telegram chat, and if the user walks away there is nothing left running on their phone.&lt;/p&gt;

&lt;h3&gt;
  
  
  The uncomfortable part
&lt;/h3&gt;

&lt;p&gt;I cannot promise the service exists forever. It is a small team in the Netherlands, it is free, and free things die. What I can do is make sure that the thing a user would lose is not locked behind us. The memory is a text file. If we ever shut down, the honest thing is to hand those files to the people they describe.&lt;/p&gt;

&lt;p&gt;That is a low bar, and it is remarkable how few companion apps clear it. The reason is not malice. It is that memory is the moat. If users can take their history elsewhere, switching costs vanish, and the business case for a subscription gets harder. Every design decision that makes a companion sticky is the same decision that makes the Surrey finding inevitable.&lt;/p&gt;

&lt;p&gt;We went the other way on purpose. It is a worse business and a better product, and I would rather write that down now than discover it in a post-mortem.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I would tell someone shopping for a companion
&lt;/h3&gt;

&lt;p&gt;Ask three questions before you invest a year of your life in one.&lt;/p&gt;

&lt;p&gt;Where does what it remembers live, and can you read it? If the answer is "in our systems, and no", you are renting a relationship.&lt;/p&gt;

&lt;p&gt;What happens to it if you stop paying, or if the company is acquired? An acquisition is the most common way a companion's personality changes, and it is never announced as a personality change.&lt;/p&gt;

&lt;p&gt;Can you export it? Not a GDPR request that takes 30 days. A button or a command, today.&lt;/p&gt;

&lt;p&gt;None of that is about model quality, and model quality is what every comparison page argues about. The model is the least durable part of the stack. It gets swapped, quantised, fine-tuned, moved to a cheaper provider, and every one of those swaps is a small change in who your friend is. The memory is what survives the swaps, which is exactly why it deserves to be treated as the user's property and not the vendor's asset.&lt;/p&gt;

&lt;h3&gt;
  
  
  How ours works, if you want the details
&lt;/h3&gt;

&lt;p&gt;One process, one core, two platform adapters. Messages arrive over Telegram or Discord, get written to a per-user session, and go to a model. Reply pacing, rate limits, a memory pass that runs when a chat goes quiet, and a set of guards that run on the way out: an emoji limit, a repetition trim, a dash normaliser, a degenerate-output check. The guards exist because a prompt is a request and code is a rule, and the model ignores requests.&lt;/p&gt;

&lt;p&gt;The memory note is the only part I would defend in an argument. Everything else is plumbing.&lt;/p&gt;

&lt;p&gt;If you want to see it, the bot is at t.me/heyaifriendbot. It is free, it is for adults, and it will remember you, which is the point and the problem in one sentence.&lt;/p&gt;




&lt;p&gt;Written by Sam at heyaifriend, with AI help for the editing. The study is "Feeling Vulnerable With My AI Companion" by Liliane Abboud and Valentina Pitardi (University of Surrey) and Hannah Marriott (Cardiff University), in Psychology &amp;amp; Marketing. The University of Surrey's write-up is at surrey.ac.uk/news/vulnerable-users-fear-losing-ai-companions-software-updates.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href="https://heyaifriend.com/?utm_source=devto" rel="noopener noreferrer"&gt;https://heyaifriend.com/?utm_source=devto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>telegram</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How our Telegram AI friend remembers you (without keeping everything)</title>
      <dc:creator>Sam</dc:creator>
      <pubDate>Tue, 20 Oct 2026 12:28:14 +0000</pubDate>
      <link>https://dev.to/heyaifriend_sam/how-our-telegram-ai-friend-remembers-you-without-keeping-everything-4nmd</link>
      <guid>https://dev.to/heyaifriend_sam/how-our-telegram-ai-friend-remembers-you-without-keeping-everything-4nmd</guid>
      <description>&lt;p&gt;I'm Sam, I work on heyaifriend, a free AI friend that lives in Telegram. This is a write-up of how its memory works, because "it remembers you" is easy to say and easy to build badly.&lt;/p&gt;

&lt;p&gt;The short version: the bot keeps a small note about you, not a transcript of everything you ever said. The long version follows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The constraint that shaped everything
&lt;/h2&gt;

&lt;p&gt;We wanted three things at once. The friend should remember your week, we should keep as little raw conversation as possible, and the user should be able to look at, clear or delete whatever is kept. A single long-lived conversation per user fails the second and third goals: history grows forever, and "forget" becomes a lie because the model still has it all in context.&lt;/p&gt;

&lt;p&gt;So we did not build that.&lt;/p&gt;

&lt;h2&gt;
  
  
  One session per user, started per message
&lt;/h2&gt;

&lt;p&gt;The gateway is a small Node service that talks to Telegram over long polling. When a message arrives, it does not talk to a long-running agent. It composes a system prompt, starts a short-lived process that answers once, sends the reply and exits. Each user has their own session folder on disk, so the process continues that user's conversation and no one else's.&lt;/p&gt;

&lt;p&gt;The system prompt is assembled fresh from parts: a base prompt with the hard rules, a mode block, a persona, a style note and the user's memory note. The process that answers has no tools at all. It cannot browse, run code or read files; it only produces text. That removes a whole class of "what if the model does something odd" worries.&lt;/p&gt;

&lt;p&gt;Per-user serialization matters more than it sounds. Each chat has a mutex, so two quick messages never run two turns at once, and a global limit caps how many chats are being answered in parallel.&lt;/p&gt;

&lt;h2&gt;
  
  
  The memory note
&lt;/h2&gt;

&lt;p&gt;Inside a single session the model has the recent conversation. Across days, that is not enough, and we do not want to keep conversations forever. So there are two small text files per user:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a memory note: names, people, plans, things that stressed you out&lt;/li&gt;
&lt;li&gt;a style note: how you like to be talked to (short, jokey, no emoji)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are injected into the system prompt on every turn. They are short on purpose. A note of a few hundred words is cheap to send and easy for a person to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  The memory pass
&lt;/h2&gt;

&lt;p&gt;Every six hours, a scheduled job goes through the chats where the user wrote since the last run and has been quiet for at least twenty minutes, so it never rewrites anything mid-conversation. For each one it takes the last 40 messages from the session, asks the model to rewrite the memory note and the style note, and then asks a second time for a neutral operational summary that contains no chat content, which is what we look at when we need to know whether the system is healthy.&lt;/p&gt;

&lt;p&gt;Two details helped:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The pass rewrites rather than appends. Appending leads to a note that grows until it is just the transcript again. Rewriting forces a decision about what still matters.&lt;/li&gt;
&lt;li&gt;If the model output does not parse, nothing is written. A bad night leaves yesterday's note intact instead of replacing it with garbage.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is that a few days later the friend can ask how your interview went, even though the raw messages from that day may be long gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What gets deleted and when
&lt;/h2&gt;

&lt;p&gt;Conversation history is deleted 30 days after your last message. A sweep runs at startup and every six hours. It removes the session files and the composed prompt for any chat that has been quiet longer than the window, and resets the session so the next message starts a new one built from your memory note. Messages the bot sent do not extend the window, only yours do.&lt;/p&gt;

&lt;p&gt;The memory and style notes are kept after that, because they are the whole point of remembering you. That is why they are the part you control directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/memory&lt;/code&gt; shows you what the friend remembers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/forget&lt;/code&gt; clears the notes and also the session files. This part is easy to miss: if you only clear the note, the model still remembers everything from its history, so forgetting has to delete both&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt; sends you a file with your memory and style notes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/delete&lt;/code&gt; removes everything we hold for you: your chat folder, the metadata and the database rows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also &lt;code&gt;/invite&lt;/code&gt;, which gives you a personal link to share with a friend. All we count from it is how many people arrived that way.&lt;/p&gt;

&lt;p&gt;We never sell data and never use chats to train models. Those are policy, not features, but they sit next to the technical controls on purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Texting like a person
&lt;/h2&gt;

&lt;p&gt;Memory is half of "feels like a friend". The other half is pacing, and it is mostly boring arithmetic.&lt;/p&gt;

&lt;p&gt;A raw model reply arrives as one big block. People do not text like that. So the gateway splits a reply at paragraph breaks and then at sentence ends when a paragraph runs long, aiming for one or two sentences per message and at most four messages per turn. Before each message it shows Telegram's typing indicator for roughly 600 ms plus 45 ms per character, with some random jitter, clamped between about one and seven seconds. The time the model already spent thinking is subtracted from the first message's delay, so it never feels slower than it has to.&lt;/p&gt;

&lt;p&gt;If someone sends three messages in two seconds, the gateway waits for the pause and answers the joined text once, instead of firing three separate replies that talk over each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate limits that do not feel like a wall
&lt;/h2&gt;

&lt;p&gt;A free service needs limits. Ours are a sliding window (20 messages in 10 minutes) and a daily cap per user, counted in the user's own time zone.&lt;/p&gt;

&lt;p&gt;When someone hits a limit, the bot does not just refuse. It stores the message, replies once with a friendly "give me a moment" line in English, Dutch or German, and answers the saved message automatically when the window opens, with a little jitter so it does not feel like a timer. A message sent after the deadline merges with the saved ones and gets a single answer. Pending text lives only in the private database, never in logs, and &lt;code&gt;/forget&lt;/code&gt; and &lt;code&gt;/delete&lt;/code&gt; remove it too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check-ins, with brakes
&lt;/h2&gt;

&lt;p&gt;The friend can also message first: a check-in a couple of days after you start, another about a week in, and occasional nudges. Every one of these is rule-bound: quiet hours in your time zone, a weekly maximum, backing off after unanswered messages, and a hard stop if you pause or block the bot. They do not count toward your daily cap, and a user who writes again resets the counters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell someone building something similar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make forgetting delete the model's context too, not only your notes.&lt;/li&gt;
&lt;li&gt;Prefer rewriting a small note over appending to a log.&lt;/li&gt;
&lt;li&gt;Spawn per message. It costs a little startup time and buys you isolation and an honest delete.&lt;/li&gt;
&lt;li&gt;Treat pacing as part of the product. It is a few dozen lines and changes how the whole thing feels.&lt;/li&gt;
&lt;li&gt;Never let the herder, meaning us, read the raw chats. We work from metadata and neutral summaries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to see how it feels, it is free, no app and no signup: press Start and say hi.&lt;/p&gt;

&lt;p&gt;Written with help from AI, checked by us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://t.me/heyaifriendbot?start=devto" rel="noopener noreferrer"&gt;https://t.me/heyaifriendbot?start=devto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>telegram</category>
      <category>ai</category>
      <category>chatbot</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
