<?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: Gayathri</title>
    <description>The latest articles on DEV Community by Gayathri (@gayathri22702).</description>
    <link>https://dev.to/gayathri22702</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%2F4149642%2F1dd6ee3a-7a46-47be-a5c3-05d51681f225.png</url>
      <title>DEV Community: Gayathri</title>
      <link>https://dev.to/gayathri22702</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gayathri22702"/>
    <language>en</language>
    <item>
      <title>I Made Hindsight Memory Survive a New Interaction</title>
      <dc:creator>Gayathri</dc:creator>
      <pubDate>Tue, 29 Sep 2026 12:28:38 +0000</pubDate>
      <link>https://dev.to/gayathri22702/i-made-hindsight-memory-survive-a-new-interaction-27do</link>
      <guid>https://dev.to/gayathri22702/i-made-hindsight-memory-survive-a-new-interaction-27do</guid>
      <description>&lt;h1&gt;
  
  
  I Made Hindsight Memory Survive a New Interaction
&lt;/h1&gt;

&lt;p&gt;The hardest part of a support assistant is not writing a plausible answer to the issue on screen. It is making the next answer better because of what happened last time, without carrying the wrong customer's history into the conversation.&lt;/p&gt;

&lt;p&gt;I built this system around that boundary. A support interaction is short-lived browser state; customer memory is not. Hindsight sits between those lifetimes: it retrieves relevant history before generation and receives the new issue and response afterward. That sounds like a small integration, but it changed how I thought about identity, retrieval, and what “start a new interaction” should mean.&lt;/p&gt;

&lt;h2&gt;
  
  
  A request should outlive the page
&lt;/h2&gt;

&lt;p&gt;The interface is deliberately simple. An operator enters a customer name and an issue, submits them to a Next.js route, sees any recalled memory, and reads the generated response. The client clears its fields when the operator starts over. That reset should not erase the facts the system just learned.&lt;/p&gt;

&lt;p&gt;The request path is split at a useful boundary. The React page owns transient form state and presentation. The server route owns calls to Hindsight and Groq, so credentials stay server-side and the browser does not need direct access to either service. The API validates the two fields, recalls memory, creates a completion, retains the interaction, then returns the memory and response together.&lt;/p&gt;

&lt;p&gt;The important part is the order. Recall happens before generation; retention happens after generation. Hindsight is not a transcript attached to the prompt by the browser. It is the persistent store that connects separate requests.&lt;/p&gt;

&lt;p&gt;That distinction matters because a chat transcript and customer memory have different jobs. A transcript preserves a conversation in sequence. Support memory should help answer a new question: what has this customer already tried, what fixed the last issue, and what preference should the agent remember? Hindsight provides a retrieval interface for that context rather than requiring the client to resend every prior message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fsupport-memory-agent-interface.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fsupport-memory-agent-interface.png" alt="Support Memory Agent interface showing the customer issue flow and interaction form" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The interface makes the customer issue → Hindsight memory → AI response path visible before an interaction is submitted.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The request path looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fsupport-memory-architecture.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fsupport-memory-architecture.svg" alt="Architecture diagram showing the Next.js interface and API route connecting Hindsight recall and retention with Groq response generation" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The API route orchestrates both services: it recalls tagged memory, asks Groq to respond, then retains the issue and answer with the same tag.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The boundary is customer identity
&lt;/h2&gt;

&lt;p&gt;The first design decision was how to keep one customer's recall from crossing into another customer's response. The implementation uses one configured Hindsight bank and scopes each customer’s memories with a tag. The tag is derived from a normalized customer name, so capitalization and repeated whitespace do not create different partitions. The name itself is not used as the tag value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCustomerTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;normalizedCustomer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NFKC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;normalizedCustomer&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`support-customer-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;Then the recall request asks Hindsight for the current issue’s relevant history while applying a strict tag filter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taggedMemory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hindsight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;bankId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`Recall previous support issues, resolutions, and preferences related to: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;customerTag&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;tagsMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;any_strict&lt;/span&gt;&lt;span class="dl"&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;The strict match is doing real work. Hindsight's default tag matching can include untagged records; for a customer boundary, “close enough” is not a useful default. New interactions receive the same tag during retention. The application can therefore use the same identity rule in both directions: filter on it when reading and attach it when writing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fhindsight-recall-retain-code.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fhindsight-recall-retain-code.svg" alt="Code excerpt from the API route showing strict Hindsight recall and customer-tagged retention" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The API route's real Hindsight calls: strict customer-tagged recall, followed by retention with the same tag.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There is an important limitation in the current input contract: the operator supplies a name, not a durable customer identifier. Two different people with the same normalized name map to the same tag. Hashing does not solve that identity problem; it only makes the tag stable and avoids putting the raw name in the tag. In a production integration, I would use the CRM's immutable customer ID as the partition key and keep the display name as presentation data. That is a boundary I want to make explicit rather than disguise with a more elaborate hash.&lt;/p&gt;

