How I Built a Content Agent That Learns with Hindsight A developer built ContentMind, a Next.js content-strategy agent that uses the Hindsight memory service to retain historical post performance and feedback, recall relevant memories per request, and feed them to a Groq-hosted LLM for recommendations. The system stores a synthetic dataset for a technology education brand in Supabase for auth and application data, with Hindsight providing the persistent memory layer and Groq generating the final strategy output. The developer kept the Hindsight client behind a small service layer so the rest of the app has a simple interface for retaining and recalling content. How I Built a Content Agent That Learns with Hindsight Most AI content tools can generate a good recommendation once. The harder problem is getting the next recommendation to change because of what happened before. I built ContentMind around that problem: instead of treating every content strategy request as a fresh prompt, the agent recalls relevant history, uses that context to make a decision, and retains feedback so future decisions can be informed by experience. What I Wanted ContentMind to Remember A normal prompt can tell an LLM what I want right now. It does not automatically give the model a durable record of what happened in previous interactions. For a content strategy system, that missing history matters. A useful strategist should be able to answer questions such as which topics and formats performed well, what underperformed, what the audience prefers, what feedback has already been given, and which content gaps remain. ContentMind is built around those questions. The application stores a synthetic historical dataset for a technology education brand called TechNova. The dataset contains historical posts with topics, formats, platforms, dates, views, likes, comments, shares, saves, engagement rates, outcomes, summaries, and target audiences. That information is converted into memory and stored in Hindsight. The agent can then retrieve the memories that are relevant to a new strategy question instead of starting from an empty context every time. How the System Fits Together The application is a Next.js application using the App Router, React, TypeScript, and Tailwind CSS. The server-side API routes connect three services: Browser | v Next.js / React | +--------------------+ | | v v Supabase Next.js API Routes Auth + PostgreSQL | +---- Hindsight Cloud | +---- Groq Supabase handles authentication and the application database. Hindsight provides the persistent memory layer. Groq generates the final strategy recommendation using the memories returned by Hindsight. There is no separate backend service. The Next.js API routes act as the server-side boundary, which also means the Hindsight and Groq credentials can remain server-side. The repository uses the official Hindsight client: import { HindsightClient } from '@vectorize-io/hindsight-client'; function getHindsightClient { const apiKey = process.env.HINDSIGHT API KEY; const baseUrl = process.env.HINDSIGHT BASE URL || ' https://api.hindsight.vectorize.io https://api.hindsight.vectorize.io '; if apiKey { throw new Error 'HINDSIGHT API KEY environment variable is not set' ; } return new HindsightClient { baseUrl, apiKey, } ; } I kept the Hindsight client behind a small service layer instead of calling it throughout the UI. That gave the rest of the application a simple interface for retaining and recalling content. The Memory Loop: Retain, Recall, Decide Screenshot: ContentMind demo context screen showing the memory-driven workflow. Place the demo context screenshot here. The core of ContentMind is a simple loop: Historical data / feedback | v RETAIN | v HINDSIGHT | v RECALL | v Strategy Agent | v GROQ LLM | v Recommendation | v Feedback | +------ RETAIN This is the part I found more interesting than simply connecting an LLM to a database. The application is not trying to put the entire history into every prompt. Instead, it asks the memory system for information relevant to the current question. The Hindsight service exposes that directly: export async function recallRelevantContent query: string, budget: 'low' | 'mid' | 'high' = 'mid' { const client = getHindsightClient ; const bankId = getBankId ; const response = await client.recall bankId, query, { budget, maxTokens: 4096, } ; return response.results || ; } The query becomes the retrieval signal. For example, when the user asks: What cybersecurity content should we create? ContentMind recalls memories related to cybersecurity, historical performance, audience preferences, and previously stored patterns. That means the model receives relevant experience rather than just the latest question. Seeding the Agent With Experience Before the agent can learn from new interactions, it needs some history to work with. ContentMind has a seed endpoint that prepares a memory bank with several kinds of information: Brand profile Audience preferences High-performing content patterns Underperforming content patterns Content-gap analysis Selected historical posts The seed operation uses Hindsight's batch retention rather than making a separate request for every memory: await retainBatch contentItems ; return NextResponse.json { success: true, message: Successfully seeded ${contentItems.length} memories into Hindsight , itemsSeeded: contentItems.length, breakdown: { brandProfile: 1, audiencePreferences: 1, performancePatterns: 4, contentGaps: 1, historicalPosts: topPosts.length, }, } ; The historical data is also deliberately stored as structured natural-language memory. For example, a retained historical post contains its title, topic, subtopic, format, platform, date, performance, outcome, summary, and target audience. That gives retrieval enough context to connect a question with a previous content outcome. Recall Happens Before the LLM The strategy endpoint is where the pieces meet. The API first checks that both Hindsight and Groq are configured. It then retrieves relevant memories and passes them into the strategy generator. The important part is the ordering: const memories = await recallRelevantContent query, budget as 'low' | 'mid' | 'high' ; const recommendation = await generateStrategyRecommendation query, memories, true ; I intentionally kept retrieval before generation. The LLM should not be responsible for remembering the history itself. Hindsight handles retrieval, and Groq handles the language-model reasoning over the retrieved context. That separation also makes the system easier to reason about. Turning Memories Into a Strategy Screenshot: Strategy screen showing the cybersecurity recommendation and memories used. Place the strategy screenshot here. Once Hindsight returns relevant memories, ContentMind converts them into context for the LLM. The strategy service builds a readable memory context: const memoryContext = memories.length 0 ? memories .map m, i = Memory ${i + 1}: ${m.text} .join '\n\n' : 'No specific historical memories retrieved.'; The system prompt then tells the model how to use that evidence. It explicitly instructs the model to: ground recommendations in historical memories reference patterns found in the data avoid inventing performance data acknowledge limited evidence learn from both successful and unsuccessful content identify content gaps and audience preferences The recommendation is returned as structured JSON rather than free-form text: const completion = await groq.chat.completions.create { messages: { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt }, , model: 'openai/gpt-oss-120b', temperature: 0.7, max tokens: 2000, response format: { type: 'json object' }, } ; That gives the UI predictable fields such as: recommendation reasoning suggestedTopics suggestedFormats targetAudience confidence memoriesUsed The UI can then show not only the recommendation but also how much memory influenced it. A Concrete Example Screenshot: Recall screen showing 335 memories, 45 historical posts, and 12 audience signals. Place the recall screenshot here. The clearest way to see the system is to ask the same type of question a content strategist might ask: In the seeded dataset, practical cybersecurity demonstrations perform better than generic awareness content. For example, the historical data contains practical demonstrations such as API security testing and XSS testing, while generic cybersecurity awareness posts have lower engagement in the dataset. When ContentMind recalls those patterns, the resulting recommendation becomes more specific: Focus on practical cybersecurity demonstrations and attack/defense scenarios. The interface then surfaces suggested topics such as: Penetration Testing SIEM Implementation and formats such as: Tutorial Hands-on Guide The UI also displays the number of memories used to produce the recommendation. That detail matters. Instead of presenting an answer as if it appeared from nowhere, ContentMind exposes the connection between the recommendation and the memory layer. Feedback Becomes Another Memory Recall alone is not enough. If a user says that a recommendation was useful, that information should become part of the system's future context. ContentMind has a feedback endpoint for exactly that. let feedbackContent = ''; if helpful { feedbackContent = Positive Feedback: User found the recommendation helpful. + ${feedback ? User comment: "${feedback}" : ''} ; if query { feedbackContent += Original query: "${query}" ; } } else { feedbackContent = Negative Feedback: User found the recommendation not helpful. + ${feedback User comment: "${feedback}" ? : 'No specific reason provided.' } That feedback is then retained in Hindsight: await retainFeedback feedbackContent, 'user feedback' ; Feedback becomes another memory that can participate in later retrieval. That creates a loop: Question ↓ Recall ↓ Recommendation ↓ User feedback ↓ Retain ↓ Future recall ↓ Different or more specific recommendation This is a much more useful mental model for an agent than treating memory as a static archive. Why Hindsight Was Useful Here I could have built a conventional search layer over historical posts and manually constructed a large prompt. That would solve part of the problem, but ContentMind needs to store different kinds of experience: historical posts, performance patterns, audience preferences, brand information, content gaps, and user feedback. Hindsight gives the application a common memory interface for retaining and recalling those pieces of experience. The key benefit is not simply persistence. It is that the strategy pipeline can ask for memories relevant to the current question instead of pushing the entire history into every prompt. What I Learned Adding a memory page to an AI application is not the same as building a memory-driven agent. The important question is: Does retrieved experience actually change what the agent does? In ContentMind, memory is retrieved before strategy generation, so the answer can be grounded in previous content outcomes and feedback. I initially thought the interesting part would be storing a large amount of history. It turns out that storing information is only half of the problem. The useful part is retrieving the right memories for the question being asked. A strategy agent does not need every historical post every time. It needs the subset of experience that helps answer the current question. A user's comment such as "our audience responds better to practical demonstrations" can be more valuable than another generic prompt. By retaining feedback, the system has a way to turn an interaction into future context. Groq is responsible for generating the recommendation. Hindsight is responsible for the persistent memory layer. Keeping those responsibilities separate made the architecture easier to understand and easier to change. Exposing memory usage alongside the recommendation makes the source of the answer easier to understand. The user can see that the response is grounded in recalled experience rather than appearing from nowhere. A Note on the Current Architecture ContentMind uses Supabase for authentication and PostgreSQL application data, with Row Level Security policies protecting workspace data. The Hindsight integration is organized around a configurable HINDSIGHT BANK ID. For a larger multi-user deployment, I would scope that bank to the authenticated workspace or user as well, so independent customers never share an agent memory bank. Persistent memory introduces an isolation problem that deserves the same attention as ordinary application data. Conclusion The most important change in ContentMind was changing the assumption that every strategy request should start from zero. With Hindsight in the loop, ContentMind can retain historical content knowledge and feedback, recall relevant experience, and use that context to generate a strategy. The resulting architecture is simple: ┌───────────────┐ │ ContentMind │ └───────┬───────┘ | ┌───────▼───────┐ │ Next.js │ └───┬───────┬───┘ | | ┌────────▼─┐ ┌─▼────────┐ │ Supabase │ │ Groq │ │ Auth + DB│ │ LLM │ └──────────┘ └────┬─────┘ | ┌──────▼──────┐ │ Hindsight │ │ Recall │ │ Retain │ │ Reflect │ └──────┬──────┘ | Future decisions The idea I would carry into other agent systems is straightforward: if an agent is expected to improve over time, memory cannot be an afterthought. It needs to sit directly in the path between what the agent has experienced and what it decides to do next. Further Reading Hindsight GitHub Hindsight documentation Vectorize agent memory Project ContentMind GitHub repository : - https://github.com/saivarshith9347/contentmind.git https://github.com/saivarshith9347/contentmind.git Live ContentMind application:- https://contentmind-sigma.vercel.app/ https://contentmind-sigma.vercel.app/