{"slug": "how-i-built-a-content-agent-that-learns-with-hindsight", "title": "How I Built a Content Agent That Learns with Hindsight", "summary": "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.", "body_md": "How I Built a Content Agent That Learns with Hindsight\n\nMost AI content tools can generate a good recommendation once. The harder problem is getting the next recommendation to change because of what happened before.\n\nI 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.\n\nWhat I Wanted ContentMind to Remember\n\nA 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.\n\nFor a content strategy system, that missing history matters.\n\nA 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.\n\nContentMind is built around those questions.\n\nThe 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.\n\nThat 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.\n\nHow the System Fits Together\n\nThe application is a Next.js application using the App Router, React, TypeScript, and Tailwind CSS.\n\nThe server-side API routes connect three services:\n\nBrowser\n\n   |\n\n   v\n\nNext.js / React\n\n   |\n\n   +--------------------+\n\n   |                    |\n\n   v                    v\n\nSupabase             Next.js API Routes\n\nAuth + PostgreSQL         |\n\n                          +---- Hindsight Cloud\n\n                          |\n\n                          +---- Groq\n\nSupabase handles authentication and the application database. Hindsight provides the persistent memory layer. Groq generates the final strategy recommendation using the memories returned by Hindsight.\n\nThere 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.\n\nThe repository uses the official Hindsight client:\n\nimport { HindsightClient } from '@vectorize-io/hindsight-client';\n\nfunction getHindsightClient() {\n\n  const apiKey = process.env.HINDSIGHT_API_KEY;\n\n  const baseUrl =\n\n    process.env.HINDSIGHT_BASE_URL ||\n\n    '[https://api.hindsight.vectorize.io](https://api.hindsight.vectorize.io)';\n\nif (!apiKey) {\n\n    throw new Error(\n\n      'HINDSIGHT_API_KEY environment variable is not set'\n\n    );\n\n  }\n\nreturn new HindsightClient({\n\n    baseUrl,\n\n    apiKey,\n\n  });\n\n}\n\nI 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.\n\nThe Memory Loop: Retain, Recall, Decide\n\nScreenshot: ContentMind demo context screen showing the memory-driven workflow. Place the demo context screenshot here.\n\nThe core of ContentMind is a simple loop:\n\nHistorical data / feedback\n\n          |\n\n          v\n\n       RETAIN\n\n          |\n\n          v\n\n       HINDSIGHT\n\n          |\n\n          v\n\n        RECALL\n\n          |\n\n          v\n\n     Strategy Agent\n\n          |\n\n          v\n\n       GROQ LLM\n\n          |\n\n          v\n\n     Recommendation\n\n          |\n\n          v\n\n       Feedback\n\n          |\n\n          +------> RETAIN\n\nThis is the part I found more interesting than simply connecting an LLM to a database.\n\nThe 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.\n\nThe Hindsight service exposes that directly:\n\nexport async function recallRelevantContent(\n\n  query: string,\n\n  budget: 'low' | 'mid' | 'high' = 'mid'\n\n) {\n\n  const client = getHindsightClient();\n\n  const bankId = getBankId();\n\nconst response = await client.recall(bankId, query, {\n\n    budget,\n\n    maxTokens: 4096,\n\n  });\n\nreturn response.results || [];\n\n}\n\nThe query becomes the retrieval signal.\n\nFor example, when the user asks:\n\nWhat cybersecurity content should we create?\n\nContentMind recalls memories related to cybersecurity, historical performance, audience preferences, and previously stored patterns.\n\nThat means the model receives relevant experience rather than just the latest question.\n\nSeeding the Agent With Experience\n\nBefore the agent can learn from new interactions, it needs some history to work with.\n\nContentMind has a seed endpoint that prepares a memory bank with several kinds of information:\n\nBrand profile\n\nAudience preferences\n\nHigh-performing content patterns\n\nUnderperforming content patterns\n\nContent-gap analysis\n\nSelected historical posts\n\nThe seed operation uses Hindsight's batch retention rather than making a separate request for every memory:\n\nawait retainBatch(contentItems);\n\nreturn NextResponse.json({\n\n  success: true,\n\n  message: `Successfully seeded ${contentItems.length} memories into Hindsight`,\n\n  itemsSeeded: contentItems.length,\n\n  breakdown: {\n\n    brandProfile: 1,\n\n    audiencePreferences: 1,\n\n    performancePatterns: 4,\n\n    contentGaps: 1,\n\n    historicalPosts: topPosts.length,\n\n  },\n\n});\n\nThe historical data is also deliberately stored as structured natural-language memory.\n\nFor example, a retained historical post contains its title, topic, subtopic, format, platform, date, performance, outcome, summary, and target audience.\n\nThat gives retrieval enough context to connect a question with a previous content outcome.\n\nRecall Happens Before the LLM\n\nThe strategy endpoint is where the pieces meet.\n\nThe API first checks that both Hindsight and Groq are configured. It then retrieves relevant memories and passes them into the strategy generator.\n\nThe important part is the ordering:\n\nconst memories = await recallRelevantContent(\n\n  query,\n\n  budget as 'low' | 'mid' | 'high'\n\n);\n\nconst recommendation =\n\n  await generateStrategyRecommendation(\n\n    query,\n\n    memories,\n\n    true\n\n  );\n\nI intentionally kept retrieval before generation.\n\nThe LLM should not be responsible for remembering the history itself. Hindsight handles retrieval, and Groq handles the language-model reasoning over the retrieved context.\n\nThat separation also makes the system easier to reason about.\n\nTurning Memories Into a Strategy\n\nScreenshot: Strategy screen showing the cybersecurity recommendation and memories used. Place the strategy screenshot here.\n\nOnce Hindsight returns relevant memories, ContentMind converts them into context for the LLM.\n\nThe strategy service builds a readable memory context:\n\nconst memoryContext = memories.length > 0\n\n  ? memories\n\n      .map((m, i) => `Memory ${i + 1}: ${m.text}`)\n\n      .join('\\n\\n')\n\n  : 'No specific historical memories retrieved.';\n\nThe system prompt then tells the model how to use that evidence.\n\nIt explicitly instructs the model to:\n\nground recommendations in historical memories\n\nreference patterns found in the data\n\navoid inventing performance data\n\nacknowledge limited evidence\n\nlearn from both successful and unsuccessful content\n\nidentify content gaps and audience preferences\n\nThe recommendation is returned as structured JSON rather than free-form text:\n\nconst completion =\n\n  await groq.chat.completions.create({\n\n    messages: [\n\n      { role: 'system', content: systemPrompt },\n\n      { role: 'user', content: userPrompt },\n\n    ],\n\n    model: 'openai/gpt-oss-120b',\n\n    temperature: 0.7,\n\n    max_tokens: 2000,\n\n    response_format: { type: 'json_object' },\n\n  });\n\nThat gives the UI predictable fields such as:\n\nrecommendation\n\nreasoning\n\nsuggestedTopics\n\nsuggestedFormats\n\ntargetAudience\n\nconfidence\n\nmemoriesUsed\n\nThe UI can then show not only the recommendation but also how much memory influenced it.\n\nA Concrete Example\n\nScreenshot: Recall screen showing 335 memories, 45 historical posts, and 12 audience signals. Place the recall screenshot here.\n\nThe clearest way to see the system is to ask the same type of question a content strategist might ask:\n\nIn the seeded dataset, practical cybersecurity demonstrations perform better than generic awareness content.\n\nFor 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.\n\nWhen ContentMind recalls those patterns, the resulting recommendation becomes more specific:\n\nFocus on practical cybersecurity demonstrations and attack/defense scenarios.\n\nThe interface then surfaces suggested topics such as:\n\nPenetration Testing\n\nSIEM Implementation\n\nand formats such as:\n\nTutorial\n\nHands-on Guide\n\nThe UI also displays the number of memories used to produce the recommendation.\n\nThat detail matters.\n\nInstead of presenting an answer as if it appeared from nowhere, ContentMind exposes the connection between the recommendation and the memory layer.\n\nFeedback Becomes Another Memory\n\nRecall alone is not enough.\n\nIf a user says that a recommendation was useful, that information should become part of the system's future context.\n\nContentMind has a feedback endpoint for exactly that.\n\nlet feedbackContent = '';\n\nif (helpful) {\n\n  feedbackContent =\n\n`Positive Feedback: User found the recommendation helpful.` +\n\n`${feedback ?` User comment: \"${feedback}\"`: ''}`;\n\nif (query) {\n\n    feedbackContent +=\n\n`Original query: \"${query}\"`;\n\n  }\n\n} else {\n\n  feedbackContent =\n\n`Negative Feedback: User found the recommendation not helpful.` +\n\n`${feedback` User comment: \"${feedback}\"\n\n      ?\n\n      : 'No specific reason provided.'\n\n    }\n\nThat feedback is then retained in Hindsight:\n\nawait retainFeedback(\n\n  feedbackContent,\n\n  'user_feedback'\n\n);\n\nFeedback becomes another memory that can participate in later retrieval.\n\nThat creates a loop:\n\nQuestion\n\n   ↓\n\nRecall\n\n   ↓\n\nRecommendation\n\n   ↓\n\nUser feedback\n\n   ↓\n\nRetain\n\n   ↓\n\nFuture recall\n\n   ↓\n\nDifferent or more specific recommendation\n\nThis is a much more useful mental model for an agent than treating memory as a static archive.\n\nWhy Hindsight Was Useful Here\n\nI 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.\n\nHindsight gives the application a common memory interface for retaining and recalling those pieces of experience.\n\nThe 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.\n\nWhat I Learned\n\nAdding a memory page to an AI application is not the same as building a memory-driven agent.\n\nThe important question is:\n\nDoes retrieved experience actually change what the agent does?\n\nIn ContentMind, memory is retrieved before strategy generation, so the answer can be grounded in previous content outcomes and feedback.\n\nI initially thought the interesting part would be storing a large amount of history.\n\nIt turns out that storing information is only half of the problem.\n\nThe useful part is retrieving the right memories for the question being asked.\n\nA strategy agent does not need every historical post every time. It needs the subset of experience that helps answer the current question.\n\nA user's comment such as \"our audience responds better to practical demonstrations\" can be more valuable than another generic prompt.\n\nBy retaining feedback, the system has a way to turn an interaction into future context.\n\nGroq is responsible for generating the recommendation. Hindsight is responsible for the persistent memory layer.\n\nKeeping those responsibilities separate made the architecture easier to understand and easier to change.\n\nExposing 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.\n\nA Note on the Current Architecture\n\nContentMind uses Supabase for authentication and PostgreSQL application data, with Row Level Security policies protecting workspace data.\n\nThe 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.\n\nConclusion\n\nThe most important change in ContentMind was changing the assumption that every strategy request should start from zero.\n\nWith Hindsight in the loop, ContentMind can retain historical content knowledge and feedback, recall relevant experience, and use that context to generate a strategy.\n\nThe resulting architecture is simple:\n\n```\n         ┌───────────────┐\n         │   ContentMind │\n         └───────┬───────┘\n                 |\n         ┌───────▼───────┐\n         │    Next.js    │\n         └───┬───────┬───┘\n             |       |\n    ┌────────▼─┐   ┌─▼────────┐\n    │ Supabase │   │   Groq   │\n    │ Auth + DB│   │   LLM    │\n    └──────────┘   └────┬─────┘\n                        |\n                 ┌──────▼──────┐\n                 │  Hindsight  │\n                 │ Recall      │\n                 │ Retain      │\n                 │ Reflect     │\n                 └──────┬──────┘\n                        |\n                 Future decisions\n```\n\nThe 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.\n\nFurther Reading\n\nHindsight GitHub\n\nHindsight documentation\n\nVectorize agent memory\n\nProject\n\nContentMind GitHub repository : -[https://github.com/saivarshith9347/contentmind.git](https://github.com/saivarshith9347/contentmind.git)\n\nLive ContentMind application:-[https://contentmind-sigma.vercel.app/](https://contentmind-sigma.vercel.app/)", "url": "https://wpnews.pro/news/how-i-built-a-content-agent-that-learns-with-hindsight", "canonical_source": "https://dev.to/varshith_07e1cc3c6ee80c38/how-i-built-a-content-agent-that-learns-with-hindsight-2696", "published_at": "2026-09-29 03:39:03+00:00", "updated_at": "2026-09-29 03:46:40.905126+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "large-language-models", "ai-products", "developer-tools"], "entities": ["ContentMind", "Hindsight", "Vectorize", "Groq", "Supabase", "Next.js", "TechNova"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/how-i-built-a-content-agent-that-learns-with-hindsight", "markdown": "https://wpnews.pro/news/how-i-built-a-content-agent-that-learns-with-hindsight.md", "text": "https://wpnews.pro/news/how-i-built-a-content-agent-that-learns-with-hindsight.txt", "jsonld": "https://wpnews.pro/news/how-i-built-a-content-agent-that-learns-with-hindsight.jsonld"}}