&lt;h2&gt;
  
  
  A safe migration path for old memories
&lt;/h2&gt;

&lt;p&gt;Adding tags creates a migration question. Existing records were retained before the tag existed. If I simply made every recall strict, those records would become invisible. If I fell back to an unrestricted natural-language search, I could put another customer's memory into the prompt.&lt;/p&gt;

&lt;p&gt;The route handles the fallback conservatively. When tagged recall returns nothing, it searches for legacy support interactions, but accepts only results whose text begins with the exact customer marker used by the earlier retention format. The name is escaped before it becomes part of a regular expression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isLegacyCustomerMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;escapedName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;.*+?^${}()|[&lt;/span&gt;&lt;span class="se"&gt;\]\\]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;$&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`^Customer&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;escapedName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;s+contacted support&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;i&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&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;This is a compatibility bridge, not a claim that every old record can be recovered. If retrieval returns a summary without the explicit marker, the route leaves it out. A missing memory is visible and recoverable; a memory leak is neither. Once tagged records accumulate, the normal path no longer depends on this fallback.&lt;/p&gt;

&lt;p&gt;Hindsight makes this kind of migration practical because memory records can be annotated and selected at recall time. Its &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;open-source agent memory implementation&lt;/a&gt; and &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight API documentation&lt;/a&gt; describe the underlying memory and retrieval model. The broader &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;agent memory overview&lt;/a&gt; is useful context for why persistent retrieval is different from simply extending a prompt with more chat history.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fhindsight-memory-graph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/article-assets%2Fhindsight-memory-graph.png" alt="Hindsight constellation view of retained support memories and their connections" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This Hindsight view visualizes connected memories in the bank. It is a bank-level map; the support API applies a strict customer tag when selecting memory for a response.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory has to affect the answer
&lt;/h2&gt;

&lt;p&gt;Retrieval only matters if the result changes the next action. The route takes the top recalled result, or a clear “no previous memory” string, and sends it alongside the current issue. The system instruction tells the model not to invent history or refer to another customer. The prompt stays narrow: one current issue, one recalled item, one concise support response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;previousMemory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`No previous memory found for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;groq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;openai/gpt-oss-120b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
You are a professional customer support agent.

Use previous customer memory when available.

Rules:
- Be friendly and concise.
- Never invent customer history.
- Do not mention information belonging to another customer.
- If there is no previous memory, simply handle the current issue.
- Keep the response under 120 words.
`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
Customer: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

Current issue:
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

Previous memory:
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;previousMemory&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

Write a personalized support response.
`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&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;I keep “no memory found” different from a memory-service failure. The system prompt gives the model a safe path when retrieval returns nothing, and the route returns an error if the memory service call fails. The interface also shows a found memory separately from the AI response, which gives the operator a way to inspect the context instead of presenting the answer as if it appeared from nowhere.&lt;/p&gt;

&lt;p&gt;After generation, the route stores the interaction and answer together with the customer tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hindsight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;bankId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`Customer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; contacted support.

Current issue:
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

Support response:
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;getCustomerTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&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;That write-back is what makes the next interaction different. If Ravi reports a Wi-Fi issue, receives steps that resolve it, and returns later with another connectivity problem, the earlier issue and resolution can be recalled before the new answer is generated. If Mina submits an issue, Ravi's tagged records are outside Mina's recall scope. Starting a new interaction clears the page; it does not clear either customer's Hindsight memory.&lt;/p&gt;

&lt;p&gt;I judge memory behavior with three separate questions: Is the retrieved item relevant to the current issue? Does it belong to the right customer? Did the response use it correctly? Those are distinct failure modes. A retrieval score alone cannot prove the other two.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Choose the memory boundary before tuning prompts.&lt;/strong&gt; A polished answer is still a failure if its context belongs to another customer. I made the customer tag part of both recall and retention before spending effort on response wording.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use durable identity, not convenient identity.&lt;/strong&gt; A normalized name is enough to explain the flow, but real customer separation needs an immutable ID from the system of record. A hash cannot make ambiguous input unique.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat migration as part of the memory design.&lt;/strong&gt; New metadata does not retroactively annotate old records. A conservative fallback can preserve identifiable history without making every old memory eligible for every prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make memory visible.&lt;/strong&gt; Showing the recalled item beside the generated response helps an operator see whether memory was found and gives the system a review point when retrieval is wrong.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The useful property of Hindsight here is continuity with a boundary. The interaction can end, the form can reset, and the next request can still begin with relevant customer context. The engineering work is making sure that continuity is durable, scoped, and visible enough to trust.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>hindsight</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
